@@ -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+
16411739static 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