[PATCH v3 3/4] KVM: arm64: Enable writable for ID_AA64PFR0_EL1
Jing Zhang
jingzhangos at google.com
Wed Apr 5 10:21:45 PDT 2023
Return an error if userspace tries to set SVE field of the register
to a value that conflicts with SVE configuration for the guest.
SIMD/FP/SVE fields of the requested value are validated according to
Arm ARM.
Signed-off-by: Jing Zhang <jingzhangos at google.com>
---
arch/arm64/kvm/id_regs.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/id_regs.c b/arch/arm64/kvm/id_regs.c
index 11d3a1d46ee5..20d1a2d2a0cc 100644
--- a/arch/arm64/kvm/id_regs.c
+++ b/arch/arm64/kvm/id_regs.c
@@ -283,6 +283,9 @@ static u64 read_sanitised_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AMU);
+ if (!system_supports_sve())
+ val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE);
+
return val;
}
@@ -291,6 +294,22 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
u64 val)
{
u8 csv2, csv3;
+ int fp, simd;
+ bool has_sve = id_aa64pfr0_sve(val);
+
+ simd = cpuid_feature_extract_signed_field(val, ID_AA64PFR0_EL1_AdvSIMD_SHIFT);
+ fp = cpuid_feature_extract_signed_field(val, ID_AA64PFR0_EL1_FP_SHIFT);
+ /* AdvSIMD field must have the same value as FP field */
+ if (simd != fp)
+ return -EINVAL;
+
+ /* fp must be supported when sve is supported */
+ if (has_sve && (fp < 0))
+ return -EINVAL;
+
+ /* Check if there is a conflict with a request via KVM_ARM_VCPU_INIT */
+ if (vcpu_has_sve(vcpu) ^ has_sve)
+ return -EPERM;
/*
* Allow AA64PFR0_EL1.CSV2 to be set from userspace as long as
@@ -582,7 +601,7 @@ const struct sys_reg_desc id_reg_descs[KVM_ARM_ID_REG_NUM] = {
.get_user = get_id_reg,
.set_user = set_id_aa64pfr0_el1,
.reset = read_sanitised_id_aa64pfr0_el1,
- .val = ID_AA64PFR0_EL1_CSV2_MASK | ID_AA64PFR0_EL1_CSV3_MASK, },
+ .val = GENMASK(63, 0), },
ID_SANITISED(ID_AA64PFR1_EL1),
ID_UNALLOCATED(4, 2),
ID_UNALLOCATED(4, 3),
--
2.40.0.348.gf938b09366-goog
More information about the linux-arm-kernel
mailing list