@@ -1038,42 +1038,34 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
1038
1038
{ SYS_DESC(SYS_PMEVTYPERn_EL0(n)), \
1039
1039
access_pmu_evtyper, reset_unknown, (PMEVTYPER0_EL0 + n), }
1040
1040
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 )
1043
1043
{
1044
1044
kvm_inject_undefined (vcpu );
1045
1045
1046
1046
return false;
1047
1047
}
1048
1048
1049
1049
/* 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 }
1068
1054
1069
1055
static unsigned int ptrauth_visibility (const struct kvm_vcpu * vcpu ,
1070
1056
const struct sys_reg_desc * rd )
1071
1057
{
1072
1058
return vcpu_has_ptrauth (vcpu ) ? 0 : REG_HIDDEN ;
1073
1059
}
1074
1060
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
+ */
1075
1067
#define __PTRAUTH_KEY (k ) \
1076
- { SYS_DESC(SYS_## k), trap_ptrauth , reset_unknown, k, \
1068
+ { SYS_DESC(SYS_## k), undef_access , reset_unknown, k, \
1077
1069
.visibility = ptrauth_visibility}
1078
1070
1079
1071
#define PTRAUTH_KEY (k ) \
@@ -1128,9 +1120,8 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
1128
1120
if (!vcpu_has_sve (vcpu ))
1129
1121
val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT );
1130
1122
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 );
1134
1125
} else if (id == SYS_ID_AA64PFR1_EL1 ) {
1135
1126
val &= ~(0xfUL << ID_AA64PFR1_MTE_SHIFT );
1136
1127
} 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,
1213
1204
return REG_HIDDEN ;
1214
1205
}
1215
1206
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
+
1216
1241
/*
1217
1242
* cpufeature ID register user accessors
1218
1243
*
@@ -1341,13 +1366,6 @@ static bool access_ccsidr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
1341
1366
return true;
1342
1367
}
1343
1368
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
-
1351
1369
/* sys_reg_desc initialiser for known cpufeature ID registers */
1352
1370
#define ID_SANITISED (name ) { \
1353
1371
SYS_DESC(SYS_##name), \
@@ -1472,7 +1490,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
1472
1490
1473
1491
/* AArch64 ID registers */
1474
1492
/* 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 , },
1476
1495
ID_SANITISED (ID_AA64PFR1_EL1 ),
1477
1496
ID_UNALLOCATED (4 ,2 ),
1478
1497
ID_UNALLOCATED (4 ,3 ),
@@ -1515,8 +1534,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
1515
1534
{ SYS_DESC (SYS_ACTLR_EL1 ), access_actlr , reset_actlr , ACTLR_EL1 },
1516
1535
{ SYS_DESC (SYS_CPACR_EL1 ), NULL , reset_val , CPACR_EL1 , 0 },
1517
1536
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 },
1520
1539
1521
1540
{ SYS_DESC (SYS_ZCR_EL1 ), NULL , reset_val , ZCR_EL1 , 0 , .visibility = sve_visibility },
1522
1541
{ 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[] = {
1542
1561
{ SYS_DESC (SYS_ERXMISC0_EL1 ), trap_raz_wi },
1543
1562
{ SYS_DESC (SYS_ERXMISC1_EL1 ), trap_raz_wi },
1544
1563
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 },
1547
1566
1548
1567
{ SYS_DESC (SYS_FAR_EL1 ), access_vm_reg , reset_unknown , FAR_EL1 },
1549
1568
{ SYS_DESC (SYS_PAR_EL1 ), NULL , reset_unknown , PAR_EL1 },
@@ -1579,6 +1598,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
1579
1598
{ SYS_DESC (SYS_CONTEXTIDR_EL1 ), access_vm_reg , reset_val , CONTEXTIDR_EL1 , 0 },
1580
1599
{ SYS_DESC (SYS_TPIDR_EL1 ), NULL , reset_unknown , TPIDR_EL1 },
1581
1600
1601
+ { SYS_DESC (SYS_SCXTNUM_EL1 ), undef_access },
1602
+
1582
1603
{ SYS_DESC (SYS_CNTKCTL_EL1 ), NULL , reset_val , CNTKCTL_EL1 , 0 },
1583
1604
1584
1605
{ SYS_DESC (SYS_CCSIDR_EL1 ), access_ccsidr },
@@ -1607,14 +1628,16 @@ static const struct sys_reg_desc sys_reg_descs[] = {
1607
1628
{ SYS_DESC (SYS_TPIDR_EL0 ), NULL , reset_unknown , TPIDR_EL0 },
1608
1629
{ SYS_DESC (SYS_TPIDRRO_EL0 ), NULL , reset_unknown , TPIDRRO_EL0 },
1609
1630
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 },
1618
1641
AMU_AMEVCNTR0_EL0 (0 ),
1619
1642
AMU_AMEVCNTR0_EL0 (1 ),
1620
1643
AMU_AMEVCNTR0_EL0 (2 ),
0 commit comments