Skip to content

Commit a7f49a9

Browse files
committed
Merge branch 'kvm-arm64/el2-reg-visibility' into kvmarm/next
* kvm-arm64/el2-reg-visibility: : Fixes to EL2 register visibility, courtesy of Marc Zyngier : : - Expose EL2 VGICv3 registers via the VGIC attributes accessor, not the : KVM_{GET,SET}_ONE_REG ioctls : : - Condition visibility of FGT registers on the presence of FEAT_FGT in : the VM KVM: arm64: selftest: vgic-v3: Add basic GICv3 sysreg userspace access test KVM: arm64: Enforce the sorting of the GICv3 system register table KVM: arm64: Clarify the check for reset callback in check_sysreg_table() KVM: arm64: vgic-v3: Fix ordering of ICH_HCR_EL2 KVM: arm64: Document registers exposed via KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS KVM: arm64: selftests: get-reg-list: Add base EL2 registers KVM: arm64: selftests: get-reg-list: Simplify feature dependency KVM: arm64: Advertise FGT2 registers to userspace KVM: arm64: Condition FGT registers on feature availability KVM: arm64: Expose GICv3 EL2 registers via KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS KVM: arm64: Let GICv3 save/restore honor visibility attribute KVM: arm64: Define helper for ICH_VTR_EL2 KVM: arm64: Define constant value for ICC_SRE_EL2 KVM: arm64: Don't advertise ICH_*_EL2 registers through GET_ONE_REG KVM: arm64: Make RVBAR_EL2 accesses UNDEF Signed-off-by: Oliver Upton <[email protected]>
2 parents d9b9fa2 + 3435bd7 commit a7f49a9

File tree

6 files changed

+669
-94
lines changed

6 files changed

+669
-94
lines changed

Documentation/virt/kvm/devices/arm-vgic-v3.rst

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -202,16 +202,69 @@ Groups:
202202
KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS accesses the CPU interface registers for the
203203
CPU specified by the mpidr field.
204204

205-
CPU interface registers access is not implemented for AArch32 mode.
206-
Error -ENXIO is returned when accessed in AArch32 mode.
205+
The available registers are:
206+
207+
=============== ====================================================
208+
ICC_PMR_EL1
209+
ICC_BPR0_EL1
210+
ICC_AP0R0_EL1
211+
ICC_AP0R1_EL1 when the host implements at least 6 bits of priority
212+
ICC_AP0R2_EL1 when the host implements 7 bits of priority
213+
ICC_AP0R3_EL1 when the host implements 7 bits of priority
214+
ICC_AP1R0_EL1
215+
ICC_AP1R1_EL1 when the host implements at least 6 bits of priority
216+
ICC_AP1R2_EL1 when the host implements 7 bits of priority
217+
ICC_AP1R3_EL1 when the host implements 7 bits of priority
218+
ICC_BPR1_EL1
219+
ICC_CTLR_EL1
220+
ICC_SRE_EL1
221+
ICC_IGRPEN0_EL1
222+
ICC_IGRPEN1_EL1
223+
=============== ====================================================
224+
225+
When EL2 is available for the guest, these registers are also available:
226+
227+
============= ====================================================
228+
ICH_AP0R0_EL2
229+
ICH_AP0R1_EL2 when the host implements at least 6 bits of priority
230+
ICH_AP0R2_EL2 when the host implements 7 bits of priority
231+
ICH_AP0R3_EL2 when the host implements 7 bits of priority
232+
ICH_AP1R0_EL2
233+
ICH_AP1R1_EL2 when the host implements at least 6 bits of priority
234+
ICH_AP1R2_EL2 when the host implements 7 bits of priority
235+
ICH_AP1R3_EL2 when the host implements 7 bits of priority
236+
ICH_HCR_EL2
237+
ICC_SRE_EL2
238+
ICH_VTR_EL2
239+
ICH_VMCR_EL2
240+
ICH_LR0_EL2
241+
ICH_LR1_EL2
242+
ICH_LR2_EL2
243+
ICH_LR3_EL2
244+
ICH_LR4_EL2
245+
ICH_LR5_EL2
246+
ICH_LR6_EL2
247+
ICH_LR7_EL2
248+
ICH_LR8_EL2
249+
ICH_LR9_EL2
250+
ICH_LR10_EL2
251+
ICH_LR11_EL2
252+
ICH_LR12_EL2
253+
ICH_LR13_EL2
254+
ICH_LR14_EL2
255+
ICH_LR15_EL2
256+
============= ====================================================
257+
258+
CPU interface registers are only described using the AArch64
259+
encoding.
207260

