Skip to content

Commit 0401f7e

Browse files
Fuad TabbaMarc Zyngier
authored andcommitted
KVM: arm64: Set protected VM traps based on its view of feature registers
Now that the VM's feature id registers are initialized with the values of the supported features, use those values to determine which traps to set using kvm_has_feature(). Signed-off-by: Fuad Tabba <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]>
1 parent 9df9186 commit 0401f7e

File tree

2 files changed

+30
-61
lines changed

2 files changed

+30
-61
lines changed

arch/arm64/kvm/hyp/nvhe/pkvm.c

Lines changed: 30 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ static void pkvm_vcpu_reset_hcr(struct kvm_vcpu *vcpu)
5252

5353
static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
5454
{
55-
const u64 id_aa64pfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
56-
const u64 id_aa64pfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR1_EL1);
57-
const u64 id_aa64mmfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR1_EL1);
55+
struct kvm *kvm = vcpu->kvm;
5856
u64 val = vcpu->arch.hcr_el2;
5957

6058
/* No support for AArch32. */
@@ -70,62 +68,54 @@ static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
7068
*/
7169
val |= HCR_TACR | HCR_TIDCP | HCR_TID3 | HCR_TID1;
7270

73-
/* Trap RAS */
74-
if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_RAS), id_aa64pfr0)) {
71+
if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP)) {
7572
val |= HCR_TERR | HCR_TEA;
7673
val &= ~(HCR_FIEN);
7774
}
7875

79-
/* Trap AMU */
80-
if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AMU), id_aa64pfr0))
76+
if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP))
8177
val &= ~(HCR_AMVOFFEN);
8278

83-
/* Memory Tagging: Trap and Treat as Untagged if not supported. */
84-
if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE), id_aa64pfr1)) {
79+
if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, MTE, IMP)) {
8580
val |= HCR_TID5;
8681
val &= ~(HCR_DCT | HCR_ATA);
8782
}
8883

89-
/* Trap LOR */
90-
if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_LO), id_aa64mmfr1))
84+
if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, LO, IMP))
9185
val |= HCR_TLOR;
9286

9387
vcpu->arch.hcr_el2 = val;
9488
}
9589

9690
static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
9791
{
98-
const u64 id_aa64pfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
99-
const u64 id_aa64pfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR1_EL1);
100-
const u64 id_aa64dfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
92+
struct kvm *kvm = vcpu->kvm;
10193
u64 val = vcpu->arch.cptr_el2;
10294

10395
if (!has_hvhe()) {
10496
val |= CPTR_NVHE_EL2_RES1;
10597
val &= ~(CPTR_NVHE_EL2_RES0);
10698
}
10799

108-
/* Trap AMU */
109-
if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AMU), id_aa64pfr0))
100+
if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP))
110101
val |= CPTR_EL2_TAM;
111102

112-
/* Trap SVE */
113-
if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), id_aa64pfr0)) {
103+
/* SVE can be disabled by userspace even if supported. */
104+
if (!vcpu_has_sve(vcpu)) {
114105
if (has_hvhe())
115106
val &= ~(CPACR_ELx_ZEN);
116107
else
117108
val |= CPTR_EL2_TZ;
118109
}
119110

120111
/* No SME support in KVM. */
121-
BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME), id_aa64pfr1));
112+
BUG_ON(kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP));
122113
if (has_hvhe())
123114
val &= ~(CPACR_ELx_SMEN);
124115
else
125116
val |= CPTR_EL2_TSM;
126117

127-
/* Trap Trace */
128-
if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceVer), id_aa64dfr0)) {
118+
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP)) {
129119
if (has_hvhe())
130120
val |= CPACR_EL1_TTA;
131121
else
@@ -137,40 +127,33 @@ static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
137127

138128
static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
139129
{
140-
const u64 id_aa64dfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
141-
const u64 id_aa64mmfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR0_EL1);
130+
struct kvm *kvm = vcpu->kvm;
142131
u64 val = vcpu->arch.mdcr_el2;
143132

144-
/* Trap/constrain PMU */
145-
if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), id_aa64dfr0)) {
133+
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, IMP)) {
146134
val |= MDCR_EL2_TPM | MDCR_EL2_TPMCR;
147135
val &= ~(MDCR_EL2_HPME | MDCR_EL2_MTPME | MDCR_EL2_HPMN_MASK);
148136
}
149137

