Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Check for KVM_GET_REG_LIST regressions.
0004  *
0005  * Copyright (C) 2020, Red Hat, Inc.
0006  *
0007  * When attempting to migrate from a host with an older kernel to a host
0008  * with a newer kernel we allow the newer kernel on the destination to
0009  * list new registers with get-reg-list. We assume they'll be unused, at
0010  * least until the guest reboots, and so they're relatively harmless.
0011  * However, if the destination host with the newer kernel is missing
0012  * registers which the source host with the older kernel has, then that's
0013  * a regression in get-reg-list. This test checks for that regression by
0014  * checking the current list against a blessed list. We should never have
0015  * missing registers, but if new ones appear then they can probably be
0016  * added to the blessed list. A completely new blessed list can be created
0017  * by running the test with the --list command line argument.
0018  *
0019  * Note, the blessed list should be created from the oldest possible
0020  * kernel. We can't go older than v4.15, though, because that's the first
0021  * release to expose the ID system registers in KVM_GET_REG_LIST, see
0022  * commit 93390c0a1b20 ("arm64: KVM: Hide unsupported AArch64 CPU features
0023  * from guests"). Also, one must use the --core-reg-fixup command line
0024  * option when running on an older kernel that doesn't include df205b5c6328
0025  * ("KVM: arm64: Filter out invalid core register IDs in KVM_GET_REG_LIST")
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      * DEMUX register presence depends on the host's CLIDR_EL1.
0117      * This means there's no set of them that we can bless.
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      * core_off is the offset into struct kvm_regs
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  * Older kernels listed each 32-bit word of CORE registers separately.
0316  * For 64 and 128-bit registers we need to ignore the extra words. We
0317  * also need to fixup the sizes, because the older kernels stated all
0318  * registers were 64-bit, even when they weren't.
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              * These offsets are pointing at padding.
0342              * We need to ignore them too.
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      * We only test that we can get the register and then write back the
0447      * same value. Some registers may allow other values to be written
0448      * back, but others only allow some bits to be changed, and at least
0449      * for ID registers set will fail if the value does not exactly match
0450      * what was returned by get. If registers that allow other values to
0451      * be written need to have the other values tested, then we should
0452      * create a new set of tests for those in a new independent test
0453      * executable.
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         /* rejects_set registers are rejected after KVM_ARM_VCPU_FINALIZE */
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, &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, &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          * We only want to print the register list of a single config.
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  * The current blessed list was primed with the output of kernel version
0652  * v4.15 with --core-reg-fixup and then later updated with new registers.
0653  *
0654  * The blessed list is up to date with kernel version v5.13-rc3
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),      /* KVM_REG_ARM_PSCI_VERSION */
0701     KVM_REG_ARM_FW_REG(1),      /* KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1 */
0702     KVM_REG_ARM_FW_REG(2),      /* KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2 */
0703     KVM_REG_ARM_FW_REG(3),      /* KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3 */
0704     KVM_REG_ARM_FW_FEAT_BMAP_REG(0),    /* KVM_REG_ARM_STD_BMAP */
0705     KVM_REG_ARM_FW_FEAT_BMAP_REG(1),    /* KVM_REG_ARM_STD_HYP_BMAP */
0706     KVM_REG_ARM_FW_FEAT_BMAP_REG(2),    /* KVM_REG_ARM_VENDOR_HYP_BMAP */
0707     ARM64_SYS_REG(3, 3, 14, 3, 1),  /* CNTV_CTL_EL0 */
0708     ARM64_SYS_REG(3, 3, 14, 3, 2),  /* CNTV_CVAL_EL0 */
0709     ARM64_SYS_REG(3, 3, 14, 0, 2),
0710     ARM64_SYS_REG(3, 0, 0, 0, 0),   /* MIDR_EL1 */
0711     ARM64_SYS_REG(3, 0, 0, 0, 6),   /* REVIDR_EL1 */
0712     ARM64_SYS_REG(3, 1, 0, 0, 1),   /* CLIDR_EL1 */
0713     ARM64_SYS_REG(3, 1, 0, 0, 7),   /* AIDR_EL1 */
0714     ARM64_SYS_REG(3, 3, 0, 0, 1),   /* CTR_EL0 */
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),   /* MDCCINT_EL1 */
0724     ARM64_SYS_REG(2, 0, 0, 2, 2),   /* MDSCR_EL1 */
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),   /* OSLSR_EL1 */
0782     ARM64_SYS_REG(2, 4, 0, 7, 0),   /* DBGVCR32_EL2 */
0783     ARM64_SYS_REG(3, 0, 0, 0, 5),   /* MPIDR_EL1 */
0784     ARM64_SYS_REG(3, 0, 0, 1, 0),   /* ID_PFR0_EL1 */
0785     ARM64_SYS_REG(3, 0, 0, 1, 1),   /* ID_PFR1_EL1 */
0786     ARM64_SYS_REG(3, 0, 0, 1, 2),   /* ID_DFR0_EL1 */
0787     ARM64_SYS_REG(3, 0, 0, 1, 3),   /* ID_AFR0_EL1 */
0788     ARM64_SYS_REG(3, 0, 0, 1, 4),   /* ID_MMFR0_EL1 */
0789     ARM64_SYS_REG(3, 0, 0, 1, 5),   /* ID_MMFR1_EL1 */
0790     ARM64_SYS_REG(3, 0, 0, 1, 6),   /* ID_MMFR2_EL1 */
0791     ARM64_SYS_REG(3, 0, 0, 1, 7),   /* ID_MMFR3_EL1 */
0792     ARM64_SYS_REG(3, 0, 0, 2, 0),   /* ID_ISAR0_EL1 */
0793     ARM64_SYS_REG(3, 0, 0, 2, 1),   /* ID_ISAR1_EL1 */
0794     ARM64_SYS_REG(3, 0, 0, 2, 2),   /* ID_ISAR2_EL1 */
0795     ARM64_SYS_REG(3, 0, 0, 2, 3),   /* ID_ISAR3_EL1 */
0796     ARM64_SYS_REG(3, 0, 0, 2, 4),   /* ID_ISAR4_EL1 */
0797     ARM64_SYS_REG(3, 0, 0, 2, 5),   /* ID_ISAR5_EL1 */
0798     ARM64_SYS_REG(3, 0, 0, 2, 6),   /* ID_MMFR4_EL1 */
0799     ARM64_SYS_REG(3, 0, 0, 2, 7),   /* ID_ISAR6_EL1 */
0800     ARM64_SYS_REG(3, 0, 0, 3, 0),   /* MVFR0_EL1 */
0801     ARM64_SYS_REG(3, 0, 0, 3, 1),   /* MVFR1_EL1 */
0802     ARM64_SYS_REG(3, 0, 0, 3, 2),   /* MVFR2_EL1 */
0803     ARM64_SYS_REG(3, 0, 0, 3, 3),
0804     ARM64_SYS_REG(3, 0, 0, 3, 4),   /* ID_PFR2_EL1 */
0805     ARM64_SYS_REG(3, 0, 0, 3, 5),   /* ID_DFR1_EL1 */
0806     ARM64_SYS_REG(3, 0, 0, 3, 6),   /* ID_MMFR5_EL1 */
0807     ARM64_SYS_REG(3, 0, 0, 3, 7),
0808     ARM64_SYS_REG(3, 0, 0, 4, 0),   /* ID_AA64PFR0_EL1 */
0809     ARM64_SYS_REG(3, 0, 0, 4, 1),   /* ID_AA64PFR1_EL1 */
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),   /* ID_AA64ZFR0_EL1 */
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),   /* ID_AA64DFR0_EL1 */
0817     ARM64_SYS_REG(3, 0, 0, 5, 1),   /* ID_AA64DFR1_EL1 */
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),   /* ID_AA64AFR0_EL1 */
0821     ARM64_SYS_REG(3, 0, 0, 5, 5),   /* ID_AA64AFR1_EL1 */
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),   /* ID_AA64ISAR0_EL1 */
0825     ARM64_SYS_REG(3, 0, 0, 6, 1),   /* ID_AA64ISAR1_EL1 */
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),   /* ID_AA64MMFR0_EL1 */
0833     ARM64_SYS_REG(3, 0, 0, 7, 1),   /* ID_AA64MMFR1_EL1 */
0834     ARM64_SYS_REG(3, 0, 0, 7, 2),   /* ID_AA64MMFR2_EL1 */
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),   /* SCTLR_EL1 */
0841     ARM64_SYS_REG(3, 0, 1, 0, 1),   /* ACTLR_EL1 */
0842     ARM64_SYS_REG(3, 0, 1, 0, 2),   /* CPACR_EL1 */
0843     ARM64_SYS_REG(3, 0, 2, 0, 0),   /* TTBR0_EL1 */
0844     ARM64_SYS_REG(3, 0, 2, 0, 1),   /* TTBR1_EL1 */
0845     ARM64_SYS_REG(3, 0, 2, 0, 2),   /* TCR_EL1 */
0846     ARM64_SYS_REG(3, 0, 5, 1, 0),   /* AFSR0_EL1 */
0847     ARM64_SYS_REG(3, 0, 5, 1, 1),   /* AFSR1_EL1 */
0848     ARM64_SYS_REG(3, 0, 5, 2, 0),   /* ESR_EL1 */
0849     ARM64_SYS_REG(3, 0, 6, 0, 0),   /* FAR_EL1 */
0850     ARM64_SYS_REG(3, 0, 7, 4, 0),   /* PAR_EL1 */
0851     ARM64_SYS_REG(3, 0, 10, 2, 0),  /* MAIR_EL1 */
0852     ARM64_SYS_REG(3, 0, 10, 3, 0),  /* AMAIR_EL1 */
0853     ARM64_SYS_REG(3, 0, 12, 0, 0),  /* VBAR_EL1 */
0854     ARM64_SYS_REG(3, 0, 12, 1, 1),  /* DISR_EL1 */
0855     ARM64_SYS_REG(3, 0, 13, 0, 1),  /* CONTEXTIDR_EL1 */
0856     ARM64_SYS_REG(3, 0, 13, 0, 4),  /* TPIDR_EL1 */
0857     ARM64_SYS_REG(3, 0, 14, 1, 0),  /* CNTKCTL_EL1 */
0858     ARM64_SYS_REG(3, 2, 0, 0, 0),   /* CSSELR_EL1 */
0859     ARM64_SYS_REG(3, 3, 13, 0, 2),  /* TPIDR_EL0 */
0860     ARM64_SYS_REG(3, 3, 13, 0, 3),  /* TPIDRRO_EL0 */
0861     ARM64_SYS_REG(3, 4, 3, 0, 0),   /* DACR32_EL2 */
0862     ARM64_SYS_REG(3, 4, 5, 0, 1),   /* IFSR32_EL2 */
0863     ARM64_SYS_REG(3, 4, 5, 3, 0),   /* FPEXC32_EL2 */
0864 };
0865 
0866 static __u64 pmu_regs[] = {
0867     ARM64_SYS_REG(3, 0, 9, 14, 1),  /* PMINTENSET_EL1 */
0868     ARM64_SYS_REG(3, 0, 9, 14, 2),  /* PMINTENCLR_EL1 */
0869     ARM64_SYS_REG(3, 3, 9, 12, 0),  /* PMCR_EL0 */
0870     ARM64_SYS_REG(3, 3, 9, 12, 1),  /* PMCNTENSET_EL0 */
0871     ARM64_SYS_REG(3, 3, 9, 12, 2),  /* PMCNTENCLR_EL0 */
0872     ARM64_SYS_REG(3, 3, 9, 12, 3),  /* PMOVSCLR_EL0 */
0873     ARM64_SYS_REG(3, 3, 9, 12, 4),  /* PMSWINC_EL0 */
0874     ARM64_SYS_REG(3, 3, 9, 12, 5),  /* PMSELR_EL0 */
0875     ARM64_SYS_REG(3, 3, 9, 13, 0),  /* PMCCNTR_EL0 */
0876     ARM64_SYS_REG(3, 3, 9, 14, 0),  /* PMUSERENR_EL0 */
0877     ARM64_SYS_REG(3, 3, 9, 14, 3),  /* PMOVSSET_EL0 */
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), /* PMCCFILTR_EL0 */
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),   /* ZCR_EL1 */
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),   /* APIAKEYLO_EL1 */
1038     ARM64_SYS_REG(3, 0, 2, 1, 1),   /* APIAKEYHI_EL1 */
1039     ARM64_SYS_REG(3, 0, 2, 1, 2),   /* APIBKEYLO_EL1 */
1040     ARM64_SYS_REG(3, 0, 2, 1, 3),   /* APIBKEYHI_EL1 */
1041     ARM64_SYS_REG(3, 0, 2, 2, 0),   /* APDAKEYLO_EL1 */
1042     ARM64_SYS_REG(3, 0, 2, 2, 1),   /* APDAKEYHI_EL1 */
1043     ARM64_SYS_REG(3, 0, 2, 2, 2),   /* APDBKEYLO_EL1 */
1044     ARM64_SYS_REG(3, 0, 2, 2, 3)    /* APDBKEYHI_EL1 */
1045 };
1046 
1047 static __u64 pauth_generic_regs[] = {
1048     ARM64_SYS_REG(3, 0, 2, 3, 0),   /* APGAKEYLO_EL1 */
1049     ARM64_SYS_REG(3, 0, 2, 3, 1),   /* APGAKEYHI_EL1 */
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);