208261
Errors:
209262

210-
======= =====================================================
211-
-ENXIO Getting or setting this register is not yet supported
263+
======= =================================================
264+
-ENXIO Getting or setting this register is not supported
212265
-EBUSY VCPU is running
213266
-EINVAL Invalid mpidr or register value supplied
214-
======= =====================================================
267+
======= =================================================
215268

216269

217270
KVM_DEV_ARM_VGIC_GRP_NR_IRQS

arch/arm64/kvm/sys_regs.c

Lines changed: 82 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ static bool get_el2_to_el1_mapping(unsigned int reg,
108108
PURE_EL2_SYSREG( HACR_EL2 );
109109
PURE_EL2_SYSREG( VTTBR_EL2 );
110110
PURE_EL2_SYSREG( VTCR_EL2 );
111-
PURE_EL2_SYSREG( RVBAR_EL2 );
112111
PURE_EL2_SYSREG( TPIDR_EL2 );
113112
PURE_EL2_SYSREG( HPFAR_EL2 );
114113
PURE_EL2_SYSREG( HCRX_EL2 );
@@ -534,8 +533,7 @@ static bool access_gic_sre(struct kvm_vcpu *vcpu,
534533
return ignore_write(vcpu, p);
535534

536535
if (p->Op1 == 4) { /* ICC_SRE_EL2 */
537-
p->regval = (ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_SRE |
538-
ICC_SRE_EL1_DIB | ICC_SRE_EL1_DFB);
536+
p->regval = KVM_ICC_SRE_EL2;
539537
} else { /* ICC_SRE_EL1 */
540538
p->regval = vcpu->arch.vgic_cpu.vgic_v3.vgic_sre;
541539
}
@@ -774,6 +772,12 @@ static u64 reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
774772
return mpidr;
775773
}
776774

775+
static unsigned int hidden_visibility(const struct kvm_vcpu *vcpu,
776+
const struct sys_reg_desc *r)
777+
{
778+
return REG_HIDDEN;
779+
}
780+
777781
static unsigned int pmu_visibility(const struct kvm_vcpu *vcpu,
778782
const struct sys_reg_desc *r)
779783
{
@@ -2335,6 +2339,10 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu,
23352339
EL2_REG_FILTERED(name, acc, rst, v, el2_visibility)
23362340

23372341
#define EL2_REG_VNCR(name, rst, v) EL2_REG(name, bad_vncr_trap, rst, v)
2342+
#define EL2_REG_VNCR_FILT(name, vis) \
2343+
EL2_REG_FILTERED(name, bad_vncr_trap, reset_val, 0, vis)
2344+
#define EL2_REG_VNCR_GICv3(name) \
2345+
EL2_REG_VNCR_FILT(name, hidden_visibility)
23382346
#define EL2_REG_REDIR(name, rst, v) EL2_REG(name, bad_redir_trap, rst, v)
23392347

23402348
/*
@@ -2538,11 +2546,7 @@ static bool access_gic_vtr(struct kvm_vcpu *vcpu,
25382546
if (p->is_write)
25392547
return write_to_read_only(vcpu, p, r);
25402548

2541-
p->regval = kvm_vgic_global_state.ich_vtr_el2;
2542-
p->regval &= ~(ICH_VTR_EL2_DVIM |
2543-
ICH_VTR_EL2_A3V |
2544-
ICH_VTR_EL2_IDbits);
2545-
p->regval |= ICH_VTR_EL2_nV4;
2549+
p->regval = kvm_get_guest_vtr_el2();
25462550

25472551
return true;
25482552
}
@@ -2613,6 +2617,26 @@ static unsigned int tcr2_el2_visibility(const struct kvm_vcpu *vcpu,
26132617
return __el2_visibility(vcpu, rd, tcr2_visibility);
26142618
}
26152619

2620+
static unsigned int fgt2_visibility(const struct kvm_vcpu *vcpu,
2621+
const struct sys_reg_desc *rd)
2622+
{
2623+
if (el2_visibility(vcpu, rd) == 0 &&
2624+
kvm_has_feat(vcpu->kvm, ID_AA64MMFR0_EL1, FGT, FGT2))
2625+
return 0;
2626+
2627+
return REG_HIDDEN;
2628+
}
2629+
2630+
static unsigned int fgt_visibility(const struct kvm_vcpu *vcpu,
2631+
const struct sys_reg_desc *rd)
2632+
{
2633+
if (el2_visibility(vcpu, rd) == 0 &&
2634+
kvm_has_feat(vcpu->kvm, ID_AA64MMFR0_EL1, FGT, IMP))
2635+
return 0;
2636+
2637+
return REG_HIDDEN;
2638+
}
2639+
26162640
static unsigned int s1pie_visibility(const struct kvm_vcpu *vcpu,
26172641
const struct sys_reg_desc *rd)
26182642
{
@@ -3352,8 +3376,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
33523376
EL2_REG(MDCR_EL2, access_mdcr, reset_mdcr, 0),
33533377
EL2_REG(CPTR_EL2, access_rw, reset_val, CPTR_NVHE_EL2_RES1),
33543378
EL2_REG_VNCR(HSTR_EL2, reset_val, 0),
3355-
EL2_REG_VNCR(HFGRTR_EL2, reset_val, 0),
3356-
EL2_REG_VNCR(HFGWTR_EL2, reset_val, 0),
3379+
EL2_REG_VNCR_FILT(HFGRTR_EL2, fgt_visibility),
3380+
EL2_REG_VNCR_FILT(HFGWTR_EL2, fgt_visibility),
33573381
EL2_REG_VNCR(HFGITR_EL2, reset_val, 0),
33583382
EL2_REG_VNCR(HACR_EL2, reset_val, 0),
33593383

@@ -3373,9 +3397,14 @@ static const struct sys_reg_desc sys_reg_descs[] = {
33733397
vncr_el2_visibility),
33743398

33753399
{ SYS_DESC(SYS_DACR32_EL2), undef_access, reset_unknown, DACR32_EL2 },
3376-
EL2_REG_VNCR(HDFGRTR_EL2, reset_val, 0),
3377-
EL2_REG_VNCR(HDFGWTR_EL2, reset_val, 0),
3378-
EL2_REG_VNCR(HAFGRTR_EL2, reset_val, 0),
3400+
EL2_REG_VNCR_FILT(HDFGRTR2_EL2, fgt2_visibility),
3401+
EL2_REG_VNCR_FILT(HDFGWTR2_EL2, fgt2_visibility),
3402+
EL2_REG_VNCR_FILT(HFGRTR2_EL2, fgt2_visibility),
3403+
EL2_REG_VNCR_FILT(HFGWTR2_EL2, fgt2_visibility),
3404+
EL2_REG_VNCR_FILT(HDFGRTR_EL2, fgt_visibility),
3405+
EL2_REG_VNCR_FILT(HDFGWTR_EL2, fgt_visibility),
3406+
EL2_REG_VNCR_FILT(HAFGRTR_EL2, fgt_visibility),
3407+
EL2_REG_VNCR_FILT(HFGITR2_EL2, fgt2_visibility),
33793408
EL2_REG_REDIR(SPSR_EL2, reset_val, 0),
33803409
EL2_REG_REDIR(ELR_EL2, reset_val, 0),
33813410
{ SYS_DESC(SYS_SP_EL1), access_sp_el1},
@@ -3417,44 +3446,44 @@ static const struct sys_reg_desc sys_reg_descs[] = {
34173446
{ SYS_DESC(SYS_MPAMVPM7_EL2), undef_access },
34183447

34193448
EL2_REG(VBAR_EL2, access_rw, reset_val, 0),
3420-
EL2_REG(RVBAR_EL2, access_rw, reset_val, 0),
3449+
{ SYS_DESC(SYS_RVBAR_EL2), undef_access },
34213450
{ SYS_DESC(SYS_RMR_EL2), undef_access },
34223451
EL2_REG_VNCR(VDISR_EL2, reset_unknown, 0),
34233452

3424-
EL2_REG_VNCR(ICH_AP0R0_EL2, reset_val, 0),
3425-
EL2_REG_VNCR(ICH_AP0R1_EL2, reset_val, 0),
3426-
EL2_REG_VNCR(ICH_AP0R2_EL2, reset_val, 0),
3427-
EL2_REG_VNCR(ICH_AP0R3_EL2, reset_val, 0),
3428-
EL2_REG_VNCR(ICH_AP1R0_EL2, reset_val, 0),
3429-
EL2_REG_VNCR(ICH_AP1R1_EL2, reset_val, 0),
3430-
EL2_REG_VNCR(ICH_AP1R2_EL2, reset_val, 0),
3431-
EL2_REG_VNCR(ICH_AP1R3_EL2, reset_val, 0),
3453+
EL2_REG_VNCR_GICv3(ICH_AP0R0_EL2),
3454+
EL2_REG_VNCR_GICv3(ICH_AP0R1_EL2),
3455+
EL2_REG_VNCR_GICv3(ICH_AP0R2_EL2),
3456+
EL2_REG_VNCR_GICv3(ICH_AP0R3_EL2),
3457+
EL2_REG_VNCR_GICv3(ICH_AP1R0_EL2),
3458+
EL2_REG_VNCR_GICv3(ICH_AP1R1_EL2),
3459+
EL2_REG_VNCR_GICv3(ICH_AP1R2_EL2),
3460+
EL2_REG_VNCR_GICv3(ICH_AP1R3_EL2),
34323461

34333462
{ SYS_DESC(SYS_ICC_SRE_EL2), access_gic_sre },
34343463

3435-
EL2_REG_VNCR(ICH_HCR_EL2, reset_val, 0),
3464+
EL2_REG_VNCR_GICv3(ICH_HCR_EL2),
34363465
{ SYS_DESC(SYS_ICH_VTR_EL2), access_gic_vtr },
34373466
{ SYS_DESC(SYS_ICH_MISR_EL2), access_gic_misr },
34383467
{ SYS_DESC(SYS_ICH_EISR_EL2), access_gic_eisr },
34393468
{ SYS_DESC(SYS_ICH_ELRSR_EL2), access_gic_elrsr },
3440-
EL2_REG_VNCR(ICH_VMCR_EL2, reset_val, 0),
3441-
3442-
EL2_REG_VNCR(ICH_LR0_EL2, reset_val, 0),
3443-
EL2_REG_VNCR(ICH_LR1_EL2, reset_val, 0),
3444-
EL2_REG_VNCR(ICH_LR2_EL2, reset_val, 0),
3445-
EL2_REG_VNCR(ICH_LR3_EL2, reset_val, 0),
3446-
EL2_REG_VNCR(ICH_LR4_EL2, reset_val, 0),
3447-
EL2_REG_VNCR(ICH_LR5_EL2, reset_val, 0),
3448-
EL2_REG_VNCR(ICH_LR6_EL2, reset_val, 0),
3449-
EL2_REG_VNCR(ICH_LR7_EL2, reset_val, 0),
3450-
EL2_REG_VNCR(ICH_LR8_EL2, reset_val, 0),
3451-
EL2_REG_VNCR(ICH_LR9_EL2, reset_val, 0),
3452-
EL2_REG_VNCR(ICH_LR10_EL2, reset_val, 0),
3453-
EL2_REG_VNCR(ICH_LR11_EL2, reset_val, 0),
3454-
EL2_REG_VNCR(ICH_LR12_EL2, reset_val, 0),
3455-
EL2_REG_VNCR(ICH_LR13_EL2, reset_val, 0),
3456-
EL2_REG_VNCR(ICH_LR14_EL2, reset_val, 0),
3457-
EL2_REG_VNCR(ICH_LR15_EL2, reset_val, 0),
3469+
EL2_REG_VNCR_GICv3(ICH_VMCR_EL2),
3470+
3471+
EL2_REG_VNCR_GICv3(ICH_LR0_EL2),
3472+
EL2_REG_VNCR_GICv3(ICH_LR1_EL2),
3473+
EL2_REG_VNCR_GICv3(ICH_LR2_EL2),
3474+
EL2_REG_VNCR_GICv3(ICH_LR3_EL2),
3475+
EL2_REG_VNCR_GICv3(ICH_LR4_EL2),
3476+
EL2_REG_VNCR_GICv3(ICH_LR5_EL2),
3477+
EL2_REG_VNCR_GICv3(ICH_LR6_EL2),
3478+
EL2_REG_VNCR_GICv3(ICH_LR7_EL2),
3479+
EL2_REG_VNCR_GICv3(ICH_LR8_EL2),
3480+
EL2_REG_VNCR_GICv3(ICH_LR9_EL2),
3481+
EL2_REG_VNCR_GICv3(ICH_LR10_EL2),
3482+
EL2_REG_VNCR_GICv3(ICH_LR11_EL2),
3483+
EL2_REG_VNCR_GICv3(ICH_LR12_EL2),
3484+
EL2_REG_VNCR_GICv3(ICH_LR13_EL2),
3485+
EL2_REG_VNCR_GICv3(ICH_LR14_EL2),
3486+
EL2_REG_VNCR_GICv3(ICH_LR15_EL2),
34583487

34593488
EL2_REG(CONTEXTIDR_EL2, access_rw, reset_val, 0),
34603489
EL2_REG(TPIDR_EL2, access_rw, reset_val, 0),
@@ -4323,12 +4352,12 @@ static const struct sys_reg_desc cp15_64_regs[] = {
43234352
};
43244353

43254354
static bool check_sysreg_table(const struct sys_reg_desc *table, unsigned int n,
4326-
bool is_32)
4355+
bool reset_check)
43274356
{
43284357
unsigned int i;
43294358

43304359
for (i = 0; i < n; i++) {
4331-
if (!is_32 && table[i].reg && !table[i].reset) {
4360+
if (reset_check && table[i].reg && !table[i].reset) {
43324361
kvm_err("sys_reg table %pS entry %d (%s) lacks reset\n",
43334362
&table[i], i, table[i].name);
43344363
return false;
@@ -5317,18 +5346,22 @@ int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu)
53175346

53185347
int __init kvm_sys_reg_table_init(void)
53195348
{
5349+
const struct sys_reg_desc *gicv3_regs;
53205350
bool valid = true;
5321-
unsigned int i;
5351+
unsigned int i, sz;
53225352
int ret = 0;
53235353

53245354
/* Make sure tables are unique and in order. */
5325-
valid &= check_sysreg_table(sys_reg_descs, ARRAY_SIZE(sys_reg_descs), false);
5326-
valid &= check_sysreg_table(cp14_regs, ARRAY_SIZE(cp14_regs), true);
5327-
valid &= check_sysreg_table(cp14_64_regs, ARRAY_SIZE(cp14_64_regs), true);
5328-
valid &= check_sysreg_table(cp15_regs, ARRAY_SIZE(cp15_regs), true);
5329-
valid &= check_sysreg_table(cp15_64_regs, ARRAY_SIZE(cp15_64_regs), true);
5355+
valid &= check_sysreg_table(sys_reg_descs, ARRAY_SIZE(sys_reg_descs), true);
5356+
valid &= check_sysreg_table(cp14_regs, ARRAY_SIZE(cp14_regs), false);
5357+
valid &= check_sysreg_table(cp14_64_regs, ARRAY_SIZE(cp14_64_regs), false);
5358+
valid &= check_sysreg_table(cp15_regs, ARRAY_SIZE(cp15_regs), false);
5359+
valid &= check_sysreg_table(cp15_64_regs, ARRAY_SIZE(cp15_64_regs), false);
53305360
valid &= check_sysreg_table(sys_insn_descs, ARRAY_SIZE(sys_insn_descs), false);
53315361

5362+
gicv3_regs = vgic_v3_get_sysreg_table(&sz);
5363+
valid &= check_sysreg_table(gicv3_regs, sz, false);
5364+
53325365
if (!valid)
53335366
return -EINVAL;
53345367

0 commit comments

Comments
 (0)