Skip to content

Commit 2589dbd

Browse files
author
Marc Zyngier
committed
KVM: arm64: Consolidate allowed and restricted VM feature checks
The definitions for features allowed and allowed with restrictions for protected guests, which are based on feature registers, were defined and checked for separately, even though they are handled in the same way. This could result in missing checks for certain features, e.g., pointer authentication, causing traps for allowed features. Consolidate the definitions into one. Use that new definition to construct the guest view of the feature registers for consistency. Signed-off-by: Fuad Tabba <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]>
1 parent 78d4f34 commit 2589dbd

File tree

3 files changed

+26
-43
lines changed

3 files changed

+26
-43
lines changed

arch/arm64/kvm/hyp/include/nvhe/fixed_config.h

Lines changed: 19 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,8 @@
1414
* guest virtual machines, depending on the mode KVM is running in and on the
1515
* type of guest that is running.
1616
*
17-
* The ALLOW masks represent a bitmask of feature fields that are allowed
18-
* without any restrictions as long as they are supported by the system.
19-
*
20-
* The RESTRICT_UNSIGNED masks, if present, represent unsigned fields for
21-
* features that are restricted to support at most the specified feature.
17+
* Each field in the masks represents the highest supported *unsigned* value for
18+
* the feature, if supported by the system.
2219
*
2320
* If a feature field is not present in either, than it is not supported.
2421
*
@@ -34,24 +31,20 @@
3431
* - Floating-point and Advanced SIMD
3532
* - Data Independent Timing
3633
* - Spectre/Meltdown Mitigation
37-
*/
38-
#define PVM_ID_AA64PFR0_ALLOW (\
39-
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP) | \
40-
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD) | \
41-
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_DIT) | \
42-
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2) | \
43-
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3) \
44-
)
45-
46-
/*
34+
*
4735
* Restrict to the following *unsigned* features for protected VMs:
4836
* - AArch64 guests only (no support for AArch32 guests):
4937
* AArch32 adds complexity in trap handling, emulation, condition codes,
5038
* etc...
5139
* - RAS (v1)
5240
* Supported by KVM
5341
*/
54-
#define PVM_ID_AA64PFR0_RESTRICT_UNSIGNED (\
42+
#define PVM_ID_AA64PFR0_ALLOW (\
43+
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP) | \
44+
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD) | \
45+
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_DIT) | \
46+
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2) | \
47+
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3) | \
5548
SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL0, IMP) | \
5649
SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL1, IMP) | \
5750
SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL2, IMP) | \
@@ -77,20 +70,16 @@
7770
* - Distinction between Secure and Non-secure Memory
7871
* - Mixed-endian at EL0 only
7972
* - Non-context synchronizing exception entry and exit
73+
*
74+
* Restrict to the following *unsigned* features for protected VMs:
75+
* - 40-bit IPA
76+
* - 16-bit ASID
8077
*/
8178
#define PVM_ID_AA64MMFR0_ALLOW (\
8279
ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_BIGEND) | \
8380
ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_SNSMEM) | \
8481
ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_BIGENDEL0) | \
85-
ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_EXS) \
86-
)
87-
88-
/*
89-
* Restrict to the following *unsigned* features for protected VMs:
90-
* - 40-bit IPA
91-
* - 16-bit ASID
92-
*/
93-
#define PVM_ID_AA64MMFR0_RESTRICT_UNSIGNED (\
82+
ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_EXS) | \
9483
FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_PARANGE), ID_AA64MMFR0_EL1_PARANGE_40) | \
9584
FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_ASIDBITS), ID_AA64MMFR0_EL1_ASIDBITS_16) \
9685
)
@@ -185,15 +174,6 @@
185174
)
186175

