Skip to content

Commit 1a68acd

Browse files
jingzhangosabuehaze14
authored andcommitted
KVM: arm64: Enable writable for ID_AA64PFR0_EL1
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@google.com>
1 parent 0e3dcc5 commit 1a68acd

File tree

1 file changed

+29
-2
lines changed

1 file changed

+29
-2
lines changed

arch/arm64/kvm/sys_regs.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,9 +1437,36 @@ static u64 read_sanitised_id_aa64pfr1_el1(struct kvm_vcpu *vcpu,
14371437
/* SME is not supported */
14381438
val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME);
14391439

1440+
if (!system_supports_sve())
1441+
val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE);
1442+
14401443
return val;
14411444
}
14421445

1446+
static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
1447+
const struct sys_reg_desc *rd,
1448+
u64 val)
1449+
{
1450+
int fp, simd;
1451+
bool has_sve = id_aa64pfr0_sve(val);
1452+
1453+
simd = cpuid_feature_extract_signed_field(val, ID_AA64PFR0_EL1_AdvSIMD_SHIFT);
1454+
fp = cpuid_feature_extract_signed_field(val, ID_AA64PFR0_EL1_FP_SHIFT);
1455+
/* AdvSIMD field must have the same value as FP field */
1456+
if (simd != fp)
1457+
return -EINVAL;
1458+
1459+
/* fp must be supported when sve is supported */
1460+
if (has_sve && (fp < 0))
1461+
return -EINVAL;
1462+
1463+
/* Check if there is a conflict with a request via KVM_ARM_VCPU_INIT */
1464+
if (vcpu_has_sve(vcpu) ^ has_sve)
1465+
return -EPERM;
1466+
1467+
return set_id_reg(vcpu, rd, val);
1468+
}
1469+
14431470
static u64 read_sanitised_id_aa64dfr0_el1(struct kvm_vcpu *vcpu,
14441471
const struct sys_reg_desc *rd)
14451472
{
@@ -1879,9 +1906,9 @@ static const struct sys_reg_desc sys_reg_descs[] = {
18791906
{ SYS_DESC(SYS_ID_AA64PFR0_EL1),
18801907
.access = access_id_reg,
18811908
.get_user = get_id_reg,
1882-
.set_user = set_id_reg,
1909+
.set_user = set_id_aa64pfr0_el1,
18831910
.reset = read_sanitised_id_aa64pfr0_el1,
1884-
.val = ID_AA64PFR0_EL1_CSV2_MASK | ID_AA64PFR0_EL1_CSV3_MASK, },
1911+
.val = GENMASK(63, 0), },
18851912
{ SYS_DESC(SYS_ID_AA64PFR1_EL1),
18861913
.access = access_id_reg,
18871914
.get_user = get_id_reg,

0 commit comments

Comments
 (0)