0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #include <stdio.h>
0028 #include <stdlib.h>
0029 #include <string.h>
0030 #include <unistd.h>
0031 #include <sys/types.h>
0032 #include <sys/wait.h>
0033 #include "kvm_util.h"
0034 #include "test_util.h"
0035 #include "processor.h"
0036
0037 static struct kvm_reg_list *reg_list;
0038 static __u64 *blessed_reg, blessed_n;
0039
0040 struct reg_sublist {
0041 const char *name;
0042 long capability;
0043 int feature;
0044 bool finalize;
0045 __u64 *regs;
0046 __u64 regs_n;
0047 __u64 *rejects_set;
0048 __u64 rejects_set_n;
0049 };
0050
0051 struct vcpu_config {
0052 char *name;
0053 struct reg_sublist sublists[];
0054 };
0055
0056 static struct vcpu_config *vcpu_configs[];
0057 static int vcpu_configs_n;
0058
0059 #define for_each_sublist(c, s) \
0060 for ((s) = &(c)->sublists[0]; (s)->regs; ++(s))
0061
0062 #define for_each_reg(i) \
0063 for ((i) = 0; (i) < reg_list->n; ++(i))
0064
0065 #define for_each_reg_filtered(i) \
0066 for_each_reg(i) \
0067 if (!filter_reg(reg_list->reg[i]))
0068
0069 #define for_each_missing_reg(i) \
0070 for ((i) = 0; (i) < blessed_n; ++(i)) \
0071 if (!find_reg(reg_list->reg, reg_list->n, blessed_reg[i]))
0072
0073 #define for_each_new_reg(i) \
0074 for_each_reg_filtered(i) \
0075 if (!find_reg(blessed_reg, blessed_n, reg_list->reg[i]))
0076
0077 static const char *config_name(struct vcpu_config *c)
0078 {
0079 struct reg_sublist *s;
0080 int len = 0;
0081
0082 if (c->name)
0083 return c->name;
0084
0085 for_each_sublist(c, s)
0086 len += strlen(s->name) + 1;
0087
0088 c->name = malloc(len);
0089
0090 len = 0;
0091 for_each_sublist(c, s) {
0092 if (!strcmp(s->name, "base"))
0093 continue;
0094 strcat(c->name + len, s->name);
0095 len += strlen(s->name) + 1;
0096 c->name[len - 1] = '+';
0097 }
0098 c->name[len - 1] = '\0';
0099
0100 return c->name;
0101 }
0102
0103 static bool has_cap(struct vcpu_config *c, long capability)
0104 {
0105 struct reg_sublist *s;
0106
0107 for_each_sublist(c, s)
0108 if (s->capability == capability)
0109 return true;
0110 return false;
0111 }
0112
0113 static bool filter_reg(__u64 reg)
0114 {
0115
0116
0117
0118
0119 if ((reg & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX)
0120 return true;
0121
0122 return false;
0123 }
0124
0125 static bool find_reg(__u64 regs[], __u64 nr_regs, __u64 reg)
0126 {
0127 int i;
0128
0129 for (i = 0; i < nr_regs; ++i)
0130 if (reg == regs[i])
0131 return true;
0132 return false;
0133 }
0134
0135 static const char *str_with_index(const char *template, __u64 index)
0136 {
0137 char *str, *p;
0138 int n;
0139
0140 str = strdup(template);
0141 p = strstr(str, "##");
0142 n = sprintf(p, "%lld", index);
0143 strcat(p + n, strstr(template, "##") + 2);
0144
0145 return (const char *)str;
0146 }
0147
0148 #define REG_MASK (KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_ARM_COPROC_MASK)
0149
0150 #define CORE_REGS_XX_NR_WORDS 2
0151 #define CORE_SPSR_XX_NR_WORDS 2
0152 #define CORE_FPREGS_XX_NR_WORDS 4
0153
0154 static const char *core_id_to_str(struct vcpu_config *c, __u64 id)
0155 {
0156 __u64 core_off = id & ~REG_MASK, idx;
0157
0158
0159
0160
0161 switch (core_off) {
0162 case KVM_REG_ARM_CORE_REG(regs.regs[0]) ...
0163 KVM_REG_ARM_CORE_REG(regs.regs[30]):
0164 idx = (core_off - KVM_REG_ARM_CORE_REG(regs.regs[0])) / CORE_REGS_XX_NR_WORDS;
0165 TEST_ASSERT(idx < 31, "%s: Unexpected regs.regs index: %lld", config_name(c), idx);
0166 return str_with_index("KVM_REG_ARM_CORE_REG(regs.regs[##])", idx);
0167 case KVM_REG_ARM_CORE_REG(regs.sp):
0168 return "KVM_REG_ARM_CORE_REG(regs.sp)";
0169 case KVM_REG_ARM_CORE_REG(regs.pc):
0170 return "KVM_REG_ARM_CORE_REG(regs.pc)";
0171 case KVM_REG_ARM_CORE_REG(regs.pstate):
0172 return "KVM_REG_ARM_CORE_REG(regs.pstate)";
0173 case KVM_REG_ARM_CORE_REG(sp_el1):
0174 return "KVM_REG_ARM_CORE_REG(sp_el1)";
0175 case KVM_REG_ARM_CORE_REG(elr_el1):
0176 return "KVM_REG_ARM_CORE_REG(elr_el1)";
0177 case KVM_REG_ARM_CORE_REG(spsr[0]) ...
0178 KVM_REG_ARM_CORE_REG(spsr[KVM_NR_SPSR - 1]):
0179 idx = (core_off - KVM_REG_ARM_CORE_REG(spsr[0])) / CORE_SPSR_XX_NR_WORDS;
0180 TEST_ASSERT(idx < KVM_NR_SPSR, "%s: Unexpected spsr index: %lld", config_name(c), idx);
0181 return str_with_index("KVM_REG_ARM_CORE_REG(spsr[##])", idx);
0182 case KVM_REG_ARM_CORE_REG(fp_regs.vregs[0]) ...
0183 KVM_REG_ARM_CORE_REG(fp_regs.vregs[31]):
0184 idx = (core_off - KVM_REG_ARM_CORE_REG(fp_regs.vregs[0])) / CORE_FPREGS_XX_NR_WORDS;
0185 TEST_ASSERT(idx < 32, "%s: Unexpected fp_regs.vregs index: %lld", config_name(c), idx);
0186 return str_with_index("KVM_REG_ARM_CORE_REG(fp_regs.vregs[##])", idx);
0187 case KVM_REG_ARM_CORE_REG(fp_regs.fpsr):
0188 return "KVM_REG_ARM_CORE_REG(fp_regs.fpsr)";
0189 case KVM_REG_ARM_CORE_REG(fp_regs.fpcr):
0190 return "KVM_REG_ARM_CORE_REG(fp_regs.fpcr)";
0191 }
0192
0193 TEST_FAIL("%s: Unknown core reg id: 0x%llx", config_name(c), id);
0194 return NULL;
0195 }
0196
0197 static const char *sve_id_to_str(struct vcpu_config *c, __u64 id)
0198 {
0199 __u64 sve_off, n, i;
0200
0201 if (id == KVM_REG_ARM64_SVE_VLS)
0202 return "KVM_REG_ARM64_SVE_VLS";
0203
0204 sve_off = id & ~(REG_MASK | ((1ULL << 5) - 1));
0205 i = id & (KVM_ARM64_SVE_MAX_SLICES - 1);
0206
0207 TEST_ASSERT(i == 0, "%s: Currently we don't expect slice > 0, reg id 0x%llx", config_name(c), id);
0208
0209 switch (sve_off) {
0210 case KVM_REG_ARM64_SVE_ZREG_BASE ...
0211 KVM_REG_ARM64_SVE_ZREG_BASE + (1ULL << 5) * KVM_ARM64_SVE_NUM_ZREGS - 1:
0212 n = (id >> 5) & (KVM_ARM64_SVE_NUM_ZREGS - 1);
0213 TEST_ASSERT(id == KVM_REG_ARM64_SVE_ZREG(n, 0),
0214 "%s: Unexpected bits set in SVE ZREG id: 0x%llx", config_name(c), id);
0215 return str_with_index("KVM_REG_ARM64_SVE_ZREG(##, 0)", n);
0216 case KVM_REG_ARM64_SVE_PREG_BASE ...
0217 KVM_REG_ARM64_SVE_PREG_BASE + (1ULL << 5) * KVM_ARM64_SVE_NUM_PREGS - 1:
0218 n = (id >> 5) & (KVM_ARM64_SVE_NUM_PREGS - 1);
0219 TEST_ASSERT(id == KVM_REG_ARM64_SVE_PREG(n, 0),
0220 "%s: Unexpected bits set in SVE PREG id: 0x%llx", config_name(c), id);
0221 return str_with_index("KVM_REG_ARM64_SVE_PREG(##, 0)", n);
0222 case KVM_REG_ARM64_SVE_FFR_BASE:
0223 TEST_ASSERT(id == KVM_REG_ARM64_SVE_FFR(0),
0224 "%s: Unexpected bits set in SVE FFR id: 0x%llx", config_name(c), id);
0225 return "KVM_REG_ARM64_SVE_FFR(0)";
0226 }
0227
0228 return NULL;
0229 }
0230
0231 static void print_reg(struct vcpu_config *c, __u64 id)
0232 {
0233 unsigned op0, op1, crn, crm, op2;
0234 const char *reg_size = NULL;
0235
0236 TEST_ASSERT((id & KVM_REG_ARCH_MASK) == KVM_REG_ARM64,
0237 "%s: KVM_REG_ARM64 missing in reg id: 0x%llx", config_name(c), id);
0238
0239 switch (id & KVM_REG_SIZE_MASK) {
0240 case KVM_REG_SIZE_U8:
0241 reg_size = "KVM_REG_SIZE_U8";
0242 break;
0243 case KVM_REG_SIZE_U16:
0244 reg_size = "KVM_REG_SIZE_U16";
0245 break;
0246 case KVM_REG_SIZE_U32:
0247 reg_size = "KVM_REG_SIZE_U32";
0248 break;
0249 case KVM_REG_SIZE_U64:
0250 reg_size = "KVM_REG_SIZE_U64";
0251 break;
0252 case KVM_REG_SIZE_U128:
0253 reg_size = "KVM_REG_SIZE_U128";
0254 break;
0255 case KVM_REG_SIZE_U256:
0256 reg_size = "KVM_REG_SIZE_U256";
0257 break;
0258 case KVM_REG_SIZE_U512:
0259 reg_size = "KVM_REG_SIZE_U512";
0260 break;
0261 case KVM_REG_SIZE_U1024:
0262 reg_size = "KVM_REG_SIZE_U1024";
0263 break;
0264 case KVM_REG_SIZE_U2048:
0265 reg_size = "KVM_REG_SIZE_U2048";
0266 break;
0267 default:
0268 TEST_FAIL("%s: Unexpected reg size: 0x%llx in reg id: 0x%llx",
0269 config_name(c), (id & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT, id);
0270 }
0271
0272 switch (id & KVM_REG_ARM_COPROC_MASK) {
0273 case KVM_REG_ARM_CORE:
0274 printf("\tKVM_REG_ARM64 | %s | KVM_REG_ARM_CORE | %s,\n", reg_size, core_id_to_str(c, id));
0275 break;
0276 case KVM_REG_ARM_DEMUX:
0277 TEST_ASSERT(!(id & ~(REG_MASK | KVM_REG_ARM_DEMUX_ID_MASK | KVM_REG_ARM_DEMUX_VAL_MASK)),
0278 "%s: Unexpected bits set in DEMUX reg id: 0x%llx", config_name(c), id);
0279 printf("\tKVM_REG_ARM64 | %s | KVM_REG_ARM_DEMUX | KVM_REG_ARM_DEMUX_ID_CCSIDR | %lld,\n",
0280 reg_size, id & KVM_REG_ARM_DEMUX_VAL_MASK);
0281 break;
0282 case KVM_REG_ARM64_SYSREG:
0283 op0 = (id & KVM_REG_ARM64_SYSREG_OP0_MASK) >> KVM_REG_ARM64_SYSREG_OP0_SHIFT;
0284 op1 = (id & KVM_REG_ARM64_SYSREG_OP1_MASK) >> KVM_REG_ARM64_SYSREG_OP1_SHIFT;
0285 crn = (id & KVM_REG_ARM64_SYSREG_CRN_MASK) >> KVM_REG_ARM64_SYSREG_CRN_SHIFT;
0286 crm = (id & KVM_REG_ARM64_SYSREG_CRM_MASK) >> KVM_REG_ARM64_SYSREG_CRM_SHIFT;
0287 op2 = (id & KVM_REG_ARM64_SYSREG_OP2_MASK) >> KVM_REG_ARM64_SYSREG_OP2_SHIFT;
0288 TEST_ASSERT(id == ARM64_SYS_REG(op0, op1, crn, crm, op2),
0289 "%s: Unexpected bits set in SYSREG reg id: 0x%llx", config_name(c), id);
0290 printf("\tARM64_SYS_REG(%d, %d, %d, %d, %d),\n", op0, op1, crn, crm, op2);
0291 break;
0292 case KVM_REG_ARM_FW:
0293 TEST_ASSERT(id == KVM_REG_ARM_FW_REG(id & 0xffff),
0294 "%s: Unexpected bits set in FW reg id: 0x%llx", config_name(c), id);
0295 printf("\tKVM_REG_ARM_FW_REG(%lld),\n", id & 0xffff);
0296 break;
0297 case KVM_REG_ARM_FW_FEAT_BMAP:
0298 TEST_ASSERT(id == KVM_REG_ARM_FW_FEAT_BMAP_REG(id & 0xffff),
0299 "%s: Unexpected bits set in the bitmap feature FW reg id: 0x%llx", config_name(c), id);
0300 printf("\tKVM_REG_ARM_FW_FEAT_BMAP_REG(%lld),\n", id & 0xffff);
0301 break;
0302 case KVM_REG_ARM64_SVE:
0303 if (has_cap(c, KVM_CAP_ARM_SVE))
0304 printf("\t%s,\n", sve_id_to_str(c, id));
0305 else
0306 TEST_FAIL("%s: KVM_REG_ARM64_SVE is an unexpected coproc type in reg id: 0x%llx", config_name(c), id);
0307 break;
0308 default:
0309 TEST_FAIL("%s: Unexpected coproc type: 0x%llx in reg id: 0x%llx",
0310 config_name(c), (id & KVM_REG_ARM_COPROC_MASK) >> KVM_REG_ARM_COPROC_SHIFT, id);
0311 }
0312 }
0313
0314
0315
0316
0317
0318
0319
0320 static void core_reg_fixup(void)
0321 {
0322 struct kvm_reg_list *tmp;
0323 __u64 id, core_off;
0324 int i;
0325
0326 tmp = calloc(1, sizeof(*tmp) + reg_list->n * sizeof(__u64));
0327
0328 for (i = 0; i < reg_list->n; ++i) {
0329 id = reg_list->reg[i];
0330
0331 if ((id & KVM_REG_ARM_COPROC_MASK) != KVM_REG_ARM_CORE) {
0332 tmp->reg[tmp->n++] = id;
0333 continue;
0334 }
0335
0336 core_off = id & ~REG_MASK;
0337
0338 switch (core_off) {
0339 case 0x52: case 0xd2: case 0xd6:
0340
0341
0342
0343
0344 continue;
0345 case KVM_REG_ARM_CORE_REG(fp_regs.vregs[0]) ...
0346 KVM_REG_ARM_CORE_REG(fp_regs.vregs[31]):
0347 if (core_off & 3)
0348 continue;
0349 id &= ~KVM_REG_SIZE_MASK;
0350 id |= KVM_REG_SIZE_U128;
0351 tmp->reg[tmp->n++] = id;
0352 continue;
0353 case KVM_REG_ARM_CORE_REG(fp_regs.fpsr):
0354 case KVM_REG_ARM_CORE_REG(fp_regs.fpcr):
0355 id &= ~KVM_REG_SIZE_MASK;
0356 id |= KVM_REG_SIZE_U32;
0357 tmp->reg[tmp->n++] = id;
0358 continue;
0359 default:
0360 if (core_off & 1)
0361 continue;
0362 tmp->reg[tmp->n++] = id;
0363 break;
0364 }
0365 }
0366
0367 free(reg_list);
0368 reg_list = tmp;
0369 }
0370
0371 static void prepare_vcpu_init(struct vcpu_config *c, struct kvm_vcpu_init *init)
0372 {
0373 struct reg_sublist *s;
0374
0375 for_each_sublist(c, s)
0376 if (s->capability)
0377 init->features[s->feature / 32] |= 1 << (s->feature % 32);
0378 }
0379
0380 static void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_config *c)
0381 {
0382 struct reg_sublist *s;
0383 int feature;
0384
0385 for_each_sublist(c, s) {
0386 if (s->finalize) {
0387 feature = s->feature;
0388 vcpu_ioctl(vcpu, KVM_ARM_VCPU_FINALIZE, &feature);
0389 }
0390 }
0391 }
0392
0393 static void check_supported(struct vcpu_config *c)
0394 {
0395 struct reg_sublist *s;
0396
0397 for_each_sublist(c, s) {
0398 if (!s->capability)
0399 continue;
0400
0401 __TEST_REQUIRE(kvm_has_cap(s->capability),
0402 "%s: %s not available, skipping tests\n",
0403 config_name(c), s->name);
0404 }
0405 }
0406
0407 static bool print_list;
0408 static bool print_filtered;
0409 static bool fixup_core_regs;
0410
0411 static void run_test(struct vcpu_config *c)
0412 {
0413 struct kvm_vcpu_init init = { .target = -1, };
0414 int new_regs = 0, missing_regs = 0, i, n;
0415 int failed_get = 0, failed_set = 0, failed_reject = 0;
0416 struct kvm_vcpu *vcpu;
0417 struct kvm_vm *vm;
0418 struct reg_sublist *s;
0419
0420 check_supported(c);
0421
0422 vm = vm_create_barebones();
0423 prepare_vcpu_init(c, &init);
0424 vcpu = __vm_vcpu_add(vm, 0);
0425 aarch64_vcpu_setup(vcpu, &init);
0426 finalize_vcpu(vcpu, c);
0427
0428 reg_list = vcpu_get_reg_list(vcpu);
0429
0430 if (fixup_core_regs)
0431 core_reg_fixup();
0432
0433 if (print_list || print_filtered) {
0434 putchar('\n');
0435 for_each_reg(i) {
0436 __u64 id = reg_list->reg[i];
0437 if ((print_list && !filter_reg(id)) ||
0438 (print_filtered && filter_reg(id)))
0439 print_reg(c, id);
0440 }
0441 putchar('\n');
0442 return;
0443 }
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455 for_each_reg(i) {
0456 uint8_t addr[2048 / 8];
0457 struct kvm_one_reg reg = {
0458 .id = reg_list->reg[i],
0459 .addr = (__u64)&addr,
0460 };
0461 bool reject_reg = false;
0462 int ret;
0463
0464 ret = __vcpu_get_reg(vcpu, reg_list->reg[i], &addr);
0465 if (ret) {
0466 printf("%s: Failed to get ", config_name(c));
0467 print_reg(c, reg.id);
0468 putchar('\n');
0469 ++failed_get;
0470 }
0471
0472
0473 for_each_sublist(c, s) {
0474 if (s->rejects_set && find_reg(s->rejects_set, s->rejects_set_n, reg.id)) {
0475 reject_reg = true;
0476 ret = __vcpu_ioctl(vcpu, KVM_SET_ONE_REG, ®);
0477 if (ret != -1 || errno != EPERM) {
0478 printf("%s: Failed to reject (ret=%d, errno=%d) ", config_name(c), ret, errno);
0479 print_reg(c, reg.id);
0480 putchar('\n');
0481 ++failed_reject;
0482 }
0483 break;
0484 }
0485 }
0486
0487 if (!reject_reg) {
0488 ret = __vcpu_ioctl(vcpu, KVM_SET_ONE_REG, ®);
0489 if (ret) {
0490 printf("%s: Failed to set ", config_name(c));
0491 print_reg(c, reg.id);
0492 putchar('\n');
0493 ++failed_set;
0494 }
0495 }
0496 }
0497
0498 for_each_sublist(c, s)
0499 blessed_n += s->regs_n;
0500 blessed_reg = calloc(blessed_n, sizeof(__u64));
0501
0502 n = 0;
0503 for_each_sublist(c, s) {
0504 for (i = 0; i < s->regs_n; ++i)
0505 blessed_reg[n++] = s->regs[i];
0506 }
0507
0508 for_each_new_reg(i)
0509 ++new_regs;
0510
0511 for_each_missing_reg(i)
0512 ++missing_regs;
0513
0514 if (new_regs || missing_regs) {
0515 n = 0;
0516 for_each_reg_filtered(i)
0517 ++n;
0518
0519 printf("%s: Number blessed registers: %5lld\n", config_name(c), blessed_n);
0520 printf("%s: Number registers: %5lld (includes %lld filtered registers)\n",
0521 config_name(c), reg_list->n, reg_list->n - n);
0522 }
0523
0524 if (new_regs) {
0525 printf("\n%s: There are %d new registers.\n"
0526 "Consider adding them to the blessed reg "
0527 "list with the following lines:\n\n", config_name(c), new_regs);
0528 for_each_new_reg(i)
0529 print_reg(c, reg_list->reg[i]);
0530 putchar('\n');
0531 }
0532
0533 if (missing_regs) {
0534 printf("\n%s: There are %d missing registers.\n"
0535 "The following lines are missing registers:\n\n", config_name(c), missing_regs);
0536 for_each_missing_reg(i)
0537 print_reg(c, blessed_reg[i]);
0538 putchar('\n');
0539 }
0540
0541 TEST_ASSERT(!missing_regs && !failed_get && !failed_set && !failed_reject,
0542 "%s: There are %d missing registers; "
0543 "%d registers failed get; %d registers failed set; %d registers failed reject",
0544 config_name(c), missing_regs, failed_get, failed_set, failed_reject);
0545
0546 pr_info("%s: PASS\n", config_name(c));
0547 blessed_n = 0;
0548 free(blessed_reg);
0549 free(reg_list);
0550 kvm_vm_free(vm);
0551 }
0552
0553 static void help(void)
0554 {
0555 struct vcpu_config *c;
0556 int i;
0557
0558 printf(
0559 "\n"
0560 "usage: get-reg-list [--config=<selection>] [--list] [--list-filtered] [--core-reg-fixup]\n\n"
0561 " --config=<selection> Used to select a specific vcpu configuration for the test/listing\n"
0562 " '<selection>' may be\n");
0563
0564 for (i = 0; i < vcpu_configs_n; ++i) {
0565 c = vcpu_configs[i];
0566 printf(
0567 " '%s'\n", config_name(c));
0568 }
0569
0570 printf(
0571 "\n"
0572 " --list Print the register list rather than test it (requires --config)\n"
0573 " --list-filtered Print registers that would normally be filtered out (requires --config)\n"
0574 " --core-reg-fixup Needed when running on old kernels with broken core reg listings\n"
0575 "\n"
0576 );
0577 }
0578
0579 static struct vcpu_config *parse_config(const char *config)
0580 {
0581 struct vcpu_config *c;
0582 int i;
0583
0584 if (config[8] != '=')
0585 help(), exit(1);
0586
0587 for (i = 0; i < vcpu_configs_n; ++i) {
0588 c = vcpu_configs[i];
0589 if (strcmp(config_name(c), &config[9]) == 0)
0590 break;
0591 }
0592
0593 if (i == vcpu_configs_n)
0594 help(), exit(1);
0595
0596 return c;
0597 }
0598
0599 int main(int ac, char **av)
0600 {
0601 struct vcpu_config *c, *sel = NULL;
0602 int i, ret = 0;
0603 pid_t pid;
0604
0605 for (i = 1; i < ac; ++i) {
0606 if (strcmp(av[i], "--core-reg-fixup") == 0)
0607 fixup_core_regs = true;
0608 else if (strncmp(av[i], "--config", 8) == 0)
0609 sel = parse_config(av[i]);
0610 else if (strcmp(av[i], "--list") == 0)
0611 print_list = true;
0612 else if (strcmp(av[i], "--list-filtered") == 0)
0613 print_filtered = true;
0614 else if (strcmp(av[i], "--help") == 0 || strcmp(av[1], "-h") == 0)
0615 help(), exit(0);
0616 else
0617 help(), exit(1);
0618 }
0619
0620 if (print_list || print_filtered) {
0621
0622
0623
0624 if (!sel)
0625 help(), exit(1);
0626 }
0627
0628 for (i = 0; i < vcpu_configs_n; ++i) {
0629 c = vcpu_configs[i];
0630 if (sel && c != sel)
0631 continue;
0632
0633 pid = fork();
0634
0635 if (!pid) {
0636 run_test(c);
0637 exit(0);
0638 } else {
0639 int wstatus;
0640 pid_t wpid = wait(&wstatus);
0641 TEST_ASSERT(wpid == pid && WIFEXITED(wstatus), "wait: Unexpected return");
0642 if (WEXITSTATUS(wstatus) && WEXITSTATUS(wstatus) != KSFT_SKIP)
0643 ret = KSFT_FAIL;
0644 }
0645 }
0646
0647 return ret;
0648 }
0649
0650
0651
0652
0653
0654
0655
0656 static __u64 base_regs[] = {
0657 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[0]),
0658 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[1]),
0659 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[2]),
0660 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[3]),
0661 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[4]),
0662 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[5]),
0663 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[6]),
0664 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[7]),
0665 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[8]),
0666 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[9]),
0667 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[10]),
0668 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[11]),
0669 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[12]),
0670 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[13]),
0671 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[14]),
0672 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[15]),
0673 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[16]),
0674 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[17]),
0675 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[18]),
0676 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[19]),
0677 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[20]),
0678 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[21]),
0679 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[22]),
0680 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[23]),
0681 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[24]),
0682 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[25]),
0683 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[26]),
0684 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[27]),
0685 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[28]),
0686 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[29]),
0687 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.regs[30]),
0688 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.sp),
0689 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.pc),
0690 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(regs.pstate),
0691 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(sp_el1),
0692 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(elr_el1),
0693 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(spsr[0]),
0694 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(spsr[1]),
0695 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(spsr[2]),
0696 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(spsr[3]),
0697 KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(spsr[4]),
0698 KVM_REG_ARM64 | KVM_REG_SIZE_U32 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.fpsr),
0699 KVM_REG_ARM64 | KVM_REG_SIZE_U32 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.fpcr),
0700 KVM_REG_ARM_FW_REG(0),
0701 KVM_REG_ARM_FW_REG(1),
0702 KVM_REG_ARM_FW_REG(2),
0703 KVM_REG_ARM_FW_REG(3),
0704 KVM_REG_ARM_FW_FEAT_BMAP_REG(0),
0705 KVM_REG_ARM_FW_FEAT_BMAP_REG(1),
0706 KVM_REG_ARM_FW_FEAT_BMAP_REG(2),
0707 ARM64_SYS_REG(3, 3, 14, 3, 1),
0708 ARM64_SYS_REG(3, 3, 14, 3, 2),
0709 ARM64_SYS_REG(3, 3, 14, 0, 2),
0710 ARM64_SYS_REG(3, 0, 0, 0, 0),
0711 ARM64_SYS_REG(3, 0, 0, 0, 6),
0712 ARM64_SYS_REG(3, 1, 0, 0, 1),
0713 ARM64_SYS_REG(3, 1, 0, 0, 7),
0714 ARM64_SYS_REG(3, 3, 0, 0, 1),
0715 ARM64_SYS_REG(2, 0, 0, 0, 4),
0716 ARM64_SYS_REG(2, 0, 0, 0, 5),
0717 ARM64_SYS_REG(2, 0, 0, 0, 6),
0718 ARM64_SYS_REG(2, 0, 0, 0, 7),
0719 ARM64_SYS_REG(2, 0, 0, 1, 4),
0720 ARM64_SYS_REG(2, 0, 0, 1, 5),
0721 ARM64_SYS_REG(2, 0, 0, 1, 6),
0722 ARM64_SYS_REG(2, 0, 0, 1, 7),
0723 ARM64_SYS_REG(2, 0, 0, 2, 0),
0724 ARM64_SYS_REG(2, 0, 0, 2, 2),
0725 ARM64_SYS_REG(2, 0, 0, 2, 4),
0726 ARM64_SYS_REG(2, 0, 0, 2, 5),
0727 ARM64_SYS_REG(2, 0, 0, 2, 6),
0728 ARM64_SYS_REG(2, 0, 0, 2, 7),
0729 ARM64_SYS_REG(2, 0, 0, 3, 4),
0730 ARM64_SYS_REG(2, 0, 0, 3, 5),
0731 ARM64_SYS_REG(2, 0, 0, 3, 6),
0732 ARM64_SYS_REG(2, 0, 0, 3, 7),
0733 ARM64_SYS_REG(2, 0, 0, 4, 4),
0734 ARM64_SYS_REG(2, 0, 0, 4, 5),
0735 ARM64_SYS_REG(2, 0, 0, 4, 6),
0736 ARM64_SYS_REG(2, 0, 0, 4, 7),
0737 ARM64_SYS_REG(2, 0, 0, 5, 4),
0738 ARM64_SYS_REG(2, 0, 0, 5, 5),
0739 ARM64_SYS_REG(2, 0, 0, 5, 6),
0740 ARM64_SYS_REG(2, 0, 0, 5, 7),
0741 ARM64_SYS_REG(2, 0, 0, 6, 4),
0742 ARM64_SYS_REG(2, 0, 0, 6, 5),
0743 ARM64_SYS_REG(2, 0, 0, 6, 6),
0744 ARM64_SYS_REG(2, 0, 0, 6, 7),
0745 ARM64_SYS_REG(2, 0, 0, 7, 4),
0746 ARM64_SYS_REG(2, 0, 0, 7, 5),
0747 ARM64_SYS_REG(2, 0, 0, 7, 6),
0748 ARM64_SYS_REG(2, 0, 0, 7, 7),
0749 ARM64_SYS_REG(2, 0, 0, 8, 4),
0750 ARM64_SYS_REG(2, 0, 0, 8, 5),
0751 ARM64_SYS_REG(2, 0, 0, 8, 6),
0752 ARM64_SYS_REG(2, 0, 0, 8, 7),
0753 ARM64_SYS_REG(2, 0, 0, 9, 4),
0754 ARM64_SYS_REG(2, 0, 0, 9, 5),
0755 ARM64_SYS_REG(2, 0, 0, 9, 6),
0756 ARM64_SYS_REG(2, 0, 0, 9, 7),
0757 ARM64_SYS_REG(2, 0, 0, 10, 4),
0758 ARM64_SYS_REG(2, 0, 0, 10, 5),
0759 ARM64_SYS_REG(2, 0, 0, 10, 6),
0760 ARM64_SYS_REG(2, 0, 0, 10, 7),
0761 ARM64_SYS_REG(2, 0, 0, 11, 4),
0762 ARM64_SYS_REG(2, 0, 0, 11, 5),
0763 ARM64_SYS_REG(2, 0, 0, 11, 6),
0764 ARM64_SYS_REG(2, 0, 0, 11, 7),
0765 ARM64_SYS_REG(2, 0, 0, 12, 4),
0766 ARM64_SYS_REG(2, 0, 0, 12, 5),
0767 ARM64_SYS_REG(2, 0, 0, 12, 6),
0768 ARM64_SYS_REG(2, 0, 0, 12, 7),
0769 ARM64_SYS_REG(2, 0, 0, 13, 4),
0770 ARM64_SYS_REG(2, 0, 0, 13, 5),
0771 ARM64_SYS_REG(2, 0, 0, 13, 6),
0772 ARM64_SYS_REG(2, 0, 0, 13, 7),
0773 ARM64_SYS_REG(2, 0, 0, 14, 4),
0774 ARM64_SYS_REG(2, 0, 0, 14, 5),
0775 ARM64_SYS_REG(2, 0, 0, 14, 6),
0776 ARM64_SYS_REG(2, 0, 0, 14, 7),
0777 ARM64_SYS_REG(2, 0, 0, 15, 4),
0778 ARM64_SYS_REG(2, 0, 0, 15, 5),
0779 ARM64_SYS_REG(2, 0, 0, 15, 6),
0780 ARM64_SYS_REG(2, 0, 0, 15, 7),
0781 ARM64_SYS_REG(2, 0, 1, 1, 4),
0782 ARM64_SYS_REG(2, 4, 0, 7, 0),
0783 ARM64_SYS_REG(3, 0, 0, 0, 5),
0784 ARM64_SYS_REG(3, 0, 0, 1, 0),
0785 ARM64_SYS_REG(3, 0, 0, 1, 1),
0786 ARM64_SYS_REG(3, 0, 0, 1, 2),
0787 ARM64_SYS_REG(3, 0, 0, 1, 3),
0788 ARM64_SYS_REG(3, 0, 0, 1, 4),
0789 ARM64_SYS_REG(3, 0, 0, 1, 5),
0790 ARM64_SYS_REG(3, 0, 0, 1, 6),
0791 ARM64_SYS_REG(3, 0, 0, 1, 7),
0792 ARM64_SYS_REG(3, 0, 0, 2, 0),
0793 ARM64_SYS_REG(3, 0, 0, 2, 1),
0794 ARM64_SYS_REG(3, 0, 0, 2, 2),
0795 ARM64_SYS_REG(3, 0, 0, 2, 3),
0796 ARM64_SYS_REG(3, 0, 0, 2, 4),
0797 ARM64_SYS_REG(3, 0, 0, 2, 5),
0798 ARM64_SYS_REG(3, 0, 0, 2, 6),
0799 ARM64_SYS_REG(3, 0, 0, 2, 7),
0800 ARM64_SYS_REG(3, 0, 0, 3, 0),
0801 ARM64_SYS_REG(3, 0, 0, 3, 1),
0802 ARM64_SYS_REG(3, 0, 0, 3, 2),
0803 ARM64_SYS_REG(3, 0, 0, 3, 3),
0804 ARM64_SYS_REG(3, 0, 0, 3, 4),
0805 ARM64_SYS_REG(3, 0, 0, 3, 5),
0806 ARM64_SYS_REG(3, 0, 0, 3, 6),
0807 ARM64_SYS_REG(3, 0, 0, 3, 7),
0808 ARM64_SYS_REG(3, 0, 0, 4, 0),
0809 ARM64_SYS_REG(3, 0, 0, 4, 1),
0810 ARM64_SYS_REG(3, 0, 0, 4, 2),
0811 ARM64_SYS_REG(3, 0, 0, 4, 3),
0812 ARM64_SYS_REG(3, 0, 0, 4, 4),
0813 ARM64_SYS_REG(3, 0, 0, 4, 5),
0814 ARM64_SYS_REG(3, 0, 0, 4, 6),
0815 ARM64_SYS_REG(3, 0, 0, 4, 7),
0816 ARM64_SYS_REG(3, 0, 0, 5, 0),
0817 ARM64_SYS_REG(3, 0, 0, 5, 1),
0818 ARM64_SYS_REG(3, 0, 0, 5, 2),
0819 ARM64_SYS_REG(3, 0, 0, 5, 3),
0820 ARM64_SYS_REG(3, 0, 0, 5, 4),
0821 ARM64_SYS_REG(3, 0, 0, 5, 5),
0822 ARM64_SYS_REG(3, 0, 0, 5, 6),
0823 ARM64_SYS_REG(3, 0, 0, 5, 7),
0824 ARM64_SYS_REG(3, 0, 0, 6, 0),
0825 ARM64_SYS_REG(3, 0, 0, 6, 1),
0826 ARM64_SYS_REG(3, 0, 0, 6, 2),
0827 ARM64_SYS_REG(3, 0, 0, 6, 3),
0828 ARM64_SYS_REG(3, 0, 0, 6, 4),
0829 ARM64_SYS_REG(3, 0, 0, 6, 5),
0830 ARM64_SYS_REG(3, 0, 0, 6, 6),
0831 ARM64_SYS_REG(3, 0, 0, 6, 7),
0832 ARM64_SYS_REG(3, 0, 0, 7, 0),
0833 ARM64_SYS_REG(3, 0, 0, 7, 1),
0834 ARM64_SYS_REG(3, 0, 0, 7, 2),
0835 ARM64_SYS_REG(3, 0, 0, 7, 3),
0836 ARM64_SYS_REG(3, 0, 0, 7, 4),
0837 ARM64_SYS_REG(3, 0, 0, 7, 5),
0838 ARM64_SYS_REG(3, 0, 0, 7, 6),
0839 ARM64_SYS_REG(3, 0, 0, 7, 7),
0840 ARM64_SYS_REG(3, 0, 1, 0, 0),
0841 ARM64_SYS_REG(3, 0, 1, 0, 1),
0842 ARM64_SYS_REG(3, 0, 1, 0, 2),
0843 ARM64_SYS_REG(3, 0, 2, 0, 0),
0844 ARM64_SYS_REG(3, 0, 2, 0, 1),
0845 ARM64_SYS_REG(3, 0, 2, 0, 2),
0846 ARM64_SYS_REG(3, 0, 5, 1, 0),
0847 ARM64_SYS_REG(3, 0, 5, 1, 1),
0848 ARM64_SYS_REG(3, 0, 5, 2, 0),
0849 ARM64_SYS_REG(3, 0, 6, 0, 0),
0850 ARM64_SYS_REG(3, 0, 7, 4, 0),
0851 ARM64_SYS_REG(3, 0, 10, 2, 0),
0852 ARM64_SYS_REG(3, 0, 10, 3, 0),
0853 ARM64_SYS_REG(3, 0, 12, 0, 0),
0854 ARM64_SYS_REG(3, 0, 12, 1, 1),
0855 ARM64_SYS_REG(3, 0, 13, 0, 1),
0856 ARM64_SYS_REG(3, 0, 13, 0, 4),
0857 ARM64_SYS_REG(3, 0, 14, 1, 0),
0858 ARM64_SYS_REG(3, 2, 0, 0, 0),
0859 ARM64_SYS_REG(3, 3, 13, 0, 2),
0860 ARM64_SYS_REG(3, 3, 13, 0, 3),
0861 ARM64_SYS_REG(3, 4, 3, 0, 0),
0862 ARM64_SYS_REG(3, 4, 5, 0, 1),
0863 ARM64_SYS_REG(3, 4, 5, 3, 0),
0864 };
0865
0866 static __u64 pmu_regs[] = {
0867 ARM64_SYS_REG(3, 0, 9, 14, 1),
0868 ARM64_SYS_REG(3, 0, 9, 14, 2),
0869 ARM64_SYS_REG(3, 3, 9, 12, 0),
0870 ARM64_SYS_REG(3, 3, 9, 12, 1),
0871 ARM64_SYS_REG(3, 3, 9, 12, 2),
0872 ARM64_SYS_REG(3, 3, 9, 12, 3),
0873 ARM64_SYS_REG(3, 3, 9, 12, 4),
0874 ARM64_SYS_REG(3, 3, 9, 12, 5),
0875 ARM64_SYS_REG(3, 3, 9, 13, 0),
0876 ARM64_SYS_REG(3, 3, 9, 14, 0),
0877 ARM64_SYS_REG(3, 3, 9, 14, 3),
0878 ARM64_SYS_REG(3, 3, 14, 8, 0),
0879 ARM64_SYS_REG(3, 3, 14, 8, 1),
0880 ARM64_SYS_REG(3, 3, 14, 8, 2),
0881 ARM64_SYS_REG(3, 3, 14, 8, 3),
0882 ARM64_SYS_REG(3, 3, 14, 8, 4),
0883 ARM64_SYS_REG(3, 3, 14, 8, 5),
0884 ARM64_SYS_REG(3, 3, 14, 8, 6),
0885 ARM64_SYS_REG(3, 3, 14, 8, 7),
0886 ARM64_SYS_REG(3, 3, 14, 9, 0),
0887 ARM64_SYS_REG(3, 3, 14, 9, 1),
0888 ARM64_SYS_REG(3, 3, 14, 9, 2),
0889 ARM64_SYS_REG(3, 3, 14, 9, 3),
0890 ARM64_SYS_REG(3, 3, 14, 9, 4),
0891 ARM64_SYS_REG(3, 3, 14, 9, 5),
0892 ARM64_SYS_REG(3, 3, 14, 9, 6),
0893 ARM64_SYS_REG(3, 3, 14, 9, 7),
0894 ARM64_SYS_REG(3, 3, 14, 10, 0),
0895 ARM64_SYS_REG(3, 3, 14, 10, 1),
0896 ARM64_SYS_REG(3, 3, 14, 10, 2),
0897 ARM64_SYS_REG(3, 3, 14, 10, 3),
0898 ARM64_SYS_REG(3, 3, 14, 10, 4),
0899 ARM64_SYS_REG(3, 3, 14, 10, 5),
0900 ARM64_SYS_REG(3, 3, 14, 10, 6),
0901 ARM64_SYS_REG(3, 3, 14, 10, 7),
0902 ARM64_SYS_REG(3, 3, 14, 11, 0),
0903 ARM64_SYS_REG(3, 3, 14, 11, 1),
0904 ARM64_SYS_REG(3, 3, 14, 11, 2),
0905 ARM64_SYS_REG(3, 3, 14, 11, 3),
0906 ARM64_SYS_REG(3, 3, 14, 11, 4),
0907 ARM64_SYS_REG(3, 3, 14, 11, 5),
0908 ARM64_SYS_REG(3, 3, 14, 11, 6),
0909 ARM64_SYS_REG(3, 3, 14, 12, 0),
0910 ARM64_SYS_REG(3, 3, 14, 12, 1),
0911 ARM64_SYS_REG(3, 3, 14, 12, 2),
0912 ARM64_SYS_REG(3, 3, 14, 12, 3),
0913 ARM64_SYS_REG(3, 3, 14, 12, 4),
0914 ARM64_SYS_REG(3, 3, 14, 12, 5),
0915 ARM64_SYS_REG(3, 3, 14, 12, 6),
0916 ARM64_SYS_REG(3, 3, 14, 12, 7),
0917 ARM64_SYS_REG(3, 3, 14, 13, 0),
0918 ARM64_SYS_REG(3, 3, 14, 13, 1),
0919 ARM64_SYS_REG(3, 3, 14, 13, 2),
0920 ARM64_SYS_REG(3, 3, 14, 13, 3),
0921 ARM64_SYS_REG(3, 3, 14, 13, 4),
0922 ARM64_SYS_REG(3, 3, 14, 13, 5),
0923 ARM64_SYS_REG(3, 3, 14, 13, 6),
0924 ARM64_SYS_REG(3, 3, 14, 13, 7),
0925 ARM64_SYS_REG(3, 3, 14, 14, 0),
0926 ARM64_SYS_REG(3, 3, 14, 14, 1),
0927 ARM64_SYS_REG(3, 3, 14, 14, 2),
0928 ARM64_SYS_REG(3, 3, 14, 14, 3),
0929 ARM64_SYS_REG(3, 3, 14, 14, 4),
0930 ARM64_SYS_REG(3, 3, 14, 14, 5),
0931 ARM64_SYS_REG(3, 3, 14, 14, 6),
0932 ARM64_SYS_REG(3, 3, 14, 14, 7),
0933 ARM64_SYS_REG(3, 3, 14, 15, 0),
0934 ARM64_SYS_REG(3, 3, 14, 15, 1),
0935 ARM64_SYS_REG(3, 3, 14, 15, 2),
0936 ARM64_SYS_REG(3, 3, 14, 15, 3),
0937 ARM64_SYS_REG(3, 3, 14, 15, 4),
0938 ARM64_SYS_REG(3, 3, 14, 15, 5),
0939 ARM64_SYS_REG(3, 3, 14, 15, 6),
0940 ARM64_SYS_REG(3, 3, 14, 15, 7),
0941 };
0942
0943 static __u64 vregs[] = {
0944 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[0]),
0945 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[1]),
0946 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[2]),
0947 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[3]),
0948 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[4]),
0949 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[5]),
0950 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[6]),
0951 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[7]),
0952 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[8]),
0953 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[9]),
0954 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[10]),
0955 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[11]),
0956 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[12]),
0957 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[13]),
0958 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[14]),
0959 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[15]),
0960 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[16]),
0961 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[17]),
0962 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[18]),
0963 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[19]),
0964 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[20]),
0965 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[21]),
0966 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[22]),
0967 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[23]),
0968 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[24]),
0969 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[25]),
0970 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[26]),
0971 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[27]),
0972 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[28]),
0973 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[29]),
0974 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[30]),
0975 KVM_REG_ARM64 | KVM_REG_SIZE_U128 | KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(fp_regs.vregs[31]),
0976 };
0977
0978 static __u64 sve_regs[] = {
0979 KVM_REG_ARM64_SVE_VLS,
0980 KVM_REG_ARM64_SVE_ZREG(0, 0),
0981 KVM_REG_ARM64_SVE_ZREG(1, 0),
0982 KVM_REG_ARM64_SVE_ZREG(2, 0),
0983 KVM_REG_ARM64_SVE_ZREG(3, 0),
0984 KVM_REG_ARM64_SVE_ZREG(4, 0),
0985 KVM_REG_ARM64_SVE_ZREG(5, 0),
0986 KVM_REG_ARM64_SVE_ZREG(6, 0),
0987 KVM_REG_ARM64_SVE_ZREG(7, 0),
0988 KVM_REG_ARM64_SVE_ZREG(8, 0),
0989 KVM_REG_ARM64_SVE_ZREG(9, 0),
0990 KVM_REG_ARM64_SVE_ZREG(10, 0),
0991 KVM_REG_ARM64_SVE_ZREG(11, 0),
0992 KVM_REG_ARM64_SVE_ZREG(12, 0),
0993 KVM_REG_ARM64_SVE_ZREG(13, 0),
0994 KVM_REG_ARM64_SVE_ZREG(14, 0),
0995 KVM_REG_ARM64_SVE_ZREG(15, 0),
0996 KVM_REG_ARM64_SVE_ZREG(16, 0),
0997 KVM_REG_ARM64_SVE_ZREG(17, 0),
0998 KVM_REG_ARM64_SVE_ZREG(18, 0),
0999 KVM_REG_ARM64_SVE_ZREG(19, 0),
1000 KVM_REG_ARM64_SVE_ZREG(20, 0),
1001 KVM_REG_ARM64_SVE_ZREG(21, 0),
1002 KVM_REG_ARM64_SVE_ZREG(22, 0),
1003 KVM_REG_ARM64_SVE_ZREG(23, 0),
1004 KVM_REG_ARM64_SVE_ZREG(24, 0),
1005 KVM_REG_ARM64_SVE_ZREG(25, 0),
1006 KVM_REG_ARM64_SVE_ZREG(26, 0),
1007 KVM_REG_ARM64_SVE_ZREG(27, 0),
1008 KVM_REG_ARM64_SVE_ZREG(28, 0),
1009 KVM_REG_ARM64_SVE_ZREG(29, 0),
1010 KVM_REG_ARM64_SVE_ZREG(30, 0),
1011 KVM_REG_ARM64_SVE_ZREG(31, 0),
1012 KVM_REG_ARM64_SVE_PREG(0, 0),
1013 KVM_REG_ARM64_SVE_PREG(1, 0),
1014 KVM_REG_ARM64_SVE_PREG(2, 0),
1015 KVM_REG_ARM64_SVE_PREG(3, 0),
1016 KVM_REG_ARM64_SVE_PREG(4, 0),
1017 KVM_REG_ARM64_SVE_PREG(5, 0),
1018 KVM_REG_ARM64_SVE_PREG(6, 0),
1019 KVM_REG_ARM64_SVE_PREG(7, 0),
1020 KVM_REG_ARM64_SVE_PREG(8, 0),
1021 KVM_REG_ARM64_SVE_PREG(9, 0),
1022 KVM_REG_ARM64_SVE_PREG(10, 0),
1023 KVM_REG_ARM64_SVE_PREG(11, 0),
1024 KVM_REG_ARM64_SVE_PREG(12, 0),
1025 KVM_REG_ARM64_SVE_PREG(13, 0),
1026 KVM_REG_ARM64_SVE_PREG(14, 0),
1027 KVM_REG_ARM64_SVE_PREG(15, 0),
1028 KVM_REG_ARM64_SVE_FFR(0),
1029 ARM64_SYS_REG(3, 0, 1, 2, 0),
1030 };
1031
1032 static __u64 sve_rejects_set[] = {
1033 KVM_REG_ARM64_SVE_VLS,
1034 };
1035
1036 static __u64 pauth_addr_regs[] = {
1037 ARM64_SYS_REG(3, 0, 2, 1, 0),
1038 ARM64_SYS_REG(3, 0, 2, 1, 1),
1039 ARM64_SYS_REG(3, 0, 2, 1, 2),
1040 ARM64_SYS_REG(3, 0, 2, 1, 3),
1041 ARM64_SYS_REG(3, 0, 2, 2, 0),
1042 ARM64_SYS_REG(3, 0, 2, 2, 1),
1043 ARM64_SYS_REG(3, 0, 2, 2, 2),
1044 ARM64_SYS_REG(3, 0, 2, 2, 3)
1045 };
1046
1047 static __u64 pauth_generic_regs[] = {
1048 ARM64_SYS_REG(3, 0, 2, 3, 0),
1049 ARM64_SYS_REG(3, 0, 2, 3, 1),
1050 };
1051
1052 #define BASE_SUBLIST \
1053 { "base", .regs = base_regs, .regs_n = ARRAY_SIZE(base_regs), }
1054 #define VREGS_SUBLIST \
1055 { "vregs", .regs = vregs, .regs_n = ARRAY_SIZE(vregs), }
1056 #define PMU_SUBLIST \
1057 { "pmu", .capability = KVM_CAP_ARM_PMU_V3, .feature = KVM_ARM_VCPU_PMU_V3, \
1058 .regs = pmu_regs, .regs_n = ARRAY_SIZE(pmu_regs), }
1059 #define SVE_SUBLIST \
1060 { "sve", .capability = KVM_CAP_ARM_SVE, .feature = KVM_ARM_VCPU_SVE, .finalize = true, \
1061 .regs = sve_regs, .regs_n = ARRAY_SIZE(sve_regs), \
1062 .rejects_set = sve_rejects_set, .rejects_set_n = ARRAY_SIZE(sve_rejects_set), }
1063 #define PAUTH_SUBLIST \
1064 { \
1065 .name = "pauth_address", \
1066 .capability = KVM_CAP_ARM_PTRAUTH_ADDRESS, \
1067 .feature = KVM_ARM_VCPU_PTRAUTH_ADDRESS, \
1068 .regs = pauth_addr_regs, \
1069 .regs_n = ARRAY_SIZE(pauth_addr_regs), \
1070 }, \
1071 { \
1072 .name = "pauth_generic", \
1073 .capability = KVM_CAP_ARM_PTRAUTH_GENERIC, \
1074 .feature = KVM_ARM_VCPU_PTRAUTH_GENERIC, \
1075 .regs = pauth_generic_regs, \
1076 .regs_n = ARRAY_SIZE(pauth_generic_regs), \
1077 }
1078
1079 static struct vcpu_config vregs_config = {
1080 .sublists = {
1081 BASE_SUBLIST,
1082 VREGS_SUBLIST,
1083 {0},
1084 },
1085 };
1086 static struct vcpu_config vregs_pmu_config = {
1087 .sublists = {
1088 BASE_SUBLIST,
1089 VREGS_SUBLIST,
1090 PMU_SUBLIST,
1091 {0},
1092 },
1093 };
1094 static struct vcpu_config sve_config = {
1095 .sublists = {
1096 BASE_SUBLIST,
1097 SVE_SUBLIST,
1098 {0},
1099 },
1100 };
1101 static struct vcpu_config sve_pmu_config = {
1102 .sublists = {
1103 BASE_SUBLIST,
1104 SVE_SUBLIST,
1105 PMU_SUBLIST,
1106 {0},
1107 },
1108 };
1109 static struct vcpu_config pauth_config = {
1110 .sublists = {
1111 BASE_SUBLIST,
1112 VREGS_SUBLIST,
1113 PAUTH_SUBLIST,
1114 {0},
1115 },
1116 };
1117 static struct vcpu_config pauth_pmu_config = {
1118 .sublists = {
1119 BASE_SUBLIST,
1120 VREGS_SUBLIST,
1121 PAUTH_SUBLIST,
1122 PMU_SUBLIST,
1123 {0},
1124 },
1125 };
1126
1127 static struct vcpu_config *vcpu_configs[] = {
1128 &vregs_config,
1129 &vregs_pmu_config,
1130 &sve_config,
1131 &sve_pmu_config,
1132 &pauth_config,
1133 &pauth_pmu_config,
1134 };
1135 static int vcpu_configs_n = ARRAY_SIZE(vcpu_configs);