[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 50/54] target/riscv/kvm: support KVM_GET_REG_LIST
From: |
Alistair Francis |
Subject: |
[PULL 50/54] target/riscv/kvm: support KVM_GET_REG_LIST |
Date: |
Thu, 12 Oct 2023 14:10:47 +1000 |
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
KVM for RISC-V started supporting KVM_GET_REG_LIST in Linux 6.6. It
consists of a KVM ioctl() that retrieves a list of all available regs
for get_one_reg/set_one_reg. Regs that aren't present in the list aren't
supported in the host.
This simplifies our lives when initing the KVM regs since we don't have
to always attempt a KVM_GET_ONE_REG for all regs QEMU knows. We'll only
attempt a get_one_reg() if we're sure the reg is supported, i.e. it was
retrieved by KVM_GET_REG_LIST. Any error in get_one_reg() will then
always considered fatal, instead of having to handle special error codes
that might indicate a non-fatal failure.
Start by moving the current kvm_riscv_init_multiext_cfg() logic into a
new kvm_riscv_read_multiext_legacy() helper. We'll prioritize using
KVM_GET_REG_LIST, so check if we have it available and, in case we
don't, use the legacy() logic.
Otherwise, retrieve the available reg list and use it to check if the
host supports our known KVM regs, doing the usual get_one_reg() for
the supported regs and setting cpu->cfg accordingly.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Message-ID: <20231003132148.797921-3-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/kvm/kvm-cpu.c | 96 +++++++++++++++++++++++++++++++++++++-
1 file changed, 95 insertions(+), 1 deletion(-)
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index c3daf74fe9..090d617627 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -771,7 +771,8 @@ static void kvm_riscv_read_cbomz_blksize(RISCVCPU *cpu,
KVMScratchCPU *kvmcpu,
}
}
-static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
+static void kvm_riscv_read_multiext_legacy(RISCVCPU *cpu,
+ KVMScratchCPU *kvmcpu)
{
CPURISCVState *env = &cpu->env;
uint64_t val;
@@ -812,6 +813,99 @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu,
KVMScratchCPU *kvmcpu)
}
}
+static int uint64_cmp(const void *a, const void *b)
+{
+ uint64_t val1 = *(const uint64_t *)a;
+ uint64_t val2 = *(const uint64_t *)b;
+
+ if (val1 < val2) {
+ return -1;
+ }
+
+ if (val1 > val2) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
+{
+ KVMCPUConfig *multi_ext_cfg;
+ struct kvm_one_reg reg;
+ struct kvm_reg_list rl_struct;
+ struct kvm_reg_list *reglist;
+ uint64_t val, reg_id, *reg_search;
+ int i, ret;
+
+ rl_struct.n = 0;
+ ret = ioctl(kvmcpu->cpufd, KVM_GET_REG_LIST, &rl_struct);
+
+ /*
+ * If KVM_GET_REG_LIST isn't supported we'll get errno 22
+ * (EINVAL). Use read_legacy() in this case.
+ */
+ if (errno == EINVAL) {
+ return kvm_riscv_read_multiext_legacy(cpu, kvmcpu);
+ } else if (errno != E2BIG) {
+ /*
+ * E2BIG is an expected error message for the API since we
+ * don't know the number of registers. The right amount will
+ * be written in rl_struct.n.
+ *
+ * Error out if we get any other errno.
+ */
+ error_report("Error when accessing get-reg-list, code: %s",
+ strerrorname_np(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ reglist = g_malloc(sizeof(struct kvm_reg_list) +
+ rl_struct.n * sizeof(uint64_t));
+ reglist->n = rl_struct.n;
+ ret = ioctl(kvmcpu->cpufd, KVM_GET_REG_LIST, reglist);
+ if (ret) {
+ error_report("Error when reading KVM_GET_REG_LIST, code %s ",
+ strerrorname_np(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ /* sort reglist to use bsearch() */
+ qsort(®list->reg, reglist->n, sizeof(uint64_t), uint64_cmp);
+
+ for (i = 0; i < ARRAY_SIZE(kvm_multi_ext_cfgs); i++) {
+ multi_ext_cfg = &kvm_multi_ext_cfgs[i];
+ reg_id = kvm_riscv_reg_id(&cpu->env, KVM_REG_RISCV_ISA_EXT,
+ multi_ext_cfg->kvm_reg_id);
+ reg_search = bsearch(®_id, reglist->reg, reglist->n,
+ sizeof(uint64_t), uint64_cmp);
+ if (!reg_search) {
+ continue;
+ }
+
+ reg.id = reg_id;
+ reg.addr = (uint64_t)&val;
+ ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®);
+ if (ret != 0) {
+ error_report("Unable to read ISA_EXT KVM register %s, "
+ "error code: %s", multi_ext_cfg->name,
+ strerrorname_np(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ multi_ext_cfg->supported = true;
+ kvm_cpu_cfg_set(cpu, multi_ext_cfg, val);
+ }
+
+ if (cpu->cfg.ext_icbom) {
+ kvm_riscv_read_cbomz_blksize(cpu, kvmcpu, &kvm_cbom_blocksize);
+ }
+
+ if (cpu->cfg.ext_icboz) {
+ kvm_riscv_read_cbomz_blksize(cpu, kvmcpu, &kvm_cboz_blocksize);
+ }
+}
+
static void riscv_init_kvm_registers(Object *cpu_obj)
{
RISCVCPU *cpu = RISCV_CPU(cpu_obj);
--
2.41.0
- [PULL 40/54] target/riscv/cpu.c: export isa_edata_arr[], (continued)
- [PULL 40/54] target/riscv/cpu.c: export isa_edata_arr[], Alistair Francis, 2023/10/12
- [PULL 41/54] target/riscv/cpu: move priv spec functions to tcg-cpu.c, Alistair Francis, 2023/10/12
- [PULL 42/54] target/riscv: add riscv_cpu_get_name(), Alistair Francis, 2023/10/12
- [PULL 43/54] target/riscv/tcg-cpu.c: add extension properties for all cpus, Alistair Francis, 2023/10/12
- [PULL 46/54] hw/misc/sifive_test.c: replace exit calls with proper shutdown, Alistair Francis, 2023/10/12
- [PULL 45/54] softmmu: pass the main loop status to gdb "Wxx" packet, Alistair Francis, 2023/10/12
- [PULL 47/54] hw/char: riscv_htif: replace exit calls with proper shutdown, Alistair Francis, 2023/10/12
- [PULL 44/54] softmmu: add means to pass an exit code when requesting a shutdown, Alistair Francis, 2023/10/12
- [PULL 48/54] gdbstub: replace exit calls with proper shutdown for softmmu, Alistair Francis, 2023/10/12
- [PULL 49/54] target/riscv/kvm: improve 'init_multiext_cfg' error msg, Alistair Francis, 2023/10/12
- [PULL 50/54] target/riscv/kvm: support KVM_GET_REG_LIST,
Alistair Francis <=
- [PULL 51/54] target/riscv/tcg: remove RVG warning, Alistair Francis, 2023/10/12
- [PULL 52/54] target/riscv: Use env_archcpu for better performance, Alistair Francis, 2023/10/12
- [PULL 53/54] target/riscv: deprecate capital 'Z' CPU properties, Alistair Francis, 2023/10/12
- [PULL 54/54] target/riscv: Fix vfwmaccbf16.vf, Alistair Francis, 2023/10/12
- Re: [PULL 00/54] riscv-to-apply queue, Stefan Hajnoczi, 2023/10/13