Skip to content

Commit 9fe9663

Browse files
Marc Zyngieroupton
authored andcommitted
KVM: arm64: Expose GICv3 EL2 registers via KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS
Expose all the GICv3 EL2 registers through the usual GICv3 save/restore interface, making it possible for a VMM to access the EL2 state. Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20250714122634.3334816-7-maz@kernel.org Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
1 parent 1d14c97 commit 9fe9663

1 file changed

Lines changed: 113 additions & 0 deletions

File tree

arch/arm64/kvm/vgic-sys-reg-v3.c

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,91 @@ static int get_gic_sre(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
297297
return 0;
298298
}
299299

300+
static int set_gic_ich_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
301+
u64 val)
302+
{
303+
__vcpu_assign_sys_reg(vcpu, r->reg, val);
304+
return 0;
305+
}
306+
307+
static int get_gic_ich_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
308+
u64 *val)
309+
{
310+
*val = __vcpu_sys_reg(vcpu, r->reg);
311+
return 0;
312+
}
313+
314+
static int set_gic_ich_apr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
315+
u64 val)
316+
{
317+
u8 idx = r->Op2 & 3;
318+
319+
if (idx > vgic_v3_max_apr_idx(vcpu))
320+
return -EINVAL;
321+
322+
return set_gic_ich_reg(vcpu, r, val);
323+
}
324+
325+
static int get_gic_ich_apr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
326+
u64 *val)
327+
{
328+
u8 idx = r->Op2 & 3;
329+
330+
if (idx > vgic_v3_max_apr_idx(vcpu))
331+
return -EINVAL;
332+
333+
return get_gic_ich_reg(vcpu, r, val);
334+
}
335+
336+
static int set_gic_icc_sre(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
337+
u64 val)
338+
{
339+
if (val != KVM_ICC_SRE_EL2)
340+
return -EINVAL;
341+
return 0;
342+
}
343+
344+
static int get_gic_icc_sre(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
345+
u64 *val)
346+
{
347+
*val = KVM_ICC_SRE_EL2;
348+
return 0;
349+
}
350+
351+
static int set_gic_ich_vtr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
352+
u64 val)
353+
{
354+
if (val != kvm_get_guest_vtr_el2())
355+
return -EINVAL;
356+
return 0;
357+
}
358+
359+
static int get_gic_ich_vtr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
360+
u64 *val)
361+
{
362+
*val = kvm_get_guest_vtr_el2();
363+
return 0;
364+
}
365+
366+
static unsigned int el2_visibility(const struct kvm_vcpu *vcpu,
367+
const struct sys_reg_desc *rd)
368+
{
369+
return vcpu_has_nv(vcpu) ? 0 : REG_HIDDEN;
370+
}
371+
372+
#define __EL2_REG(r, acc, i) \
373+
{ \
374+
SYS_DESC(SYS_ ## r), \
375+
.get_user = get_gic_ ## acc, \
376+
.set_user = set_gic_ ## acc, \
377+
.reg = i, \
378+
.visibility = el2_visibility, \
379+
}
380+
381+
#define EL2_REG(r, acc) __EL2_REG(r, acc, r)
382+
383+
#define EL2_REG_RO(r, acc) __EL2_REG(r, acc, 0)
384+
300385
static const struct sys_reg_desc gic_v3_icc_reg_descs[] = {
301386
{ SYS_DESC(SYS_ICC_PMR_EL1),
302387
.set_user = set_gic_pmr, .get_user = get_gic_pmr, },
@@ -328,6 +413,34 @@ static const struct sys_reg_desc gic_v3_icc_reg_descs[] = {
328413
.set_user = set_gic_grpen0, .get_user = get_gic_grpen0, },
329414
{ SYS_DESC(SYS_ICC_IGRPEN1_EL1),
330415
.set_user = set_gic_grpen1, .get_user = get_gic_grpen1, },
416+
EL2_REG(ICH_AP0R0_EL2, ich_apr),
417+
EL2_REG(ICH_AP0R1_EL2, ich_apr),
418+
EL2_REG(ICH_AP0R2_EL2, ich_apr),
419+
EL2_REG(ICH_AP0R3_EL2, ich_apr),
420+
EL2_REG(ICH_AP1R0_EL2, ich_apr),
421+
EL2_REG(ICH_AP1R1_EL2, ich_apr),
422+
EL2_REG(ICH_AP1R2_EL2, ich_apr),
423+
EL2_REG(ICH_AP1R3_EL2, ich_apr),
424+
EL2_REG(ICH_HCR_EL2, ich_reg),
425+
EL2_REG_RO(ICC_SRE_EL2, icc_sre),
426+
EL2_REG_RO(ICH_VTR_EL2, ich_vtr),
427+
EL2_REG(ICH_VMCR_EL2, ich_reg),
428+
EL2_REG(ICH_LR0_EL2, ich_reg),
429+
EL2_REG(ICH_LR1_EL2, ich_reg),
430+
EL2_REG(ICH_LR2_EL2, ich_reg),
431+
EL2_REG(ICH_LR3_EL2, ich_reg),
432+
EL2_REG(ICH_LR4_EL2, ich_reg),
433+
EL2_REG(ICH_LR5_EL2, ich_reg),
434+
EL2_REG(ICH_LR6_EL2, ich_reg),
435+
EL2_REG(ICH_LR7_EL2, ich_reg),
436+
EL2_REG(ICH_LR8_EL2, ich_reg),
437+
EL2_REG(ICH_LR9_EL2, ich_reg),
438+
EL2_REG(ICH_LR10_EL2, ich_reg),
439+
EL2_REG(ICH_LR11_EL2, ich_reg),
440+
EL2_REG(ICH_LR12_EL2, ich_reg),
441+
EL2_REG(ICH_LR13_EL2, ich_reg),
442+
EL2_REG(ICH_LR14_EL2, ich_reg),
443+
EL2_REG(ICH_LR15_EL2, ich_reg),
331444
};
332445

333446
static u64 attr_to_id(u64 attr)

0 commit comments

Comments
 (0)