diff mbox series

[RFC,v5,14/21] hw/core/machine: Allow dynamic registration of valid CPU types

Message ID 20250424222112.36194-15-philmd@linaro.org
State New
Headers show
Series single-binary: Make hw/arm/ common | expand

Commit Message

Philippe Mathieu-Daudé April 24, 2025, 10:21 p.m. UTC
Add MachineClass::get_valid_cpu_types(), a helper that
returns a dynamic list of CPU types. Since the helper
takes a MachineState argument, we know the machine is
created by the time we call it.

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

Comments

Pierrick Bouvier April 24, 2025, 10:43 p.m. UTC | #1
On 4/24/25 15:21, Philippe Mathieu-Daudé wrote:
> Add MachineClass::get_valid_cpu_types(), a helper that
> returns a dynamic list of CPU types. Since the helper
> takes a MachineState argument, we know the machine is
> created by the time we call it.
> 
> Suggested-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>   include/hw/boards.h |  4 ++++
>   hw/core/machine.c   | 26 ++++++++++++++++++++++++++
>   2 files changed, 30 insertions(+)
> 
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index 3573907d597..700e4f4ccf3 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -259,6 +259,9 @@ typedef struct {
>    * @smbios_memory_device_size:
>    *    Default size of memory device,
>    *    SMBIOS 3.1.0 "7.18 Memory Device (Type 17)"
> + * @get_valid_cpu_types:
> + *    Returns a list of valid CPU types for this board. May be NULL
> + *    if not needed.
>    */
>   struct MachineClass {
>       /*< private >*/
> @@ -306,6 +309,7 @@ struct MachineClass {
>       bool ignore_memory_transaction_failures;
>       int numa_mem_align_shift;
>       const char * const *valid_cpu_types;
> +    GPtrArray *(*get_valid_cpu_types)(const MachineState *ms);
>       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 ed01798d37c..0901a92b32a 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -1581,6 +1581,32 @@ static bool is_cpu_type_supported(const MachineState *machine, Error **errp)
>                   error_append_hint(errp, "\n");
>               }
>   
> +            return false;
> +        }
> +    } else if (mc->get_valid_cpu_types) {

Since we'll keep both valid_cpu_types, and get_value_cpu_types, instead 
of doing a full replacement, would that be possible to add an assert here?

g_assert(!mc->valid_cpu_types);

and

g_assert(!mc->get_valid_cpu_types) in branch above.

This way, we make sure only one is defined.

With that,
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
diff mbox series

Patch

diff --git a/include/hw/boards.h b/include/hw/boards.h
index 3573907d597..700e4f4ccf3 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -259,6 +259,9 @@  typedef struct {
  * @smbios_memory_device_size:
  *    Default size of memory device,
  *    SMBIOS 3.1.0 "7.18 Memory Device (Type 17)"
+ * @get_valid_cpu_types:
+ *    Returns a list of valid CPU types for this board. May be NULL
+ *    if not needed.
  */
 struct MachineClass {
     /*< private >*/
@@ -306,6 +309,7 @@  struct MachineClass {
     bool ignore_memory_transaction_failures;
     int numa_mem_align_shift;
     const char * const *valid_cpu_types;
+    GPtrArray *(*get_valid_cpu_types)(const MachineState *ms);
     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 ed01798d37c..0901a92b32a 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1581,6 +1581,32 @@  static bool is_cpu_type_supported(const MachineState *machine, Error **errp)
                 error_append_hint(errp, "\n");
             }
 
+            return false;
+        }
+    } else if (mc->get_valid_cpu_types) {
+        GPtrArray *vct = mc->get_valid_cpu_types(machine);
+        bool valid = false;
+
+        for (i = 0; i < vct->len; i++) {
+            if (object_class_dynamic_cast(oc, vct->pdata[i])) {
+                valid = true;
+                break;
+            }
+        }
+
+        if (!valid) {
+            g_autofree char *requested = cpu_model_from_type(machine->cpu_type);
+
+            error_setg(errp, "Invalid CPU model: %s", requested);
+            error_append_hint(errp, "The valid models are: ");
+            for (i = 0; i < vct->len; i++) {
+                g_autofree char *model = cpu_model_from_type(vct->pdata[i]);
+                error_append_hint(errp, "%s%s",
+                                  model, i + 1 == vct->len ? "\n" : ", ");
+            }
+        }
+        g_ptr_array_free(vct, true);
+        if (!valid) {
             return false;
         }
     }