Skip to content

Commit a68cddb

Browse files
broonieoupton
authored andcommitted
KVM: arm64: Hide S1PIE registers from userspace when disabled for guests
When the guest does not support S1PIE we should not allow any access to the system registers it adds in order to ensure that we do not create spurious issues with guest migration. Add a visibility operation for these registers. Fixes: 86f9de9 ("KVM: arm64: Save/restore PIE registers") Signed-off-by: Mark Brown <[email protected]> Link: https://lore.kernel.org/r/[email protected] [maz: simplify by using __el2_visibility(), kvm_has_s1pie() throughout] Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent 0fcb4ee commit a68cddb

File tree

5 files changed

+33
-11
lines changed

5 files changed

+33
-11
lines changed

arch/arm64/include/asm/kvm_host.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,4 +1522,7 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
15221522
#define kvm_has_tcr2(k) \
15231523
(kvm_has_feat((k), ID_AA64MMFR3_EL1, TCRX, IMP))
15241524

1525+
#define kvm_has_s1pie(k) \
1526+
(kvm_has_feat((k), ID_AA64MMFR3_EL1, S1PIE, IMP))
1527+
15251528
#endif /* __ARM64_KVM_HOST_H__ */

arch/arm64/kvm/at.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ static enum trans_regime compute_translation_regime(struct kvm_vcpu *vcpu, u32 o
9595

9696
static bool s1pie_enabled(struct kvm_vcpu *vcpu, enum trans_regime regime)
9797
{
98-
if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S1PIE, IMP))
98+
if (!kvm_has_s1pie(vcpu->kvm))
9999
return false;
100100

