Add MachineClass::valid_cpu_types_list, a dynamic list of strings.

CPU types can be registered with machine_class_add_valid_cpu_type().

Suggested-by: Pierrick Bouvier <pierrick.bouv...@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <phi...@linaro.org>
---
 include/hw/boards.h |  8 ++++++++
 hw/core/machine.c   | 30 ++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/include/hw/boards.h b/include/hw/boards.h
index 02f43ac5d4d..647a29ff04d 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -56,6 +56,13 @@ void machine_set_cache_topo_level(MachineState *ms, 
CacheLevelAndType cache,
 bool machine_check_smp_cache(const MachineState *ms, Error **errp);
 void machine_memory_devices_init(MachineState *ms, hwaddr base, uint64_t size);
 
+/**
+ * machine_class_add_valid_cpu_type: Add type to list of valid CPUs
+ * @mc: Machine class
+ * @type: CPU type to allow (should be a subtype of TYPE_CPU)
+ */
+void machine_class_add_valid_cpu_type(MachineClass *mc, const char *type);
+
 /**
  * machine_class_allow_dynamic_sysbus_dev: Add type to list of valid devices
  * @mc: Machine class
@@ -306,6 +313,7 @@ struct MachineClass {
     bool ignore_memory_transaction_failures;
     int numa_mem_align_shift;
     const char * const *valid_cpu_types;
+    GList *valid_cpu_types_list;
     strList *allowed_dynamic_sysbus_devices;
     bool auto_enable_numa_with_memhp;
     bool auto_enable_numa_with_memdev;
diff --git a/hw/core/machine.c b/hw/core/machine.c
index f52a4f2273b..ff27d533b5c 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1538,6 +1538,12 @@ const char *machine_class_default_cpu_type(MachineClass 
*mc)
     return mc->default_cpu_type;
 }
 
+void machine_class_add_valid_cpu_type(MachineClass *mc, const char *type)
+{
+    mc->valid_cpu_types_list = g_list_prepend(mc->valid_cpu_types_list,
+                                              g_strdup(type));
+}
+
 static bool is_cpu_type_supported(const MachineState *machine, Error **errp)
 {
     MachineClass *mc = MACHINE_GET_CLASS(machine);
@@ -1581,6 +1587,30 @@ static bool is_cpu_type_supported(const MachineState 
*machine, Error **errp)
             return false;
         }
     }
+    if (mc->valid_cpu_types_list) {
+        bool valid = false;
+        unsigned count = 0;
+        GList *l;
+
+        for (l = mc->valid_cpu_types_list; !valid && l != NULL; l = l->next) {
+            valid |= !!object_class_dynamic_cast(oc, l->data);
+            count++;
+        }
+
+        if (!valid) {
+            g_autofree char *requested = 
cpu_model_from_type(machine->cpu_type);
+            mc->valid_cpu_types_list = 
g_list_reverse(mc->valid_cpu_types_list);
+            error_setg(errp, "Invalid CPU model: %s", requested);
+            error_append_hint(errp, "The valid models are: ");
+            for (l = mc->valid_cpu_types_list; l != NULL; l = l->next) {
+                g_autofree char *model = cpu_model_from_type(l->data);
+                error_append_hint(errp, "%s%s", model, --count ? ", " : "");
+            }
+            error_append_hint(errp, "\n");
+
+            return false;
+        }
+    }
 
     /* Check if CPU type is deprecated and warn if so */
     cc = CPU_CLASS(oc);
-- 
2.47.1


Reply via email to