From: Andrew Jones <ajones@ventanamicro.com>
To: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Cc: qemu-devel@nongnu.org, qemu-riscv@nongnu.org,
alistair.francis@wdc.com, bmeng@tinylab.org,
liweiwei@iscas.ac.cn, zhiwei_liu@linux.alibaba.com,
palmer@rivosinc.com, philmd@linaro.org
Subject: Re: [PATCH v7 14/20] target/riscv/kvm.c: add multi-letter extension KVM properties
Date: Wed, 5 Jul 2023 15:41:42 +0200 [thread overview]
Message-ID: <20230705-091906904fcc54a4ce96e625@orel> (raw)
In-Reply-To: <20230630100811.287315-15-dbarboza@ventanamicro.com>
On Fri, Jun 30, 2023 at 07:08:05AM -0300, Daniel Henrique Barboza wrote:
> Let's add KVM user properties for the multi-letter extensions that KVM
> currently supports: zicbom, zicboz, zihintpause, zbb, ssaia, sstc,
> svinval and svpbmt.
>
> As with MISA extensions, we're using the KVMCPUConfig type to hold
> information about the state of each extension. However, multi-letter
> extensions have more cases to cover than MISA extensions, so we're
> adding an extra 'supported' flag as well. This flag will reflect if a
> given extension is supported by KVM, i.e. KVM knows how to handle it.
> This is determined during KVM extension discovery in
> kvm_riscv_init_multiext_cfg(), where we test for EINVAL errors. Any
> other error different from EINVAL will cause an abort.
>
> The use of the 'user_set' is similar to what we already do with MISA
> extensions: the flag set only if the user is changing the extension
> state.
>
> The 'supported' flag will be used later on to make an exception for
> users that are disabling multi-letter extensions that are unknown to
> KVM.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
> ---
> target/riscv/cpu.c | 8 +++
> target/riscv/kvm.c | 119 +++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 127 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index a9df61c9b4..f348424170 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1778,6 +1778,14 @@ static void riscv_cpu_add_user_properties(Object *obj)
> riscv_cpu_add_misa_properties(obj);
>
> for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
> +#ifndef CONFIG_USER_ONLY
> + if (kvm_enabled()) {
> + /* Check if KVM created the property already */
> + if (object_property_find(obj, prop->name)) {
> + continue;
> + }
> + }
> +#endif
> qdev_property_add_static(dev, prop);
> }
>
> diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
> index 7afd6024e6..6ef81a6825 100644
> --- a/target/riscv/kvm.c
> +++ b/target/riscv/kvm.c
> @@ -113,6 +113,7 @@ typedef struct KVMCPUConfig {
> target_ulong offset;
> int kvm_reg_id;
> bool user_set;
> + bool supported;
> } KVMCPUConfig;
>
> #define KVM_MISA_CFG(_bit, _reg_id) \
> @@ -197,6 +198,81 @@ static void kvm_riscv_update_cpu_misa_ext(RISCVCPU *cpu, CPUState *cs)
> }
> }
>
> +#define CPUCFG(_prop) offsetof(struct RISCVCPUConfig, _prop)
> +
> +#define KVM_EXT_CFG(_name, _prop, _reg_id) \
> + {.name = _name, .offset = CPUCFG(_prop), \
> + .kvm_reg_id = _reg_id}
> +
> +static KVMCPUConfig kvm_multi_ext_cfgs[] = {
> + KVM_EXT_CFG("zicbom", ext_icbom, KVM_RISCV_ISA_EXT_ZICBOM),
> + KVM_EXT_CFG("zicboz", ext_icboz, KVM_RISCV_ISA_EXT_ZICBOZ),
> + KVM_EXT_CFG("zihintpause", ext_zihintpause, KVM_RISCV_ISA_EXT_ZIHINTPAUSE),
> + KVM_EXT_CFG("zbb", ext_zbb, KVM_RISCV_ISA_EXT_ZBB),
> + KVM_EXT_CFG("ssaia", ext_ssaia, KVM_RISCV_ISA_EXT_SSAIA),
> + KVM_EXT_CFG("sstc", ext_sstc, KVM_RISCV_ISA_EXT_SSTC),
> + KVM_EXT_CFG("svinval", ext_svinval, KVM_RISCV_ISA_EXT_SVINVAL),
> + KVM_EXT_CFG("svpbmt", ext_svpbmt, KVM_RISCV_ISA_EXT_SVPBMT),
> +};
> +
> +static void kvm_cpu_cfg_set(RISCVCPU *cpu, KVMCPUConfig *multi_ext,
> + uint32_t val)
> +{
> + int cpu_cfg_offset = multi_ext->offset;
> + bool *ext_enabled = (void *)&cpu->cfg + cpu_cfg_offset;
> +
> + *ext_enabled = val;
> +}
> +
> +static uint32_t kvm_cpu_cfg_get(RISCVCPU *cpu,
> + KVMCPUConfig *multi_ext)
> +{
> + int cpu_cfg_offset = multi_ext->offset;
> + bool *ext_enabled = (void *)&cpu->cfg + cpu_cfg_offset;
> +
> + return *ext_enabled;
> +}
> +
> +static void kvm_cpu_set_multi_ext_cfg(Object *obj, Visitor *v,
> + const char *name,
> + void *opaque, Error **errp)
> +{
> + KVMCPUConfig *multi_ext_cfg = opaque;
> + RISCVCPU *cpu = RISCV_CPU(obj);
> + bool value, host_val;
> +
> + if (!visit_type_bool(v, name, &value, errp)) {
> + return;
> + }
> +
> + host_val = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
> +
> + /*
> + * Ignore if the user is setting the same value
> + * as the host.
> + */
> + if (value == host_val) {
> + return;
> + }
> +
> + if (!multi_ext_cfg->supported) {
> + /*
> + * Error out if the user is trying to enable an
> + * extension that KVM doesn't support. Ignore
> + * option otherwise.
> + */
> + if (value) {
> + error_setg(errp, "KVM does not support disabling extension %s",
> + multi_ext_cfg->name);
> + }
> +
> + return;
> + }
> +
> + multi_ext_cfg->user_set = true;
> + kvm_cpu_cfg_set(cpu, multi_ext_cfg, value);
> +}
> +
> static void kvm_riscv_add_cpu_user_properties(Object *cpu_obj)
> {
> int i;
> @@ -215,6 +291,15 @@ static void kvm_riscv_add_cpu_user_properties(Object *cpu_obj)
> object_property_set_description(cpu_obj, misa_cfg->name,
> misa_cfg->description);
> }
> +
> + for (i = 0; i < ARRAY_SIZE(kvm_multi_ext_cfgs); i++) {
> + KVMCPUConfig *multi_cfg = &kvm_multi_ext_cfgs[i];
> +
> + object_property_add(cpu_obj, multi_cfg->name, "bool",
> + NULL,
> + kvm_cpu_set_multi_ext_cfg,
> + NULL, multi_cfg);
> + }
> }
>
> static int kvm_riscv_get_regs_core(CPUState *cs)
> @@ -530,6 +615,39 @@ static void kvm_riscv_init_misa_ext_mask(RISCVCPU *cpu,
> env->misa_ext = env->misa_ext_mask;
> }
>
> +static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
> +{
> + CPURISCVState *env = &cpu->env;
> + uint64_t val;
> + int i, ret;
> +
> + for (i = 0; i < ARRAY_SIZE(kvm_multi_ext_cfgs); i++) {
> + KVMCPUConfig *multi_ext_cfg = &kvm_multi_ext_cfgs[i];
> + struct kvm_one_reg reg;
> +
> + reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_ISA_EXT,
> + multi_ext_cfg->kvm_reg_id);
> + reg.addr = (uint64_t)&val;
> + ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®);
> + if (ret != 0) {
As discussed internally on Slack, since we can't use kvm_vcpu_ioctl() here
we need to properly check 'if (ret == -1)'
> + if (ret == -EINVAL) {
and here 'if (errno == EINVAL)'. But, also as discussed internally, based
on our upcoming plans to use ENOENT for missing registers, we should
change this check to be for ENOENT now. While that may seem premature, I
think it's OK, because until a KVM which returns ENOENT for missing
registers exists and is used, QEMU command lines which disable unknown
registers will be rejected. But, that will also happen even after a KVM
that returns ENOENT exits if an older KVM is used. In both cases that's
fine, as rejecting is the more conservative behavior for an error.
Finally, if the yet-to-be-posted KVM ENOENT patch never gets merged, then
we may be stuck rejecting forever anyway, since EINVAL is quite generic
and probably isn't safe to use for this purpose.
Thanks,
drew
> + /* Silently default to 'false' if KVM does not support it. */
> + multi_ext_cfg->supported = false;
> + 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);
> + exit(EXIT_FAILURE);
> + }
> + } else {
> + multi_ext_cfg->supported = true;
> + }
> +
> + kvm_cpu_cfg_set(cpu, multi_ext_cfg, val);
> + }
> +}
> +
> void kvm_riscv_init_user_properties(Object *cpu_obj)
> {
> RISCVCPU *cpu = RISCV_CPU(cpu_obj);
> @@ -542,6 +660,7 @@ void kvm_riscv_init_user_properties(Object *cpu_obj)
> kvm_riscv_add_cpu_user_properties(cpu_obj);
> kvm_riscv_init_machine_ids(cpu, &kvmcpu);
> kvm_riscv_init_misa_ext_mask(cpu, &kvmcpu);
> + kvm_riscv_init_multiext_cfg(cpu, &kvmcpu);
>
> kvm_riscv_destroy_scratch_vcpu(&kvmcpu);
> }
> --
> 2.41.0
>
next prev parent reply other threads:[~2023-07-05 13:42 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-30 10:07 [PATCH v7 00/20] target/riscv, KVM: fixes and enhancements Daniel Henrique Barboza
2023-06-30 10:07 ` [PATCH v7 01/20] target/riscv: skip features setup for KVM CPUs Daniel Henrique Barboza
2023-06-30 10:07 ` [PATCH v7 02/20] hw/riscv/virt.c: skip 'mmu-type' FDT if satp mode not set Daniel Henrique Barboza
2023-06-30 10:07 ` [PATCH v7 03/20] target/riscv/cpu.c: restrict 'mvendorid' value Daniel Henrique Barboza
2023-06-30 10:07 ` [PATCH v7 04/20] target/riscv/cpu.c: restrict 'mimpid' value Daniel Henrique Barboza
2023-06-30 10:07 ` [PATCH v7 05/20] target/riscv/cpu.c: restrict 'marchid' value Daniel Henrique Barboza
2023-06-30 10:07 ` [PATCH v7 06/20] target/riscv: use KVM scratch CPUs to init KVM properties Daniel Henrique Barboza
2023-06-30 10:07 ` [PATCH v7 07/20] target/riscv: read marchid/mimpid in kvm_riscv_init_machine_ids() Daniel Henrique Barboza
2023-06-30 10:07 ` [PATCH v7 08/20] target/riscv: handle mvendorid/marchid/mimpid for KVM CPUs Daniel Henrique Barboza
2023-06-30 10:08 ` [PATCH v7 09/20] linux-headers: Update to v6.4-rc1 Daniel Henrique Barboza
2023-06-30 10:08 ` [PATCH v7 10/20] target/riscv/kvm.c: init 'misa_ext_mask' with scratch CPU Daniel Henrique Barboza
2023-06-30 10:08 ` [PATCH v7 11/20] target/riscv/cpu: add misa_ext_info_arr[] Daniel Henrique Barboza
2023-06-30 10:15 ` Philippe Mathieu-Daudé
2023-06-30 11:27 ` Andrew Jones
2023-06-30 10:08 ` [PATCH v7 12/20] target/riscv: add KVM specific MISA properties Daniel Henrique Barboza
2023-06-30 11:29 ` Andrew Jones
2023-06-30 10:08 ` [PATCH v7 13/20] target/riscv/kvm.c: update KVM MISA bits Daniel Henrique Barboza
2023-06-30 10:08 ` [PATCH v7 14/20] target/riscv/kvm.c: add multi-letter extension KVM properties Daniel Henrique Barboza
2023-07-05 13:41 ` Andrew Jones [this message]
2023-07-05 19:47 ` Daniel Henrique Barboza
2023-06-30 10:08 ` [PATCH v7 15/20] target/riscv/cpu.c: add satp_mode properties earlier Daniel Henrique Barboza
2023-06-30 10:08 ` [PATCH v7 16/20] target/riscv/cpu.c: remove priv_ver check from riscv_isa_string_ext() Daniel Henrique Barboza
2023-06-30 10:08 ` [PATCH v7 17/20] target/riscv/cpu.c: create KVM mock properties Daniel Henrique Barboza
2023-06-30 10:08 ` [PATCH v7 18/20] target/riscv: update multi-letter extension KVM properties Daniel Henrique Barboza
2023-06-30 10:08 ` [PATCH v7 19/20] target/riscv/kvm.c: add kvmconfig_get_cfg_addr() helper Daniel Henrique Barboza
2023-06-30 10:08 ` [PATCH v7 20/20] target/riscv/kvm.c: read/write (cbom|cboz)_blocksize in KVM Daniel Henrique Barboza
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230705-091906904fcc54a4ce96e625@orel \
--to=ajones@ventanamicro.com \
--cc=alistair.francis@wdc.com \
--cc=bmeng@tinylab.org \
--cc=dbarboza@ventanamicro.com \
--cc=liweiwei@iscas.ac.cn \
--cc=palmer@rivosinc.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-riscv@nongnu.org \
--cc=zhiwei_liu@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).