@@ -1038,42 +1038,34 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
10381038 { SYS_DESC(SYS_PMEVTYPERn_EL0(n)), \
10391039 access_pmu_evtyper, reset_unknown, (PMEVTYPER0_EL0 + n), }
10401040
1041- static bool access_amu (struct kvm_vcpu * vcpu , struct sys_reg_params * p ,
1042- const struct sys_reg_desc * r )
1041+ static bool undef_access (struct kvm_vcpu * vcpu , struct sys_reg_params * p ,
1042+ const struct sys_reg_desc * r )
10431043{
10441044 kvm_inject_undefined (vcpu );
10451045
10461046 return false;
10471047}
10481048
10491049/* Macro to expand the AMU counter and type registers*/
1050- #define AMU_AMEVCNTR0_EL0 (n ) { SYS_DESC(SYS_AMEVCNTR0_EL0(n)), access_amu }
1051- #define AMU_AMEVTYPER0_EL0 (n ) { SYS_DESC(SYS_AMEVTYPER0_EL0(n)), access_amu }
1052- #define AMU_AMEVCNTR1_EL0 (n ) { SYS_DESC(SYS_AMEVCNTR1_EL0(n)), access_amu }
1053- #define AMU_AMEVTYPER1_EL0 (n ) { SYS_DESC(SYS_AMEVTYPER1_EL0(n)), access_amu }
1054-
1055- static bool trap_ptrauth (struct kvm_vcpu * vcpu ,
1056- struct sys_reg_params * p ,
1057- const struct sys_reg_desc * rd )
1058- {
1059- /*
1060- * If we land here, that is because we didn't fixup the access on exit
1061- * by allowing the PtrAuth sysregs. The only way this happens is when
1062- * the guest does not have PtrAuth support enabled.
1063- */
1064- kvm_inject_undefined (vcpu );
1065-
1066- return false;
1067- }
1050+ #define AMU_AMEVCNTR0_EL0 (n ) { SYS_DESC(SYS_AMEVCNTR0_EL0(n)), undef_access }
1051+ #define AMU_AMEVTYPER0_EL0 (n ) { SYS_DESC(SYS_AMEVTYPER0_EL0(n)), undef_access }
1052+ #define AMU_AMEVCNTR1_EL0 (n ) { SYS_DESC(SYS_AMEVCNTR1_EL0(n)), undef_access }
1053+ #define AMU_AMEVTYPER1_EL0 (n ) { SYS_DESC(SYS_AMEVTYPER1_EL0(n)), undef_access }
10681054
10691055static unsigned int ptrauth_visibility (const struct kvm_vcpu * vcpu ,
10701056 const struct sys_reg_desc * rd )
10711057{
10721058 return vcpu_has_ptrauth (vcpu ) ? 0 : REG_HIDDEN ;
10731059}
10741060
1061+ /*
1062+ * If we land here on a PtrAuth access, that is because we didn't
1063+ * fixup the access on exit by allowing the PtrAuth sysregs. The only
1064+ * way this happens is when the guest does not have PtrAuth support
1065+ * enabled.
1066+ */
10751067#define __PTRAUTH_KEY (k ) \
1076- { SYS_DESC(SYS_## k), trap_ptrauth , reset_unknown, k, \
1068+ { SYS_DESC(SYS_## k), undef_access , reset_unknown, k, \
10771069 .visibility = ptrauth_visibility}
10781070
10791071#define PTRAUTH_KEY (k ) \
@@ -1128,9 +1120,8 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
11281120 if (!vcpu_has_sve (vcpu ))
11291121 val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT );
11301122 val &= ~(0xfUL << ID_AA64PFR0_AMU_SHIFT );
1131- if (!(val & (0xfUL << ID_AA64PFR0_CSV2_SHIFT )) &&
1132- arm64_get_spectre_v2_state () == SPECTRE_UNAFFECTED )
1133- val |= (1UL << ID_AA64PFR0_CSV2_SHIFT );
1123+ val &= ~(0xfUL << ID_AA64PFR0_CSV2_SHIFT );
1124+ val |= ((u64 )vcpu -> kvm -> arch .pfr0_csv2 << ID_AA64PFR0_CSV2_SHIFT );
11341125 } else if (id == SYS_ID_AA64PFR1_EL1 ) {
11351126 val &= ~(0xfUL << ID_AA64PFR1_MTE_SHIFT );
11361127 } else if (id == SYS_ID_AA64ISAR1_EL1 && !vcpu_has_ptrauth (vcpu )) {
@@ -1213,6 +1204,40 @@ static unsigned int sve_visibility(const struct kvm_vcpu *vcpu,
12131204 return REG_HIDDEN ;
12141205}
12151206
1207+ static int set_id_aa64pfr0_el1 (struct kvm_vcpu * vcpu ,
1208+ const struct sys_reg_desc * rd ,
1209+ const struct kvm_one_reg * reg , void __user * uaddr )
1210+ {
1211+ const u64 id = sys_reg_to_index (rd );
1212+ int err ;
1213+ u64 val ;
1214+ u8 csv2 ;
1215+
1216+ err = reg_from_user (& val , uaddr , id );
1217+ if (err )
1218+ return err ;
1219+
1220+ /*
1221+ * Allow AA64PFR0_EL1.CSV2 to be set from userspace as long as
1222+ * it doesn't promise more than what is actually provided (the
1223+ * guest could otherwise be covered in ectoplasmic residue).
1224+ */
1225+ csv2 = cpuid_feature_extract_unsigned_field (val , ID_AA64PFR0_CSV2_SHIFT );
1226+ if (csv2 > 1 ||
1227+ (csv2 && arm64_get_spectre_v2_state () != SPECTRE_UNAFFECTED ))
1228+ return - EINVAL ;
1229+
1230+ /* We can only differ with CSV2, and anything else is an error */
1231+ val ^= read_id_reg (vcpu , rd , false);
1232+ val &= ~(0xFUL << ID_AA64PFR0_CSV2_SHIFT );
1233+ if (val )
1234+ return - EINVAL ;
1235+
1236+ vcpu -> kvm -> arch .pfr0_csv2 = csv2 ;
1237+
1238+ return 0 ;
1239+ }
1240+
12161241/*
12171242 * cpufeature ID register user accessors
12181243 *
@@ -1341,13 +1366,6 @@ static bool access_ccsidr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
13411366 return true;
13421367}
13431368
1344- static bool access_mte_regs (struct kvm_vcpu * vcpu , struct sys_reg_params * p ,
1345- const struct sys_reg_desc * r )
1346- {
1347- kvm_inject_undefined (vcpu );
1348- return false;
1349- }
1350-
13511369/* sys_reg_desc initialiser for known cpufeature ID registers */
13521370#define ID_SANITISED (name ) { \
13531371 SYS_DESC(SYS_##name), \
@@ -1472,7 +1490,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
14721490
14731491 /* AArch64 ID registers */
14741492 /* CRm=4 */
1475- ID_SANITISED (ID_AA64PFR0_EL1 ),
1493+ { SYS_DESC (SYS_ID_AA64PFR0_EL1 ), .access = access_id_reg ,
1494+ .get_user = get_id_reg , .set_user = set_id_aa64pfr0_el1 , },
14761495 ID_SANITISED (ID_AA64PFR1_EL1 ),
14771496 ID_UNALLOCATED (4 ,2 ),
14781497 ID_UNALLOCATED (4 ,3 ),
@@ -1515,8 +1534,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
15151534 { SYS_DESC (SYS_ACTLR_EL1 ), access_actlr , reset_actlr , ACTLR_EL1 },
15161535 { SYS_DESC (SYS_CPACR_EL1 ), NULL , reset_val , CPACR_EL1 , 0 },
15171536
1518- { SYS_DESC (SYS_RGSR_EL1 ), access_mte_regs },
1519- { SYS_DESC (SYS_GCR_EL1 ), access_mte_regs },
1537+ { SYS_DESC (SYS_RGSR_EL1 ), undef_access },
1538+ { SYS_DESC (SYS_GCR_EL1 ), undef_access },
15201539
15211540 { SYS_DESC (SYS_ZCR_EL1 ), NULL , reset_val , ZCR_EL1 , 0 , .visibility = sve_visibility },
15221541 { SYS_DESC (SYS_TTBR0_EL1 ), access_vm_reg , reset_unknown , TTBR0_EL1 },
@@ -1542,8 +1561,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
15421561 { SYS_DESC (SYS_ERXMISC0_EL1 ), trap_raz_wi },
15431562 { SYS_DESC (SYS_ERXMISC1_EL1 ), trap_raz_wi },
15441563
1545- { SYS_DESC (SYS_TFSR_EL1 ), access_mte_regs },
1546- { SYS_DESC (SYS_TFSRE0_EL1 ), access_mte_regs },
1564+ { SYS_DESC (SYS_TFSR_EL1 ), undef_access },
1565+ { SYS_DESC (SYS_TFSRE0_EL1 ), undef_access },
15471566
15481567 { SYS_DESC (SYS_FAR_EL1 ), access_vm_reg , reset_unknown , FAR_EL1 },
15491568 { SYS_DESC (SYS_PAR_EL1 ), NULL , reset_unknown , PAR_EL1 },
@@ -1579,6 +1598,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
15791598 { SYS_DESC (SYS_CONTEXTIDR_EL1 ), access_vm_reg , reset_val , CONTEXTIDR_EL1 , 0 },
15801599 { SYS_DESC (SYS_TPIDR_EL1 ), NULL , reset_unknown , TPIDR_EL1 },
15811600
1601+ { SYS_DESC (SYS_SCXTNUM_EL1 ), undef_access },
1602+
15821603 { SYS_DESC (SYS_CNTKCTL_EL1 ), NULL , reset_val , CNTKCTL_EL1 , 0 },
15831604
15841605 { SYS_DESC (SYS_CCSIDR_EL1 ), access_ccsidr },
@@ -1607,14 +1628,16 @@ static const struct sys_reg_desc sys_reg_descs[] = {
16071628 { SYS_DESC (SYS_TPIDR_EL0 ), NULL , reset_unknown , TPIDR_EL0 },
16081629 { SYS_DESC (SYS_TPIDRRO_EL0 ), NULL , reset_unknown , TPIDRRO_EL0 },
16091630
1610- { SYS_DESC (SYS_AMCR_EL0 ), access_amu },
1611- { SYS_DESC (SYS_AMCFGR_EL0 ), access_amu },
1612- { SYS_DESC (SYS_AMCGCR_EL0 ), access_amu },
1613- { SYS_DESC (SYS_AMUSERENR_EL0 ), access_amu },
1614- { SYS_DESC (SYS_AMCNTENCLR0_EL0 ), access_amu },
1615- { SYS_DESC (SYS_AMCNTENSET0_EL0 ), access_amu },
1616- { SYS_DESC (SYS_AMCNTENCLR1_EL0 ), access_amu },
1617- { SYS_DESC (SYS_AMCNTENSET1_EL0 ), access_amu },
1631+ { SYS_DESC (SYS_SCXTNUM_EL0 ), undef_access },
1632+
1633+ { SYS_DESC (SYS_AMCR_EL0 ), undef_access },
1634+ { SYS_DESC (SYS_AMCFGR_EL0 ), undef_access },
1635+ { SYS_DESC (SYS_AMCGCR_EL0 ), undef_access },
1636+ { SYS_DESC (SYS_AMUSERENR_EL0 ), undef_access },
1637+ { SYS_DESC (SYS_AMCNTENCLR0_EL0 ), undef_access },
1638+ { SYS_DESC (SYS_AMCNTENSET0_EL0 ), undef_access },
1639+ { SYS_DESC (SYS_AMCNTENCLR1_EL0 ), undef_access },
1640+ { SYS_DESC (SYS_AMCNTENSET1_EL0 ), undef_access },
16181641 AMU_AMEVCNTR0_EL0 (0 ),
16191642 AMU_AMEVCNTR0_EL0 (1 ),
16201643 AMU_AMEVCNTR0_EL0 (2 ),
0 commit comments