From nobody Thu Apr 2 19:04:01 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1774610613; cv=none; d=zohomail.com; s=zohoarc; b=OrBQJyhyRmWjNWMttk1P9wK/f54ow7QTdmx+PRSxgWTS+rkQHacrencTQvmMHkTm1JfKnDWzJfG8qXdd0PUh0G7m6dzd7tuMdQV+uUmL1Bl1ohgHKPtTTX703O4iFtw13kzZY8TOY/9xZXyPeBsRKq34QXqNMdbRfM8a5ZvnqYI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774610613; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=4YrZovDto6t0FqJWMN8zdd2dG3ackVIujvm5OvxbxII=; b=nczR3YE9wBdN69j+iIXMwaGxiPickZ5XjZ9Xk1gXYAhcrnAX5015hO/q6/EnmKlsHUafr4KO5CNDiXkt5pnUtrmrndVBgu3IYuLhPRUVykneZGVtLmXPtPPW5XJyf/CYtL1Q3jOHPYuBshNXDZ6cTb4UPmwm5g7CZdrNSWvZOEQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774610613057769.0758315637876; Fri, 27 Mar 2026 04:23:33 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w65Be-0006Md-8S; Fri, 27 Mar 2026 07:17:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w65Bc-0006LI-DU for qemu-devel@nongnu.org; Fri, 27 Mar 2026 07:17:08 -0400 Received: from mail-wr1-x436.google.com ([2a00:1450:4864:20::436]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1w65BZ-0007WQ-K1 for qemu-devel@nongnu.org; Fri, 27 Mar 2026 07:17:08 -0400 Received: by mail-wr1-x436.google.com with SMTP id ffacd0b85a97d-43b5bded412so1432102f8f.0 for ; Fri, 27 Mar 2026 04:17:05 -0700 (PDT) Received: from lanath.. (wildly.archaic.org.uk. [81.2.115.145]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43b919cf2b2sm15484227f8f.18.2026.03.27.04.17.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Mar 2026 04:17:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1774610224; x=1775215024; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4YrZovDto6t0FqJWMN8zdd2dG3ackVIujvm5OvxbxII=; b=w+4rZU36cxBSdOuKiyZPG6BP273oRmume/ZPlRiGRLvwJWtEHoOpOv7g/BxdierTbk bpMFji5hO6xdXFDtYrcqeMm27SyfnnSec8UfDLW87sFnmY8sBsXkGxwz7beaRU19PJVh ISbvki48l3wFm34ADYII8HyAx/W7+0GgNkhIoRbMkJoaCIwoPAenH9gloECf6zPifIii p0ouKPjz7Klcpkw9UvCQFWIY3y9QcxAKc+mRdnxIlv/G96zL0+XAmjZIXOMHcxYQ3PVX Tuvt+P5ijrFwtRNCPSEnPjCGAzgCugucE1wtSzUh4SGxpr5Q7cwwL4LKfmQ59ySZLRoo YmJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774610224; x=1775215024; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=4YrZovDto6t0FqJWMN8zdd2dG3ackVIujvm5OvxbxII=; b=gFGQkQaiiwYXBOb9nVX9TH519i/OHmerECcle/HkRPqwsQNBsXcMpOCMrusGGpS/LI ddeI0YuUCMSnbzPBHgXx8kB49htmpwxz34ZiWA2TDBXASo9Hk7QD+jEy8eE5dmxAExDp /zqCwbGRPyAwQhU6ctMXuCY91tFUK+tEk1bf/I35zbS5jHp/DQKhecukyr5H8xdY06aY TZkuJ53KwNnY4cROWtFv95EfEa2uGfo/zUmbhjSbWAaLStv7oEm6hown063V9G+FcIaP LUArrJmux1DwyRmD5iNEPKerkZgMBJoc3Le/+yHnSvBIM3hlHIx/A5vPeS6PjAoWQ/O+ qW0w== X-Forwarded-Encrypted: i=1; AJvYcCUxt5kzZpDGEXwAD3ce+j1ExdCsBb1kaSuTCZpd3CbAU2Hw4H/Bd+wLjuFmoUGP5WeojO6kdqLX+SvQ@nongnu.org X-Gm-Message-State: AOJu0YzmrB6Hg3ahhUplg7+ETpOegzuJBpeGAyPYKSntWYO9a6HNNG+P KGHQO+CKZmNHQvbv5bz1ywDtem8vidbRtPnA8k1gtK6Au8mWAgDulJJhpO4dDg65oNg= X-Gm-Gg: ATEYQzwDSlcRJfbN2k3UkQR7/cCNmLV5hDy/jdrSW7ctyhMPzMABSd6XxLnVqHGD4r/ RSkGS7iwjsIgmEsYwjeUoc5S2zJq4Yt2iSoMFbjwZU0M5ki55BAPowxcP7D32h6EkUA1HzCh0Qd LCCngTndugVVK30f6ria1KQcHmgSXFUXcGnVjCLNZ8MqWo7asGM13vYVKcf+SJZ9J+W/lMeZMiK bnxqPNgQZUefU1pnjDkJyTqvN3iT27i1cmdvdZxH/1TToIFJksYSWqNgJkqO7yuL+Ij6765LG9Q Vt5aOaJB4Ehjep+OsksTLdf5XbYo0b6RRlXAHGwxeumtH/4TQMDqTS0UavO9Ib96SKjK1ORn2TF j4WTdR4yJFhy++ZYa+zjCjILYpGoP11GEQ24nvkd84d0CL7NsmltSeRgAPiecrbGvlX2Qyb4hX0 UW7L9dZoewoomUcptd5VhxnLsqUsfQHsbX1UsFvizAB726RXJJf/wx3Ur/RheYXBm+Ytf1ZAHE0 j48ETcFNvmoReYC77i6of8RDDVpNi0= X-Received: by 2002:a05:6000:22c2:b0:439:b3bb:2777 with SMTP id ffacd0b85a97d-43b9e9eb148mr3219353f8f.22.1774610223787; Fri, 27 Mar 2026 04:17:03 -0700 (PDT) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: Jonathan Cameron Subject: [PATCH v2 02/65] hw/core: Permit devices to define an array of link properties Date: Fri, 27 Mar 2026 11:15:57 +0000 Message-ID: <20260327111700.795099-3-peter.maydell@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260327111700.795099-1-peter.maydell@linaro.org> References: <20260327111700.795099-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::436; envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x436.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linaro.org) X-ZM-MESSAGEID: 1774610613898154100 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 =3D qlist_new(); for (int i =3D 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 Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- hw/core/qdev-properties.c | 78 +++++++++++++++++++++++++++++++ include/hw/core/qdev-properties.h | 41 ++++++++++++++++ 2 files changed, 119 insertions(+) diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index ba8461e9a4..f8181b0d91 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -669,6 +669,7 @@ static Property array_elem_prop(Object *obj, const Prop= erty *parent_prop, * being inside the device struct. */ .offset =3D (uintptr_t)elem - (uintptr_t)obj, + .link_type =3D parent_prop->link_type, }; } =20 @@ -950,6 +951,12 @@ void qdev_prop_set_array(DeviceState *dev, const char = *name, QList *values) qobject_unref(values); } =20 +void qlist_append_link(QList *qlist, Object *obj) +{ + g_autofree char *path =3D object_get_canonical_path(obj); + qlist_append_str(qlist, path); +} + static GPtrArray *global_props(void) { static GPtrArray *gp; @@ -1059,9 +1066,80 @@ static ObjectProperty *create_link_property(ObjectCl= ass *oc, const char *name, OBJ_PROP_LINK_STRONG); } =20 +/* + * The logic in these get_link() and set_link() functions is similar + * to that used for single-element link properties in the + * object_get_link_property() and object_set_link_property() functions. + * The difference is largely in how we get the expected type of the + * link: for us it is in the Property struct, and for a single link + * property it is part of the property name on the object. + */ +static void get_link(Object *obj, Visitor *v, const char *name, void *opaq= ue, + Error **errp) +{ + const Property *prop =3D opaque; + Object **targetp =3D object_field_prop_ptr(obj, prop); + g_autofree char *path =3D NULL; + + if (*targetp) { + path =3D object_get_canonical_path(*targetp); + visit_type_str(v, name, &path, errp); + } else { + path =3D g_strdup(""); + visit_type_str(v, name, &path, errp); + } +} + +static void set_link(Object *obj, Visitor *v, const char *name, void *opaq= ue, + Error **errp) +{ + const Property *prop =3D opaque; + Object **targetp =3D object_field_prop_ptr(obj, prop); + g_autofree char *path =3D NULL; + Object *new_target, *old_target =3D *targetp; + + ERRP_GUARD(); + + /* Get the path to the object we want to set the link to */ + if (!visit_type_str(v, name, &path, errp)) { + return; + } + + /* Now get the pointer to the actual object */ + if (*path) { + new_target =3D object_resolve_and_typecheck(path, prop->name, + prop->link_type, errp); + if (!new_target) { + return; + } + } else { + new_target =3D NULL; + } + + /* + * Our link properties are always OBJ_PROP_LINK_STRONG and + * have the allow_set_link_before_realize check. + */ + qdev_prop_allow_set_link_before_realize(obj, prop->name, new_target, e= rrp); + if (*errp) { + return; + } + + *targetp =3D new_target; + object_ref(new_target); + object_unref(old_target); +} + const PropertyInfo qdev_prop_link =3D { .type =3D "link", .create =3D create_link_property, + /* + * Since we have a create method, the get and set are used + * only in get_prop_array() and set_prop_array() for the case + * where we have an array of link properties. + */ + .get =3D get_link, + .set =3D set_link, }; =20 void qdev_property_add_static(DeviceState *dev, const Property *prop) diff --git a/include/hw/core/qdev-properties.h b/include/hw/core/qdev-prope= rties.h index d8745d4c65..58527e62d5 100644 --- a/include/hw/core/qdev-properties.h +++ b/include/hw/core/qdev-properties.h @@ -168,6 +168,32 @@ extern const PropertyInfo qdev_prop_link; DEFINE_PROP(_name, _state, _field, qdev_prop_link, _ptr_type, \ .link_type =3D _type) =20 +/** + * DEFINE_PROP_LINK_ARRAY: + * @_name: name of the array + * @_state: name of the device state structure type + * @_field: uint32_t field in @_state to hold the array length + * @_arrayfield: field in @_state (of type '@_arraytype *') which + * will point to the array + * @_linktype: QOM type name of the link type + * @_arraytype: C type of the array elements + * + * Define device properties for a variable-length array _name of links + * (i.e. this is the array version of DEFINE_PROP_LINK). + * + * The array is represented as a list of QStrings in the visitor interface, + * where each string is the QOM path of the object to be linked. + */ +#define DEFINE_PROP_LINK_ARRAY(_name, _state, _field, _arrayfield, \ + _linktype, _arraytype) \ + DEFINE_PROP(_name, _state, _field, qdev_prop_array, uint32_t, \ + .set_default =3D true, \ + .defval.u =3D 0, \ + .arrayinfo =3D &qdev_prop_link, \ + .arrayfieldsize =3D sizeof(_arraytype), \ + .arrayoffset =3D offsetof(_state, _arrayfield), \ + .link_type =3D _linktype) + #define DEFINE_PROP_UINT8(_n, _s, _f, _d) \ DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_uint8, uint8_t) #define DEFINE_PROP_UINT16(_n, _s, _f, _d) \ @@ -219,6 +245,21 @@ void qdev_prop_set_enum(DeviceState *dev, const char *= name, int value); /* Takes ownership of @values */ void qdev_prop_set_array(DeviceState *dev, const char *name, QList *values= ); =20 +/** + * qlist_append_link: Add a QOM object to a QList of link properties + * @qlist: list to append to + * @obj: object to append + * + * This is a helper function for constructing a QList to pass to + * qdev_prop_set_array() when the qdev property array is an array of + * link properties (i.e. one defined with DEFINE_PROP_LINK_ARRAY). + * + * The object is encoded into the list as a QString which is the + * canonical path of the object; this is the same encoding that + * object_set_link_property() and object_get_link_property() use. + */ +void qlist_append_link(QList *qlist, Object *obj); + void *object_field_prop_ptr(Object *obj, const Property *prop); =20 void qdev_prop_register_global(GlobalProperty *prop); --=20 2.43.0