On 5/17/2026 4:28 PM, khaled saleh wrote:
The priv_spec property accepts a fixed set of values (v1.10.0, v1.11.0, 
v1.12.0, v1.13.0) but was implemented as a string type with manual 
string-to-enum conversion in custom getter/setter functions.

Convert it to use QEnumLookup with visit_type_enum() for:
- Automatic input validation by the visitor framework
- QMP introspection support (valid values are discoverable)
- Reduced boilerplate (priv_spec_from_str/to_str removed)

This resolves the "FIXME enum?" comment in cpu.c.

Signed-off-by: khaled saleh <[email protected]>
---

We usually send patches rebased on top of this tree:

https://github.com/alistair23/qemu/tree/riscv-to-apply.next

Using that tree this patch yields a trivial conflict in cpu.h.
If you can re-send it based on the tree above that would be great.


Patch LGTM otherwise. Thanks,
Daniel


  target/riscv/cpu.c         | 59 +++++++++++---------------------------
  target/riscv/cpu.h         |  1 +
  target/riscv/tcg/tcg-cpu.c |  3 +-
  3 files changed, 20 insertions(+), 43 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 506a018d52..8365471572 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -26,6 +26,7 @@
  #include "internals.h"
  #include "qapi/error.h"
  #include "qapi/visitor.h"
+#include "qapi/util.h"
  #include "qemu/error-report.h"
  #include "hw/core/qdev-properties.h"
  #include "hw/core/qdev-prop-internal.h"
@@ -1655,51 +1656,25 @@ static const PropertyInfo prop_pmp_granularity = {
      .set = prop_pmp_granularity_set,
  };
-static int priv_spec_from_str(const char *priv_spec_str)
-{
-    int priv_version = -1;
-
-    if (!g_strcmp0(priv_spec_str, PRIV_VER_1_13_0_STR)) {
-        priv_version = PRIV_VERSION_1_13_0;
-    } else if (!g_strcmp0(priv_spec_str, PRIV_VER_1_12_0_STR)) {
-        priv_version = PRIV_VERSION_1_12_0;
-    } else if (!g_strcmp0(priv_spec_str, PRIV_VER_1_11_0_STR)) {
-        priv_version = PRIV_VERSION_1_11_0;
-    } else if (!g_strcmp0(priv_spec_str, PRIV_VER_1_10_0_STR)) {
-        priv_version = PRIV_VERSION_1_10_0;
-    }
-
-    return priv_version;
-}
+static const char *const priv_spec_str[] = {
+    [PRIV_VERSION_1_10_0] = PRIV_VER_1_10_0_STR,
+    [PRIV_VERSION_1_11_0] = PRIV_VER_1_11_0_STR,
+    [PRIV_VERSION_1_12_0] = PRIV_VER_1_12_0_STR,
+    [PRIV_VERSION_1_13_0] = PRIV_VER_1_13_0_STR,
+};
-const char *priv_spec_to_str(int priv_version)
-{
-    switch (priv_version) {
-    case PRIV_VERSION_1_10_0:
-        return PRIV_VER_1_10_0_STR;
-    case PRIV_VERSION_1_11_0:
-        return PRIV_VER_1_11_0_STR;
-    case PRIV_VERSION_1_12_0:
-        return PRIV_VER_1_12_0_STR;
-    case PRIV_VERSION_1_13_0:
-        return PRIV_VER_1_13_0_STR;
-    default:
-        return NULL;
-    }
-}
+const QEnumLookup priv_spec_lookup = {
+    .array = priv_spec_str,
+    .size = ARRAY_SIZE(priv_spec_str),
+};
static void prop_priv_spec_set(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
  {
      RISCVCPU *cpu = RISCV_CPU(obj);
-    g_autofree char *value = NULL;
-    int priv_version = -1;
-
-    visit_type_str(v, name, &value, errp);
+    int priv_version;
- priv_version = priv_spec_from_str(value);
-    if (priv_version < 0) {
-        error_setg(errp, "Unsupported privilege spec version '%s'", value);
+    if (!visit_type_enum(v, name, &priv_version, &priv_spec_lookup, errp)) {
          return;
      }
@@ -1718,15 +1693,15 @@ static void prop_priv_spec_get(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
  {
      RISCVCPU *cpu = RISCV_CPU(obj);
-    const char *value = priv_spec_to_str(cpu->env.priv_ver);
+    int value = cpu->env.priv_ver;
- visit_type_str(v, name, (char **)&value, errp);
+    visit_type_enum(v, name, &value, &priv_spec_lookup, errp);
  }
static const PropertyInfo prop_priv_spec = {
-    .type = "str",
+    .type = "RISCVPrivSpec",
      .description = "priv_spec",
-    /* FIXME enum? */
+    .enum_table = &priv_spec_lookup,
      .get = prop_priv_spec_get,
      .set = prop_priv_spec_set,
  };
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index fae839cade..522b63016f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -70,6 +70,7 @@ typedef struct CPUArchState CPURISCVState;
  #define RVG RV('G')
  #define RVB RV('B')
+extern const QEnumLookup priv_spec_lookup;
  extern const uint32_t misa_bits[];
  const char *riscv_get_misa_ext_name(uint32_t bit);
  const char *riscv_get_misa_ext_description(uint32_t bit);
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 02c98cc2db..2ec4b8e98e 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -27,6 +27,7 @@
  #include "time_helper.h"
  #include "qapi/error.h"
  #include "qapi/visitor.h"
+#include "qapi/util.h"
  #include "qemu/accel.h"
  #include "qemu/error-report.h"
  #include "qemu/log.h"
@@ -86,7 +87,7 @@ static void riscv_cpu_write_misa_bit(RISCVCPU *cpu, uint32_t 
bit,
static const char *cpu_priv_ver_to_str(int priv_ver)
  {
-    const char *priv_spec_str = priv_spec_to_str(priv_ver);
+    const char *priv_spec_str = qapi_enum_lookup(&priv_spec_lookup, priv_ver);
g_assert(priv_spec_str);


Reply via email to