101101
switch (regime) {
@@ -1101,7 +1101,7 @@ static u64 __kvm_at_s1e01_fast(struct kvm_vcpu *vcpu, u32 op, u64 vaddr)
11011101
write_sysreg_el1(vcpu_read_sys_reg(vcpu, MAIR_EL1), SYS_MAIR);
11021102
if (kvm_has_tcr2(vcpu->kvm)) {
11031103
write_sysreg_el1(vcpu_read_sys_reg(vcpu, TCR2_EL1), SYS_TCR2);
1104-
if (kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S1PIE, IMP)) {
1104+
if (kvm_has_s1pie(vcpu->kvm)) {
11051105
write_sysreg_el1(vcpu_read_sys_reg(vcpu, PIR_EL1), SYS_PIR);
11061106
write_sysreg_el1(vcpu_read_sys_reg(vcpu, PIRE0_EL1), SYS_PIRE0);
11071107
}

arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ static inline bool ctxt_has_s1pie(struct kvm_cpu_context *ctxt)
5858
return false;
5959

6060
vcpu = ctxt_to_vcpu(ctxt);
61-
return kvm_has_feat(kern_hyp_va(vcpu->kvm), ID_AA64MMFR3_EL1, S1PIE, IMP);
61+
return kvm_has_s1pie(kern_hyp_va(vcpu->kvm));
6262
}
6363

6464
static inline bool ctxt_has_tcrx(struct kvm_cpu_context *ctxt)

arch/arm64/kvm/nested.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,7 +1105,7 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
11051105
res0 |= (HFGxTR_EL2_nSMPRI_EL1 | HFGxTR_EL2_nTPIDR2_EL0);
11061106
if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, THE, IMP))
11071107
res0 |= HFGxTR_EL2_nRCWMASK_EL1;
1108-
if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1PIE, IMP))
1108+
if (!kvm_has_s1pie(kvm))
11091109
res0 |= (HFGxTR_EL2_nPIRE0_EL1 | HFGxTR_EL2_nPIR_EL1);
11101110
if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1POE, IMP))
11111111
res0 |= (HFGxTR_EL2_nPOR_EL0 | HFGxTR_EL2_nPOR_EL1);
@@ -1219,7 +1219,7 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
12191219
res0 |= TCR2_EL2_AIE;
12201220
if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1POE, IMP))
12211221
res0 |= TCR2_EL2_POE | TCR2_EL2_E0POE;
1222-
if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1PIE, IMP))
1222+
if (!kvm_has_s1pie(kvm))
12231223
res0 |= TCR2_EL2_PIE;
12241224
if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, VH, IMP))
12251225
res0 |= (TCR2_EL2_E0POE | TCR2_EL2_D128 |

arch/arm64/kvm/sys_regs.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ static bool check_s1pie_access_rw(struct kvm_vcpu *vcpu,
373373
struct sys_reg_params *p,
374374
const struct sys_reg_desc *r)
375375
{
376-
if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S1PIE, IMP)) {
376+
if (!kvm_has_s1pie(vcpu->kvm)) {
377377
kvm_inject_undefined(vcpu);
378378
return false;
379379
}
@@ -2372,6 +2372,21 @@ static unsigned int tcr2_el2_visibility(const struct kvm_vcpu *vcpu,
23722372
return __el2_visibility(vcpu, rd, tcr2_visibility);
23732373
}
23742374

2375+
static unsigned int s1pie_visibility(const struct kvm_vcpu *vcpu,
2376+
const struct sys_reg_desc *rd)
2377+
{
2378+
if (kvm_has_s1pie(vcpu->kvm))
2379+
return 0;
2380+
2381+
return REG_HIDDEN;
2382+
}
2383+
2384+
static unsigned int s1pie_el2_visibility(const struct kvm_vcpu *vcpu,
2385+
const struct sys_reg_desc *rd)
2386+
{
2387+
return __el2_visibility(vcpu, rd, s1pie_visibility);
2388+
}
2389+
23752390
/*
23762391
* Architected system registers.
23772392
* Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
@@ -2637,8 +2652,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
26372652
{ SYS_DESC(SYS_PMMIR_EL1), trap_raz_wi },
26382653

26392654
{ SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 },
2640-
{ SYS_DESC(SYS_PIRE0_EL1), NULL, reset_unknown, PIRE0_EL1 },
2641-
{ SYS_DESC(SYS_PIR_EL1), NULL, reset_unknown, PIR_EL1 },
2655+
{ SYS_DESC(SYS_PIRE0_EL1), NULL, reset_unknown, PIRE0_EL1,
2656+
.visibility = s1pie_visibility },
2657+
{ SYS_DESC(SYS_PIR_EL1), NULL, reset_unknown, PIR_EL1,
2658+
.visibility = s1pie_visibility },
26422659
{ SYS_DESC(SYS_POR_EL1), NULL, reset_unknown, POR_EL1,
26432660
.visibility = s1poe_visibility },
26442661
{ SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },
@@ -2949,8 +2966,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
29492966
EL2_REG(HPFAR_EL2, access_rw, reset_val, 0),
29502967

29512968
EL2_REG(MAIR_EL2, access_rw, reset_val, 0),
2952-
EL2_REG(PIRE0_EL2, check_s1pie_access_rw, reset_val, 0),
2953-
EL2_REG(PIR_EL2, check_s1pie_access_rw, reset_val, 0),
2969+
EL2_REG_FILTERED(PIRE0_EL2, check_s1pie_access_rw, reset_val, 0,
2970+
s1pie_el2_visibility),
2971+
EL2_REG_FILTERED(PIR_EL2, check_s1pie_access_rw, reset_val, 0,
2972+
s1pie_el2_visibility),
29542973
EL2_REG(AMAIR_EL2, access_rw, reset_val, 0),
29552974

29562975
EL2_REG(VBAR_EL2, access_rw, reset_val, 0),
@@ -4867,7 +4886,7 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu)
48674886
kvm->arch.fgu[HFGITR_GROUP] |= (HFGITR_EL2_ATS1E1RP |
48684887
HFGITR_EL2_ATS1E1WP);
48694888

4870-
if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1PIE, IMP))
4889+
if (!kvm_has_s1pie(kvm))
48714890
kvm->arch.fgu[HFGxTR_GROUP] |= (HFGxTR_EL2_nPIRE0_EL1 |
48724891
HFGxTR_EL2_nPIR_EL1);
48734892

0 commit comments

Comments
 (0)