Message ID | 20231222122235.545235-9-dbarboza@ventanamicro.com |
---|---|
State | New |
Headers | show |
Series | target/riscv: deprecate riscv_cpu_options[] | expand |
22.12.2023 15:22, Daniel Henrique Barboza wrote: > > Turning 'vlen' into a class property will allow its default value to be > overwritten by cpu_init() later on, solving the issue we have now where > CPU specific settings are getting overwritten by the default. > > For 'vlen', 'elen' and the blocksize options we need a way of tracking > if the user set a value for them. This is benign for TCG since the cost > of always validating these values are small, but for KVM we need syscalls > to read the host values to make the validations. Knowing whether the > user didn't touch the values makes a difference. We'll track user setting > for these properties using a hash, like we do in the TCG driver. > > Common validation bits are moved from riscv_cpu_validate_v() to > prop_vlen_set() to be shared with KVM. > > And, as done with every option we migrated to riscv_cpu_properties[], > vendor CPUs can't have their 'vlen' value changed. > > Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> > --- > target/riscv/cpu.c | 63 +++++++++++++++++++++++++++++++++++++- > target/riscv/tcg/tcg-cpu.c | 5 --- > 2 files changed, 62 insertions(+), 6 deletions(-) > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > index d6625399a7..c2ff50bcab 100644 > --- a/target/riscv/cpu.c > +++ b/target/riscv/cpu.c > @@ -29,6 +29,7 @@ > #include "qapi/visitor.h" > #include "qemu/error-report.h" > #include "hw/qdev-properties.h" > +#include "hw/core/qdev-prop-internal.h" > #include "migration/vmstate.h" > #include "fpu/softfloat-helpers.h" > #include "sysemu/kvm.h" > @@ -53,6 +54,15 @@ const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV, > #define BYTE(x) (x) > #endif > > +/* Hash that stores general user set numeric options */ > +static GHashTable *general_user_opts; > + > +static void cpu_option_add_user_setting(const char *optname, uint32_t value) > +{ > + g_hash_table_insert(general_user_opts, (gpointer)optname, > + GUINT_TO_POINTER(value)); > +} > + > #define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \ > {#_name, _min_ver, CPU_CFG_OFFSET(_prop)} > > @@ -1244,6 +1254,8 @@ static void riscv_cpu_init(Object *obj) > IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX); > #endif /* CONFIG_USER_ONLY */ > > + general_user_opts = g_hash_table_new(g_str_hash, g_str_equal); > + > /* > * The timer and performance counters extensions were supported > * in QEMU before they were added as discrete extensions in the > @@ -1664,8 +1676,54 @@ static const PropertyInfo prop_vext_spec = { > .set = prop_vext_spec_set, > }; > > +static void prop_vlen_set(Object *obj, Visitor *v, const char *name, > + void *opaque, Error **errp) > +{ > + RISCVCPU *cpu = RISCV_CPU(obj); > + uint16_t value; > + > + if (!visit_type_uint16(v, name, &value, errp)) { > + return; > + } > + > + if (!is_power_of_2(value)) { > + error_setg(errp, "Vector extension VLEN must be power of 2"); > + return; > + } > + > + /* Always allow setting a default value */ What is the case for vlen equal to 0? Since in properties it is defined with default value set to 128. > + if (cpu->cfg.vlen == 0) { > + cpu->cfg.vlen = value; > + return; > + } > + > + if (value != cpu->cfg.vlen && riscv_cpu_is_vendor(obj)) { > + cpu_set_prop_err(cpu, name, errp); > + error_append_hint(errp, "Current '%s' val: %u\n", > + name, cpu->cfg.vlen); > + return; > + } > + > + cpu_option_add_user_setting(name, value); > + cpu->cfg.vlen = value; > +} > + > +static void prop_vlen_get(Object *obj, Visitor *v, const char *name, > + void *opaque, Error **errp) > +{ > + uint16_t value = RISCV_CPU(obj)->cfg.vlen; > + > + visit_type_uint16(v, name, &value, errp); > +} > + > +static const PropertyInfo prop_vlen = { > + .name = "vlen", > + .get = prop_vlen_get, > + .set = prop_vlen_set, > + .set_default_value = qdev_propinfo_set_default_value_uint, > +}; > + > Property riscv_cpu_options[] = { > - DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128), > DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64), > > DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64), > @@ -1687,6 +1745,9 @@ static Property riscv_cpu_properties[] = { > {.name = "priv_spec", .info = &prop_priv_spec}, > {.name = "vext_spec", .info = &prop_vext_spec}, > > + {.name = "vlen", .info = &prop_vlen, > + .set_default = true, .defval.u = 128}, > + > #ifndef CONFIG_USER_ONLY > DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC), > #endif > diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c > index 6501c29d8e..8ec858e096 100644 > --- a/target/riscv/tcg/tcg-cpu.c > +++ b/target/riscv/tcg/tcg-cpu.c > @@ -178,11 +178,6 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) > static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg, > Error **errp) > { > - if (!is_power_of_2(cfg->vlen)) { > - error_setg(errp, "Vector extension VLEN must be power of 2"); > - return; > - } > - > if (cfg->vlen > RV_VLEN_MAX || cfg->vlen < 128) { > error_setg(errp, > "Vector extension implementation only supports VLEN " > -- > 2.43.0 > >
On 12/29/23 08:22, Vladimir Isaev wrote: > 22.12.2023 15:22, Daniel Henrique Barboza wrote: >> >> Turning 'vlen' into a class property will allow its default value to be >> overwritten by cpu_init() later on, solving the issue we have now where >> CPU specific settings are getting overwritten by the default. >> >> For 'vlen', 'elen' and the blocksize options we need a way of tracking >> if the user set a value for them. This is benign for TCG since the cost >> of always validating these values are small, but for KVM we need syscalls >> to read the host values to make the validations. Knowing whether the >> user didn't touch the values makes a difference. We'll track user setting >> for these properties using a hash, like we do in the TCG driver. >> >> Common validation bits are moved from riscv_cpu_validate_v() to >> prop_vlen_set() to be shared with KVM. >> >> And, as done with every option we migrated to riscv_cpu_properties[], >> vendor CPUs can't have their 'vlen' value changed. >> >> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> >> --- >> target/riscv/cpu.c | 63 +++++++++++++++++++++++++++++++++++++- >> target/riscv/tcg/tcg-cpu.c | 5 --- >> 2 files changed, 62 insertions(+), 6 deletions(-) >> >> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c >> index d6625399a7..c2ff50bcab 100644 >> --- a/target/riscv/cpu.c >> +++ b/target/riscv/cpu.c >> @@ -29,6 +29,7 @@ >> #include "qapi/visitor.h" >> #include "qemu/error-report.h" >> #include "hw/qdev-properties.h" >> +#include "hw/core/qdev-prop-internal.h" >> #include "migration/vmstate.h" >> #include "fpu/softfloat-helpers.h" >> #include "sysemu/kvm.h" >> @@ -53,6 +54,15 @@ const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV, >> #define BYTE(x) (x) >> #endif >> >> +/* Hash that stores general user set numeric options */ >> +static GHashTable *general_user_opts; >> + >> +static void cpu_option_add_user_setting(const char *optname, uint32_t value) >> +{ >> + g_hash_table_insert(general_user_opts, (gpointer)optname, >> + GUINT_TO_POINTER(value)); >> +} >> + >> #define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \ >> {#_name, _min_ver, CPU_CFG_OFFSET(_prop)} >> >> @@ -1244,6 +1254,8 @@ static void riscv_cpu_init(Object *obj) >> IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX); >> #endif /* CONFIG_USER_ONLY */ >> >> + general_user_opts = g_hash_table_new(g_str_hash, g_str_equal); >> + >> /* >> * The timer and performance counters extensions were supported >> * in QEMU before they were added as discrete extensions in the >> @@ -1664,8 +1676,54 @@ static const PropertyInfo prop_vext_spec = { >> .set = prop_vext_spec_set, >> }; >> >> +static void prop_vlen_set(Object *obj, Visitor *v, const char *name, >> + void *opaque, Error **errp) >> +{ >> + RISCVCPU *cpu = RISCV_CPU(obj); >> + uint16_t value; >> + >> + if (!visit_type_uint16(v, name, &value, errp)) { >> + return; >> + } >> + >> + if (!is_power_of_2(value)) { >> + error_setg(errp, "Vector extension VLEN must be power of 2"); >> + return; >> + } >> + >> + /* Always allow setting a default value */ > > What is the case for vlen equal to 0? Since in properties it is defined with default value set to 128. The process of setting a default uses the default setter of the property. I.e. when setting vlen default value to 128, this function will be called with value = 128 when cpu->cfg.vlen is 0. If we don't special case this scenario we'll fail the "vendor CPUs don't allow changing vlen" check that comes right after. Thanks, Daniel > >> + if (cpu->cfg.vlen == 0) { >> + cpu->cfg.vlen = value; >> + return; >> + } >> + >> + if (value != cpu->cfg.vlen && riscv_cpu_is_vendor(obj)) { >> + cpu_set_prop_err(cpu, name, errp); >> + error_append_hint(errp, "Current '%s' val: %u\n", >> + name, cpu->cfg.vlen); >> + return; >> + } >> + >> + cpu_option_add_user_setting(name, value); >> + cpu->cfg.vlen = value; >> +} >> + >> +static void prop_vlen_get(Object *obj, Visitor *v, const char *name, >> + void *opaque, Error **errp) >> +{ >> + uint16_t value = RISCV_CPU(obj)->cfg.vlen; >> + >> + visit_type_uint16(v, name, &value, errp); >> +} >> + >> +static const PropertyInfo prop_vlen = { >> + .name = "vlen", >> + .get = prop_vlen_get, >> + .set = prop_vlen_set, >> + .set_default_value = qdev_propinfo_set_default_value_uint, >> +}; >> + >> Property riscv_cpu_options[] = { >> - DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128), >> DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64), >> >> DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64), >> @@ -1687,6 +1745,9 @@ static Property riscv_cpu_properties[] = { >> {.name = "priv_spec", .info = &prop_priv_spec}, >> {.name = "vext_spec", .info = &prop_vext_spec}, >> >> + {.name = "vlen", .info = &prop_vlen, >> + .set_default = true, .defval.u = 128}, >> + >> #ifndef CONFIG_USER_ONLY >> DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC), >> #endif >> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c >> index 6501c29d8e..8ec858e096 100644 >> --- a/target/riscv/tcg/tcg-cpu.c >> +++ b/target/riscv/tcg/tcg-cpu.c >> @@ -178,11 +178,6 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) >> static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg, >> Error **errp) >> { >> - if (!is_power_of_2(cfg->vlen)) { >> - error_setg(errp, "Vector extension VLEN must be power of 2"); >> - return; >> - } >> - >> if (cfg->vlen > RV_VLEN_MAX || cfg->vlen < 128) { >> error_setg(errp, >> "Vector extension implementation only supports VLEN " >> -- >> 2.43.0 >> >>
On 1/2/24 09:04, Daniel Henrique Barboza wrote: > > > On 12/29/23 08:22, Vladimir Isaev wrote: >> 22.12.2023 15:22, Daniel Henrique Barboza wrote: >>> >>> Turning 'vlen' into a class property will allow its default value to be >>> overwritten by cpu_init() later on, solving the issue we have now where >>> CPU specific settings are getting overwritten by the default. >>> >>> For 'vlen', 'elen' and the blocksize options we need a way of tracking >>> if the user set a value for them. This is benign for TCG since the cost >>> of always validating these values are small, but for KVM we need syscalls >>> to read the host values to make the validations. Knowing whether the >>> user didn't touch the values makes a difference. We'll track user setting >>> for these properties using a hash, like we do in the TCG driver. >>> >>> Common validation bits are moved from riscv_cpu_validate_v() to >>> prop_vlen_set() to be shared with KVM. >>> >>> And, as done with every option we migrated to riscv_cpu_properties[], >>> vendor CPUs can't have their 'vlen' value changed. >>> >>> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> >>> --- >>> target/riscv/cpu.c | 63 +++++++++++++++++++++++++++++++++++++- >>> target/riscv/tcg/tcg-cpu.c | 5 --- >>> 2 files changed, 62 insertions(+), 6 deletions(-) >>> >>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c >>> index d6625399a7..c2ff50bcab 100644 >>> --- a/target/riscv/cpu.c >>> +++ b/target/riscv/cpu.c >>> @@ -29,6 +29,7 @@ >>> #include "qapi/visitor.h" >>> #include "qemu/error-report.h" >>> #include "hw/qdev-properties.h" >>> +#include "hw/core/qdev-prop-internal.h" >>> #include "migration/vmstate.h" >>> #include "fpu/softfloat-helpers.h" >>> #include "sysemu/kvm.h" >>> @@ -53,6 +54,15 @@ const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV, >>> #define BYTE(x) (x) >>> #endif >>> >>> +/* Hash that stores general user set numeric options */ >>> +static GHashTable *general_user_opts; >>> + >>> +static void cpu_option_add_user_setting(const char *optname, uint32_t value) >>> +{ >>> + g_hash_table_insert(general_user_opts, (gpointer)optname, >>> + GUINT_TO_POINTER(value)); >>> +} >>> + >>> #define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \ >>> {#_name, _min_ver, CPU_CFG_OFFSET(_prop)} >>> >>> @@ -1244,6 +1254,8 @@ static void riscv_cpu_init(Object *obj) >>> IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX); >>> #endif /* CONFIG_USER_ONLY */ >>> >>> + general_user_opts = g_hash_table_new(g_str_hash, g_str_equal); >>> + >>> /* >>> * The timer and performance counters extensions were supported >>> * in QEMU before they were added as discrete extensions in the >>> @@ -1664,8 +1676,54 @@ static const PropertyInfo prop_vext_spec = { >>> .set = prop_vext_spec_set, >>> }; >>> >>> +static void prop_vlen_set(Object *obj, Visitor *v, const char *name, >>> + void *opaque, Error **errp) >>> +{ >>> + RISCVCPU *cpu = RISCV_CPU(obj); >>> + uint16_t value; >>> + >>> + if (!visit_type_uint16(v, name, &value, errp)) { >>> + return; >>> + } >>> + >>> + if (!is_power_of_2(value)) { >>> + error_setg(errp, "Vector extension VLEN must be power of 2"); >>> + return; >>> + } >>> + >>> + /* Always allow setting a default value */ >> >> What is the case for vlen equal to 0? Since in properties it is defined with default value set to 128. > > The process of setting a default uses the default setter of the property. I.e. > when setting vlen default value to 128, this function will be called with > value = 128 when cpu->cfg.vlen is 0. > > If we don't special case this scenario we'll fail the "vendor CPUs don't allow > changing vlen" check that comes right after. I'll change this design. If we need to special case the default case for every setter to not collide with the vendor CPU check, then we're better of adding the defaults manually in riscv_cpu_init(). The defaults there will be overwritten by any defaults set in the cpu_inits() of the CPUs, so in the end it's the same effect but without the extra bloat in the setters(). In fact, reading the docs we see the following note on the 'set_default' Property flag: * Property: * @set_default: true if the default value should be set from @defval, * in which case @info->set_default_value must not be NULL * (if false then no default value is set by the property system * and the field retains whatever value it was given by instance_init). So I believe putting the defaults in riscv_cpu_init() is covered by the intended design. Thanks, Daniel > > > Thanks, > > Daniel > >> >>> + if (cpu->cfg.vlen == 0) { >>> + cpu->cfg.vlen = value; >>> + return; >>> + } >>> + >>> + if (value != cpu->cfg.vlen && riscv_cpu_is_vendor(obj)) { >>> + cpu_set_prop_err(cpu, name, errp); >>> + error_append_hint(errp, "Current '%s' val: %u\n", >>> + name, cpu->cfg.vlen); >>> + return; >>> + } >>> + >>> + cpu_option_add_user_setting(name, value); >>> + cpu->cfg.vlen = value; >>> +} >>> + >>> +static void prop_vlen_get(Object *obj, Visitor *v, const char *name, >>> + void *opaque, Error **errp) >>> +{ >>> + uint16_t value = RISCV_CPU(obj)->cfg.vlen; >>> + >>> + visit_type_uint16(v, name, &value, errp); >>> +} >>> + >>> +static const PropertyInfo prop_vlen = { >>> + .name = "vlen", >>> + .get = prop_vlen_get, >>> + .set = prop_vlen_set, >>> + .set_default_value = qdev_propinfo_set_default_value_uint, >>> +}; >>> + >>> Property riscv_cpu_options[] = { >>> - DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128), >>> DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64), >>> >>> DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64), >>> @@ -1687,6 +1745,9 @@ static Property riscv_cpu_properties[] = { >>> {.name = "priv_spec", .info = &prop_priv_spec}, >>> {.name = "vext_spec", .info = &prop_vext_spec}, >>> >>> + {.name = "vlen", .info = &prop_vlen, >>> + .set_default = true, .defval.u = 128}, >>> + >>> #ifndef CONFIG_USER_ONLY >>> DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC), >>> #endif >>> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c >>> index 6501c29d8e..8ec858e096 100644 >>> --- a/target/riscv/tcg/tcg-cpu.c >>> +++ b/target/riscv/tcg/tcg-cpu.c >>> @@ -178,11 +178,6 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) >>> static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg, >>> Error **errp) >>> { >>> - if (!is_power_of_2(cfg->vlen)) { >>> - error_setg(errp, "Vector extension VLEN must be power of 2"); >>> - return; >>> - } >>> - >>> if (cfg->vlen > RV_VLEN_MAX || cfg->vlen < 128) { >>> error_setg(errp, >>> "Vector extension implementation only supports VLEN " >>> -- >>> 2.43.0 >>> >>>
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index d6625399a7..c2ff50bcab 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -29,6 +29,7 @@ #include "qapi/visitor.h" #include "qemu/error-report.h" #include "hw/qdev-properties.h" +#include "hw/core/qdev-prop-internal.h" #include "migration/vmstate.h" #include "fpu/softfloat-helpers.h" #include "sysemu/kvm.h" @@ -53,6 +54,15 @@ const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV, #define BYTE(x) (x) #endif +/* Hash that stores general user set numeric options */ +static GHashTable *general_user_opts; + +static void cpu_option_add_user_setting(const char *optname, uint32_t value) +{ + g_hash_table_insert(general_user_opts, (gpointer)optname, + GUINT_TO_POINTER(value)); +} + #define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \ {#_name, _min_ver, CPU_CFG_OFFSET(_prop)} @@ -1244,6 +1254,8 @@ static void riscv_cpu_init(Object *obj) IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX); #endif /* CONFIG_USER_ONLY */ + general_user_opts = g_hash_table_new(g_str_hash, g_str_equal); + /* * The timer and performance counters extensions were supported * in QEMU before they were added as discrete extensions in the @@ -1664,8 +1676,54 @@ static const PropertyInfo prop_vext_spec = { .set = prop_vext_spec_set, }; +static void prop_vlen_set(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + RISCVCPU *cpu = RISCV_CPU(obj); + uint16_t value; + + if (!visit_type_uint16(v, name, &value, errp)) { + return; + } + + if (!is_power_of_2(value)) { + error_setg(errp, "Vector extension VLEN must be power of 2"); + return; + } + + /* Always allow setting a default value */ + if (cpu->cfg.vlen == 0) { + cpu->cfg.vlen = value; + return; + } + + if (value != cpu->cfg.vlen && riscv_cpu_is_vendor(obj)) { + cpu_set_prop_err(cpu, name, errp); + error_append_hint(errp, "Current '%s' val: %u\n", + name, cpu->cfg.vlen); + return; + } + + cpu_option_add_user_setting(name, value); + cpu->cfg.vlen = value; +} + +static void prop_vlen_get(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + uint16_t value = RISCV_CPU(obj)->cfg.vlen; + + visit_type_uint16(v, name, &value, errp); +} + +static const PropertyInfo prop_vlen = { + .name = "vlen", + .get = prop_vlen_get, + .set = prop_vlen_set, + .set_default_value = qdev_propinfo_set_default_value_uint, +}; + Property riscv_cpu_options[] = { - DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128), DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64), DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64), @@ -1687,6 +1745,9 @@ static Property riscv_cpu_properties[] = { {.name = "priv_spec", .info = &prop_priv_spec}, {.name = "vext_spec", .info = &prop_vext_spec}, + {.name = "vlen", .info = &prop_vlen, + .set_default = true, .defval.u = 128}, + #ifndef CONFIG_USER_ONLY DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC), #endif diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c index 6501c29d8e..8ec858e096 100644 --- a/target/riscv/tcg/tcg-cpu.c +++ b/target/riscv/tcg/tcg-cpu.c @@ -178,11 +178,6 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg, Error **errp) { - if (!is_power_of_2(cfg->vlen)) { - error_setg(errp, "Vector extension VLEN must be power of 2"); - return; - } - if (cfg->vlen > RV_VLEN_MAX || cfg->vlen < 128) { error_setg(errp, "Vector extension implementation only supports VLEN "
Turning 'vlen' into a class property will allow its default value to be overwritten by cpu_init() later on, solving the issue we have now where CPU specific settings are getting overwritten by the default. For 'vlen', 'elen' and the blocksize options we need a way of tracking if the user set a value for them. This is benign for TCG since the cost of always validating these values are small, but for KVM we need syscalls to read the host values to make the validations. Knowing whether the user didn't touch the values makes a difference. We'll track user setting for these properties using a hash, like we do in the TCG driver. Common validation bits are moved from riscv_cpu_validate_v() to prop_vlen_set() to be shared with KVM. And, as done with every option we migrated to riscv_cpu_properties[], vendor CPUs can't have their 'vlen' value changed. Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> --- target/riscv/cpu.c | 63 +++++++++++++++++++++++++++++++++++++- target/riscv/tcg/tcg-cpu.c | 5 --- 2 files changed, 62 insertions(+), 6 deletions(-)