From patchwork Tue Oct 29 21:16:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Xu X-Patchwork-Id: 13855542 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5A67BD74941 for ; Tue, 29 Oct 2024 21:17:13 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t5tZm-0002N3-UV; Tue, 29 Oct 2024 17:16:30 -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 1t5tZa-0002Lh-LV for qemu-devel@nongnu.org; Tue, 29 Oct 2024 17:16:21 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t5tZZ-0007cM-34 for qemu-devel@nongnu.org; Tue, 29 Oct 2024 17:16:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730236576; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=kY+kbURi2Pxc2UnQSzuDl6KSUoQC+SP5OP047RlJNdA=; b=cbomNCfFVD1AFHSAaYXds2R5bR2LxZydIrUNBDSDCrRFOz2OovB6BdJdddb/sO7IFnxR97 ND+xTY5wpwT2fuoC31T6vgy5KBSX0rovLUbOAVM1uC86Mx2lXeZsZ8HVdyebnsnHAV2n5f cGD8Y3ec7mIqYHrxXo6pkk5u1fOIKn0= Received: from mail-ot1-f69.google.com (mail-ot1-f69.google.com [209.85.210.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-606-XXRtcpj2PMaKvtFwaHe2dA-1; Tue, 29 Oct 2024 17:16:15 -0400 X-MC-Unique: XXRtcpj2PMaKvtFwaHe2dA-1 Received: by mail-ot1-f69.google.com with SMTP id 46e09a7af769-7181a10a0bbso5006147a34.3 for ; Tue, 29 Oct 2024 14:16:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730236573; x=1730841373; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kY+kbURi2Pxc2UnQSzuDl6KSUoQC+SP5OP047RlJNdA=; b=gw8A7H9sNjC/ov+1Pmrw0NLzjY5ehQbNrB853oqD2cEl1KW+HIwoFBkKUmDGEjHObA evHeBjm/VaBMYzzVUsFzf2mm2DwhvR1Y6IV+ifLWDDvlVCvTkBHkkGnsOIdkad4pmBU5 DOhSGUVghqNBMtWnfck0YL8kH5H+Ix8pRQrK9oLZ/hm+PL+11JhghOBzyvSlEXFmES4w exVhGcyJhc5OpSOBIJ7DCt07Xngor5U6wCmhRGEoMenFLfcQuZFVnzXhAnZI+EaKICm/ k2cSDOs4XcXTdntVlubshfgS9D4WGZYayMNJPPMMF2fwjoducyo8fXT0gWmuFFjVUtQ5 Bk7Q== X-Gm-Message-State: AOJu0YzfmnoXYayllHtfq/hJpVoI0jbnQZw7010yZSfzIPXdSEI2cqcn 4/1N1Zyjued8IzKtzz5Pq5LgCq2tFpFRoUYF2HsPD1ru5y61fR2Uu1G89wowqnhhJahQODXl7V/ t0N0KlQ/BIgB+pRKUlZibXs+OiO7G7UjTkUHQBQWA81TjwETfpGekr9WCPX2vpDlwNn21ZPVLR6 I2QE9OGO70CrDtDsLwu0gX2CEJGWnGJ3htVA== X-Received: by 2002:a05:6830:6001:b0:718:fcc:cf76 with SMTP id 46e09a7af769-71867eb1b81mr14233948a34.0.1730236573431; Tue, 29 Oct 2024 14:16:13 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFo1LujMOyCXcfV15vIuQeNgLjRPkQ7LJc5r34HjPDZ/VLz4YMl2Vxa8htGQxlOEKsCoX+dSA== X-Received: by 2002:a05:6830:6001:b0:718:fcc:cf76 with SMTP id 46e09a7af769-71867eb1b81mr14233915a34.0.1730236572869; Tue, 29 Oct 2024 14:16:12 -0700 (PDT) Received: from x1n.redhat.com (pool-99-254-114-190.cpe.net.cable.rogers.com. [99.254.114.190]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-46132292c97sm48481691cf.49.2024.10.29.14.16.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Oct 2024 14:16:11 -0700 (PDT) From: Peter Xu To: qemu-devel@nongnu.org Cc: Markus Armbruster , Peter Maydell , Eduardo Habkost , Paolo Bonzini , Mark Cave-Ayland , Igor Mammedov , "Michael S . Tsirkin" , Alex Williamson , "Dr . David Alan Gilbert" , peterx@redhat.com, =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , =?utf-8?q?Phi?= =?utf-8?q?lippe_Mathieu-Daud=C3=A9?= , =?utf-8?q?C=C3=A9?= =?utf-8?q?dric_Le_Goater?= , Fabiano Rosas , Juraj Marcin Subject: [PATCH RFC v2 1/7] qom: Track dynamic initiations of random object class Date: Tue, 29 Oct 2024 17:16:01 -0400 Message-ID: <20241029211607.2114845-2-peterx@redhat.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20241029211607.2114845-1-peterx@redhat.com> References: <20241029211607.2114845-1-peterx@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=peterx@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -23 X-Spam_score: -2.4 X-Spam_bar: -- X-Spam_report: (-2.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.302, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add a helper object_new_allowed(), use it to track all the places in QEMU where a new (and especially, random) object can be created. Currently, it is some form of a cleanup, just to put together all the errors where QEMU wants to avoid instantiations of abstract classes. The follow up patch will add more restriction on what object we can create. A side effect of the cleanup: we could have reported the error message in different ways even if the reason is always the same (attempts to create an instance for an abstract class). Now we always report the same message, could be different from before, but hopefully still worthwhile to change. Signed-off-by: Peter Xu --- include/qom/object.h | 13 +++++++++++++ chardev/char.c | 4 +--- hw/core/cpu-common.c | 13 +++++++++---- qom/object.c | 17 +++++++++++++++-- qom/object_interfaces.c | 3 +-- system/qdev-monitor.c | 4 +--- 6 files changed, 40 insertions(+), 14 deletions(-) diff --git a/include/qom/object.h b/include/qom/object.h index 2af9854675..32f1af2986 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -627,6 +627,19 @@ Object *object_new_with_class(ObjectClass *klass); */ Object *object_new(const char *typename); +/** + * object_new_allowed: + * @klass: The class to instantiate, or fetch instance from. + * @errp: The pointer to an Error* that might be filled + * + * This function detects whether creating a new object of specificed class + * is allowed. For example, we do not allow initiations of abstract class. + * + * Returns: True if new objects allowed, false otherwise. When false is + * returned, errp will be set with a proper error message. + */ +bool object_new_allowed(ObjectClass *klass, Error **errp); + /** * object_new_with_props: * @typename: The name of the type of the object to instantiate. diff --git a/chardev/char.c b/chardev/char.c index a1722aa076..7fa5b82585 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -533,9 +533,7 @@ static const ChardevClass *char_get_class(const char *driver, Error **errp) return NULL; } - if (object_class_is_abstract(oc)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver", - "a non-abstract device type"); + if (!object_new_allowed(oc, errp)) { return NULL; } diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c index 09c7903594..1815b08ba0 100644 --- a/hw/core/cpu-common.c +++ b/hw/core/cpu-common.c @@ -154,12 +154,17 @@ ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model) assert(cc->class_by_name); assert(cpu_model); oc = cc->class_by_name(cpu_model); - if (object_class_dynamic_cast(oc, typename) && - !object_class_is_abstract(oc)) { - return oc; + + if (!object_class_dynamic_cast(oc, typename)) { + return NULL; } - return NULL; + /* TODO: allow error message to be passed to the callers */ + if (!object_new_allowed(oc, NULL)) { + return NULL; + } + + return oc; } static void cpu_common_parse_features(const char *typename, char *features, diff --git a/qom/object.c b/qom/object.c index 11424cf471..4f3739fd85 100644 --- a/qom/object.c +++ b/qom/object.c @@ -797,6 +797,19 @@ Object *object_new(const char *typename) return object_new_with_type(ti); } +bool object_new_allowed(ObjectClass *klass, Error **errp) +{ + ERRP_GUARD(); + + /* Abstract classes are not instantiable */ + if (object_class_is_abstract(klass)) { + error_setg(errp, "Object type '%s' is abstract", + klass->type->name); + return false; + } + + return true; +} Object *object_new_with_props(const char *typename, Object *parent, @@ -831,10 +844,10 @@ Object *object_new_with_propv(const char *typename, return NULL; } - if (object_class_is_abstract(klass)) { - error_setg(errp, "object type '%s' is abstract", typename); + if (!object_new_allowed(klass, errp)) { return NULL; } + obj = object_new_with_type(klass->type); if (!object_set_propv(obj, errp, vargs)) { diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c index e0833c8bfe..d68faf2234 100644 --- a/qom/object_interfaces.c +++ b/qom/object_interfaces.c @@ -102,8 +102,7 @@ Object *user_creatable_add_type(const char *type, const char *id, return NULL; } - if (object_class_is_abstract(klass)) { - error_setg(errp, "object type '%s' is abstract", type); + if (!object_new_allowed(klass, errp)) { return NULL; } diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c index 44994ea0e1..5609e73635 100644 --- a/system/qdev-monitor.c +++ b/system/qdev-monitor.c @@ -255,9 +255,7 @@ static DeviceClass *qdev_get_device_class(const char **driver, Error **errp) return NULL; } - if (object_class_is_abstract(oc)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver", - "a non-abstract device type"); + if (!object_new_allowed(oc, errp)) { return NULL; } From patchwork Tue Oct 29 21:16:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Xu X-Patchwork-Id: 13855545 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A33A2D74941 for ; Tue, 29 Oct 2024 21:17:16 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t5tZq-0002Oz-Cr; Tue, 29 Oct 2024 17:16:34 -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 1t5tZh-0002MK-NE for qemu-devel@nongnu.org; Tue, 29 Oct 2024 17:16:26 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t5tZf-0007ci-I6 for qemu-devel@nongnu.org; Tue, 29 Oct 2024 17:16:25 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730236582; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=T+pcnIucz22VKrCtERmTjcQct9vNMkt9sbGgjhKvJik=; b=HTYb6cVbK9BHYLsfj5FS7M4UvXV5G7Qlnf80tRu+91lLRLKnNKZi19gW8+pFByZi5rrA3w ZxfWOR7Enkz7PPxkXN0wJfP4aUW3M36O4fgMEvylpCeRbBKtDlWMjn2/9uJW8NPS4OKjGe yuY+14UYYlpGomfeG2wEzHx9fMm6SnA= Received: from mail-yb1-f200.google.com (mail-yb1-f200.google.com [209.85.219.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-161-4Yp79fQPO0qDDGreN1-6Ng-1; Tue, 29 Oct 2024 17:16:18 -0400 X-MC-Unique: 4Yp79fQPO0qDDGreN1-6Ng-1 Received: by mail-yb1-f200.google.com with SMTP id 3f1490d57ef6-e30c637c956so1591825276.2 for ; Tue, 29 Oct 2024 14:16:18 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730236577; x=1730841377; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=T+pcnIucz22VKrCtERmTjcQct9vNMkt9sbGgjhKvJik=; b=Q+XbowoG7Iw61uFBOQy09PbcRpvGLPoJtOyTzw1radtSirjSz1RdZniWN0CHtoYWQC jvX9zZc+4vRSYfjb7ZGOmQclILmjjs5dzly/nDs3sP+SeKuPLGTUKfkhkP93+t0bCboC YTI7QUF0Q4CeAcj7m8OCc97erPjoQte6PwOp6zNQFXo5z0q4vHd+P0C6E3R+g2NH7TiV MQRQYtx5CBAbO+C89QmgbE+HyP/71Oe/SZQcqXI8O5qUghozqdjl8ypEI/t+euuqgBG3 eHgh66+NOhW+fOQhTMemSkluy5l50BqdnDJejDWjHCtcfHENibEtQvnKH/ds8EHeHkgQ HFrQ== X-Gm-Message-State: AOJu0YwzKddKSUTs5c/W/FqKeXCXaYQ9jcSCpi2nHUlDlLLCLDRwCX4h XCLkQczLqewJAgykzqr0mft0/8wtZF70lQK/wpIi9bmehpz6r3k9kSKa2aCpfXZmnMSoZmauPK6 pYmsvrC5GgmLcBL95GW5DOjwuCVLI5IHG91rWo1LLgPYj5YK2Gr7w6cDFMOcoRIxmrtwxS6updF xEmhyCS7A5uSWn4ykbq0XahmVcHea3fECJ7Q== X-Received: by 2002:a05:6902:188c:b0:e29:48ae:562 with SMTP id 3f1490d57ef6-e3087a5b026mr14497847276.21.1730236576565; Tue, 29 Oct 2024 14:16:16 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGUFZ1rqENjX+R5z32YsreDF/F/tZw+JxeIpCIjETWIeEC+0TK2+FnyW/8tRZTXqkVxXCD7NQ== X-Received: by 2002:a05:6902:188c:b0:e29:48ae:562 with SMTP id 3f1490d57ef6-e3087a5b026mr14497742276.21.1730236574862; Tue, 29 Oct 2024 14:16:14 -0700 (PDT) Received: from x1n.redhat.com (pool-99-254-114-190.cpe.net.cable.rogers.com. [99.254.114.190]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-46132292c97sm48481691cf.49.2024.10.29.14.16.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Oct 2024 14:16:14 -0700 (PDT) From: Peter Xu To: qemu-devel@nongnu.org Cc: Markus Armbruster , Peter Maydell , Eduardo Habkost , Paolo Bonzini , Mark Cave-Ayland , Igor Mammedov , "Michael S . Tsirkin" , Alex Williamson , "Dr . David Alan Gilbert" , peterx@redhat.com, =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , =?utf-8?q?Phi?= =?utf-8?q?lippe_Mathieu-Daud=C3=A9?= , =?utf-8?q?C=C3=A9?= =?utf-8?q?dric_Le_Goater?= , Fabiano Rosas , Juraj Marcin Subject: [PATCH RFC v2 2/7] qom: TYPE_SINGLETON interface Date: Tue, 29 Oct 2024 17:16:02 -0400 Message-ID: <20241029211607.2114845-3-peterx@redhat.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20241029211607.2114845-1-peterx@redhat.com> References: <20241029211607.2114845-1-peterx@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=peterx@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -23 X-Spam_score: -2.4 X-Spam_bar: -- X-Spam_report: (-2.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.302, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This patch introduces a new QOM interface called SINGLETON. The singleton interface declares an object class which can only create one instance globally. Backgrounds / Use Cases ======================= There can be some existing classes that can start to benefit from it. One example is vIOMMU implementations. QEMU emulated vIOMMUs are normally implemented on top of a generic device, however it's special enough to normally only allow one instance of it for the whole system, attached to the root complex. These vIOMMU classes can be singletons in this case, so that QEMU can fail or detect yet another attempt of creating such devices for more than once, which can be fatal errors to a system. We used to have some special code guarding it from happening. In x86, pc_machine_device_pre_plug_cb() has code to detect when vIOMMU is created more than once, for instance. With singleton class, logically we could consider dropping the special code, but start to rely on QOM to make sure there's only one vIOMMU for the whole system emulation. There is a similar demand raising recently (even if the problem existed over years) in migration. Firstly, the migration object can currently be created randomly, even though not wanted, e.g. during qom-list-properties QMP commands. Ideally, there can be cases where we want to have an object walking over the properties, we could use the existing migration object instead of dynamically create one. Meanwhile, migration has a long standing issue on current_migration pointer, where it can point to freed data after the migration object is finalized. It is debatable that the pointer can be cleared after the main thread (1) join() the migration thread first, then (2) release the last refcount for the migration object and clear the pointer. However there's still major challenges [1]. With singleton, we could have a slightly but hopefully working workaround to clear the pointer during finalize(). Design ====== The idea behind is pretty simple: any object that can only be created once can now declare the TYPE_SINGLETON interface. Then, QOM facilities will make sure it won't be created more than once for the whole QEMU lifecycle. Whenever possible (e.g., on object_new_allowed() checks), pretty error message will be generated to report an error. QOM also guards at the core of object_new() so that any further violation of trying to create a singleton more than once will crash QEMU as a programming error. For example, qom-list-properties, device-list-properties, etc., will be smart enough to not try to create temporary singleton objects if the class is a singleton class and if there's existing instance created. Such usages should be rare, and this patch introduced object_new_or_fetch() just for it, which either create a new temp object when available, or fetch the instance if we found an existing singleton instance. There're only two such use cases. Meanwhile, we also guard device-add or similar paths using the singleton check in object_new_allowed(), so that it'll fail properly if a singleton class instantiate more than one object. Glib Singleton implementation ============================= One note here to mention the Glib implementation of singletons [1]. QEMU chose not to follow Glib's implementation because Glib's version is not thread safe on the constructor, so that two concurrent g_object_new() on a single can race. It's not ideal to QEMU, as QEMU has to not only support the event-driven context which is normally lock-free, but also the case where threads are heavily used. It could be QEMU's desire to properly support multi-threading by default on such new interface. The "bad" side effect of that is, QEMU's object_new() on singletons can assert failures if the singleton existed, but that's also part of the design so as to forbid such from happening, taking which as a programming error. Meanwhile since we have pretty ways to fail elsewhere on qdev creations, it should already guard us in a clean way, from anywhere that the user could try to create the singleton more than once. The current QEMU impl also guarantees object_new() always return a newly allocated object as long as properly returned, rather than silently return an existing object as what Glib's impl would do. I see it a benefit, so as to avoid unknown caller manipulate a global object, wrongly assuming it was temporarily created. [1] https://lore.kernel.org/qemu-devel/20190228122822.GD4970@work-vm/ [2] https://lore.kernel.org/r/ZxtqGQbd4Hq4APtm@redhat.com Signed-off-by: Peter Xu --- qapi/qdev.json | 2 +- qapi/qom.json | 2 +- include/qom/object.h | 12 ++++++++ include/qom/object_interfaces.h | 51 +++++++++++++++++++++++++++++++++ qom/object.c | 33 +++++++++++++++++++++ qom/object_interfaces.c | 30 +++++++++++++++++++ qom/qom-qmp-cmds.c | 4 +-- 7 files changed, 130 insertions(+), 4 deletions(-) diff --git a/qapi/qdev.json b/qapi/qdev.json index 53d147c7b4..f9ca1aa1df 100644 --- a/qapi/qdev.json +++ b/qapi/qdev.json @@ -22,7 +22,7 @@ # # .. note:: Objects can create properties at runtime, for example to # describe links between different devices and/or objects. These -# properties are not included in the output of this command. +# properties may or may not be included in the output of this command. # # Since: 1.2 ## diff --git a/qapi/qom.json b/qapi/qom.json index 321ccd708a..00345b0715 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -197,7 +197,7 @@ # # .. note:: Objects can create properties at runtime, for example to # describe links between different devices and/or objects. These -# properties are not included in the output of this command. +# properties may or may not be included in the output of this command. # # Returns: a list of ObjectPropertyInfo describing object properties # diff --git a/include/qom/object.h b/include/qom/object.h index 32f1af2986..e0d4173dfd 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -640,6 +640,18 @@ Object *object_new(const char *typename); */ bool object_new_allowed(ObjectClass *klass, Error **errp); +/** + * object_new_or_fetch: + * @klass: The class to instantiate, or fetch instance from. + * + * This function will either initialize a new object using heap allocated + * memory, or fetch one object if the object is a singleton and the only + * instance has already been created. + * + * Returns: The fetched object (either newly initiated or existing). + */ +Object *object_new_or_fetch(ObjectClass *klass); + /** * object_new_with_props: * @typename: The name of the type of the object to instantiate. diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h index 02b11a7ef0..48b77cf6c4 100644 --- a/include/qom/object_interfaces.h +++ b/include/qom/object_interfaces.h @@ -177,4 +177,55 @@ bool user_creatable_del(const char *id, Error **errp); */ void user_creatable_cleanup(void); +#define TYPE_SINGLETON "singleton" + +typedef struct SingletonClass SingletonClass; +DECLARE_CLASS_CHECKERS(SingletonClass, SINGLETON, TYPE_SINGLETON) + +/** + * SingletonClass: + * + * @parent_class: the base class + * @get_instance: fetch the singleton instance and elevate its refcount if + * it is created, NULL otherwise. + * + * Singleton class describes the type of object classes that can only + * provide one instance for the whole lifecycle of QEMU. It will fail the + * operation if one attemps to create more than one instance. + * + * One can fetch the single object using class's get_instance() callback if + * it was created before. This can be useful for operations like QMP + * qom-list-properties, where dynamically creating an object might not be + * feasible. + * + * Classes with TYPE_SINGLETON must provide get_instance() implementation, + * make sure the refcount is elevanted before returning, so that the + * instance (if existed) can never be freed concurrently once returned. + */ +struct SingletonClass { + /* */ + InterfaceClass parent_class; + /* */ + Object *(*get_instance)(void); +}; + +/** + * object_class_is_singleton: + * + * @class: the class to detect singleton + * + * Returns: true if it's a singleton class, false otherwise. + */ +bool object_class_is_singleton(ObjectClass *class); + +/** + * singleton_get_instance: + * + * @class: the class to fetch singleton instance + * + * Returns: the Object with elevated refcount if the class is a singleton + * class and the singleton object is created, NULL otherwise. + */ +Object *singleton_get_instance(ObjectClass *class); + #endif diff --git a/qom/object.c b/qom/object.c index 4f3739fd85..c7c6f3e397 100644 --- a/qom/object.c +++ b/qom/object.c @@ -553,6 +553,9 @@ static void object_initialize_with_type(Object *obj, size_t size, TypeImpl *type g_assert(type->abstract == false); g_assert(size >= type->instance_size); + /* Singleton class can only create one object */ + g_assert(!singleton_get_instance(type->class)); + memset(obj, 0, type->instance_size); obj->class = type->class; object_ref(obj); @@ -808,9 +811,39 @@ bool object_new_allowed(ObjectClass *klass, Error **errp) return false; } + if (object_class_is_singleton(klass)) { + Object *obj = singleton_get_instance(klass); + + if (obj) { + object_unref(obj); + /* + * TODO: Enhance the error message. E.g., the singleton class + * can provide a per-class error message in SingletonClass. + */ + error_setg(errp, "Object type '%s' conflicts with " + "an existing singleton instance", + klass->type->name); + return false; + } + } + return true; } +Object *object_new_or_fetch(ObjectClass *klass) +{ + Object *obj; + + if (object_class_is_singleton(klass)) { + obj = singleton_get_instance(klass); + if (obj) { + return obj; + } + } + + return object_new_with_class(klass); +} + Object *object_new_with_props(const char *typename, Object *parent, const char *id, diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c index d68faf2234..548e1f344f 100644 --- a/qom/object_interfaces.c +++ b/qom/object_interfaces.c @@ -353,6 +353,29 @@ void user_creatable_cleanup(void) object_unparent(object_get_objects_root()); } +bool object_class_is_singleton(ObjectClass *class) +{ + return !!object_class_dynamic_cast(class, TYPE_SINGLETON); +} + +Object *singleton_get_instance(ObjectClass *class) +{ + SingletonClass *singleton = + (SingletonClass *)object_class_dynamic_cast(class, TYPE_SINGLETON); + + if (!singleton) { + return NULL; + } + + /* + * NOTE: it's only safe to do object_ref() in the ->get_instance() + * callback, because logically speaking any object* returned here might + * get free()ed concurrently if without the elevated refcount. The + * hooks need to provide proper locking if a race condition is possible. + */ + return singleton->get_instance(); +} + static void register_types(void) { static const TypeInfo uc_interface_info = { @@ -361,7 +384,14 @@ static void register_types(void) .class_size = sizeof(UserCreatableClass), }; + static const TypeInfo singleton_interface_info = { + .name = TYPE_SINGLETON, + .parent = TYPE_INTERFACE, + .class_size = sizeof(SingletonClass), + }; + type_register_static(&uc_interface_info); + type_register_static(&singleton_interface_info); } type_init(register_types) diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c index e91a235347..3aa51c4c95 100644 --- a/qom/qom-qmp-cmds.c +++ b/qom/qom-qmp-cmds.c @@ -141,7 +141,7 @@ ObjectPropertyInfoList *qmp_device_list_properties(const char *typename, return NULL; } - obj = object_new(typename); + obj = object_new_or_fetch(klass); object_property_iter_init(&iter, obj); while ((prop = object_property_iter_next(&iter))) { @@ -202,7 +202,7 @@ ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename, if (object_class_is_abstract(klass)) { object_class_property_iter_init(&iter, klass); } else { - obj = object_new(typename); + obj = object_new_or_fetch(klass); object_property_iter_init(&iter, obj); } while ((prop = object_property_iter_next(&iter))) { From patchwork Tue Oct 29 21:16:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Xu X-Patchwork-Id: 13855544 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A1772D74943 for ; Tue, 29 Oct 2024 21:17:13 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t5tZm-0002N4-Ua; Tue, 29 Oct 2024 17:16:30 -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 1t5tZe-0002Lu-VE for qemu-devel@nongnu.org; Tue, 29 Oct 2024 17:16:23 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t5tZd-0007cc-EI for qemu-devel@nongnu.org; Tue, 29 Oct 2024 17:16:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730236580; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JQg2SOV+gtaMkPFPn63KBHnXYSyfJvjfUv1rUTqt8SY=; b=ZOemug29mD5g5GBl6VbPIERzK1xBPwjFuC5A61/M+b3arMa3p3oqkXzNUXbhdqVhsh/AJk kUsuw8xhu4vlLPaIKxBs3tYhKBujMwYXq5ctGOfNXlnyP9Eat8Qzyu0ySgChMl0ndrennG z+OuIQvJTcKwJ1SQt9edSLdAPieDZ5I= Received: from mail-yw1-f200.google.com (mail-yw1-f200.google.com [209.85.128.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-443-E9RBDmIBO1u0I1Jjfxa4zg-1; Tue, 29 Oct 2024 17:16:19 -0400 X-MC-Unique: E9RBDmIBO1u0I1Jjfxa4zg-1 Received: by mail-yw1-f200.google.com with SMTP id 00721157ae682-6e36cfed818so96380897b3.3 for ; Tue, 29 Oct 2024 14:16:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730236577; x=1730841377; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JQg2SOV+gtaMkPFPn63KBHnXYSyfJvjfUv1rUTqt8SY=; b=PEki2zKATaVkh4JVI9WkGseN1UGSpSPAyvNHKtb34YDh3afkkgW7urF+iQkJN1cI0B N6ow4JgzoQg3AFiPvqEDAL4pC8NCkbbPPVHOK/0th9Ut73zSioUZJ0bXy1g7ediK+5YI IInrSQo6sNp1gjwUCijjz5COLdzZZmif2NcwmIS3TqUA8YJU+xKK8C2Fja2XbMjoxWtp Xy+r7TqdKS94T3cXiZEBM3ru/JGhzUg+WNpH5Wex1Lzy7HnoCuoCGKqCohfFiAJ1JX1X b00L14visg5TKiFBQsDtcCif1QjlwKLSgo1sQOPocvrqbL5m5thEvLl4t3TiVQ400tuV 9i6w== X-Gm-Message-State: AOJu0YwL6m8szPdNuhyXOTnbM1ruEvo4EqVkbhsG2CAfju0p1nag0jqk pe7X3cRGYo5SkzWg34Zjo9SXX8OSHlHHO8Hlp380mgpYt2WVy9XDLKVm3gFvN2n0Sf/71WWL+i/ 4k25w46cYsfCWcqHGyALJX8GfZo9ACw5kG+/WGEJCnpdd8kbon/t+/Qow2iV/BLm853logHJGdY xpDKZeIwE0E6timx+JrRsVfl7fRgsxNOa0YQ== X-Received: by 2002:a05:690c:6409:b0:6d4:4a0c:fcf0 with SMTP id 00721157ae682-6e9d8a67b92mr140606747b3.20.1730236577557; Tue, 29 Oct 2024 14:16:17 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFzwTbs7FQjp0FYvD+rG65rEiZuh+usOEHFF1wFPh2XZe/AXARhV0v4XxIS9qqQL079XSuevA== X-Received: by 2002:a05:690c:6409:b0:6d4:4a0c:fcf0 with SMTP id 00721157ae682-6e9d8a67b92mr140606357b3.20.1730236577122; Tue, 29 Oct 2024 14:16:17 -0700 (PDT) Received: from x1n.redhat.com (pool-99-254-114-190.cpe.net.cable.rogers.com. [99.254.114.190]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-46132292c97sm48481691cf.49.2024.10.29.14.16.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Oct 2024 14:16:16 -0700 (PDT) From: Peter Xu To: qemu-devel@nongnu.org Cc: Markus Armbruster , Peter Maydell , Eduardo Habkost , Paolo Bonzini , Mark Cave-Ayland , Igor Mammedov , "Michael S . Tsirkin" , Alex Williamson , "Dr . David Alan Gilbert" , peterx@redhat.com, =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , =?utf-8?q?Phi?= =?utf-8?q?lippe_Mathieu-Daud=C3=A9?= , =?utf-8?q?C=C3=A9?= =?utf-8?q?dric_Le_Goater?= , Fabiano Rosas , Juraj Marcin Subject: [PATCH RFC v2 3/7] qdev: Make device_set_realized() be fully prepared with !machine Date: Tue, 29 Oct 2024 17:16:03 -0400 Message-ID: <20241029211607.2114845-4-peterx@redhat.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20241029211607.2114845-1-peterx@redhat.com> References: <20241029211607.2114845-1-peterx@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=peterx@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -23 X-Spam_score: -2.4 X-Spam_bar: -- X-Spam_report: (-2.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.302, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org We're going to enable qdev_get_machine() to work even before machine is created. Make device_set_realized() be prepared with it. Currently, a device can be realized even before machine is created, but only in one of QEMU's qtest, test-global-qdev-props.c. Right now, the test_static_prop_subprocess() test (which creates one simple object without machine created) will internally make "/machine" to be a container. Now explicitly support that case when there's no real "/machine" object around, then unattached devices will be put under root ("/") rather than "/machine". Mostly only for this test case, or for any future test cases only. Note that this shouldn't affect anything else that relies on a real machine being there but only unit tests like mentioned, because if "/machine" is created as a container as of now, it'll fail QEMU very soon later on qemu_create_machine() trying to create the real machine, seeing that there's a conflict. Signed-off-by: Peter Xu --- hw/core/qdev.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index db36f54d91..5c83f48b33 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -490,9 +490,17 @@ static void device_set_realized(Object *obj, bool value, Error **errp) if (!obj->parent) { gchar *name = g_strdup_printf("device[%d]", unattached_count++); + Object *root = qdev_get_machine(); - object_property_add_child(container_get(qdev_get_machine(), - "/unattached"), + /* + * We could have qdev test cases trying to realize() a device + * without machine created. In that case we use the root. + */ + if (!root) { + root = object_get_root(); + } + + object_property_add_child(container_get(root, "/unattached"), name, obj); unattached_parent = true; g_free(name); From patchwork Tue Oct 29 21:16:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Xu X-Patchwork-Id: 13855554 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EE935D74941 for ; Tue, 29 Oct 2024 21:18:28 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t5tZs-0002Pe-8O; Tue, 29 Oct 2024 17:16:36 -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 1t5tZm-0002NO-V5 for qemu-devel@nongnu.org; Tue, 29 Oct 2024 17:16:30 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t5tZk-0007d2-W8 for qemu-devel@nongnu.org; Tue, 29 Oct 2024 17:16:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730236585; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bGscfKpqzkKw2z0pwGkeUsLF9GAsvAy96M3qbQI4qYM=; b=d7rEWb6bOFezlwq+BvTlbOfXEkmP32oADCUFG3s8pXbbri5UGZntsu6VlJYnKsrWqHbaRb QOR63i0vHg3lyNiZm93REEWutePS6kCXDSGotyLL3Dv5Ww5wui+705zRr9Z3gW8T0SmugA In083iwQy2rYHZAi/NYICyatrd3o8Z4= Received: from mail-oo1-f69.google.com (mail-oo1-f69.google.com [209.85.161.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-505-OEu8E5eaOgqhDPrg6jiWow-1; Tue, 29 Oct 2024 17:16:21 -0400 X-MC-Unique: OEu8E5eaOgqhDPrg6jiWow-1 Received: by mail-oo1-f69.google.com with SMTP id 006d021491bc7-5eb9c053637so5280580eaf.1 for ; Tue, 29 Oct 2024 14:16:21 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730236580; x=1730841380; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=bGscfKpqzkKw2z0pwGkeUsLF9GAsvAy96M3qbQI4qYM=; b=E7ZqlpqaxZIlReicc+jJuAAkt9Z+YyWP08BnGxwVYosnLVAO/Qhq8qGNDM4HqJgKKa wwy+Gism2a22kyzyWEdSUh8bi05e9nYrDjzylY8EGxiYqIXTVVu79bdZQfcBEx0YxpIT VU1TxuJX29WTOM+WjvgvBUIoX7+Y0UMS7gS3raVaRLVeVE2hf1xJyARajjTrDwNWFk0i OcAFPtM6SadxBflZIQG5aio6fI2acohTksyLevehcBaIwX54qzDz5jRFX+ybSnMIX1ZW AcSFFHg6GpvVay1mH4Z1C7yw2DKJzafZflVJna4W8NdcdvtOcAhf/S62ZRSWnC+3hGB/ g8iA== X-Gm-Message-State: AOJu0YwknJGmdwHQqtXwfirZSb8J9MjYuK8DnVuV19D1oiKU2bSK4Ggi +/9xbjc/adJ6Er9/FjwcgaoUbgnRsu1cJqAfk/WcnA80EDVhr5kV5BCD6npmHhVDNjKPXJl3sVa 7k9afZly5QoCqpPwnSHDExI6Iu6i9lVPVGdjUuhh+NiZy9HXlhu7xBivKDSUIRkEBhoYsy9dOXn x8EEcCICQhCqXOrHu7nGeShs58R0nIRjrIZQ== X-Received: by 2002:a05:6359:4c8b:b0:1c3:7070:4442 with SMTP id e5c5f4694b2df-1c3f9e87977mr570092655d.12.1730236580329; Tue, 29 Oct 2024 14:16:20 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHyUSzfCQCKaRSuBIBI9St1GTAfYmIx/z/6MTNOLQR0Rt7LLJzXWoUKTTh2rB4myepRulOmUA== X-Received: by 2002:a05:6359:4c8b:b0:1c3:7070:4442 with SMTP id e5c5f4694b2df-1c3f9e87977mr570088855d.12.1730236579911; Tue, 29 Oct 2024 14:16:19 -0700 (PDT) Received: from x1n.redhat.com (pool-99-254-114-190.cpe.net.cable.rogers.com. [99.254.114.190]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-46132292c97sm48481691cf.49.2024.10.29.14.16.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Oct 2024 14:16:18 -0700 (PDT) From: Peter Xu To: qemu-devel@nongnu.org Cc: Markus Armbruster , Peter Maydell , Eduardo Habkost , Paolo Bonzini , Mark Cave-Ayland , Igor Mammedov , "Michael S . Tsirkin" , Alex Williamson , "Dr . David Alan Gilbert" , peterx@redhat.com, =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , =?utf-8?q?Phi?= =?utf-8?q?lippe_Mathieu-Daud=C3=A9?= , =?utf-8?q?C=C3=A9?= =?utf-8?q?dric_Le_Goater?= , Fabiano Rosas , Juraj Marcin Subject: [PATCH RFC v2 4/7] qdev: Make qdev_get_machine() safe before machine creates Date: Tue, 29 Oct 2024 17:16:04 -0400 Message-ID: <20241029211607.2114845-5-peterx@redhat.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20241029211607.2114845-1-peterx@redhat.com> References: <20241029211607.2114845-1-peterx@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=peterx@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -23 X-Spam_score: -2.4 X-Spam_bar: -- X-Spam_report: (-2.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.302, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org qdev_get_machine() is the helper that QEMU heavily uses in most places to fetch the current machine object after it's created. It can only be called after the machine is created as of now, otherwise a container can be wrongly created at path "/machine", and that could crash QEMU later. It's not an issue for now, because all code paths will currently make sure this helper won't be called too early, e.g., before the machine object is properly created and attached under the object root path. This patch makes this behavior more predictable, by never trying to wrongly create a container if the object is missing. This enables the helper to be used even before the machine is created, as long as the caller can properly handle a NULL return (which says, "machine is not yet created"). No functional change intended as of now, but will start to make use of it in later patches, where qdev_get_machine() can start to be use before machine creations. Signed-off-by: Peter Xu --- hw/core/qdev.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 5c83f48b33..c867aed28a 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -840,7 +840,13 @@ Object *qdev_get_machine(void) static Object *dev; if (dev == NULL) { - dev = container_get(object_get_root(), "/machine"); + /* + * NOTE: dev can keep being NULL if machine is not yet created! + * In which case the function will properly return NULL. + * + * Whenever machine object is created and found once, we cache it. + */ + dev = object_resolve_path_component(object_get_root(), "machine"); } return dev; From patchwork Tue Oct 29 21:16:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Xu X-Patchwork-Id: 13855553 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DE8EFD74940 for ; Tue, 29 Oct 2024 21:18:26 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t5tZs-0002PT-7Z; Tue, 29 Oct 2024 17:16:36 -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 1t5tZl-0002Mt-21 for qemu-devel@nongnu.org; Tue, 29 Oct 2024 17:16:30 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t5tZi-0007cv-O7 for qemu-devel@nongnu.org; Tue, 29 Oct 2024 17:16:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730236585; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2WucjuAZvLcYLETBN7D9EbmGFAmMsBIxe7HZXwoj7cY=; b=OXZLzWujElQxy7wsw/6MiuvgxA4ind6v7M3y6L0krmhADK/V2N62KYsYUfA1baPF9/sFyY Qw4ZkdV/hSQMX+NCGI6JDC33Y2lHmORoj7apAlQun9m0PWfEw7B5mXN2RHSbOLP0B2sz5A dEFHDylnHDaCmrlPUgYIOLseUMTM1Nc= Received: from mail-oo1-f70.google.com (mail-oo1-f70.google.com [209.85.161.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-104-3Avnn1PCOE28yGNyOuRYug-1; Tue, 29 Oct 2024 17:16:23 -0400 X-MC-Unique: 3Avnn1PCOE28yGNyOuRYug-1 Received: by mail-oo1-f70.google.com with SMTP id 006d021491bc7-5eb9c053637so5280606eaf.1 for ; Tue, 29 Oct 2024 14:16:23 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730236582; x=1730841382; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2WucjuAZvLcYLETBN7D9EbmGFAmMsBIxe7HZXwoj7cY=; b=LF/uUZgf1Hlc3avxFdKqqV1SS3Mc2X7uYpzhaJYqPE89PmyOxzp46ZimwFRyp/WQpS 3UOKxgwXr+pCP2SMX82LIkNyIiog1iNTU6D4CZKQfNZulkUwEBNyxvZ5QZ8ZIpYgTK1u WCGmDqeLs667+ySDN1h3hEmyBsFqHSaNVAYr3jlGQWBRZ/HFu4XpQtw3gvaUdeZPl7HB sUzpixX5ONfmHkHOO1cxyhtkW5Bku4/qBfVMGVHckbN0w0Rr6+XgmcUOiB/VskD6oL0/ LLw0cyBZjOrztFpA/uuSbhW1XUIcKEH4buv3sI1PZp4w6R+XGvQWeHpUHxFuUkmuwaY4 7yTw== X-Gm-Message-State: AOJu0YzOl6jD7PfXt5g9LflVwPa08igo8G7jYWOqvZfEOQGNSqjv12// aAjhjohTVbREsEAuPRquJx8b6MSFHXFjHNeX3zklsmALeV8R12chUMi09e2eMoS20HQ9X+YCw9T Nl3Bc1sDfPGJNbM8igoznYTCEcLND6FCSXRvxubujr/9vym1hGrxpk6NBi68jBbTE9Ic2Lt6C+k xIArXGIYgwZaCens5kJvSXKglTNJcZlDaLuA== X-Received: by 2002:a05:6359:4105:b0:1b1:acd5:dd98 with SMTP id e5c5f4694b2df-1c3f9dfd566mr638240755d.7.1730236582611; Tue, 29 Oct 2024 14:16:22 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEgOmcFAnUN1KgLuP3yZyH/g++S30HGw1Ujy8xWARa1hYx5rmwLhGRQJDQtqAYoYiVkNtjEVA== X-Received: by 2002:a05:6359:4105:b0:1b1:acd5:dd98 with SMTP id e5c5f4694b2df-1c3f9dfd566mr638236755d.7.1730236582196; Tue, 29 Oct 2024 14:16:22 -0700 (PDT) Received: from x1n.redhat.com (pool-99-254-114-190.cpe.net.cable.rogers.com. [99.254.114.190]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-46132292c97sm48481691cf.49.2024.10.29.14.16.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Oct 2024 14:16:21 -0700 (PDT) From: Peter Xu To: qemu-devel@nongnu.org Cc: Markus Armbruster , Peter Maydell , Eduardo Habkost , Paolo Bonzini , Mark Cave-Ayland , Igor Mammedov , "Michael S . Tsirkin" , Alex Williamson , "Dr . David Alan Gilbert" , peterx@redhat.com, =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , =?utf-8?q?Phi?= =?utf-8?q?lippe_Mathieu-Daud=C3=A9?= , =?utf-8?q?C=C3=A9?= =?utf-8?q?dric_Le_Goater?= , Fabiano Rosas , Juraj Marcin Subject: [PATCH RFC v2 5/7] x86/iommu: Make x86-iommu a singleton object Date: Tue, 29 Oct 2024 17:16:05 -0400 Message-ID: <20241029211607.2114845-6-peterx@redhat.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20241029211607.2114845-1-peterx@redhat.com> References: <20241029211607.2114845-1-peterx@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=peterx@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -23 X-Spam_score: -2.4 X-Spam_bar: -- X-Spam_report: (-2.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.302, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org X86 IOMMUs cannot be created more than one on a system yet. Make it a singleton so it guards the system from accidentally create yet another IOMMU object when one already presents. Now if someone tries to create more than one, e.g., via: ./qemu -M q35 -device intel-iommu -device intel-iommu The error will change from: qemu-system-x86_64: -device intel-iommu: QEMU does not support multiple vIOMMUs for x86 yet. To: qemu-system-x86_64: -device intel-iommu: Class 'intel-iommu' only supports one instance Unfortunately, yet we can't remove the singleton check in the machine hook (pc_machine_device_pre_plug_cb), because there can also be virtio-iommu involved, which doesn't share a common parent class yet. But with this, it should be closer to reach that goal to check singleton by QOM one day. Note: after this patch, x86_iommu_get_default() might be called very early, even before machine is created (e.g., cmdline "-device intel-iommu,help"). In this case we need to be prepared with such, and that also means the default iommu is not yet around. Signed-off-by: Peter Xu --- hw/i386/x86-iommu.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c index 60af896225..ec45b80306 100644 --- a/hw/i386/x86-iommu.c +++ b/hw/i386/x86-iommu.c @@ -26,6 +26,7 @@ #include "qemu/error-report.h" #include "trace.h" #include "sysemu/kvm.h" +#include "qom/object_interfaces.h" void x86_iommu_iec_register_notifier(X86IOMMUState *iommu, iec_notify_fn fn, void *data) @@ -79,9 +80,15 @@ void x86_iommu_irq_to_msi_message(X86IOMMUIrq *irq, MSIMessage *msg_out) X86IOMMUState *x86_iommu_get_default(void) { - MachineState *ms = MACHINE(qdev_get_machine()); - PCMachineState *pcms = - PC_MACHINE(object_dynamic_cast(OBJECT(ms), TYPE_PC_MACHINE)); + Object *machine = qdev_get_machine(); + PCMachineState *pcms; + + /* If machine has not been created, so is the vIOMMU */ + if (!machine) { + return NULL; + } + + pcms = PC_MACHINE(object_dynamic_cast(machine, TYPE_PC_MACHINE)); if (pcms && object_dynamic_cast(OBJECT(pcms->iommu), TYPE_X86_IOMMU_DEVICE)) { @@ -133,10 +140,19 @@ static Property x86_iommu_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static Object *x86_iommu_get_instance(void) +{ + return object_ref(OBJECT(x86_iommu_get_default())); +} + static void x86_iommu_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + SingletonClass *singleton = SINGLETON_CLASS(klass); + dc->realize = x86_iommu_realize; + singleton->get_instance = x86_iommu_get_instance; + device_class_set_props(dc, x86_iommu_properties); } @@ -152,6 +168,10 @@ static const TypeInfo x86_iommu_info = { .class_init = x86_iommu_class_init, .class_size = sizeof(X86IOMMUClass), .abstract = true, + .interfaces = (InterfaceInfo[]) { + { TYPE_SINGLETON }, + { } + } }; static void x86_iommu_register_types(void) From patchwork Tue Oct 29 21:16:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Xu X-Patchwork-Id: 13855552 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E835BD74941 for ; Tue, 29 Oct 2024 21:18:06 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t5ta0-0002RZ-Ro; Tue, 29 Oct 2024 17:16:44 -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 1t5tZm-0002NP-UT for qemu-devel@nongnu.org; Tue, 29 Oct 2024 17:16:30 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t5tZk-0007dC-R8 for qemu-devel@nongnu.org; Tue, 29 Oct 2024 17:16:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730236587; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=S1CHVDDrF1k42GawPCowe3EhPn3LYquuM+4EuRYWzKA=; b=AFPt7hWogpKGOOi0YJFkIS17CkMWgZshE2L424Dakde0xyaqyyxaUMfsE+n+2XPBvNgs/Q UKh9PDhKE8DswPpA//RVuDBYhoLspQWziY0+LuRc+IQgYn9/yvPYWrgySn/BivEjluOIlt WuISAcb9AkgMDbZO/ElO9so5M8O7Xqk= Received: from mail-yw1-f200.google.com (mail-yw1-f200.google.com [209.85.128.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-125-WVpFe935PlWoiG7csGjArg-1; Tue, 29 Oct 2024 17:16:26 -0400 X-MC-Unique: WVpFe935PlWoiG7csGjArg-1 Received: by mail-yw1-f200.google.com with SMTP id 00721157ae682-6e7f633af02so84445707b3.3 for ; Tue, 29 Oct 2024 14:16:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730236585; x=1730841385; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=S1CHVDDrF1k42GawPCowe3EhPn3LYquuM+4EuRYWzKA=; b=PKp66erBZh3lONwZnh9NKBkhztfQL08WKieGZfvZdV9y91IsAztCBItPbXOMJmKGSC Pd6sDu/ZP13g9cx08MqSYEiwrUkEutsjLUSW8UbafzYgYon1/A2NXIqH0tI08XSM9MMI ltOuj75U0pOKJxNMvp5QozduTGK4uj0+1VGp3d7vJUAyOcyFhn4/VqNqQW/aPREqPHVo NiOPsNNdO8D8ma9VLoIgdOBj70cDWAAU33NQ8TtbKV9/nTgoYof/An2/Qvq6bVJ1POqz VlrzPKuHymrbf6d2ZlXn0qXZ4GF6OGFv0xT2S38ibOs5VMUSFdgaM12ru4gfgp1gXxmM XUIA== X-Gm-Message-State: AOJu0YwUpSoQY1UDC+cbvwP7+4oPlj063lAt03v67Ygi9jWmuuQ1oEJg eWX+s3ejhGIOU6vVlA2gy6gDnlGtpa/j5jhwf6ioS2mFyH0KLDlZbqxZ17Tof8LmbtI6LcpfAvG 0P3eJTMwtvwtwtbuI3khu79gThNEvGF0CxSEjlycyoP5EOixeRYIQZuiPc4qHlYAjbReViDneIU GdC95gYtjPA5oIjRBtCmCV5HwROA2cXSq8Zw== X-Received: by 2002:a05:6902:2e0d:b0:e2b:c7b1:eab8 with SMTP id 3f1490d57ef6-e3087a5f2bbmr13742788276.21.1730236585013; Tue, 29 Oct 2024 14:16:25 -0700 (PDT) X-Google-Smtp-Source: AGHT+IG39Zo/f66f4fcqAxZX1cGZ5rwPvnu65EqXydG/X2GLh5J+HCuu3eFX2ObUm4PgdtLeet2FGQ== X-Received: by 2002:a05:6902:2e0d:b0:e2b:c7b1:eab8 with SMTP id 3f1490d57ef6-e3087a5f2bbmr13742753276.21.1730236584645; Tue, 29 Oct 2024 14:16:24 -0700 (PDT) Received: from x1n.redhat.com (pool-99-254-114-190.cpe.net.cable.rogers.com. [99.254.114.190]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-46132292c97sm48481691cf.49.2024.10.29.14.16.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Oct 2024 14:16:23 -0700 (PDT) From: Peter Xu To: qemu-devel@nongnu.org Cc: Markus Armbruster , Peter Maydell , Eduardo Habkost , Paolo Bonzini , Mark Cave-Ayland , Igor Mammedov , "Michael S . Tsirkin" , Alex Williamson , "Dr . David Alan Gilbert" , peterx@redhat.com, =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , =?utf-8?q?Phi?= =?utf-8?q?lippe_Mathieu-Daud=C3=A9?= , =?utf-8?q?C=C3=A9?= =?utf-8?q?dric_Le_Goater?= , Fabiano Rosas , Juraj Marcin Subject: [PATCH RFC v2 6/7] migration: Make migration object a singleton object Date: Tue, 29 Oct 2024 17:16:06 -0400 Message-ID: <20241029211607.2114845-7-peterx@redhat.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20241029211607.2114845-1-peterx@redhat.com> References: <20241029211607.2114845-1-peterx@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=peterx@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -23 X-Spam_score: -2.4 X-Spam_bar: -- X-Spam_report: (-2.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.302, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This makes the migration object a singleton unit. After this, we can do something slightly tricky later on with the guarantee that nobody will be able to create the object twice. Signed-off-by: Peter Xu --- migration/migration.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/migration/migration.c b/migration/migration.c index 021faee2f3..f4456f7142 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -45,6 +45,7 @@ #include "qapi/qmp/qerror.h" #include "qapi/qmp/qnull.h" #include "qemu/rcu.h" +#include "qom/object_interfaces.h" #include "postcopy-ram.h" #include "qemu/thread.h" #include "trace.h" @@ -3833,11 +3834,19 @@ fail: migrate_fd_cleanup(s); } +static Object *migration_get_instance(void) +{ + return object_ref(OBJECT(current_migration)); +} + static void migration_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + SingletonClass *singleton = SINGLETON_CLASS(klass); dc->user_creatable = false; + singleton->get_instance = migration_get_instance; + device_class_set_props(dc, migration_properties); } @@ -3910,6 +3919,10 @@ static const TypeInfo migration_type = { .instance_size = sizeof(MigrationState), .instance_init = migration_instance_init, .instance_finalize = migration_instance_finalize, + .interfaces = (InterfaceInfo[]) { + { TYPE_SINGLETON }, + { } + } }; static void register_migration_types(void) From patchwork Tue Oct 29 21:16:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Xu X-Patchwork-Id: 13855551 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A5081D74940 for ; Tue, 29 Oct 2024 21:17:39 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t5ta1-0002Sd-Q5; Tue, 29 Oct 2024 17:16:45 -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 1t5tZp-0002Op-Gn for qemu-devel@nongnu.org; Tue, 29 Oct 2024 17:16:34 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t5tZo-0007dW-1y for qemu-devel@nongnu.org; Tue, 29 Oct 2024 17:16:33 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730236590; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nIsEGl5Q0LBUrispxqDInl3LntXkgTEgoJOrk5dnpfs=; b=a4uj1VvyWX0p0tF6XMoJy6x646KoSjZYn7dbLESKq0y+zvQmIEROcEprLbFhApboO5uhcf LtuToIUKmnactBYIfeILHlz7C+NrV54M2lTZ3QTmRe3FtrPOW7KgHMBK7hfHKuC7peg2Zg dmKWp4jN/UoeN7s9WhTj3bhmHflo5vU= Received: from mail-qt1-f200.google.com (mail-qt1-f200.google.com [209.85.160.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-197-x5h4FlbQMoyxTPVvXRaSug-1; Tue, 29 Oct 2024 17:16:28 -0400 X-MC-Unique: x5h4FlbQMoyxTPVvXRaSug-1 Received: by mail-qt1-f200.google.com with SMTP id d75a77b69052e-460b07774a7so128433051cf.2 for ; Tue, 29 Oct 2024 14:16:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730236587; x=1730841387; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nIsEGl5Q0LBUrispxqDInl3LntXkgTEgoJOrk5dnpfs=; b=jEm17crmCDO1uVXKwbBcEzM4FNWoNBKC99vGSL4VIPcZUNDgkKTdxVxDvAec4lRk2U 1q9sSvBgU0xT3aI7xwqOg2sl/GB9Xb1nKBNPPVtHxh7YBkXfCxVxW9y/4mPGGhBGyTKA HinjyjemQ6a6QProwvBUlN645oYe21cxYNoleNBEsXm4REfW1RDsdpjZ5ME9MIjeuqY+ 8A20q/H3nXZH7ruy7ETQEnxdM6iUUJJrECos5AzP3MCsxRglYr92qreZWaOrDKf+IeXq LCDUrVt5p8PjR87UId9vSC6BQsnHjIhC8kBwyDBfwtbbg9P6CPymLNXJs8UXOSBkCnhn QGpw== X-Gm-Message-State: AOJu0YzjkvUpLxA1tBs+VUlY6G0ZUVF4bFGypa5IjakV+uZITuSv6kTo kyXDDNnnGR2fIalipOkn4ZD/uyhGVOze9HYkYRneK//bPjYkVqt5r/GuHnnRCdLTzb4tWIf/K1O nac7TFQ42GuIvTgmDNaaLW5caXpk2KwOrkgm97edIilEOwJG+5Lf8xWyfYptCfe6ZXUrSLhf1Kp YnCoENyzV+6Fahj7nfeCscT2cTKjfjQYOqBQ== X-Received: by 2002:a05:622a:1896:b0:461:11b:d22d with SMTP id d75a77b69052e-461717c6eebmr12288581cf.54.1730236587273; Tue, 29 Oct 2024 14:16:27 -0700 (PDT) X-Google-Smtp-Source: AGHT+IESJb6kh6IVqr8qStiAr4LASjj3zrStCPSYzub9j4zoi08upMUxJCbk/8yAQ8dpaPX23AZR6Q== X-Received: by 2002:a05:622a:1896:b0:461:11b:d22d with SMTP id d75a77b69052e-461717c6eebmr12288261cf.54.1730236586840; Tue, 29 Oct 2024 14:16:26 -0700 (PDT) Received: from x1n.redhat.com (pool-99-254-114-190.cpe.net.cable.rogers.com. [99.254.114.190]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-46132292c97sm48481691cf.49.2024.10.29.14.16.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Oct 2024 14:16:25 -0700 (PDT) From: Peter Xu To: qemu-devel@nongnu.org Cc: Markus Armbruster , Peter Maydell , Eduardo Habkost , Paolo Bonzini , Mark Cave-Ayland , Igor Mammedov , "Michael S . Tsirkin" , Alex Williamson , "Dr . David Alan Gilbert" , peterx@redhat.com, =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , =?utf-8?q?Phi?= =?utf-8?q?lippe_Mathieu-Daud=C3=A9?= , =?utf-8?q?C=C3=A9?= =?utf-8?q?dric_Le_Goater?= , Fabiano Rosas , Juraj Marcin Subject: [PATCH RFC v2 7/7] migration: Reset current_migration properly Date: Tue, 29 Oct 2024 17:16:07 -0400 Message-ID: <20241029211607.2114845-8-peterx@redhat.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20241029211607.2114845-1-peterx@redhat.com> References: <20241029211607.2114845-1-peterx@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=peterx@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -23 X-Spam_score: -2.4 X-Spam_bar: -- X-Spam_report: (-2.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.302, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org current_migration is never reset, even if the migration object is freed already. It means anyone references that can trigger UAF and it'll be hard to debug. Properly clear the pointer now. So far the only place to do is via its own finalize(), which means QEMU is releasing the last refcount and right before freeing the object memory. Meanwhile, QEMU won't know who holds the last refcount, so it can't reset the variable manually / explicitly. To make it more readable, also initialize the variable in the instance_init() so it's very well paired at least. Signed-off-by: Peter Xu --- migration/migration.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index f4456f7142..70b9ef8228 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -233,9 +233,11 @@ static int migration_stop_vm(MigrationState *s, RunState state) void migration_object_init(void) { - /* This can only be called once. */ - assert(!current_migration); - current_migration = MIGRATION_OBJ(object_new(TYPE_MIGRATION)); + /* This creates the singleton migration object */ + object_new(TYPE_MIGRATION); + + /* This should be set now when initialize the singleton object */ + assert(current_migration); /* * Init the migrate incoming object as well no matter whether @@ -3864,12 +3866,27 @@ static void migration_instance_finalize(Object *obj) qemu_sem_destroy(&ms->rp_state.rp_pong_acks); qemu_sem_destroy(&ms->postcopy_qemufile_src_sem); error_free(ms->error); + + /* + * We know we only have one instance of migration, and when reaching + * here it means migration object is going away. Clear the global + * reference to reflect that. + */ + current_migration = NULL; } static void migration_instance_init(Object *obj) { MigrationState *ms = MIGRATION_OBJ(obj); + /* + * There can only be one migration object globally. Keep a record of + * the pointer in current_migration, which will be reset after the + * object finalize(). + */ + assert(!current_migration); + current_migration = ms; + ms->state = MIGRATION_STATUS_NONE; ms->mbps = -1; ms->pages_per_second = -1;