On 04/09/2026 06:04, Cédric Le Goater wrote:

Add a DT-style alias container /machine/labels where board code registers
link<> properties pointing to well-known devices. Tests can then resolve
a device with a single QMP call (qom-get /machine/labels/<name>) instead
of walking the bus hierarchy.

Signed-off-by: Cédric Le Goater <[email protected]>
---
  include/hw/arm/aspeed.h | 12 ++++++++++++
  hw/arm/aspeed.c         | 10 ++++++++++
  2 files changed, 22 insertions(+)

diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
index 245d02e5f757..0b8b40262767 100644
--- a/include/hw/arm/aspeed.h
+++ b/include/hw/arm/aspeed.h
@@ -128,4 +128,16 @@ void aspeed_machine_ast2600_class_emmc_init(ObjectClass 
*oc);
   */
  void aspeed_connect_serial_hds_to_uarts(AspeedMachineState *bmc);
+/*
+ * aspeed_machine_add_label:
+ * @bmc: pointer to the #AspeedMachineState.
+ * @label: the label name for the device.
+ * @target: the device object to register.
+ *
+ * Register a well-known device under /machine/labels/<label> as a
+ * read-only link.  Aborts on duplicate label names.
+ */
+void aspeed_machine_add_label(AspeedMachineState *bmc, const char *label,
+                              Object *target);
+
  #endif
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 1f8d5d3e132d..79b8d55d66da 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -127,6 +127,14 @@ void aspeed_connect_serial_hds_to_uarts(AspeedMachineState 
*bmc)
      }
  }
+void aspeed_machine_add_label(AspeedMachineState *bmc, const char *label,
+                              Object *target)
+{
+    Object *labels = object_resolve_path_component(OBJECT(bmc), "labels");
+
+    object_property_add_const_link(labels, label, target);
+}
+
  static void aspeed_machine_init(MachineState *machine)
  {
      AspeedMachineState *bmc = ASPEED_MACHINE(machine);
@@ -137,6 +145,8 @@ static void aspeed_machine_init(MachineState *machine)
      DriveInfo *emmc0 = NULL;
      bool boot_emmc;
+ object_property_add_new_container(OBJECT(machine), "labels");
+
      bmc->soc = ASPEED_SOC(object_new(amc->soc_name));
      object_property_add_child(OBJECT(machine), "soc", OBJECT(bmc->soc));
      object_unref(OBJECT(bmc->soc));

Thanks for the proposal, Cédric! A few comments from me below:

1) Is there any reason it should be called labels as opposed to aliases? The aliases name as used in Open Firmware feels more intuitive to me.

2) If there is agreement in this approach, is there any reason why we shouldn't create /machine/labels (or equivalent) for all QOM trees? I certainly think it would be a useful addition going forward.

3) Is there any reason why we need to provide the machine object directly to the aspeed_machine_add_label() function? If possible I think it makes sense to avoid the direct machine reference, in case the underlying implementation changes i.e.


  void machine_add_alias(const char *alias, Object *target)
  {
     Object *aliases = object_resolve_path("/machine/aliases",  NULL);

     object_property_add_const_link(aliases, alias, target);
  }


Even better perhaps we should also generate an error if the alias already exists to ensure they are always unique i.e.


  bool machine_add_alias(const char *alias, Object *target,
                         Error **errp)
  {
     Object *aliases = object_resolve_path("/machine/aliases",  NULL);

     if (object_resolve_path_component(aliases, alias)) {
         error_setg(errp, "machine alias '%s' already exists");
         return false;
     }

     return (object_property_add_const_link(aliases, alias, target) !=
             NULL);
  }


4) Should we create a page in the documentation explaining which devices/objects should be included in the alias list, which ones are added automatically, and what naming conventions should be used for devices e.g. serial0, net0 for a network device etc.?

5) What should happen to aliases for devices that are hot-plugged/hot-unplugged?


ATB,

Mark.


Reply via email to