Skip to content

Commit fc63c7e

Browse files
Suraj Jitindar Singhabuehaze14
authored andcommitted
KVM: arm64: Enable writable for ID_AA64ISAR1_EL0
All valid fields in ID_AA64ISAR1_EL0 are writable from userspace with this change. Return an error if userspace tries to set i8mm, bf16, gpi or gpa to an invalid configuration based on the Arm Architecture Reference Manual for A-profile architecture [1]. [1] https://developer.arm.com/documentation/ddi0487/latest/ Signed-off-by: Suraj Jitindar Singh <surajjs@amazon.com>
1 parent 004d6dd commit fc63c7e

File tree

1 file changed

+104
-1
lines changed

1 file changed

+104
-1
lines changed

arch/arm64/kvm/sys_regs.c

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1638,6 +1638,104 @@ static int set_id_aa64isar0_el1(struct kvm_vcpu *vcpu,
16381638
return set_id_reg(vcpu, rd, val);
16391639
}
16401640

1641+
static int set_id_aa64isar1_el1(struct kvm_vcpu *vcpu,
1642+
const struct sys_reg_desc *rd,
1643+
u64 val)
1644+
{
1645+
u8 zfr0_i8mm, zfr0_bf16, gpa3, sme;
1646+
u8 i8mm, bf16, gpi, gpa;
1647+
int advsimd;
1648+
1649+
/* Fields in the register we're trying to set - ISAR1 */
1650+
i8mm = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_I8MM), val);
1651+
bf16 = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_BF16), val);
1652+
gpi = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI), val);
1653+
gpa = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPA), val);
1654+
1655+
/* Fields in ZFR0 */
1656+
zfr0_i8mm = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ZFR0_EL1_I8MM),
1657+
IDREG(vcpu->kvm, SYS_ID_AA64ZFR0_EL1));
1658+
zfr0_bf16 = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ZFR0_EL1_BF16),
1659+
IDREG(vcpu->kvm, SYS_ID_AA64ZFR0_EL1));
1660+
1661+
/* Fields in ISAR2 */
1662+
gpa3 = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_GPA3),
1663+
IDREG(vcpu->kvm, SYS_ID_AA64ISAR2_EL1));
1664+
1665+
/* Fields in PFR1 */
1666+
sme = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME),
1667+
IDREG(vcpu->kvm, SYS_ID_AA64PFR1_EL1));
1668+
1669+
/* Fields in PFR0 */
1670+
advsimd = cpuid_feature_extract_signed_field(IDREG(vcpu->kvm,
1671+
SYS_ID_AA64PFR0_EL1),
1672+
ID_AA64PFR0_EL1_AdvSIMD_SHIFT);
1673+
1674+
/*
1675+
* From Arm Architecture Reference Manual for A-profile architecture
1676+
* (https://developer.arm.com/documentation/ddi0487/latest/)
1677+
* D19.2.62:
1678+
* I8MM, bits [55:52]
1679+
* When Advanced SIMD and SVE are both implemented, this field must
1680+
* return the same value as ID_AA64ZFR0_EL1.I8MM.
1681+
*/
1682+
if (vcpu_has_sve(vcpu) && advsimd) {
1683+
if (i8mm != zfr0_i8mm)
1684+
return -EINVAL;
1685+
}
1686+
1687+
/*
1688+
* From Arm Architecture Reference Manual for A-profile architecture
1689+
* (https://developer.arm.com/documentation/ddi0487/latest/)
1690+
* D19.2.62:
1691+
* BF16, bits [47:44]
1692+
* When FEAT_SVE or FEAT_SME is implemented, this field must return
1693+
* the same value as ID_AA64ZFR0_EL1.BF16.
1694+
*/
1695+
if (vcpu_has_sve(vcpu) || sme) {
1696+
if (bf16 != zfr0_bf16)
1697+
return -EINVAL;
1698+
}
1699+
1700+
/*
1701+
* From Arm Architecture Reference Manual for A-profile architecture
1702+
* (https://developer.arm.com/documentation/ddi0487/latest/)
1703+
* D19.2.62:
1704+
* GPI, bits [31:28]
1705+
* If the value of ID_AA64ISAR1_EL1.GPA is nonzero, or the value of
1706+
* ID_AA64ISAR2_EL1.GPA3 is nonzero, this field must have the value
1707+
* 0b0000.
1708+
*/
1709+
if (gpi && (gpa || gpa3)) {
1710+
return -EINVAL;
1711+
}
1712+
1713+
/*
1714+
* From Arm Architecture Reference Manual for A-profile architecture
1715+
* (https://developer.arm.com/documentation/ddi0487/latest/)
1716+
* D19.2.62:
1717+
* GPA, bits [27:24]
1718+
* If the value of ID_AA64ISAR1_EL1.GPI is nonzero, or the value of
1719+
* ID_AA64ISAR2_EL1.GPA3 is nonzero, this field must have the value
1720+
* 0b0000.
1721+
*/
1722+
if (gpa && (gpi || gpa3)) {
1723+
return -EINVAL;
1724+
}
1725+
1726+
/* Check ptrauth state matches that requested in vcpu features */
1727+
if ((gpi || gpa || gpa3) != vcpu_has_ptrauth(vcpu))
1728+
return -EINVAL;
1729+
1730+
/*
1731+
* No need to validate API or APA, since they are FTR_EXACT they must
1732+
* match the host value. And who are we to argue if the host screwed
1733+
* these up.
1734+
*/
1735+
1736+
return set_id_reg(vcpu, rd, val);
1737+
}
1738+
16411739
static u64 read_sanitised_id_aa64isar2_el1(struct kvm_vcpu *vcpu,
16421740
const struct sys_reg_desc *rd)
16431741
{
@@ -2001,7 +2099,12 @@ static const struct sys_reg_desc sys_reg_descs[] = {
20012099
.set_user = set_id_aa64isar0_el1,
20022100
.reset = general_read_kvm_sanitised_reg,
20032101
.val = GENMASK(63, 0), },
2004-
ID_SANITISED(ID_AA64ISAR1_EL1),
2102+
{ SYS_DESC(SYS_ID_AA64ISAR1_EL1),
2103+
.access = access_id_reg,
2104+
.get_user = get_id_reg,
2105+
.set_user = set_id_aa64isar1_el1,
2106+
.reset = general_read_kvm_sanitised_reg,
2107+
.val = GENMASK(63, 0), },
20052108
{ SYS_DESC(SYS_ID_AA64ISAR2_EL1),
20062109
.access = access_id_reg,
20072110
.get_user = get_id_reg,

0 commit comments

Comments
 (0)