@@ -1063,13 +1063,12 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
1063
1063
}
1064
1064
1065
1065
/* Read a sanitised cpufeature ID register by sys_reg_desc */
1066
- static u64 read_id_reg (const struct kvm_vcpu * vcpu ,
1067
- struct sys_reg_desc const * r , bool raz )
1066
+ static u64 read_id_reg (const struct kvm_vcpu * vcpu , struct sys_reg_desc const * r )
1068
1067
{
1069
1068
u32 id = reg_to_encoding (r );
1070
1069
u64 val ;
1071
1070
1072
- if (raz )
1071
+ if (sysreg_visible_as_raz ( vcpu , r ) )
1073
1072
return 0 ;
1074
1073
1075
1074
val = read_sanitised_ftr_reg (id );
@@ -1145,34 +1144,37 @@ static unsigned int id_visibility(const struct kvm_vcpu *vcpu,
1145
1144
return 0 ;
1146
1145
}
1147
1146
1148
- /* cpufeature ID register access trap handlers */
1149
-
1150
- static bool __access_id_reg (struct kvm_vcpu * vcpu ,
1151
- struct sys_reg_params * p ,
1152
- const struct sys_reg_desc * r ,
1153
- bool raz )
1147
+ static unsigned int aa32_id_visibility (const struct kvm_vcpu * vcpu ,
1148
+ const struct sys_reg_desc * r )
1154
1149
{
1155
- if (p -> is_write )
1156
- return write_to_read_only (vcpu , p , r );
1150
+ /*
1151
+ * AArch32 ID registers are UNKNOWN if AArch32 isn't implemented at any
1152
+ * EL. Promote to RAZ/WI in order to guarantee consistency between
1153
+ * systems.
1154
+ */
1155
+ if (!kvm_supports_32bit_el0 ())
1156
+ return REG_RAZ | REG_USER_WI ;
1157
1157
1158
- p -> regval = read_id_reg (vcpu , r , raz );
1159
- return true;
1158
+ return id_visibility (vcpu , r );
1160
1159
}
1161
1160
1161
+ static unsigned int raz_visibility (const struct kvm_vcpu * vcpu ,
1162
+ const struct sys_reg_desc * r )
1163
+ {
1164
+ return REG_RAZ ;
1165
+ }
1166
+
1167
+ /* cpufeature ID register access trap handlers */
1168
+
1162
1169
static bool access_id_reg (struct kvm_vcpu * vcpu ,
1163
1170
struct sys_reg_params * p ,
1164
1171
const struct sys_reg_desc * r )
1165
1172
{
1166
- bool raz = sysreg_visible_as_raz (vcpu , r );
1167
-
1168
- return __access_id_reg (vcpu , p , r , raz );
1169
- }
1173
+ if (p -> is_write )
1174
+ return write_to_read_only (vcpu , p , r );
1170
1175
1171
- static bool access_raz_id_reg (struct kvm_vcpu * vcpu ,
1172
- struct sys_reg_params * p ,
1173
- const struct sys_reg_desc * r )
1174
- {
1175
- return __access_id_reg (vcpu , p , r , true);
1176
+ p -> regval = read_id_reg (vcpu , r );
1177
+ return true;
1176
1178
}
1177
1179
1178
1180
/* Visibility overrides for SVE-specific control registers */
@@ -1208,7 +1210,7 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
1208
1210
return - EINVAL ;
1209
1211
1210
1212
/* We can only differ with CSV[23], and anything else is an error */
1211
- val ^= read_id_reg (vcpu , rd , false );
1213
+ val ^= read_id_reg (vcpu , rd );
1212
1214
val &= ~((0xFUL << ID_AA64PFR0_CSV2_SHIFT ) |
1213
1215
(0xFUL << ID_AA64PFR0_CSV3_SHIFT ));
1214
1216
if (val )
@@ -1227,45 +1229,21 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
1227
1229
* are stored, and for set_id_reg() we don't allow the effective value
1228
1230
* to be changed.
1229
1231
*/
1230
- static int __get_id_reg (const struct kvm_vcpu * vcpu ,
1231
- const struct sys_reg_desc * rd , u64 * val ,
1232
- bool raz )
1233
- {
1234
- * val = read_id_reg (vcpu , rd , raz );
1235
- return 0 ;
1236
- }
1237
-
1238
- static int __set_id_reg (const struct kvm_vcpu * vcpu ,
1239
- const struct sys_reg_desc * rd , u64 val ,
1240
- bool raz )
1241
- {
1242
- /* This is what we mean by invariant: you can't change it. */
1243
- if (val != read_id_reg (vcpu , rd , raz ))
1244
- return - EINVAL ;
1245
-
1246
- return 0 ;
1247
- }
1248
-
1249
1232
static int get_id_reg (struct kvm_vcpu * vcpu , const struct sys_reg_desc * rd ,
1250
1233
u64 * val )
1251
1234
{
1252
- bool raz = sysreg_visible_as_raz (vcpu , rd );
1253
-
1254
- return __get_id_reg (vcpu , rd , val , raz );
1235
+ * val = read_id_reg (vcpu , rd );
1236
+ return 0 ;
1255
1237
}
1256
1238
1257
1239
static int set_id_reg (struct kvm_vcpu * vcpu , const struct sys_reg_desc * rd ,
1258
1240
u64 val )
1259
1241
{
1260
- bool raz = sysreg_visible_as_raz (vcpu , rd );
1261
-
1262
- return __set_id_reg (vcpu , rd , val , raz );
1263
- }
1242
+ /* This is what we mean by invariant: you can't change it. */
1243
+ if (val != read_id_reg (vcpu , rd ))
1244
+ return - EINVAL ;
1264
1245
1265
- static int set_raz_id_reg (struct kvm_vcpu * vcpu , const struct sys_reg_desc * rd ,
1266
- u64 val )
1267
- {
1268
- return __set_id_reg (vcpu , rd , val , true);
1246
+ return 0 ;
1269
1247
}
1270
1248
1271
1249
static int get_raz_reg (struct kvm_vcpu * vcpu , const struct sys_reg_desc * rd ,
@@ -1367,16 +1345,26 @@ static unsigned int mte_visibility(const struct kvm_vcpu *vcpu,
1367
1345
.visibility = id_visibility, \
1368
1346
}
1369
1347
1348
+ /* sys_reg_desc initialiser for known cpufeature ID registers */
1349
+ #define AA32_ID_SANITISED (name ) { \
1350
+ SYS_DESC(SYS_##name), \
1351
+ .access = access_id_reg, \
1352
+ .get_user = get_id_reg, \
1353
+ .set_user = set_id_reg, \
1354
+ .visibility = aa32_id_visibility, \
1355
+ }
1356
+
1370
1357
/*
1371
1358
* sys_reg_desc initialiser for architecturally unallocated cpufeature ID
1372
1359
* register with encoding Op0=3, Op1=0, CRn=0, CRm=crm, Op2=op2
1373
1360
* (1 <= crm < 8, 0 <= Op2 < 8).
1374
1361
*/
1375
1362
#define ID_UNALLOCATED (crm , op2 ) { \
1376
1363
Op0(3), Op1(0), CRn(0), CRm(crm), Op2(op2), \
1377
- .access = access_raz_id_reg, \
1378
- .get_user = get_raz_reg, \
1379
- .set_user = set_raz_id_reg, \
1364
+ .access = access_id_reg, \
1365
+ .get_user = get_id_reg, \
1366
+ .set_user = set_id_reg, \
1367
+ .visibility = raz_visibility \
1380
1368
}
1381
1369
1382
1370
/*
@@ -1386,9 +1374,10 @@ static unsigned int mte_visibility(const struct kvm_vcpu *vcpu,
1386
1374
*/
1387
1375
#define ID_HIDDEN (name ) { \
1388
1376
SYS_DESC(SYS_##name), \
1389
- .access = access_raz_id_reg, \
1390
- .get_user = get_raz_reg, \
1391
- .set_user = set_raz_id_reg, \
1377
+ .access = access_id_reg, \
1378
+ .get_user = get_id_reg, \
1379
+ .set_user = set_id_reg, \
1380
+ .visibility = raz_visibility, \
1392
1381
}
1393
1382
1394
1383
/*
@@ -1452,33 +1441,33 @@ static const struct sys_reg_desc sys_reg_descs[] = {
1452
1441
1453
1442
/* AArch64 mappings of the AArch32 ID registers */
1454
1443
/* CRm=1 */
1455
- ID_SANITISED (ID_PFR0_EL1 ),
1456
- ID_SANITISED (ID_PFR1_EL1 ),
1457
- ID_SANITISED (ID_DFR0_EL1 ),
1444
+ AA32_ID_SANITISED (ID_PFR0_EL1 ),
1445
+ AA32_ID_SANITISED (ID_PFR1_EL1 ),
1446
+ AA32_ID_SANITISED (ID_DFR0_EL1 ),
1458
1447
ID_HIDDEN (ID_AFR0_EL1 ),
1459
- ID_SANITISED (ID_MMFR0_EL1 ),
1460
- ID_SANITISED (ID_MMFR1_EL1 ),
1461
- ID_SANITISED (ID_MMFR2_EL1 ),
1462
- ID_SANITISED (ID_MMFR3_EL1 ),
1448
+ AA32_ID_SANITISED (ID_MMFR0_EL1 ),
1449
+ AA32_ID_SANITISED (ID_MMFR1_EL1 ),
1450
+ AA32_ID_SANITISED (ID_MMFR2_EL1 ),
1451
+ AA32_ID_SANITISED (ID_MMFR3_EL1 ),
1463
1452
1464
1453
/* CRm=2 */
1465
- ID_SANITISED (ID_ISAR0_EL1 ),
1466
- ID_SANITISED (ID_ISAR1_EL1 ),
1467
- ID_SANITISED (ID_ISAR2_EL1 ),
1468
- ID_SANITISED (ID_ISAR3_EL1 ),
1469
- ID_SANITISED (ID_ISAR4_EL1 ),
1470
- ID_SANITISED (ID_ISAR5_EL1 ),
1471
- ID_SANITISED (ID_MMFR4_EL1 ),
1472
- ID_SANITISED (ID_ISAR6_EL1 ),
1454
+ AA32_ID_SANITISED (ID_ISAR0_EL1 ),
1455
+ AA32_ID_SANITISED (ID_ISAR1_EL1 ),
1456
+ AA32_ID_SANITISED (ID_ISAR2_EL1 ),
1457
+ AA32_ID_SANITISED (ID_ISAR3_EL1 ),
1458
+ AA32_ID_SANITISED (ID_ISAR4_EL1 ),
1459
+ AA32_ID_SANITISED (ID_ISAR5_EL1 ),
1460
+ AA32_ID_SANITISED (ID_MMFR4_EL1 ),
1461
+ AA32_ID_SANITISED (ID_ISAR6_EL1 ),
1473
1462
1474
1463
/* CRm=3 */
1475
- ID_SANITISED (MVFR0_EL1 ),
1476
- ID_SANITISED (MVFR1_EL1 ),
1477
- ID_SANITISED (MVFR2_EL1 ),
1464
+ AA32_ID_SANITISED (MVFR0_EL1 ),
1465
+ AA32_ID_SANITISED (MVFR1_EL1 ),
1466
+ AA32_ID_SANITISED (MVFR2_EL1 ),
1478
1467
ID_UNALLOCATED (3 ,3 ),
1479
- ID_SANITISED (ID_PFR2_EL1 ),
1468
+ AA32_ID_SANITISED (ID_PFR2_EL1 ),
1480
1469
ID_HIDDEN (ID_DFR1_EL1 ),
1481
- ID_SANITISED (ID_MMFR5_EL1 ),
1470
+ AA32_ID_SANITISED (ID_MMFR5_EL1 ),
1482
1471
ID_UNALLOCATED (3 ,7 ),
1483
1472
1484
1473
/* AArch64 ID registers */
@@ -2809,6 +2798,9 @@ int kvm_sys_reg_set_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg,
2809
2798
if (!r )
2810
2799
return - ENOENT ;
2811
2800
2801
+ if (sysreg_user_write_ignore (vcpu , r ))
2802
+ return 0 ;
2803
+
2812
2804
if (r -> set_user ) {
2813
2805
ret = (r -> set_user )(vcpu , r , val );
2814
2806
} else {
0 commit comments