150-
/* Trap Debug */
151-
if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DebugVer), id_aa64dfr0))
138+
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DebugVer, IMP))
152139
val |= MDCR_EL2_TDRA | MDCR_EL2_TDA;
153140

154-
/* Trap OS Double Lock */
155-
if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DoubleLock), id_aa64dfr0))
141+
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DoubleLock, IMP))
156142
val |= MDCR_EL2_TDOSA;
157143

158-
/* Trap SPE */
159-
if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMSVer), id_aa64dfr0)) {
144+
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSVer, IMP)) {
160145
val |= MDCR_EL2_TPMS;
161146
val &= ~MDCR_EL2_E2PB_MASK;
162147
}
163148

164-
/* Trap Trace Filter */
165-
if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceFilt), id_aa64dfr0))
149+
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceFilt, IMP))
166150
val |= MDCR_EL2_TTRF;
167151

168-
/* Trap External Trace */
169-
if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_ExtTrcBuff), id_aa64dfr0))
152+
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, ExtTrcBuff, IMP))
170153
val |= MDCR_EL2_E2TB_MASK;
171154

172155
/* Trap Debug Communications Channel registers */
173-
if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_FGT), id_aa64mmfr0))
156+
if (!kvm_has_feat(kvm, ID_AA64MMFR0_EL1, FGT, IMP))
174157
val |= MDCR_EL2_TDCC;
175158

176159
vcpu->arch.mdcr_el2 = val;
@@ -182,31 +165,24 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
182165
*/
183166
static int pkvm_check_pvm_cpu_features(struct kvm_vcpu *vcpu)
184167
{
185-
/*
186-
* PAuth is allowed if supported by the system and the vcpu.
187-
* Properly checking for PAuth requires checking various fields in
188-
* ID_AA64ISAR1_EL1 and ID_AA64ISAR2_EL1. The way that fixed config
189-
* is controlled now in pKVM does not easily allow that. This will
190-
* change later to follow the changes upstream wrt fixed configuration
191-
* and nested virt.
192-
*/
193-
BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI),
194-
PVM_ID_AA64ISAR1_ALLOW));
168+
struct kvm *kvm = vcpu->kvm;
195169

196170
/* Protected KVM does not support AArch32 guests. */
197-
BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0),
198-
PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL0_IMP);
199-
BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
200-
PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL1_IMP);
171+
if (kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL0, AARCH32) ||
172+
kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL1, AARCH32))
173+
return -EINVAL;
201174

202175
/*
203176
* Linux guests assume support for floating-point and Advanced SIMD. Do
204177
* not change the trapping behavior for these from the KVM default.
205178
*/
206-
BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP),
207-
PVM_ID_AA64PFR0_ALLOW));
208-
BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD),
209-
PVM_ID_AA64PFR0_ALLOW));
179+
if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, FP, IMP) ||
180+
!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AdvSIMD, IMP))
181+
return -EINVAL;
182+
183+
/* No SME support in KVM right now. Check to catch if it changes. */
184+
if (kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP))
185+
return -EINVAL;
210186

211187
return 0;
212188
}

arch/arm64/kvm/hyp/nvhe/sys_regs.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -286,13 +286,6 @@ static bool pvm_access_id_aarch32(struct kvm_vcpu *vcpu,
286286
return false;
287287
}
288288

289-
/*
290-
* No support for AArch32 guests, therefore, pKVM has no sanitized copy
291-
* of AArch32 feature id registers.
292-
*/
293-
BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
294-
PVM_ID_AA64PFR0_ALLOW) > ID_AA64PFR0_EL1_EL1_IMP);
295-
296289
return pvm_access_raz_wi(vcpu, p, r);
297290
}
298291

0 commit comments

Comments
 (0)