187176
/* Restrict pointer authentication to the basic version. */
188-
#define PVM_ID_AA64ISAR1_RESTRICT_UNSIGNED (\
189-
FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), ID_AA64ISAR1_EL1_APA_PAuth) | \
190-
FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), ID_AA64ISAR1_EL1_API_PAuth) \
191-
)
192-
193-
#define PVM_ID_AA64ISAR2_RESTRICT_UNSIGNED (\
194-
FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_APA3), ID_AA64ISAR2_EL1_APA3_PAuth) \
195-
)
196-
197177
#define PVM_ID_AA64ISAR1_ALLOW (\
198178
ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_DPB) | \
199179
ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_JSCVT) | \
@@ -206,13 +186,16 @@
206186
ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_SPECRES) | \
207187
ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_BF16) | \
208188
ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_DGH) | \
209-
ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_I8MM) \
189+
ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_I8MM) | \
190+
FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), ID_AA64ISAR1_EL1_APA_PAuth) | \
191+
FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), ID_AA64ISAR1_EL1_API_PAuth) \
210192
)
211193

212194
#define PVM_ID_AA64ISAR2_ALLOW (\
213195
ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_ATS1A)| \
214196
ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_GPA3) | \
215-
ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_MOPS) \
197+
ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_MOPS) | \
198+
FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_APA3), ID_AA64ISAR2_EL1_APA3_PAuth) \
216199
)
217200

218201
u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id);

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ static void pvm_init_traps_aa64pfr0(struct kvm_vcpu *vcpu)
3636

3737
/* Protected KVM does not support AArch32 guests. */
3838
BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0),
39-
PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) != ID_AA64PFR0_EL1_EL0_IMP);
39+
PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL0_IMP);
4040
BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
41-
PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) != ID_AA64PFR0_EL1_EL1_IMP);
41+
PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL1_IMP);
4242

4343
/*
4444
* Linux guests assume support for floating-point and Advanced SIMD. Do
@@ -362,8 +362,8 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
362362
if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), PVM_ID_AA64PFR0_ALLOW))
363363
set_bit(KVM_ARM_VCPU_SVE, allowed_features);
364364

365-
if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), PVM_ID_AA64ISAR1_RESTRICT_UNSIGNED) &&
366-
FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), PVM_ID_AA64ISAR1_RESTRICT_UNSIGNED))
365+
if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), PVM_ID_AA64ISAR1_ALLOW) &&
366+
FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), PVM_ID_AA64ISAR1_ALLOW))
367367
set_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, allowed_features);
368368

369369
if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI), PVM_ID_AA64ISAR1_ALLOW) &&

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ static u64 get_pvm_id_aa64pfr0(const struct kvm_vcpu *vcpu)
8989
u64 allow_mask = PVM_ID_AA64PFR0_ALLOW;
9090

9191
set_mask |= get_restricted_features_unsigned(id_aa64pfr0_el1_sys_val,
92-
PVM_ID_AA64PFR0_RESTRICT_UNSIGNED);
92+
PVM_ID_AA64PFR0_ALLOW);
9393

9494
return (id_aa64pfr0_el1_sys_val & allow_mask) | set_mask;
9595
}
@@ -189,7 +189,7 @@ static u64 get_pvm_id_aa64mmfr0(const struct kvm_vcpu *vcpu)
189189
u64 set_mask;
190190

191191
set_mask = get_restricted_features_unsigned(id_aa64mmfr0_el1_sys_val,
192-
PVM_ID_AA64MMFR0_RESTRICT_UNSIGNED);
192+
PVM_ID_AA64MMFR0_ALLOW);
193193

194194
return (id_aa64mmfr0_el1_sys_val & PVM_ID_AA64MMFR0_ALLOW) | set_mask;
195195
}
@@ -276,7 +276,7 @@ static bool pvm_access_id_aarch32(struct kvm_vcpu *vcpu,
276276
* of AArch32 feature id registers.
277277
*/
278278
BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
279-
PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) > ID_AA64PFR0_EL1_EL1_IMP);
279+
PVM_ID_AA64PFR0_ALLOW) > ID_AA64PFR0_EL1_EL1_IMP);
280280

281281
return pvm_access_raz_wi(vcpu, p, r);
282282
}

0 commit comments

Comments
 (0)