On Mon, 23 Feb 2026 17:01:08 +0000
Peter Maydell <[email protected]> wrote:

> Currently we allow devices to define "link properties" with
> DEFINE_PROP_LINK(): these are a way to give a device a pointer to
> another QOM object.  (Under the hood this is done by handing it the
> canonical QOM path for the object.)
> 
> We also allow devices to define "array properties" with
> DEFINE_PROP_ARRAY(): these are a way to give a device a
> variable-length array of properties.
> 
> However, there is no way to define an array of link properties.  If
> you try to do it by passing qdev_prop_link as the arrayprop argument
> to DEFINE_PROP_ARRAY() you will get a crash because qdev_prop_link
> does not provide the .set and .get methods in its PropertyInfo
> struct.
> 
> This patch implements a new DEFINE_PROP_LINK_ARRAY(). In
> a device you can use it like this:
> 
> struct MyDevice {
>     ...
>     uint32_t num_cpus;
>     ARMCPU **cpus;
> }
> 
> and in your Property array:
>     DEFINE_PROP_LINK_ARRAY("cpus", MyDevice, num_cpus, cpus,
>                            TYPE_ARM_CPU, ARMCPU *),
> 
> The array property code will fill in s->num_cpus, allocate memory in
> s->cpus, and populate it with pointers.
> 
> On the device-creation side you set the property in the same way as
> the existing array properties, using the new qlist_append_link()
> function to append to the QList:
> 
>     QList *cpulist = qlist_new();
>     for (int i = 0; i < cpus; i++) {
>         qlist_append_link(cpulist, OBJECT(cpu[i]));
>     }
>     qdev_prop_set_array(mydev, "cpus", cpulist);
> 
> The implementation is mostly in the provision of the .set and
> .get methods to the qdev_prop_link PropertyInfo struct. The
> code of these methods parallels the code in
> object_set_link_property() and object_get_link_property().  We can't
> completely share the code with those functions because of differences
> in where we get the information like the target QOM type, but I have
> pulled out a new function object_resolve_and_typecheck() for the
> shared "given a QOM path and a type, give me the object or an error"
> code.
> 
> Signed-off-by: Peter Maydell <[email protected]>

Hi Peter,

Looks good to me, but I'm not confident enough on this stuff to give
tags.  A couple of trivial things inline.

Jonathan

> ---
> I want this specifically for the GICv5 interrupt controller device
> I'm working on.  I'd like to be able to pass in links to the CPUs
> connected to the GIC, so that we don't have to have the code assume
> that it's connected to CPU numbers 0,1,2... the way the current
> GICv3 code does.
> 
> I think Phil also had a proposed series a while back that wanted
> to do something similar with one of the existing devices.
> 
> I figured I'd post this early for review, though obviously it's a
> little unmotivated until I have my new GICv5 code into enough shape
> to submit. This is tested, but with my work-in-progress code.

You probably want to update this set of notes given it's in your
GICv5 set now!

> diff --git a/include/qom/object.h b/include/qom/object.h
> index 26df6137b9..48fdbf353e 100644
> --- a/include/qom/object.h
> +++ b/include/qom/object.h
> @@ -1750,6 +1750,25 @@ ObjectProperty 
> *object_class_property_add_link(ObjectClass *oc,
>                                              Object *val, Error **errp),
>                                ObjectPropertyLinkFlags flags);
>  
> +
> +/**
> + * object_resolve_and_typecheck:
> + * @path: path to look up
> + * @name: name of property we are resolving for (used only in error messages)
> + * @target_type: QOM type we expect @path to resolve to
> + * @errp: error
> + *
> + * Look up the object at @path and return it. If it does not have
> + * the correct type @target_type, return NULL and set @errp.
> + *
> + * This is similar to object_resolve_path_type(), but it insists on
> + * a non-ambiguous path and it produces error messages that are specialised
> + * to the use case of setting a link property on an object.
> + */
> +Object *object_resolve_and_typecheck(const char *path,
> +                                     const char *name,
> +                                     const char *target_type, Error **errp);

I'm not sure why you went with this wrapping. I'd combine the first two lines.

> +
>  /**
>   * object_property_add_str:
>   * @obj: the object to add a property to
> diff --git a/qom/object.c b/qom/object.c
> index ff8ede8a32..90b8f3461e 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -1895,26 +1895,13 @@ static void object_get_link_property(Object *obj, 
> Visitor *v,
>      }
>  }
>  
> -/*
> - * object_resolve_link:
> - *
> - * Lookup an object and ensure its type matches the link property type.  This
> - * is similar to object_resolve_path() except type verification against the
> - * link property is performed.
> - *
> - * Returns: The matched object or NULL on path lookup failures.
> - */
> -static Object *object_resolve_link(Object *obj, const char *name,
> -                                   const char *path, Error **errp)
> +Object *object_resolve_and_typecheck(const char *path,
> +                                     const char *name,

As above.

> +                                     const char *target_type, Error **errp)



Reply via email to