* [PATCH v2 0/2] riscv, kvm: support KVM_GET_REG_LIST
@ 2023-10-03 13:21 Daniel Henrique Barboza
2023-10-03 13:21 ` [PATCH v2 1/2] target/riscv/kvm: improve 'init_multiext_cfg' error msg Daniel Henrique Barboza
2023-10-03 13:21 ` [PATCH v2 2/2] target/riscv/kvm: support KVM_GET_REG_LIST Daniel Henrique Barboza
0 siblings, 2 replies; 8+ messages in thread
From: Daniel Henrique Barboza @ 2023-10-03 13:21 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
Hi,
In this new version all instances of "error_setg(&error_fatal, ..." were
replaced with error_report() and exit(1), as suggested by Phil in v1.
No other changes made.
Changes from v1:
- patches 1 and 2:
- replace 'error_setg(&error_fatal" with error_report() and exit(1)
- v1 link: https://lore.kernel.org/qemu-riscv/20231003113259.771539-1-dbarboza@ventanamicro.com/
Daniel Henrique Barboza (2):
target/riscv/kvm: improve 'init_multiext_cfg' error msg
target/riscv/kvm: support KVM_GET_REG_LIST
target/riscv/kvm/kvm-cpu.c | 100 +++++++++++++++++++++++++++++++++++--
1 file changed, 97 insertions(+), 3 deletions(-)
--
2.41.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/2] target/riscv/kvm: improve 'init_multiext_cfg' error msg
2023-10-03 13:21 [PATCH v2 0/2] riscv, kvm: support KVM_GET_REG_LIST Daniel Henrique Barboza
@ 2023-10-03 13:21 ` Daniel Henrique Barboza
2023-10-03 13:25 ` Philippe Mathieu-Daudé
` (2 more replies)
2023-10-03 13:21 ` [PATCH v2 2/2] target/riscv/kvm: support KVM_GET_REG_LIST Daniel Henrique Barboza
1 sibling, 3 replies; 8+ messages in thread
From: Daniel Henrique Barboza @ 2023-10-03 13:21 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
Our error message is returning the value of 'ret', which will be always
-1 in case of error, and will not be that useful:
qemu-system-riscv64: Unable to read ISA_EXT KVM register ssaia, error -1
Improve the error message by outputting 'errno' instead of 'ret'. Use
strerrorname_np() to output the error name instead of the error code.
This will give us what we need to know right away:
qemu-system-riscv64: Unable to read ISA_EXT KVM register ssaia, error code: ENOENT
Given that we're going to exit(1) in this condition instead of
attempting to recover, remove the 'kvm_riscv_destroy_scratch_vcpu()'
call.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
target/riscv/kvm/kvm-cpu.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index c6615cb807..c3daf74fe9 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -792,8 +792,8 @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
val = false;
} else {
error_report("Unable to read ISA_EXT KVM register %s, "
- "error %d", multi_ext_cfg->name, ret);
- kvm_riscv_destroy_scratch_vcpu(kvmcpu);
+ "error code: %s", multi_ext_cfg->name,
+ strerrorname_np(errno));
exit(EXIT_FAILURE);
}
} else {
--
2.41.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 2/2] target/riscv/kvm: support KVM_GET_REG_LIST
2023-10-03 13:21 [PATCH v2 0/2] riscv, kvm: support KVM_GET_REG_LIST Daniel Henrique Barboza
2023-10-03 13:21 ` [PATCH v2 1/2] target/riscv/kvm: improve 'init_multiext_cfg' error msg Daniel Henrique Barboza
@ 2023-10-03 13:21 ` Daniel Henrique Barboza
2023-10-04 8:08 ` Andrew Jones
2023-10-09 1:13 ` Alistair Francis
1 sibling, 2 replies; 8+ messages in thread
From: Daniel Henrique Barboza @ 2023-10-03 13:21 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
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>
---
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
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] target/riscv/kvm: improve 'init_multiext_cfg' error msg
2023-10-03 13:21 ` [PATCH v2 1/2] target/riscv/kvm: improve 'init_multiext_cfg' error msg Daniel Henrique Barboza
@ 2023-10-03 13:25 ` Philippe Mathieu-Daudé
2023-10-04 8:01 ` Andrew Jones
2023-10-09 0:59 ` Alistair Francis
2 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-10-03 13:25 UTC (permalink / raw)
To: Daniel Henrique Barboza, qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones
On 3/10/23 15:21, Daniel Henrique Barboza wrote:
> Our error message is returning the value of 'ret', which will be always
> -1 in case of error, and will not be that useful:
>
> qemu-system-riscv64: Unable to read ISA_EXT KVM register ssaia, error -1
>
> Improve the error message by outputting 'errno' instead of 'ret'. Use
> strerrorname_np() to output the error name instead of the error code.
> This will give us what we need to know right away:
>
> qemu-system-riscv64: Unable to read ISA_EXT KVM register ssaia, error code: ENOENT
>
> Given that we're going to exit(1) in this condition instead of
> attempting to recover, remove the 'kvm_riscv_destroy_scratch_vcpu()'
> call.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
> target/riscv/kvm/kvm-cpu.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] target/riscv/kvm: improve 'init_multiext_cfg' error msg
2023-10-03 13:21 ` [PATCH v2 1/2] target/riscv/kvm: improve 'init_multiext_cfg' error msg Daniel Henrique Barboza
2023-10-03 13:25 ` Philippe Mathieu-Daudé
@ 2023-10-04 8:01 ` Andrew Jones
2023-10-09 0:59 ` Alistair Francis
2 siblings, 0 replies; 8+ messages in thread
From: Andrew Jones @ 2023-10-04 8:01 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, bmeng, liweiwei,
zhiwei_liu, palmer
On Tue, Oct 03, 2023 at 10:21:47AM -0300, Daniel Henrique Barboza wrote:
> Our error message is returning the value of 'ret', which will be always
> -1 in case of error, and will not be that useful:
>
> qemu-system-riscv64: Unable to read ISA_EXT KVM register ssaia, error -1
>
> Improve the error message by outputting 'errno' instead of 'ret'. Use
> strerrorname_np() to output the error name instead of the error code.
> This will give us what we need to know right away:
>
> qemu-system-riscv64: Unable to read ISA_EXT KVM register ssaia, error code: ENOENT
>
> Given that we're going to exit(1) in this condition instead of
> attempting to recover, remove the 'kvm_riscv_destroy_scratch_vcpu()'
> call.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
> target/riscv/kvm/kvm-cpu.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
> index c6615cb807..c3daf74fe9 100644
> --- a/target/riscv/kvm/kvm-cpu.c
> +++ b/target/riscv/kvm/kvm-cpu.c
> @@ -792,8 +792,8 @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
> val = false;
> } else {
> error_report("Unable to read ISA_EXT KVM register %s, "
> - "error %d", multi_ext_cfg->name, ret);
> - kvm_riscv_destroy_scratch_vcpu(kvmcpu);
> + "error code: %s", multi_ext_cfg->name,
> + strerrorname_np(errno));
> exit(EXIT_FAILURE);
> }
> } else {
> --
> 2.41.0
>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] target/riscv/kvm: support KVM_GET_REG_LIST
2023-10-03 13:21 ` [PATCH v2 2/2] target/riscv/kvm: support KVM_GET_REG_LIST Daniel Henrique Barboza
@ 2023-10-04 8:08 ` Andrew Jones
2023-10-09 1:13 ` Alistair Francis
1 sibling, 0 replies; 8+ messages in thread
From: Andrew Jones @ 2023-10-04 8:08 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, bmeng, liweiwei,
zhiwei_liu, palmer
On Tue, Oct 03, 2023 at 10:21:48AM -0300, Daniel Henrique Barboza wrote:
> 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>
> ---
> 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
>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] target/riscv/kvm: improve 'init_multiext_cfg' error msg
2023-10-03 13:21 ` [PATCH v2 1/2] target/riscv/kvm: improve 'init_multiext_cfg' error msg Daniel Henrique Barboza
2023-10-03 13:25 ` Philippe Mathieu-Daudé
2023-10-04 8:01 ` Andrew Jones
@ 2023-10-09 0:59 ` Alistair Francis
2 siblings, 0 replies; 8+ messages in thread
From: Alistair Francis @ 2023-10-09 0:59 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, bmeng, liweiwei,
zhiwei_liu, palmer, ajones
On Wed, Oct 4, 2023 at 12:46 AM Daniel Henrique Barboza
<dbarboza@ventanamicro.com> wrote:
>
> Our error message is returning the value of 'ret', which will be always
> -1 in case of error, and will not be that useful:
>
> qemu-system-riscv64: Unable to read ISA_EXT KVM register ssaia, error -1
>
> Improve the error message by outputting 'errno' instead of 'ret'. Use
> strerrorname_np() to output the error name instead of the error code.
> This will give us what we need to know right away:
>
> qemu-system-riscv64: Unable to read ISA_EXT KVM register ssaia, error code: ENOENT
>
> Given that we're going to exit(1) in this condition instead of
> attempting to recover, remove the 'kvm_riscv_destroy_scratch_vcpu()'
> call.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/kvm/kvm-cpu.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
> index c6615cb807..c3daf74fe9 100644
> --- a/target/riscv/kvm/kvm-cpu.c
> +++ b/target/riscv/kvm/kvm-cpu.c
> @@ -792,8 +792,8 @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
> val = false;
> } else {
> error_report("Unable to read ISA_EXT KVM register %s, "
> - "error %d", multi_ext_cfg->name, ret);
> - kvm_riscv_destroy_scratch_vcpu(kvmcpu);
> + "error code: %s", multi_ext_cfg->name,
> + strerrorname_np(errno));
> exit(EXIT_FAILURE);
> }
> } else {
> --
> 2.41.0
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] target/riscv/kvm: support KVM_GET_REG_LIST
2023-10-03 13:21 ` [PATCH v2 2/2] target/riscv/kvm: support KVM_GET_REG_LIST Daniel Henrique Barboza
2023-10-04 8:08 ` Andrew Jones
@ 2023-10-09 1:13 ` Alistair Francis
1 sibling, 0 replies; 8+ messages in thread
From: Alistair Francis @ 2023-10-09 1:13 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, bmeng, liweiwei,
zhiwei_liu, palmer, ajones
On Wed, Oct 4, 2023 at 12:48 AM Daniel Henrique Barboza
<dbarboza@ventanamicro.com> wrote:
>
> 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>
Alistair
> ---
> 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
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-10-09 1:15 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-03 13:21 [PATCH v2 0/2] riscv, kvm: support KVM_GET_REG_LIST Daniel Henrique Barboza
2023-10-03 13:21 ` [PATCH v2 1/2] target/riscv/kvm: improve 'init_multiext_cfg' error msg Daniel Henrique Barboza
2023-10-03 13:25 ` Philippe Mathieu-Daudé
2023-10-04 8:01 ` Andrew Jones
2023-10-09 0:59 ` Alistair Francis
2023-10-03 13:21 ` [PATCH v2 2/2] target/riscv/kvm: support KVM_GET_REG_LIST Daniel Henrique Barboza
2023-10-04 8:08 ` Andrew Jones
2023-10-09 1:13 ` Alistair Francis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).