On Fri, 6 Mar 2026 at 11:11, Jonathan Cameron <[email protected]> wrote: > > 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!
Yes :-) > > 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. Yeah, I'm not sure why it ended up like this either. Sometimes that happens because I change my mind on the name of a function and don't notice that it means the wrapping can be done differently, but I have no recollection of what the process was in this specific case. I agree that putting the first two arguments on one line is better. -- PMM
