From patchwork Fri Feb 21 17:03:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13986060 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 977C4C021B3 for ; Fri, 21 Feb 2025 17:04:39 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tlWRQ-0006jn-Ar; Fri, 21 Feb 2025 12:03:56 -0500 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 1tlWRN-0006cI-VF for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:03:53 -0500 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 1tlWRM-0001OE-0E for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:03:53 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1740157431; 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=0g4/7JXprhjHS9Kq/Ky0pszdlpKOhaBkh9IAViO+mbo=; b=RRxcsidf7qenxIGKhtBe8ZxQrVHMCBiw4OuIqo5xsYaDadZu5orBM6QyrPAdHvduamP4UF EY2P7BWHmt61qvGoGE/OW3UH+UPTwNP1tA4u9YxXSPqKKi/xQWuXcd/0qaTzzhFUkgV+Mu gNrvY+p8kXebBoyCLm4iHewl9tlbEvA= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-626-O_1whEdTPeKCF4scU9v1LQ-1; Fri, 21 Feb 2025 12:03:47 -0500 X-MC-Unique: O_1whEdTPeKCF4scU9v1LQ-1 X-Mimecast-MFC-AGG-ID: O_1whEdTPeKCF4scU9v1LQ_1740157426 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-4393e873962so12153655e9.3 for ; Fri, 21 Feb 2025 09:03:47 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740157426; x=1740762226; 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=0g4/7JXprhjHS9Kq/Ky0pszdlpKOhaBkh9IAViO+mbo=; b=ec8oj/dmd6UqEB8tF2fjcco0Zvt5GPok8K3Q27c4z0itdBaOoQ6pId5877xP7+B0Lu XlLZZG8vMSAk8iL5AZvh1JB7FhZlWc2iJsHsFuvkBz8a2MTB8Ji5ljonf1KFx7sMMFMT a3xthBodab1WgB5GOJb05CWcjANgKG/fts3ldrqEItKeseN8ZZPtI6TVQmqzKx9CgcFn XJqoK8V9tSXvEtEhAZvZgX12Eh1BZr2I2VYlk+UW679zWDLEoMIzt1gXz+pXkXDttu90 U2Gv0qYjkZS8wAsFMVJxTI+Dc6tBLp9eT1bOIWKpviZRao5FKgmSdyRMuQIGIBfYvwKb Vksw== X-Gm-Message-State: AOJu0YyZzc7Y4MXG8WX/zML4cRf4Jq9kUqWk+EFbE7fg90nN3MbLeayA W5kqxrbacBEgsvxzziAJRc63q4G4DOVjgriPagX96YLU+HZ7Blr3Ze627WWxBFn8r0kTlWb0+mQ Onki3CGZi5OC8Mwz598PvLi4XLWSwXm78I/PHf/w0uVGpOKFDCXo7CKk7ALrjcOKUXKHyopqtro OiYU4ONOSx9Z9PqMPeMvxtB2eyIpPQD4kWqKKuO1o= X-Gm-Gg: ASbGncsa2U9YjKpYPQRdjovFMepSO3ytw9+YXnN6yHWwON6CYWLe3tSb5Ewmb2k7hwv W4mx+ECHWD6O+YAq2m73xnheGX6AC1eLz6gsAJTSmKufi6x6dKrLIJnG3rtcuup9U2jF9pJRPmC 1Akgn8QhCuHYj57dxhKL4BFxzK2JSF0n084jIh8l49VnU9W4nNKTQGny0v1tkcDv1EC31l9+/ST jBhFSSUYS4Gb+1OetleT4Znhxnnj9Rib7thR6NFLTl7A+5M1LFgkgYHj3YZ+Bt+fiX4FGBgZW/S HRg9KLWKS9pqD9vAT0I= X-Received: by 2002:a05:600c:4ecc:b0:439:84d3:f7ee with SMTP id 5b1f17b1804b1-439ae2189bemr27774635e9.24.1740157425843; Fri, 21 Feb 2025 09:03:45 -0800 (PST) X-Google-Smtp-Source: AGHT+IHtZV5PSFgZqTOdAUJyQQTcqb6e++ndjRbyVA7u2lzRkwjkjWYbB7b6ugUaJc4QQsNIsJE8pg== X-Received: by 2002:a05:600c:4ecc:b0:439:84d3:f7ee with SMTP id 5b1f17b1804b1-439ae2189bemr27773765e9.24.1740157424715; Fri, 21 Feb 2025 09:03:44 -0800 (PST) Received: from [192.168.10.48] ([151.95.61.185]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-439b0371b7bsm23277985e9.33.2025.02.21.09.03.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Feb 2025 09:03:44 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: qemu-rust@nongnu.org Subject: [PATCH 01/15] rust: add IsA bounds to QOM implementation traits Date: Fri, 21 Feb 2025 18:03:28 +0100 Message-ID: <20250221170342.63591-2-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250221170342.63591-1-pbonzini@redhat.com> References: <20250221170342.63591-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.424, 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 Check that the right bounds are provided to the qom_isa! macro whenever the class is defined to implement a certain class. This removes the need to add IsA<> bounds together with the *Impl trait bounds. Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/qdev.rs | 2 +- rust/qemu-api/src/qom.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs index 3a7aa4def62..c4dd26b582c 100644 --- a/rust/qemu-api/src/qdev.rs +++ b/rust/qemu-api/src/qdev.rs @@ -86,7 +86,7 @@ pub trait ResettablePhasesImpl { } /// Trait providing the contents of [`DeviceClass`]. -pub trait DeviceImpl: ObjectImpl + ResettablePhasesImpl { +pub trait DeviceImpl: ObjectImpl + ResettablePhasesImpl + IsA { /// _Realization_ is the second stage of device creation. It contains /// all operations that depend on device properties and can fail (note: /// this is not yet supported for Rust devices). diff --git a/rust/qemu-api/src/qom.rs b/rust/qemu-api/src/qom.rs index 3d5ab2d9018..10ce359becb 100644 --- a/rust/qemu-api/src/qom.rs +++ b/rust/qemu-api/src/qom.rs @@ -37,6 +37,8 @@ //! * a trait for virtual method implementations, for example `DeviceImpl`. //! Child classes implement this trait to provide their own behavior for //! virtual methods. The trait's methods take `&self` to access instance data. +//! The traits have the appropriate specialization of `IsA<>` as a supertrait, +//! for example `IsA` for `DeviceImpl`. //! //! * an implementation of [`ClassInitImpl`], for example //! `ClassInitImpl`. This fills the vtable in the class struct; @@ -497,7 +499,7 @@ impl ObjectDeref for &mut T {} impl ObjectCastMut for &mut T {} /// Trait a type must implement to be registered with QEMU. -pub trait ObjectImpl: ObjectType + ClassInitImpl { +pub trait ObjectImpl: ObjectType + ClassInitImpl + IsA { /// The parent of the type. This should match the first field of the /// struct that implements `ObjectImpl`, minus the `ParentField<_>` wrapper. type ParentType: ObjectType; From patchwork Fri Feb 21 17:03:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13986063 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 4BCE1C021B6 for ; Fri, 21 Feb 2025 17:05:25 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tlWRX-0006oA-Lv; Fri, 21 Feb 2025 12:04:03 -0500 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 1tlWRP-0006gf-43 for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:03:55 -0500 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 1tlWRN-0001OX-6E for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:03:54 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1740157432; 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=1nJY4+DKOnRdgOSJbixQgGwalcHO4gTnjYN+sbdUtTI=; b=RlNjmN6xySA3oVcoGWhUlY34d9rNJwWK5cccg1hOnU+FAaa862hkO+Q7PJya3uuw9M/sVN tnZrUWm2mWxDk0mk7+4yzrf5GKURmrV8c7BwdNJI4gFCyy746GEcn2AaiY7xWdfilDivvp f/LzX9ivGsxsrD1FoO3J9ovFBeQX9n4= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-253-IUY3wfD4MUKy81kSyCNTZQ-1; Fri, 21 Feb 2025 12:03:50 -0500 X-MC-Unique: IUY3wfD4MUKy81kSyCNTZQ-1 X-Mimecast-MFC-AGG-ID: IUY3wfD4MUKy81kSyCNTZQ_1740157430 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-38f3eb82fceso1122071f8f.0 for ; Fri, 21 Feb 2025 09:03:50 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740157429; x=1740762229; 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=1nJY4+DKOnRdgOSJbixQgGwalcHO4gTnjYN+sbdUtTI=; b=guAb+JSihzZsvCKv2/dK7xmFCCSBelZwjTHwU2XQg1kS3471puT3I0oTe5goXnEmCL mo2Keem2+D82BMOcfD36qxogoyT73QWCoM4/KGOpOsgaJwX/2A0BeSW/jaGgX9PiXKkG lMFwEyAepeQzONEJ1djT74YHsXpVXPavZxqoGPblCoFmTxnme1+7YfA0fqidWSSZPPLK uAmEemPeAYR0021HkvYCc0ovOdZzqI9dOFkAb3ROzQQrC45uT0cHsCZz5V06MUoDzKqE s/08U5oKyjAAcDNstUwdK1qFDfmpwZpSfrF8C4n28xPPqgmekcqEd66Uok7V741y4fcX YGwg== X-Gm-Message-State: AOJu0Yz/lzoM92ZPvB04dI5PfwJXOoUYxLftkcXUpddPOfh+Dn0D4EC+ PkBYNXwck4JWBTt5x9LaAzR3OXvaenICLOuIC3+cyxGO+D3x3rZrD0Jx52dJeu1DuyOlE7tcCHX nffeyv38g5BYcXWcF4kPme/hTY6ov7+Qu1z8MbG3KnAYGUdA994/0tEV2IV2yqjIDv8JTC+eLAO eMnLKUrFyTuI2n8QpUih7f8fuNEeF7OMnR1eZSskI= X-Gm-Gg: ASbGncs+7ZbvDQCeBjbH0T+zR2HRosHm99m+pvdaTvgaoZzcroevdEk4b1MtZ/i/UBM mCVotZ5Qv5dAEoqFwFLhEMFwIBUmub76PKMdICE0vXhooFwQHLRaqTmq6Pn1FAaaohLeo+Vt35T nMZmq1HLRIg9jQiUUiOz50wOQMQfiXc/WibyhLLhUIKCIfWeOasDPDSPMNFg0jVV8rCsE8prfBM XvbnEaEfIPHk5DOHJYkTLLJ3MJDwVDVAqiWxhrRJQhGYwd/vIoZMBAGEzuMBPjwaKaalfQygFBz zzi/EH3v6KVLgm1lFIk= X-Received: by 2002:a5d:4e87:0:b0:38d:a879:4778 with SMTP id ffacd0b85a97d-38f6f0529bbmr3684301f8f.33.1740157428526; Fri, 21 Feb 2025 09:03:48 -0800 (PST) X-Google-Smtp-Source: AGHT+IGHSCdTAjM6t/EsZj2CvLBtQmF/ZHcMG+AKfYF+Hr94UnN5YaIxc7Z5J3yJYVGY+iuVXnIRcg== X-Received: by 2002:a5d:4e87:0:b0:38d:a879:4778 with SMTP id ffacd0b85a97d-38f6f0529bbmr3684039f8f.33.1740157426446; Fri, 21 Feb 2025 09:03:46 -0800 (PST) Received: from [192.168.10.48] ([151.95.61.185]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-439b02f5b38sm22973835e9.24.2025.02.21.09.03.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Feb 2025 09:03:45 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: qemu-rust@nongnu.org Subject: [PATCH 02/15] rust: add SysBusDeviceImpl Date: Fri, 21 Feb 2025 18:03:29 +0100 Message-ID: <20250221170342.63591-3-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250221170342.63591-1-pbonzini@redhat.com> References: <20250221170342.63591-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.424, 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_H5=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 The only function, right now, is to ensure that anything with a SysBusDeviceClass class is a SysBusDevice. Signed-off-by: Paolo Bonzini --- rust/hw/char/pl011/src/device.rs | 5 ++++- rust/hw/timer/hpet/src/hpet.rs | 4 +++- rust/qemu-api/src/sysbus.rs | 8 +++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index fe73771021e..7063b60c0cc 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -20,7 +20,7 @@ prelude::*, qdev::{Clock, ClockEvent, DeviceImpl, DeviceState, Property, ResetType, ResettablePhasesImpl}, qom::{ClassInitImpl, ObjectImpl, Owned, ParentField}, - sysbus::{SysBusDevice, SysBusDeviceClass}, + sysbus::{SysBusDevice, SysBusDeviceClass, SysBusDeviceImpl}, vmstate::VMStateDescription, }; @@ -176,6 +176,8 @@ impl ResettablePhasesImpl for PL011State { const HOLD: Option = Some(Self::reset_hold); } +impl SysBusDeviceImpl for PL011State {} + impl PL011Registers { pub(self) fn read(&mut self, offset: RegisterOffset) -> (bool, u32) { use RegisterOffset::*; @@ -746,3 +748,4 @@ impl ObjectImpl for PL011Luminary { impl DeviceImpl for PL011Luminary {} impl ResettablePhasesImpl for PL011Luminary {} +impl SysBusDeviceImpl for PL011Luminary {} diff --git a/rust/hw/timer/hpet/src/hpet.rs b/rust/hw/timer/hpet/src/hpet.rs index 75ff5b3e8d6..b4ffccf815f 100644 --- a/rust/hw/timer/hpet/src/hpet.rs +++ b/rust/hw/timer/hpet/src/hpet.rs @@ -23,7 +23,7 @@ qdev::{DeviceImpl, DeviceMethods, DeviceState, Property, ResetType, ResettablePhasesImpl}, qom::{ObjectImpl, ObjectType, ParentField}, qom_isa, - sysbus::SysBusDevice, + sysbus::{SysBusDevice, SysBusDeviceImpl}, timer::{Timer, CLOCK_VIRTUAL}, }; @@ -887,3 +887,5 @@ fn properties() -> &'static [Property] { impl ResettablePhasesImpl for HPETState { const HOLD: Option = Some(Self::reset_hold); } + +impl SysBusDeviceImpl for HPETState {} diff --git a/rust/qemu-api/src/sysbus.rs b/rust/qemu-api/src/sysbus.rs index fa36e12178f..fee2e3d478f 100644 --- a/rust/qemu-api/src/sysbus.rs +++ b/rust/qemu-api/src/sysbus.rs @@ -14,7 +14,7 @@ irq::{IRQState, InterruptSource}, memory::MemoryRegion, prelude::*, - qdev::{DeviceClass, DeviceState}, + qdev::{DeviceClass, DeviceImpl, DeviceState}, qom::{ClassInitImpl, Owned}, }; @@ -25,10 +25,12 @@ unsafe impl ObjectType for SysBusDevice { } qom_isa!(SysBusDevice: DeviceState, Object); -// TODO: add SysBusDeviceImpl +// TODO: add virtual methods +pub trait SysBusDeviceImpl: DeviceImpl + IsA {} + impl ClassInitImpl for T where - T: ClassInitImpl, + T: SysBusDeviceImpl + ClassInitImpl, { fn class_init(sdc: &mut SysBusDeviceClass) { >::class_init(&mut sdc.parent_class); From patchwork Fri Feb 21 17:03:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13986078 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 76A29C021B3 for ; Fri, 21 Feb 2025 17:06:40 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tlWRX-0006oE-MJ; Fri, 21 Feb 2025 12:04:03 -0500 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 1tlWRQ-0006jv-2r for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:03:56 -0500 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 1tlWRO-0001Ou-3T for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:03:55 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1740157433; 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=G+2kng6sRFTLtB08RcVigadgRIcXeqRixX2Ql4tgm1M=; b=duScw2tfRxTenP3W39F5ESuuQheffkAJkXaaykU229dW2ASOG8e7OOrj8sAhuzUqdgKEf8 ppDS/fsEfyN2T+xvVxdZxUfiNxWNIiIGdJtV9PKqNNyek5H4nxvWdutfsdPSWYQB19azNV 02oSlHtSlYOi0soBTiA4hG7Huj2xBO8= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-597-JvrsMP7RN5y4omD8q4L7Hw-1; Fri, 21 Feb 2025 12:03:51 -0500 X-MC-Unique: JvrsMP7RN5y4omD8q4L7Hw-1 X-Mimecast-MFC-AGG-ID: JvrsMP7RN5y4omD8q4L7Hw_1740157430 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-438da39bb69so16012445e9.0 for ; Fri, 21 Feb 2025 09:03:51 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740157430; x=1740762230; 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=G+2kng6sRFTLtB08RcVigadgRIcXeqRixX2Ql4tgm1M=; b=aB2ja7hDyVXn4r22dN5771a9owsn9jL9kbWP3LwSPVi/sNbutxDwSMVq3XXyCRyU/3 agRzLHRmu+RBuhf61KsYLfGaaZkASOJGBzW5ZrLJvAEiCNt9Ka8Kex1BvuOqcGnRSElU CDuqv6SU1bMZdtWTzPz4QLd5hyVYbelBnj94X3uO8iuEleUCNZNn44WnUsbH0B9qQNsX q5CJpnjK3bOI8JFJnQ38pVnRSnDqNGcxpDdBeScgn/BBWLlL6dkQ4vJhhH0s0jBtDFKh idb7+4hCbyAq5E5c/16bq4hK1pXQtdiC3ZSUjaJe7QP9NbCQ3sPchcCv72e6DidrxO25 nxtw== X-Gm-Message-State: AOJu0YwU5xqf3cmV76L9ZoEFFFBoUKAsjqmgmhptdnVwREvGqaEoggwD ZcXKGU6OIoSS8rvPJImF8dhpJq3zHX8b9llplo94OxG48PbgiPskmNNGiBW/o2FyWCltikI1HjF iGzKtQs/CJmpfHCeFzlijLVZlcNpdyKYm7wMLJBHfdY0eR1vLsh1BjomqKvDVTzQaT+D6mhdk2D Teg84t8IKx+HYi7zT9u1YxbvCm0/lATEbEyCiO9Rk= X-Gm-Gg: ASbGncvDN76YgO4MLjSccnFgSRJqj5SMmTRApNmMp9nsSV8fyBdocupka8bFEbbmKQ5 +h+qNaQU675Xbriea1JhDBF4O4JyyD6Pn6XrpiMh7LZmquTAAV/dTWY7zoRaGP1c+9jMUWNI+XW 3jdP7H3Nleje1MCwtn0S8eNeeIoyglshGgj5ejLZsvrg3s+gBX5c88DsUN9GxwDQDvtVfwMzkgb YCAsFP1rl9xmTgPTaEEqppY2EMyosM3w95e4dv0CbOmU5DwtKS1lFeTxiTOsBBc68H/qBNVDjmF WQykLBqvSRoP8SgOZpo= X-Received: by 2002:a05:600c:468a:b0:439:87d2:b0fd with SMTP id 5b1f17b1804b1-439ae1e8dc2mr37053335e9.12.1740157429603; Fri, 21 Feb 2025 09:03:49 -0800 (PST) X-Google-Smtp-Source: AGHT+IGq4r8d+X1Ah+8VVeXGPFojGkr0Y/GIJbu2hBMO1Z/gUvvNGqrM95nyK7Hib7qyi4XybK+Evw== X-Received: by 2002:a05:600c:468a:b0:439:87d2:b0fd with SMTP id 5b1f17b1804b1-439ae1e8dc2mr37051615e9.12.1740157428223; Fri, 21 Feb 2025 09:03:48 -0800 (PST) Received: from [192.168.10.48] ([151.95.61.185]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-439b02ce404sm23182125e9.7.2025.02.21.09.03.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Feb 2025 09:03:47 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: qemu-rust@nongnu.org Subject: [PATCH 03/15] rust: qom: add ObjectImpl::CLASS_INIT Date: Fri, 21 Feb 2025 18:03:30 +0100 Message-ID: <20250221170342.63591-4-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250221170342.63591-1-pbonzini@redhat.com> References: <20250221170342.63591-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.424, 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_H5=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=unavailable 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 As shown in the PL011 device, the orphan rules required a manual implementation of ClassInitImpl for anything not in the qemu_api crate; this gets in the way of moving system emulation-specific code (including DeviceClass, which as a blanket ClassInitImpl implementation) into its own crate. Make ClassInitImpl optional, at the cost of having to specify the CLASS_INIT member by hand in every implementation of ObjectImpl. The next commits will get rid of it, replacing all the "impl ClassInitImpl for T" blocks with a generic class_init method on Class. Right now the definition is always the same, but do not provide a default as that will not be true once ClassInitImpl goes away. Signed-off-by: Paolo Bonzini --- rust/hw/char/pl011/src/device.rs | 3 +++ rust/hw/timer/hpet/src/hpet.rs | 3 ++- rust/qemu-api/src/qom.rs | 14 +++++++++++--- rust/qemu-api/tests/tests.rs | 3 +++ 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index 7063b60c0cc..a6da9db0bb0 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -160,6 +160,7 @@ impl ObjectImpl for PL011State { const INSTANCE_INIT: Option = Some(Self::init); const INSTANCE_POST_INIT: Option = Some(Self::post_init); + const CLASS_INIT: fn(&mut Self::Class) = >::class_init; } impl DeviceImpl for PL011State { @@ -744,6 +745,8 @@ unsafe impl ObjectType for PL011Luminary { impl ObjectImpl for PL011Luminary { type ParentType = PL011State; + + const CLASS_INIT: fn(&mut Self::Class) = >::class_init; } impl DeviceImpl for PL011Luminary {} diff --git a/rust/hw/timer/hpet/src/hpet.rs b/rust/hw/timer/hpet/src/hpet.rs index b4ffccf815f..e01b4b67064 100644 --- a/rust/hw/timer/hpet/src/hpet.rs +++ b/rust/hw/timer/hpet/src/hpet.rs @@ -21,7 +21,7 @@ }, prelude::*, qdev::{DeviceImpl, DeviceMethods, DeviceState, Property, ResetType, ResettablePhasesImpl}, - qom::{ObjectImpl, ObjectType, ParentField}, + qom::{ClassInitImpl, ObjectImpl, ObjectType, ParentField}, qom_isa, sysbus::{SysBusDevice, SysBusDeviceImpl}, timer::{Timer, CLOCK_VIRTUAL}, @@ -836,6 +836,7 @@ impl ObjectImpl for HPETState { const INSTANCE_INIT: Option = Some(Self::init); const INSTANCE_POST_INIT: Option = Some(Self::post_init); + const CLASS_INIT: fn(&mut Self::Class) = >::class_init; } // TODO: Make these properties user-configurable! diff --git a/rust/qemu-api/src/qom.rs b/rust/qemu-api/src/qom.rs index 10ce359becb..d821ac25acc 100644 --- a/rust/qemu-api/src/qom.rs +++ b/rust/qemu-api/src/qom.rs @@ -180,7 +180,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { T::INSTANCE_POST_INIT.unwrap()(unsafe { state.as_ref() }); } -unsafe extern "C" fn rust_class_init>( +unsafe extern "C" fn rust_class_init( klass: *mut ObjectClass, _data: *mut c_void, ) { @@ -190,7 +190,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { // SAFETY: klass is a T::Class, since rust_class_init // is called from QOM core as the class_init function // for class T - T::class_init(unsafe { klass.as_mut() }) + ::CLASS_INIT(unsafe { klass.as_mut() }) } unsafe extern "C" fn drop_object(obj: *mut Object) { @@ -499,7 +499,7 @@ impl ObjectDeref for &mut T {} impl ObjectCastMut for &mut T {} /// Trait a type must implement to be registered with QEMU. -pub trait ObjectImpl: ObjectType + ClassInitImpl + IsA { +pub trait ObjectImpl: ObjectType + IsA { /// The parent of the type. This should match the first field of the /// struct that implements `ObjectImpl`, minus the `ParentField<_>` wrapper. type ParentType: ObjectType; @@ -552,6 +552,14 @@ pub trait ObjectImpl: ObjectType + ClassInitImpl + IsA { // methods on ObjectClass const UNPARENT: Option = None; + + /// Store into the argument the virtual method implementations + /// for `Self`. On entry, the virtual method pointers are set to + /// the default values coming from the parent classes; the function + /// can change them to override virtual methods of a parent class. + /// + /// Usually defined as `::class_init`. + const CLASS_INIT: fn(&mut Self::Class); } /// Internal trait used to automatically fill in a class struct. diff --git a/rust/qemu-api/tests/tests.rs b/rust/qemu-api/tests/tests.rs index 03569e4a44c..9546e9d7963 100644 --- a/rust/qemu-api/tests/tests.rs +++ b/rust/qemu-api/tests/tests.rs @@ -60,6 +60,7 @@ unsafe impl ObjectType for DummyState { impl ObjectImpl for DummyState { type ParentType = DeviceState; const ABSTRACT: bool = false; + const CLASS_INIT: fn(&mut DummyClass) = >::class_init; } impl ResettablePhasesImpl for DummyState {} @@ -102,6 +103,8 @@ unsafe impl ObjectType for DummyChildState { impl ObjectImpl for DummyChildState { type ParentType = DummyState; const ABSTRACT: bool = false; + const CLASS_INIT: fn(&mut DummyChildClass) = + >::class_init; } impl ResettablePhasesImpl for DummyChildState {} From patchwork Fri Feb 21 17:03:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13986059 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 D9D03C021B6 for ; Fri, 21 Feb 2025 17:04:31 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tlWRY-0006oZ-7f; Fri, 21 Feb 2025 12:04:04 -0500 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 1tlWRT-0006kt-6o for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:01 -0500 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 1tlWRR-0001Q2-Dl for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:03:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1740157436; 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=hJleYDBCD4SDSG2l2W+THx3Wzd2iHgM0lXz/mw911rM=; b=LGz/vxGIrOTJBAGueVC6IAMID1BV0/RI72jTQz0rswiMPollkrTRpcAL+VL0bWQe9zW6tP l+m3/hivGFNPP66K0pQhQ/pZ5dMoRvOBLKPQAiJe4mValwPVkH0RzqYy23OtGlY8xqLQQd WEpxSfLZzuCNfdWUeE+ll/AY9Cao3yc= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-656-AHu6RGxDN0ymm-kyRxycTQ-1; Fri, 21 Feb 2025 12:03:55 -0500 X-MC-Unique: AHu6RGxDN0ymm-kyRxycTQ-1 X-Mimecast-MFC-AGG-ID: AHu6RGxDN0ymm-kyRxycTQ_1740157434 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-4393b6763a3so10943955e9.2 for ; Fri, 21 Feb 2025 09:03:55 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740157433; x=1740762233; 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=hJleYDBCD4SDSG2l2W+THx3Wzd2iHgM0lXz/mw911rM=; b=MEnjo01NJAOPXbVJIrah3Db5ETpwgbfbiDvNqh+VYXpt89IVkgdzqdL1GvKflodrB3 oihZNX301dcJEijVY6gmzrshrEF9XShFQ/8SXnYkc8iFvrRhVKblmzgypjFLXyr3Exsv apfdKDmPFMJh7Zpg8i0E1TctXn/hIp5QyDavC16v3BWrxFQ5ZP1u3x5evoWJwiaxyjdO j7yS7VjLpPoGtTR1eNfNYWizprtQvCIZK/awHVwzsnWMOWmY9QvQeObXK36LsoCD5hIB ScRdxpYfNDDy+l7BQWKbdST44okoNXgPAugHM7DNFsfLjJnd3ZmtQ0rM6CaNkOMprqKS D0uQ== X-Gm-Message-State: AOJu0Yy6mttQcxO1B7sXICqKQFrWeBI46wS9IbHIMloKwS/y5irlguv1 pCjDbSsBrK+na1Tk+vyiTqk8civKHFopyZ0OUZ7oLjEyQOc0Myj+Cfuot1rb5XpQ34Lv3wdZDbn 0/XAe+yrJYiFu462kpQmxCMmgp9T4wqYhQM8f3Gs0zbOY7EVxdXCNhF3iMwMVcahmfs8Y0q4GzV TxFbbeQqXK+dEv3/IYEZJitr4ndyxoMeU3PugxjPw= X-Gm-Gg: ASbGncvUkU42svnkaqgQcX2XPn6r1feUdXASzRSugiViXY7O0fz4R1JORL6Xrig0Qf9 cICVwHizcifwAxmpPQjfCqxDvM+BSCVMF33JEGlJGZ7mXP2djmJ8fR65zMaH7fN4bof/9EBvIPH WBeRieWsPKlnMInx4cWy14bTDcSv2ESJ+MUrqGwJbD6i1w/UBoj+1cbrL3l0qwCIo5zg3k5xlYu t2Iq7JXnjzTd/hhAOP2rpURvFPNMFTr6EQpnWzEXkybwDACXRyD8gGYKYV3O+CZ4CX7aCBZSFsG W2JVBNUSawIUXaXh1qw= X-Received: by 2002:a05:600c:4ed1:b0:439:a155:549d with SMTP id 5b1f17b1804b1-439ae1eacfdmr37742825e9.12.1740157432579; Fri, 21 Feb 2025 09:03:52 -0800 (PST) X-Google-Smtp-Source: AGHT+IHUJMLtPu1H85AOGMMT+HKTiV5g2ktjFALXblz6rsAXfbi9P1WnTKCL9dEoeEYDJBKe4bW0Uw== X-Received: by 2002:a05:600c:4ed1:b0:439:a155:549d with SMTP id 5b1f17b1804b1-439ae1eacfdmr37742105e9.12.1740157431971; Fri, 21 Feb 2025 09:03:51 -0800 (PST) Received: from [192.168.10.48] ([151.95.61.185]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-439b030b347sm23028795e9.26.2025.02.21.09.03.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Feb 2025 09:03:48 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: qemu-rust@nongnu.org Subject: [PATCH 04/15] rust: pl011, qemu_api tests: do not use ClassInitImpl Date: Fri, 21 Feb 2025 18:03:31 +0100 Message-ID: <20250221170342.63591-5-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250221170342.63591-1-pbonzini@redhat.com> References: <20250221170342.63591-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.424, 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 Outside the qemu_api crate, orphan rules make the usage of ClassInitImpl unwieldy. Now that it is optional, do not use it. For PL011Class, this makes it easier to provide a PL011Impl trait similar to the ones in the qemu_api crate. The device id consts are moved there. Signed-off-by: Paolo Bonzini --- rust/hw/char/pl011/src/device.rs | 38 ++++++++++++++++---------------- rust/qemu-api/tests/tests.rs | 33 ++++++++++----------------- 2 files changed, 31 insertions(+), 40 deletions(-) diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index a6da9db0bb0..fc1c8ec8d6a 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -50,11 +50,6 @@ fn index(&self, idx: hwaddr) -> &Self::Output { } } -impl DeviceId { - const ARM: Self = Self(&[0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1]); - const LUMINARY: Self = Self(&[0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1]); -} - // FIFOs use 32-bit indices instead of usize, for compatibility with // the migration stream produced by the C version of this device. #[repr(transparent)] @@ -143,16 +138,24 @@ pub struct PL011Class { device_id: DeviceId, } +trait PL011Impl: SysBusDeviceImpl + IsA { + const DEVICE_ID: DeviceId; +} + +impl PL011Class { + fn class_init(&mut self) { + self.device_id = T::DEVICE_ID; + >::class_init(&mut self.parent_class); + } +} + unsafe impl ObjectType for PL011State { type Class = PL011Class; const TYPE_NAME: &'static CStr = crate::TYPE_PL011; } -impl ClassInitImpl for PL011State { - fn class_init(klass: &mut PL011Class) { - klass.device_id = DeviceId::ARM; - >::class_init(&mut klass.parent_class); - } +impl PL011Impl for PL011State { + const DEVICE_ID: DeviceId = DeviceId(&[0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1]); } impl ObjectImpl for PL011State { @@ -160,7 +163,7 @@ impl ObjectImpl for PL011State { const INSTANCE_INIT: Option = Some(Self::init); const INSTANCE_POST_INIT: Option = Some(Self::post_init); - const CLASS_INIT: fn(&mut Self::Class) = >::class_init; + const CLASS_INIT: fn(&mut Self::Class) = Self::Class::class_init::; } impl DeviceImpl for PL011State { @@ -729,13 +732,6 @@ pub struct PL011Luminary { parent_obj: ParentField, } -impl ClassInitImpl for PL011Luminary { - fn class_init(klass: &mut PL011Class) { - klass.device_id = DeviceId::LUMINARY; - >::class_init(&mut klass.parent_class); - } -} - qom_isa!(PL011Luminary : PL011State, SysBusDevice, DeviceState, Object); unsafe impl ObjectType for PL011Luminary { @@ -746,7 +742,11 @@ unsafe impl ObjectType for PL011Luminary { impl ObjectImpl for PL011Luminary { type ParentType = PL011State; - const CLASS_INIT: fn(&mut Self::Class) = >::class_init; + const CLASS_INIT: fn(&mut Self::Class) = Self::Class::class_init::; +} + +impl PL011Impl for PL011Luminary { + const DEVICE_ID: DeviceId = DeviceId(&[0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1]); } impl DeviceImpl for PL011Luminary {} diff --git a/rust/qemu-api/tests/tests.rs b/rust/qemu-api/tests/tests.rs index 9546e9d7963..93c5637bbc3 100644 --- a/rust/qemu-api/tests/tests.rs +++ b/rust/qemu-api/tests/tests.rs @@ -13,7 +13,7 @@ cell::{self, BqlCell}, declare_properties, define_property, prelude::*, - qdev::{DeviceClass, DeviceImpl, DeviceState, Property, ResettablePhasesImpl}, + qdev::{DeviceImpl, DeviceState, Property, ResettablePhasesImpl}, qom::{ClassInitImpl, ObjectImpl, ParentField}, sysbus::SysBusDevice, vmstate::VMStateDescription, @@ -41,6 +41,12 @@ pub struct DummyClass { parent_class: ::Class, } +impl DummyClass { + pub fn class_init(self: &mut DummyClass) { + >::class_init(&mut self.parent_class); + } +} + declare_properties! { DUMMY_PROPERTIES, define_property!( @@ -60,7 +66,7 @@ unsafe impl ObjectType for DummyState { impl ObjectImpl for DummyState { type ParentType = DeviceState; const ABSTRACT: bool = false; - const CLASS_INIT: fn(&mut DummyClass) = >::class_init; + const CLASS_INIT: fn(&mut DummyClass) = DummyClass::class_init::; } impl ResettablePhasesImpl for DummyState {} @@ -74,14 +80,6 @@ fn vmsd() -> Option<&'static VMStateDescription> { } } -// `impl ClassInitImpl for T` doesn't work since it violates -// orphan rule. -impl ClassInitImpl for DummyState { - fn class_init(klass: &mut DummyClass) { - >::class_init(&mut klass.parent_class); - } -} - #[derive(qemu_api_macros::offsets)] #[repr(C)] #[derive(qemu_api_macros::Object)] @@ -103,22 +101,15 @@ unsafe impl ObjectType for DummyChildState { impl ObjectImpl for DummyChildState { type ParentType = DummyState; const ABSTRACT: bool = false; - const CLASS_INIT: fn(&mut DummyChildClass) = - >::class_init; + const CLASS_INIT: fn(&mut DummyChildClass) = DummyChildClass::class_init::; } impl ResettablePhasesImpl for DummyChildState {} impl DeviceImpl for DummyChildState {} -impl ClassInitImpl for DummyChildState { - fn class_init(klass: &mut DummyClass) { - >::class_init(&mut klass.parent_class); - } -} - -impl ClassInitImpl for DummyChildState { - fn class_init(klass: &mut DummyChildClass) { - >::class_init(&mut klass.parent_class); +impl DummyChildClass { + pub fn class_init(self: &mut DummyChildClass) { + self.parent_class.class_init::(); } } From patchwork Fri Feb 21 17:03:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13986056 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 8E77EC021B5 for ; Fri, 21 Feb 2025 17:04:16 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tlWRd-0006xA-TQ; Fri, 21 Feb 2025 12:04:09 -0500 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 1tlWRb-0006tg-MI for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:07 -0500 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 1tlWRZ-0001RN-6q for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:07 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1740157444; 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=OFO/wWi78NoYeD+/g7iAizNX0tpa55cnNvmYXRSX970=; b=LjXDtUAnZZfnBkakorlwR4NJtVkVj8ByDQdBD1aUMIdgd4+JFZw3Z4EUriQts25SJ+VozC GtKgAKkytKD/SZRXPZO8o2jIHb4D399k4HtDHP2ZN0xn51D5un4TMCXkd5El5Vc64vrDV6 s5JtsffNG7u9PFNdY5a/CuM5MhcBG3o= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-68-Tkbfi--nPrCKi-NGSj-2Bg-1; Fri, 21 Feb 2025 12:04:02 -0500 X-MC-Unique: Tkbfi--nPrCKi-NGSj-2Bg-1 X-Mimecast-MFC-AGG-ID: Tkbfi--nPrCKi-NGSj-2Bg_1740157441 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-38f32ac838cso1983890f8f.2 for ; Fri, 21 Feb 2025 09:04:02 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740157440; x=1740762240; 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=OFO/wWi78NoYeD+/g7iAizNX0tpa55cnNvmYXRSX970=; b=LGekUe5+64FM1QfH0UxuGKTCuVtJFDCOmGrWGFxImEVbIwyTTSZQ74faYbJqjlK/YV Nk9dVz9zsnXAyJRZb3c9AqUc5MHtytJuYLz7Mu9Z89kNJUrVNhGS715aREO6gTUKTFJz ZmYoyO/2FJNDLjDJnGDg9elf+dT18aWo9XssvcCJ2a6O8VcSd5cHwOzxMx5J2XGdCnTg kzWI/k2n1qhlEd+LBEFU5MFPy6ko7Mas/MrdGpFCbvFZyhpHb30SWxqdDG8YqY6aU2cy i10/bRbBsKB6313xmTa/wJ8lWA1W/WcwwO0mBRlHzyddwizLiuycB5x9cVanxZ5Oj0d/ OEUg== X-Gm-Message-State: AOJu0Yz/gWFwOpu7mx9jv9OmMTOAYiXCFXAD3cPti0bCY6sAMLd0gV/+ +ih08x5FxrXJ3/oqKg0HB7Y+FKhAzdpHDLmFCZ9FElyxl9Eo5kh3wmdgioTGMrc+yIGjg/WFEcW x8FkXrgOeEdWtoYXviBqUILqXqk7HX469dKq1+Y6w4QY6FEg/P+JtCzj8Nutvgt96psnqdznAsf IZVLdkUIIqgjqDDdoTN/fqau0rwCdFaQbXKRYtm3w= X-Gm-Gg: ASbGncsovMrhDvAO0tsVUhegmaTg3kxaNQpwp5UiFk8CbZmE8Apx6NHWkrVOTwxvQLK TRcIEIMCz59cQmWVEs1waCqkBwHLw0PlCwzA4sCa/juIbe+MtBdAW/2K+L2/0kT5lOEa8OlpWko eNEJp/pCT5IicRND1hF+hY1coIDK53w02KU7hE/EYCwdGIJrqH1hCPIF5qBwWJC8VNFA0ouzjFI HiatGactL2ZZXq53CPLjEqXQPVwelDjXEbGt4IZQMW6nnu6+ntR0GCzGPgU0T+pI8uAVBf1m5/b 2ASQpwzgg0ifILNL3Hg= X-Received: by 2002:a05:6000:4011:b0:38f:457e:3f2b with SMTP id ffacd0b85a97d-38f6e757322mr3655853f8f.6.1740157438177; Fri, 21 Feb 2025 09:03:58 -0800 (PST) X-Google-Smtp-Source: AGHT+IFCmC3GeryJTAKucnbg/IrFfauD+bo6dzvuxUmb1fjIroP6Xc5RkPQ+sicZGJobs9sS7Yy5dA== X-Received: by 2002:a05:6000:4011:b0:38f:457e:3f2b with SMTP id ffacd0b85a97d-38f6e757322mr3655620f8f.6.1740157436059; Fri, 21 Feb 2025 09:03:56 -0800 (PST) Received: from [192.168.10.48] ([151.95.61.185]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f258dcc45sm24074742f8f.33.2025.02.21.09.03.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Feb 2025 09:03:52 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: qemu-rust@nongnu.org Subject: [PATCH 05/15] rust: qom: get rid of ClassInitImpl Date: Fri, 21 Feb 2025 18:03:32 +0100 Message-ID: <20250221170342.63591-6-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250221170342.63591-1-pbonzini@redhat.com> References: <20250221170342.63591-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.424, 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 Complete the conversion from the ClassInitImpl trait to class_init() methods. This will provide more freedom to split the qemu_api crate in separate parts. Signed-off-by: Paolo Bonzini --- rust/hw/char/pl011/src/device.rs | 6 +- rust/hw/timer/hpet/src/hpet.rs | 4 +- rust/qemu-api/src/qdev.rs | 38 ++++--- rust/qemu-api/src/qom.rs | 164 +++++++++++++------------------ rust/qemu-api/src/sysbus.rs | 15 ++- rust/qemu-api/tests/tests.rs | 4 +- 6 files changed, 101 insertions(+), 130 deletions(-) diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index fc1c8ec8d6a..6896b1026f6 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -19,8 +19,8 @@ memory::{hwaddr, MemoryRegion, MemoryRegionOps, MemoryRegionOpsBuilder}, prelude::*, qdev::{Clock, ClockEvent, DeviceImpl, DeviceState, Property, ResetType, ResettablePhasesImpl}, - qom::{ClassInitImpl, ObjectImpl, Owned, ParentField}, - sysbus::{SysBusDevice, SysBusDeviceClass, SysBusDeviceImpl}, + qom::{ObjectImpl, Owned, ParentField}, + sysbus::{SysBusDevice, SysBusDeviceImpl}, vmstate::VMStateDescription, }; @@ -145,7 +145,7 @@ trait PL011Impl: SysBusDeviceImpl + IsA { impl PL011Class { fn class_init(&mut self) { self.device_id = T::DEVICE_ID; - >::class_init(&mut self.parent_class); + self.parent_class.class_init::(); } } diff --git a/rust/hw/timer/hpet/src/hpet.rs b/rust/hw/timer/hpet/src/hpet.rs index e01b4b67064..be27eb0eff4 100644 --- a/rust/hw/timer/hpet/src/hpet.rs +++ b/rust/hw/timer/hpet/src/hpet.rs @@ -21,7 +21,7 @@ }, prelude::*, qdev::{DeviceImpl, DeviceMethods, DeviceState, Property, ResetType, ResettablePhasesImpl}, - qom::{ClassInitImpl, ObjectImpl, ObjectType, ParentField}, + qom::{ObjectImpl, ObjectType, ParentField}, qom_isa, sysbus::{SysBusDevice, SysBusDeviceImpl}, timer::{Timer, CLOCK_VIRTUAL}, @@ -836,7 +836,7 @@ impl ObjectImpl for HPETState { const INSTANCE_INIT: Option = Some(Self::init); const INSTANCE_POST_INIT: Option = Some(Self::post_init); - const CLASS_INIT: fn(&mut Self::Class) = >::class_init; + const CLASS_INIT: fn(&mut Self::Class) = Self::Class::class_init::; } // TODO: Make these properties user-configurable! diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs index c4dd26b582c..c136457090c 100644 --- a/rust/qemu-api/src/qdev.rs +++ b/rust/qemu-api/src/qdev.rs @@ -19,7 +19,7 @@ chardev::Chardev, irq::InterruptSource, prelude::*, - qom::{ClassInitImpl, ObjectClass, ObjectImpl, Owned}, + qom::{ObjectClass, ObjectImpl, Owned}, vmstate::VMStateDescription, }; @@ -113,7 +113,7 @@ fn vmsd() -> Option<&'static VMStateDescription> { /// # Safety /// /// This function is only called through the QOM machinery and -/// used by the `ClassInitImpl` trait. +/// used by `DeviceClass::class_init`. /// We expect the FFI user of this function to pass a valid pointer that /// can be downcasted to type `T`. We also expect the device is /// readable/writeable from one thread at any time. @@ -127,43 +127,41 @@ unsafe impl InterfaceType for ResettableClass { unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_RESETTABLE_INTERFACE) }; } -impl ClassInitImpl for T -where - T: ResettablePhasesImpl, -{ - fn class_init(rc: &mut ResettableClass) { +impl ResettableClass { + /// Fill in the virtual methods of `ResettableClass` based on the + /// definitions in the `ResettablePhasesImpl` trait. + pub fn class_init(&mut self) { if ::ENTER.is_some() { - rc.phases.enter = Some(rust_resettable_enter_fn::); + self.phases.enter = Some(rust_resettable_enter_fn::); } if ::HOLD.is_some() { - rc.phases.hold = Some(rust_resettable_hold_fn::); + self.phases.hold = Some(rust_resettable_hold_fn::); } if ::EXIT.is_some() { - rc.phases.exit = Some(rust_resettable_exit_fn::); + self.phases.exit = Some(rust_resettable_exit_fn::); } } } -impl ClassInitImpl for T -where - T: ClassInitImpl + ClassInitImpl + DeviceImpl, -{ - fn class_init(dc: &mut DeviceClass) { +impl DeviceClass { + /// Fill in the virtual methods of `DeviceClass` based on the definitions in + /// the `DeviceImpl` trait. + pub fn class_init(&mut self) { if ::REALIZE.is_some() { - dc.realize = Some(rust_realize_fn::); + self.realize = Some(rust_realize_fn::); } if let Some(vmsd) = ::vmsd() { - dc.vmsd = vmsd; + self.vmsd = vmsd; } let prop = ::properties(); if !prop.is_empty() { unsafe { - bindings::device_class_set_props_n(dc, prop.as_ptr(), prop.len()); + bindings::device_class_set_props_n(self, prop.as_ptr(), prop.len()); } } - ResettableClass::interface_init::(dc); - >::class_init(&mut dc.parent_class); + ResettableClass::cast::(self).class_init::(); + self.parent_class.class_init::(); } } diff --git a/rust/qemu-api/src/qom.rs b/rust/qemu-api/src/qom.rs index d821ac25acc..5488643a2fd 100644 --- a/rust/qemu-api/src/qom.rs +++ b/rust/qemu-api/src/qom.rs @@ -40,11 +40,6 @@ //! The traits have the appropriate specialization of `IsA<>` as a supertrait, //! for example `IsA` for `DeviceImpl`. //! -//! * an implementation of [`ClassInitImpl`], for example -//! `ClassInitImpl`. This fills the vtable in the class struct; -//! the source for this is the `*Impl` trait; the associated consts and -//! functions if needed are wrapped to map C types into Rust types. -//! //! * a trait for instance methods, for example `DeviceMethods`. This trait is //! automatically implemented for any reference or smart pointer to a device //! instance. It calls into the vtable provides access across all subclasses @@ -54,6 +49,48 @@ //! This provides access to class-wide functionality that doesn't depend on //! instance data. Like instance methods, these are automatically inherited by //! child classes. +//! +//! # Class structures +//! +//! Each QOM class that has virtual methods describes them in a +//! _class struct_. Class structs include a parent field corresponding +//! to the vtable of the parent class, all the way up to [`ObjectClass`]. +//! +//! As mentioned above, virtual methods are defined via traits such as +//! `DeviceImpl`. Class structs do not define any trait but, conventionally, +//! all of them have a `class_init` method to initialize the virtual methods +//! based on the trait and then call the same method on the superclass. +//! +//! ```ignore +//! impl YourSubclassClass +//! { +//! pub fn class_init(&mut self) { +//! ... +//! klass.parent_class::class_init(); +//! } +//! } +//! ``` +//! +//! If a class implements a QOM interface. In that case, the function must +//! contain, for each interface, an extra forwarding call as follows: +//! +//! ```ignore +//! ResettableClass::cast::(self).class_init::(); +//! ``` +//! +//! These `class_init` functions are methods on the class rather than a trait, +//! because the bound on `T` (`DeviceImpl` in this case), will change for every +//! class struct. The functions are pointed to by the +//! [`ObjectImpl::CLASS_INIT`] function pointer. While there is no default +//! implementation, in most cases it will be enough to write it as follows: +//! +//! ```ignore +//! const CLASS_INIT: fn(&mut Self::Class)> = Self::Class::class_init::; +//! ``` +//! +//! This design incurs a small amount of code duplication but, by not using +//! traits, it allows the flexibility of implementing bindings in any crate, +//! without incurring into violations of orphan rules for traits. use std::{ ffi::CStr, @@ -279,19 +316,25 @@ pub unsafe trait InterfaceType: Sized { /// for this interface. const TYPE_NAME: &'static CStr; - /// Initialize the vtable for the interface; the generic argument `T` is the - /// type being initialized, while the generic argument `U` is the type that + /// Return the vtable for the interface; `U` is the type that /// lists the interface in its `TypeInfo`. /// + /// # Examples + /// + /// This function is usually called by a `class_init` method in `U::Class`. + /// For example, `DeviceClass::class_init` initializes its `Resettable` + /// interface as follows: + /// + /// ```ignore + /// ResettableClass::cast::(self).class_init::(); + /// ``` + /// + /// where `T` is the concrete subclass that is being initialized. + /// /// # Panics /// /// Panic if the incoming argument if `T` does not implement the interface. - fn interface_init< - T: ObjectType + ClassInitImpl + ClassInitImpl, - U: ObjectType, - >( - klass: &mut U::Class, - ) { + fn cast(klass: &mut U::Class) -> &mut Self { unsafe { // SAFETY: upcasting to ObjectClass is always valid, and the // return type is either NULL or the argument itself @@ -300,8 +343,7 @@ fn interface_init< Self::TYPE_NAME.as_ptr(), ) .cast(); - - >::class_init(result.as_mut().unwrap()) + result.as_mut().unwrap() } } } @@ -558,87 +600,20 @@ pub trait ObjectImpl: ObjectType + IsA { /// the default values coming from the parent classes; the function /// can change them to override virtual methods of a parent class. /// - /// Usually defined as `::class_init`. - const CLASS_INIT: fn(&mut Self::Class); -} - -/// Internal trait used to automatically fill in a class struct. -/// -/// Each QOM class that has virtual methods describes them in a -/// _class struct_. Class structs include a parent field corresponding -/// to the vtable of the parent class, all the way up to [`ObjectClass`]. -/// Each QOM type has one such class struct; this trait takes care of -/// initializing the `T` part of the class struct, for the type that -/// implements the trait. -/// -/// Each struct will implement this trait with `T` equal to each -/// superclass. For example, a device should implement at least -/// `ClassInitImpl<`[`DeviceClass`](crate::qdev::DeviceClass)`>` and -/// `ClassInitImpl<`[`ObjectClass`]`>`. Such implementations are made -/// in one of two ways. -/// -/// For most superclasses, `ClassInitImpl` is provided by the `qemu-api` -/// crate itself. The Rust implementation of methods will come from a -/// trait like [`ObjectImpl`] or [`DeviceImpl`](crate::qdev::DeviceImpl), -/// and `ClassInitImpl` is provided by blanket implementations that -/// operate on all implementors of the `*Impl`* trait. For example: -/// -/// ```ignore -/// impl ClassInitImpl for T -/// where -/// T: ClassInitImpl + DeviceImpl, -/// ``` -/// -/// The bound on `ClassInitImpl` is needed so that, -/// after initializing the `DeviceClass` part of the class struct, -/// the parent [`ObjectClass`] is initialized as well. -/// -/// The other case is when manual implementation of the trait is needed. -/// This covers the following cases: -/// -/// * if a class implements a QOM interface, the Rust code _has_ to define its -/// own class struct `FooClass` and implement `ClassInitImpl`. -/// `ClassInitImpl`'s `class_init` method will then forward to -/// multiple other `class_init`s, for the interfaces as well as the -/// superclass. (Note that there is no Rust example yet for using interfaces). -/// -/// * for classes implemented outside the ``qemu-api`` crate, it's not possible -/// to add blanket implementations like the above one, due to orphan rules. In -/// that case, the easiest solution is to implement -/// `ClassInitImpl` for each subclass and not have a -/// `YourSuperclassImpl` trait at all. -/// -/// ```ignore -/// impl ClassInitImpl for YourSubclass { -/// fn class_init(klass: &mut YourSuperclass) { -/// klass.some_method = Some(Self::some_method); -/// >::class_init(&mut klass.parent_class); -/// } -/// } -/// ``` -/// -/// While this method incurs a small amount of code duplication, -/// it is generally limited to the recursive call on the last line. -/// This is because classes defined in Rust do not need the same -/// glue code that is needed when the classes are defined in C code. -/// You may consider using a macro if you have many subclasses. -pub trait ClassInitImpl { - /// Initialize `klass` to point to the virtual method implementations - /// for `Self`. On entry, the virtual method pointers are set to - /// the default values coming from the parent classes; the function - /// can change them to override virtual methods of a parent class. + /// Usually defined simply as `Self::Class::class_init::`; + /// however a default implementation cannot be included here, because the + /// bounds that the `Self::Class::class_init` method places on `Self` are + /// not known in advance. /// - /// The virtual method implementations usually come from another - /// trait, for example [`DeviceImpl`](crate::qdev::DeviceImpl) - /// when `T` is [`DeviceClass`](crate::qdev::DeviceClass). + /// # Safety /// - /// On entry, `klass`'s parent class is initialized, while the other fields + /// While `klass`'s parent class is initialized on entry, the other fields /// are all zero; it is therefore assumed that all fields in `T` can be /// zeroed, otherwise it would not be possible to provide the class as a /// `&mut T`. TODO: add a bound of [`Zeroable`](crate::zeroable::Zeroable) /// to T; this is more easily done once Zeroable does not require a manual /// implementation (Rust 1.75.0). - fn class_init(klass: &mut T); + const CLASS_INIT: fn(&mut Self::Class); } /// # Safety @@ -651,13 +626,12 @@ pub trait ClassInitImpl { T::UNPARENT.unwrap()(unsafe { state.as_ref() }); } -impl ClassInitImpl for T -where - T: ObjectImpl, -{ - fn class_init(oc: &mut ObjectClass) { +impl ObjectClass { + /// Fill in the virtual methods of `ObjectClass` based on the definitions in + /// the `ObjectImpl` trait. + pub fn class_init(&mut self) { if ::UNPARENT.is_some() { - oc.unparent = Some(rust_unparent_fn::); + self.unparent = Some(rust_unparent_fn::); } } } diff --git a/rust/qemu-api/src/sysbus.rs b/rust/qemu-api/src/sysbus.rs index fee2e3d478f..04821a2b9b3 100644 --- a/rust/qemu-api/src/sysbus.rs +++ b/rust/qemu-api/src/sysbus.rs @@ -14,8 +14,8 @@ irq::{IRQState, InterruptSource}, memory::MemoryRegion, prelude::*, - qdev::{DeviceClass, DeviceImpl, DeviceState}, - qom::{ClassInitImpl, Owned}, + qdev::{DeviceImpl, DeviceState}, + qom::Owned, }; unsafe impl ObjectType for SysBusDevice { @@ -28,12 +28,11 @@ unsafe impl ObjectType for SysBusDevice { // TODO: add virtual methods pub trait SysBusDeviceImpl: DeviceImpl + IsA {} -impl ClassInitImpl for T -where - T: SysBusDeviceImpl + ClassInitImpl, -{ - fn class_init(sdc: &mut SysBusDeviceClass) { - >::class_init(&mut sdc.parent_class); +impl SysBusDeviceClass { + /// Fill in the virtual methods of `SysBusDeviceClass` based on the + /// definitions in the `SysBusDeviceImpl` trait. + pub fn class_init(self: &mut SysBusDeviceClass) { + self.parent_class.class_init::(); } } diff --git a/rust/qemu-api/tests/tests.rs b/rust/qemu-api/tests/tests.rs index 93c5637bbc3..e3985782a38 100644 --- a/rust/qemu-api/tests/tests.rs +++ b/rust/qemu-api/tests/tests.rs @@ -14,7 +14,7 @@ declare_properties, define_property, prelude::*, qdev::{DeviceImpl, DeviceState, Property, ResettablePhasesImpl}, - qom::{ClassInitImpl, ObjectImpl, ParentField}, + qom::{ObjectImpl, ParentField}, sysbus::SysBusDevice, vmstate::VMStateDescription, zeroable::Zeroable, @@ -43,7 +43,7 @@ pub struct DummyClass { impl DummyClass { pub fn class_init(self: &mut DummyClass) { - >::class_init(&mut self.parent_class); + self.parent_class.class_init::(); } } From patchwork Fri Feb 21 17:03:33 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13986058 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 939DEC021B5 for ; Fri, 21 Feb 2025 17:04:28 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tlWRg-00078Y-VP; Fri, 21 Feb 2025 12:04:13 -0500 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 1tlWRe-0006xN-0L for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:10 -0500 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 1tlWRb-0001Rq-0H for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:09 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1740157446; 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=IDuooerhK1to1+S4hiPVrqtGgOqxZ0Q0ElNK+Nffz5Y=; b=J4FpUMnEPVv7tL3uH6C9rutlpdTk3pleKgtbtkWK30amdbcc2ZO7I5UBt5teBqQIK+4ubs 7FWdNTzp+VNR/WU+SetxFr0QNoNphB1qLSdQC3V96e+gkNhX1ABZwDi9To7RewiKrmgyvD rRzxkYZGUhWbSyXTFbWjlJ9yJkUhatI= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-653-eYbs7Ut6P_yhmtPGDVGM-w-1; Fri, 21 Feb 2025 12:04:04 -0500 X-MC-Unique: eYbs7Ut6P_yhmtPGDVGM-w-1 X-Mimecast-MFC-AGG-ID: eYbs7Ut6P_yhmtPGDVGM-w_1740157443 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-38f37b4a72fso1741619f8f.1 for ; Fri, 21 Feb 2025 09:04:04 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740157442; x=1740762242; 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=IDuooerhK1to1+S4hiPVrqtGgOqxZ0Q0ElNK+Nffz5Y=; b=Osw/cwjd5RVJABmwzdjHTgCuQayFDmkwH0jqLCX1BOMH2+CUUQxaqLdJBCy/31DqW4 sW0TeYjHQQ0tpNXov8try0dNEN/QYW/y/dy8ro0cDuhuF48i3F0NZAF2nqVYZDWcABOz B9SCdApshBr9bqXEyUcm+Wjxxiz0m9jRrYVnYxTt+iauOUBUPmR4ISA37VaQZf1mYC1I vLiPB/Lx8c9/9OYo2ZFJtAw3OTEbogoEJ/uGuuxmBnvP+aiUHjyI1WswDdaS4tjFZnYw 3dtT/3ZHcK2UZwm1arovuxrzLixBF1X4mMMmxVaRjDYQnrOjzBlY9tLNBAHstuAIwQ0y tQhg== X-Gm-Message-State: AOJu0YxM5i6X2ce56nkPhm0GLhLx4P3f0W6uHgBRBbcchTlfP+AAvgP5 mCYG83SFQlkJe9ebp0JWJvIWG0/u8JYxdy0W6W87aHsEjutKavBsEA7cgqne3otAI37Kiiflt5a uAG5Eait0z4O9PiQ13Ir9HuNEafcxQoXTicXGH1135nhppYpkf/V8MvlpcMPl5XmkY8uRIlTF+Q MINmm4Uc9EAetlAkXe47C32IixvvLlm5fj+KwAFA8= X-Gm-Gg: ASbGncsmZGDBv+EDBguOnrATdOp2A8nvGvpG80/A5v9+28AoLweeFNpj75r0nDTcOJ1 0zqD+l52RI/knNY9IhjItDFRJL6LKUuvu9zF+FKSx1+EnmM/+5ZtQbjrKvmb9QmqB3Aq4JG2i9w jaskjB+eifMVDbaGjxBkUGT0bkME9bHQr7ppKElfOUVALCbYeN3jTMEn/QfHGBNJ2zIM9xOFBqp MZmoQ7oLV64uNExTjoP9uWxVcpuWo70JvqMbsdJ+mMu//5G5NomZLVx2+nxRn8j/FrYgUsjfL6F PXxAWsglBeordxAJj7Y= X-Received: by 2002:a05:6000:1ac7:b0:38d:ae1e:2f3c with SMTP id ffacd0b85a97d-38f6f51db2cmr3652613f8f.25.1740157439997; Fri, 21 Feb 2025 09:03:59 -0800 (PST) X-Google-Smtp-Source: AGHT+IGjpFHc9uvNj7Nbzsa/WYamQ7zWK2mxWvP3dv2m49lIeaql26yFVY109MkBPpNu0D31mt2JuA== X-Received: by 2002:a05:6000:1ac7:b0:38d:ae1e:2f3c with SMTP id ffacd0b85a97d-38f6f51db2cmr3652419f8f.25.1740157437844; Fri, 21 Feb 2025 09:03:57 -0800 (PST) Received: from [192.168.10.48] ([151.95.61.185]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f258b4314sm23666248f8f.9.2025.02.21.09.03.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Feb 2025 09:03:56 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: qemu-rust@nongnu.org Subject: [PATCH 06/15] rust: cell: add wrapper for FFI types Date: Fri, 21 Feb 2025 18:03:33 +0100 Message-ID: <20250221170342.63591-7-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250221170342.63591-1-pbonzini@redhat.com> References: <20250221170342.63591-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.424, 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_H5=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 Inspired by the same-named type in Linux. This type provides the compiler with a correct view of what goes on with FFI types. In addition, it separates the glue code from the bindgen-generated code, allowing traits such as Send, Sync or Zeroable to be specified independently for C and Rust structs. Signed-off-by: Paolo Bonzini --- docs/devel/rust.rst | 34 +++++-- rust/qemu-api/src/cell.rs | 191 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 210 insertions(+), 15 deletions(-) diff --git a/docs/devel/rust.rst b/docs/devel/rust.rst index e3f9e16aacb..9a621648e72 100644 --- a/docs/devel/rust.rst +++ b/docs/devel/rust.rst @@ -295,15 +295,33 @@ of ``&mut self``; access to internal fields must use *interior mutability* to go from a shared reference to a ``&mut``. Whenever C code provides you with an opaque ``void *``, avoid converting it -to a Rust mutable reference, and use a shared reference instead. Rust code -will then have to use QEMU's ``BqlRefCell`` and ``BqlCell`` type, which -enforce that locking rules for the "Big QEMU Lock" are respected. These cell -types are also known to the ``vmstate`` crate, which is able to "look inside" -them when building an in-memory representation of a ``struct``'s layout. -Note that the same is not true of a ``RefCell`` or ``Mutex``. +to a Rust mutable reference, and use a shared reference instead. The +``qemu_api::cell`` module provides wrappers that can be used to tell the +Rust compiler about interior mutability, and optionally to enforce locking +rules for the "Big QEMU Lock". In the future, similar cell types might +also be provided for ``AioContext``-based locking as well. -In the future, similar cell types might also be provided for ``AioContext``-based -locking as well. +In particular, device code will usually rely on the ``BqlRefCell`` and +``BqlCell`` type to ensure that data is accessed correctly under the +"Big QEMU Lock". These cell types are also known to the ``vmstate`` +crate, which is able to "look inside" them when building an in-memory +representation of a ``struct``'s layout. Note that the same is not true +of a ``RefCell`` or ``Mutex``. + +Bindings code instead will usually use the ``Opaque`` type, which hides +the contents of the underlying struct and can be easily converted to +a raw pointer, for use in calls to C functions. It can be used for +example as follows:: + + #[repr(transparent)] + #[derive(Debug)] + pub struct Object(Opaque); + +The bindings will then manually check for the big QEMU lock with +assertions, which allows the wrapper to be declared thread-safe:: + + unsafe impl Send for Object {} + unsafe impl Sync for Object {} Writing bindings to C code '''''''''''''''''''''''''' diff --git a/rust/qemu-api/src/cell.rs b/rust/qemu-api/src/cell.rs index eae4e2ce786..84b9eb07467 100644 --- a/rust/qemu-api/src/cell.rs +++ b/rust/qemu-api/src/cell.rs @@ -27,7 +27,7 @@ // IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -//! BQL-protected mutable containers. +//! QEMU-specific mutable containers //! //! Rust memory safety is based on this rule: Given an object `T`, it is only //! possible to have one of the following: @@ -43,8 +43,10 @@ //! usually have their pointer shared with the "outside world very early in //! their lifetime", for example when they create their //! [`MemoryRegion`s](crate::bindings::MemoryRegion). Therefore, individual -//! parts of a device must be made mutable in a controlled manner through the -//! use of cell types. +//! parts of a device must be made mutable in a controlled manner; this module +//! provides the tools to do so. +//! +//! ## Cell types //! //! [`BqlCell`] and [`BqlRefCell`] allow doing this via the Big QEMU Lock. //! While they are essentially the same single-threaded primitives that are @@ -71,7 +73,7 @@ //! QEMU device implementations is usually incorrect and can lead to //! thread-safety issues. //! -//! ## `BqlCell` +//! ### `BqlCell` //! //! [`BqlCell`] implements interior mutability by moving values in and out of //! the cell. That is, an `&mut T` to the inner value can never be obtained as @@ -91,7 +93,7 @@ //! - [`set`](BqlCell::set): this method replaces the interior value, //! dropping the replaced value. //! -//! ## `BqlRefCell` +//! ### `BqlRefCell` //! //! [`BqlRefCell`] uses Rust's lifetimes to implement "dynamic borrowing", a //! process whereby one can claim temporary, exclusive, mutable access to the @@ -111,13 +113,82 @@ //! Multiple immutable borrows are allowed via [`borrow`](BqlRefCell::borrow), //! or a single mutable borrow via [`borrow_mut`](BqlRefCell::borrow_mut). The //! thread will panic if these rules are violated or if the BQL is not held. +//! +//! ## Opaque wrappers +//! +//! The cell types from the previous section are useful at the boundaries +//! of code that requires interior mutability. When writing glue code that +//! interacts directly with C structs, however, it is useful to operate +//! at a lower level. +//! +//! C functions often violate Rust's fundamental assumptions about memory +//! safety by modifying memory even if it is shared. Furthermore, C structs +//! often start their life uninitialized and may be populated lazily. +//! +//! For this reason, this module provides the [`Opaque`] type to opt out +//! of Rust's usual guarantees about the wrapped type. Access to the wrapped +//! value is always through raw pointers, obtained via methods like +//! [`as_mut_ptr()`](Opaque::as_mut_ptr) and [`as_ptr()`](Opaque::as_ptr). These +//! pointers can then be passed to C functions or dereferenced; both actions +//! require `unsafe` blocks, making it clear where safety guarantees must be +//! manually verified. For example +//! +//! ```ignore +//! let state = Opaque::::uninit(); +//! unsafe { +//! qemu_struct_init(state.as_mut_ptr()); +//! } +//! ``` +//! +//! [`Opaque`] will usually be wrapped one level further, so that +//! bridge methods can be added to the wrapper: +//! +//! ```ignore +//! pub struct MyStruct(Opaque); +//! +//! impl MyStruct { +//! fn new() -> Pin> { +//! let result = Box::pin(Opaque::uninit()); +//! unsafe { qemu_struct_init(result.as_mut_ptr()) }; +//! result +//! } +//! } +//! ``` +//! +//! This pattern of wrapping bindgen-generated types in [`Opaque`] provides +//! several advantages: +//! +//! * The choice of traits to be implemented is not limited by the +//! bindgen-generated code. For example, [`Drop`] can be added without +//! disabling [`Copy`] on the underlying bindgen type +//! +//! * [`Send`] and [`Sync`] implementations can be controlled by the wrapper +//! type rather than being automatically derived from the C struct's layout +//! +//! * Methods can be implemented in a separate crate from the bindgen-generated +//! bindings +//! +//! * [`Debug`](std::fmt::Debug) and [`Display`](std::fmt::Display) +//! implementations can be customized to be more readable than the raw C +//! struct representation +//! +//! The [`Opaque`] type does not include BQL validation; it is possible to +//! assert in the code that the right lock is taken, to use it together +//! with a custom lock guard type, or to let C code take the lock, as +//! appropriate. It is also possible to use it with non-thread-safe +//! types, since by default (unlike [`BqlCell`] and [`BqlRefCell`] +//! it is neither `Sync` nor `Send`. +//! +//! While [`Opaque`] is necessary for C interop, it should be used sparingly +//! and only at FFI boundaries. For QEMU-specific types that need interior +//! mutability, prefer [`BqlCell`] or [`BqlRefCell`]. use std::{ cell::{Cell, UnsafeCell}, cmp::Ordering, fmt, - marker::PhantomData, - mem, + marker::{PhantomData, PhantomPinned}, + mem::{self, MaybeUninit}, ops::{Deref, DerefMut}, ptr::NonNull, }; @@ -840,3 +911,109 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { (**self).fmt(f) } } + +/// Stores an opaque value that is shared with C code. +/// +/// Often, C structs can changed when calling a C function even if they are +/// behind a shared Rust reference, or they can be initialized lazily and have +/// invalid bit patterns (e.g. `3` for a [`bool`]). This goes against Rust's +/// strict aliasing rules, which normally prevent mutation through shared +/// references. +/// +/// Wrapping the struct with `Opaque` ensures that the Rust compiler does not +/// assume the usual constraints that Rust structs require, and allows using +/// shared references on the Rust side. +/// +/// `Opaque` is `#[repr(transparent)]`, so that it matches the memory layout +/// of `T`. +#[repr(transparent)] +pub struct Opaque { + value: UnsafeCell>, + // PhantomPinned also allows multiple references to the `Opaque`, i.e. + // one `&mut Opaque` can coexist with a `&mut T` or any number of `&T`; + // see https://docs.rs/pinned-aliasable/latest/pinned_aliasable/. + _pin: PhantomPinned, +} + +impl Opaque { + /// Creates a new shared reference from a C pointer + /// + /// # Safety + /// + /// The pointer must be valid, though it need not point to a valid value. + pub unsafe fn from_raw<'a>(ptr: *mut T) -> &'a Self { + let ptr = NonNull::new(ptr).unwrap().cast::(); + // SAFETY: Self is a transparent wrapper over T + unsafe { ptr.as_ref() } + } + + /// Creates a new opaque object with uninitialized contents. + /// + /// # Safety + /// + /// Ultimately the pointer to the returned value will be dereferenced + /// in another unsafe block, for example when passing it to a C function. + /// However, this function is unsafe to "force" documenting who is going + /// to initialize and pin the value. + pub const unsafe fn uninit() -> Self { + Self { + value: UnsafeCell::new(MaybeUninit::uninit()), + _pin: PhantomPinned, + } + } + + /// Creates a new opaque object with zeroed contents. + /// + /// # Safety + /// + /// Ultimately the pointer to the returned value will be dereferenced + /// in another unsafe block, for example when passing it to a C function. + /// However, this function is unsafe to "force" documenting whether a + /// zero value is safe. + pub const unsafe fn zeroed() -> Self { + Self { + value: UnsafeCell::new(MaybeUninit::uninit()), + _pin: PhantomPinned, + } + } + + /// Returns a raw pointer to the opaque data. + pub const fn as_mut_ptr(&self) -> *mut T { + UnsafeCell::get(&self.value).cast() + } + + /// Returns a raw pointer to the opaque data. + pub const fn as_ptr(&self) -> *const T { + self.as_mut_ptr() as *const _ + } + + /// Returns a raw pointer to the opaque data. + pub const fn as_void_ptr(&self) -> *mut std::ffi::c_void { + UnsafeCell::get(&self.value).cast() + } +} + +impl fmt::Debug for Opaque { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut name: String = "Opaque<".to_string(); + name += std::any::type_name::(); + name += ">"; + f.debug_tuple(&name).field(&self.as_ptr()).finish() + } +} + +impl Default for Opaque { + fn default() -> Self { + Self { + value: UnsafeCell::new(MaybeUninit::new(T::default())), + _pin: PhantomPinned, + } + } +} + +impl Opaque { + /// Creates a new opaque object with default contents. + pub fn new() -> Self { + Self::default() + } +} From patchwork Fri Feb 21 17:03:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13986076 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 375F7C021B3 for ; Fri, 21 Feb 2025 17:06:32 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tlWRi-0007IO-Ro; Fri, 21 Feb 2025 12:04:15 -0500 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 1tlWRd-0006xM-V8 for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:10 -0500 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 1tlWRb-0001S4-U6 for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:09 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1740157447; 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=gNzmdewlktR1o4K/cScPLtSavMlzl0xOpm3FGIzKcy0=; b=Y7SABWXXW63K+9e2dCAg1OGOhUl7Kd/HivTifnZRQhPP8KJdoTR+IoZ6K7CM4J+q+ODzPd e5bwuRlDrlxJ4Hm588G01tsUpljzMjJN/xg4Xz6zpxvet+ttEpGT0n2BWbDZxNhJDI1/h3 6DQ/C55OFbakHVhvOHpfKa1DSnVuhfk= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-57-5VMpccZcNIOP1359bFSllg-1; Fri, 21 Feb 2025 12:04:05 -0500 X-MC-Unique: 5VMpccZcNIOP1359bFSllg-1 X-Mimecast-MFC-AGG-ID: 5VMpccZcNIOP1359bFSllg_1740157444 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-38f36f03312so1130563f8f.3 for ; Fri, 21 Feb 2025 09:04:05 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740157443; x=1740762243; 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=gNzmdewlktR1o4K/cScPLtSavMlzl0xOpm3FGIzKcy0=; b=B30FVP+ATqku6LI89/L9BV56zV+NE/EauEeV/VmiXT5kQTQxZIwrVPOuWAV1Pm8x31 fxqd5rZFaUnEIOQEGpGX2vK77YwANQ/s2rf8gSvk2rU0nASHcPXX1yFtxhmgq45afZLZ wTDZu4CL7Qo0U3/CvitwpOaz8aU39k8vWphVi4Pe7BTXc/+1qVLyKgoiXnWGQ0Jrm6+8 WlTE1lUDuQ/u5LjTE19EjMW9MsGFRsbuWBD66TO34MT2VBhenVek5cn6FvAUMsVvjxSk 57fP5madiztVxxlljbxR7xPBQAEYdREknNdF0gYYxQxSuTXIohd++8DoCg+yvaR61zyS 6Swg== X-Gm-Message-State: AOJu0YwQB/HAN+tfdAGuhTeaXtafsNMpBMvJwJHf1w9YcwfjFuqdDz9e RPyza9rZFTs4rI1fh0JIr6mqclbgbu9q4w+hhcznzDfpGudB6uwducTikDFbfPzzHoa6787kFmg m8fhRwb4oxaMzfp7/TETlZtFE7a+jvFqNOirS+7/P6pMxnhXwtiG19Iq8gwkk/J5/nXc9ewMMF4 A/AZkoB3DzUNZEzsvQAR/HGfhymeTxW2vL4ijWIUg= X-Gm-Gg: ASbGncvd76IoHwIagCpvFR05UttnVFSLtlICWMOT5lPBwUc+rY8Y/EtDfU13EW7D3Yz fhBc4E+JGOVA3CqkdWb8zVFihZiLyd1UN7G7/28kRXZjAV8H3+OkACzNa3mlxmltxD7+kL6kSWs 5nsVcElxVUIHk+p4dLB8Np/0EPs/Zj0xJahbiUY1dd77EgqcuxSjoUYhwbA3wggzptf5YTSbHNm wLUKAyac9PNr+cc4V6C2N9ZcpnmYRKIxYupkE0AtRzc9UrLXLmaQLdxGSyMZfS7XpTfAA+STpFT lVZxYojr6MtJB5gCYcQ= X-Received: by 2002:a05:6000:144a:b0:38d:e092:3ced with SMTP id ffacd0b85a97d-38f6e7579e0mr2240550f8f.7.1740157441411; Fri, 21 Feb 2025 09:04:01 -0800 (PST) X-Google-Smtp-Source: AGHT+IHFIfNlkw2aTy/ScMYSgifoXhFGn8mMiTLNr3x9N+9gX7sv64GeERh/Ti9Kx0/Z/bQw7ou7CQ== X-Received: by 2002:a05:6000:144a:b0:38d:e092:3ced with SMTP id ffacd0b85a97d-38f6e7579e0mr2240433f8f.7.1740157439353; Fri, 21 Feb 2025 09:03:59 -0800 (PST) Received: from [192.168.10.48] ([151.95.61.185]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259f8273sm23366483f8f.89.2025.02.21.09.03.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Feb 2025 09:03:58 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: qemu-rust@nongnu.org Subject: [PATCH 07/15] rust: qemu_api_macros: add Wrapper derive macro Date: Fri, 21 Feb 2025 18:03:34 +0100 Message-ID: <20250221170342.63591-8-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250221170342.63591-1-pbonzini@redhat.com> References: <20250221170342.63591-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.424, 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_H5=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=unavailable 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 derive macro that makes it easy to peel off all the layers of specialness (UnsafeCell, MaybeUninit, etc.) and just get a pointer to the wrapped type; and likewise add them back starting from a *mut. Signed-off-by: Paolo Bonzini --- docs/devel/rust.rst | 8 ++-- rust/qemu-api-macros/src/lib.rs | 82 ++++++++++++++++++++++++++++++++- rust/qemu-api/meson.build | 7 +-- rust/qemu-api/src/cell.rs | 31 +++++++++++++ 4 files changed, 119 insertions(+), 9 deletions(-) diff --git a/docs/devel/rust.rst b/docs/devel/rust.rst index 9a621648e72..db2b427ebd2 100644 --- a/docs/devel/rust.rst +++ b/docs/devel/rust.rst @@ -314,11 +314,13 @@ a raw pointer, for use in calls to C functions. It can be used for example as follows:: #[repr(transparent)] - #[derive(Debug)] + #[derive(Debug, qemu_api_macros::Wrapper)] pub struct Object(Opaque); -The bindings will then manually check for the big QEMU lock with -assertions, which allows the wrapper to be declared thread-safe:: +where the special ``derive`` macro provides useful methods such as +``from_raw``, ``as_ptr`` and ``as_mut_ptr``. The bindings will then +manually check for the big QEMU lock with assertions, which allows +the wrapper to be declared thread-safe:: unsafe impl Send for Object {} unsafe impl Sync for Object {} diff --git a/rust/qemu-api-macros/src/lib.rs b/rust/qemu-api-macros/src/lib.rs index 7ec218202f4..781e5271562 100644 --- a/rust/qemu-api-macros/src/lib.rs +++ b/rust/qemu-api-macros/src/lib.rs @@ -6,7 +6,7 @@ use quote::quote; use syn::{ parse_macro_input, parse_quote, punctuated::Punctuated, spanned::Spanned, token::Comma, Data, - DeriveInput, Field, Fields, Ident, Meta, Path, Token, Type, Variant, Visibility, + DeriveInput, Field, Fields, FieldsUnnamed, Ident, Meta, Path, Token, Type, Variant, Visibility, }; mod utils; @@ -33,6 +33,35 @@ fn get_fields<'a>( } } +fn get_unnamed_field<'a>(input: &'a DeriveInput, msg: &str) -> Result<&'a Field, MacroError> { + if let Data::Struct(s) = &input.data { + let unnamed = match &s.fields { + Fields::Unnamed(FieldsUnnamed { + unnamed: ref fields, + .. + }) => fields, + _ => { + return Err(MacroError::Message( + format!("Tuple struct required for {}", msg), + s.fields.span(), + )) + } + }; + if unnamed.len() != 1 { + return Err(MacroError::Message( + format!("A single field is required for {}", msg), + s.fields.span(), + )); + } + Ok(&unnamed[0]) + } else { + Err(MacroError::Message( + format!("Struct required for {}", msg), + input.ident.span(), + )) + } +} + fn is_c_repr(input: &DeriveInput, msg: &str) -> Result<(), MacroError> { let expected = parse_quote! { #[repr(C)] }; @@ -46,6 +75,19 @@ fn is_c_repr(input: &DeriveInput, msg: &str) -> Result<(), MacroError> { } } +fn is_transparent_repr(input: &DeriveInput, msg: &str) -> Result<(), MacroError> { + let expected = parse_quote! { #[repr(transparent)] }; + + if input.attrs.iter().any(|attr| attr == &expected) { + Ok(()) + } else { + Err(MacroError::Message( + format!("#[repr(transparent)] required for {}", msg), + input.ident.span(), + )) + } +} + fn derive_object_or_error(input: DeriveInput) -> Result { is_c_repr(&input, "#[derive(Object)]")?; @@ -72,6 +114,44 @@ pub fn derive_object(input: TokenStream) -> TokenStream { TokenStream::from(expanded) } +fn derive_opaque_or_error(input: DeriveInput) -> Result { + is_transparent_repr(&input, "#[derive(Wrapper)]")?; + + let name = &input.ident; + let field = &get_unnamed_field(&input, "#[derive(Wrapper)]")?; + let typ = &field.ty; + + // TODO: how to add "::qemu_api"? For now, this is only used in the + // qemu_api crate so it's not a problem. + Ok(quote! { + unsafe impl crate::cell::Wrapper for #name { + type Wrapped = <#typ as crate::cell::Wrapper>::Wrapped; + } + impl #name { + pub unsafe fn from_raw<'a>(ptr: *mut ::Wrapped) -> &'a Self { + let ptr = ::std::ptr::NonNull::new(ptr).unwrap().cast::(); + unsafe { ptr.as_ref() } + } + + pub const fn as_mut_ptr(&self) -> *mut ::Wrapped { + self.0.as_mut_ptr() + } + + pub const fn as_ptr(&self) -> *const ::Wrapped { + self.0.as_ptr() + } + } + }) +} + +#[proc_macro_derive(Wrapper)] +pub fn derive_opaque(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + let expanded = derive_opaque_or_error(input).unwrap_or_else(Into::into); + + TokenStream::from(expanded) +} + #[rustfmt::skip::macros(quote)] fn derive_offsets_or_error(input: DeriveInput) -> Result { is_c_repr(&input, "#[derive(offsets)]")?; diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build index bcf1cf780f3..6e52c4bad74 100644 --- a/rust/qemu-api/meson.build +++ b/rust/qemu-api/meson.build @@ -42,16 +42,13 @@ _qemu_api_rs = static_library( override_options: ['rust_std=2021', 'build.rust_std=2021'], rust_abi: 'rust', rust_args: _qemu_api_cfg, - dependencies: libc_dep, + dependencies: [libc_dep, qemu_api_macros], ) rust.test('rust-qemu-api-tests', _qemu_api_rs, suite: ['unit', 'rust']) -qemu_api = declare_dependency( - link_with: _qemu_api_rs, - dependencies: qemu_api_macros, -) +qemu_api = declare_dependency(link_with: _qemu_api_rs) # Rust executables do not support objects, so add an intermediate step. rust_qemu_api_objs = static_library( diff --git a/rust/qemu-api/src/cell.rs b/rust/qemu-api/src/cell.rs index 84b9eb07467..c39b9616969 100644 --- a/rust/qemu-api/src/cell.rs +++ b/rust/qemu-api/src/cell.rs @@ -1017,3 +1017,34 @@ pub fn new() -> Self { Self::default() } } + +/// Annotates [`Self`] as a transparent wrapper for another type. +/// +/// Usually defined via the [`qemu_api_macros::Wrapper`] derive macro. +/// +/// # Examples +/// +/// ``` +/// # use std::mem::ManuallyDrop; +/// # use qemu_api::cell::Wrapper; +/// #[repr(transparent)] +/// pub struct Example { +/// inner: ManuallyDrop, +/// } +/// +/// unsafe impl Wrapper for Example { +/// type Wrapped = String; +/// } +/// ``` +/// +/// # Safety +/// +/// `Self` must be a `#[repr(transparent)]` wrapper for the `Wrapped` type, +/// whether directly or indirectly. +pub unsafe trait Wrapper { + type Wrapped; +} + +unsafe impl Wrapper for Opaque { + type Wrapped = T; +} From patchwork Fri Feb 21 17:03:35 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13986062 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 478FBC021B3 for ; Fri, 21 Feb 2025 17:05:23 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tlWRm-0007ay-4v; Fri, 21 Feb 2025 12:04:20 -0500 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 1tlWRe-0006yy-W7 for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:11 -0500 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 1tlWRc-0001SA-3q for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:10 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1740157447; 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=5KajmiXkvjrUlRNrAa7EleOjJePFNbnltU4TduUDEJc=; b=ASitGiMwpc3yKzvZMiJT1ESqf1DMpvblYvsYwJwOQO2CJV80YA8UqM6pyNw6LodXyXQOct jD1C8edppgGPyCqk8amUDewuZUPDzALFSPrPV+epLfwbAAySSj3cNg0cQnaJcCJpMDB5bz Wxavfs94EhjKU8kn5egl3j6ayZXzKDQ= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-595-PR21IyH8OtOYt0mb-iSWdg-1; Fri, 21 Feb 2025 12:04:03 -0500 X-MC-Unique: PR21IyH8OtOYt0mb-iSWdg-1 X-Mimecast-MFC-AGG-ID: PR21IyH8OtOYt0mb-iSWdg_1740157442 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-38f2f438fb6so2734315f8f.1 for ; Fri, 21 Feb 2025 09:04:02 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740157441; x=1740762241; 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=5KajmiXkvjrUlRNrAa7EleOjJePFNbnltU4TduUDEJc=; b=Jf1jkG8TJIbWAozsqW3ZB4VFtruQujbsNmukbQyCPg2Hhv8CCpAQzk/b6+Zm2fnBtn CqO+KZaMlN+2OgBWa3S8aQX+CfLUGnAxLZYp1IQZwTwwSPjARNGuxmTVFSBrg9YKbT1v YxJ8scaiOr/YgjbS4DFvbBqQrU4S5p+ECcgfrAMcym/Y9v86y7qFiOpahJqaQ//qTND9 ziT0STpskczVzVK/tWXafNWyvI7ml1RIH47EPYcrVuDyJxW+vJRw4/XZc49eKBlzKrbT L0uACcj7hceCdTWFDN1y6mdFaAB8P9dNRznk29o+0VolK0QlnZjkiJI35jQcUW9Rar4R 2JEg== X-Gm-Message-State: AOJu0YzZpc31/NL+c/Y2jOj3gf/fDh1zQRsnKcPc9jF/CoO8QmN8N2HI acC0HyyVjEMHRqpFQaAJUerMoeA+fe9R1nIa/X6aE6fmhTEMGZ3EKQbLCLhd5n4tiAsudpi+8P4 WjQW1vthLQnIaZMhDP7SQVFmkmCm2VmrxzsLpJX6b9RamHwfVGh9Bxy7+K67tjzrm2AMWQhoS34 gf/I5Hcz4BbVosqXfwhGAKTN4HeNBte5J1xvGFgGQ= X-Gm-Gg: ASbGncsmdkTHzJptPsmgt5Ph6Nikc9qHFsxVgnNBdLxWVxilWO8bqJR2QEVJsah84rj YbSPxucBvXvmPCOckI49W4xUYNx5fES6IaW0+2RiN0wcsl+7Hma+jOOLnaM4F5BhktCyTRIKt03 N3k9Yul3dkQNnWD7ylBOf7E/4PPi4+NsRmWqtBdIORZFCojm1QyyCVP1Hd/5GAcD9uP/3G6Zp6Z LqCxB1jQSLlZ0nr5lnWwdRhmbPFJvAVpTn50CE4Rb3itNIuUuYp7QHHU7w5Buumg4msdmTfwVFx z6cffV4diKWwr58vmQs= X-Received: by 2002:a5d:59ad:0:b0:38f:30c7:eae4 with SMTP id ffacd0b85a97d-38f6f0c289emr3369804f8f.52.1740157441240; Fri, 21 Feb 2025 09:04:01 -0800 (PST) X-Google-Smtp-Source: AGHT+IE1Rqw5HLoCQNAcp/eBta75SgW0yjnziketJS8tDJpcLwitcrgIL/4Kh4z5OBz53O2IsmHRWw== X-Received: by 2002:a5d:59ad:0:b0:38f:30c7:eae4 with SMTP id ffacd0b85a97d-38f6f0c289emr3369718f8f.52.1740157440502; Fri, 21 Feb 2025 09:04:00 -0800 (PST) Received: from [192.168.10.48] ([151.95.61.185]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-439b02f252dsm22580065e9.22.2025.02.21.09.03.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Feb 2025 09:04:00 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: qemu-rust@nongnu.org Subject: [PATCH 08/15] rust: timer: wrap QEMUTimer with Opaque<> Date: Fri, 21 Feb 2025 18:03:35 +0100 Message-ID: <20250221170342.63591-9-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250221170342.63591-1-pbonzini@redhat.com> References: <20250221170342.63591-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.424, 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_H5=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=unavailable 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 Signed-off-by: Paolo Bonzini --- meson.build | 7 ------- rust/qemu-api/src/timer.rs | 24 +++++++++++++++++------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/meson.build b/meson.build index 8ed10b6624e..16c76c493f3 100644 --- a/meson.build +++ b/meson.build @@ -4087,13 +4087,6 @@ if have_rust foreach enum : c_bitfields bindgen_args += ['--bitfield-enum', enum] endforeach - c_nocopy = [ - 'QEMUTimer', - ] - # Used to customize Drop trait - foreach struct : c_nocopy - bindgen_args += ['--no-copy', struct] - endforeach # TODO: Remove this comment when the clang/libclang mismatch issue is solved. # diff --git a/rust/qemu-api/src/timer.rs b/rust/qemu-api/src/timer.rs index a593538917a..0305a0385ad 100644 --- a/rust/qemu-api/src/timer.rs +++ b/rust/qemu-api/src/timer.rs @@ -7,10 +7,23 @@ use crate::{ bindings::{self, qemu_clock_get_ns, timer_del, timer_init_full, timer_mod, QEMUClockType}, callbacks::FnCall, + cell::Opaque, }; -pub type Timer = bindings::QEMUTimer; -pub type TimerListGroup = bindings::QEMUTimerListGroup; +/// A safe wrapper around [`bindings::QEMUTimer`]. +#[repr(transparent)] +#[derive(Debug, Default, qemu_api_macros::Wrapper)] +pub struct Timer(Opaque); + +unsafe impl Send for Timer {} +unsafe impl Sync for Timer {} + +#[repr(transparent)] +#[derive(qemu_api_macros::Wrapper)] +pub struct TimerListGroup(Opaque); + +unsafe impl Send for TimerListGroup {} +unsafe impl Sync for TimerListGroup {} impl Timer { pub const MS: u32 = bindings::SCALE_MS; @@ -21,10 +34,6 @@ pub fn new() -> Self { Default::default() } - const fn as_mut_ptr(&self) -> *mut Self { - self as *const Timer as *mut _ - } - pub fn init_full<'timer, 'opaque: 'timer, T, F>( &'timer mut self, timer_list_group: Option<&TimerListGroup>, @@ -51,7 +60,7 @@ pub fn init_full<'timer, 'opaque: 'timer, T, F>( // SAFETY: the opaque outlives the timer unsafe { timer_init_full( - self, + self.as_mut_ptr(), if let Some(g) = timer_list_group { g as *const TimerListGroup as *mut _ } else { @@ -75,6 +84,7 @@ pub fn delete(&self) { } } +// FIXME: use something like PinnedDrop from the pinned_init crate impl Drop for Timer { fn drop(&mut self) { self.delete() From patchwork Fri Feb 21 17:03:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13986057 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 50F42C021B3 for ; Fri, 21 Feb 2025 17:04:28 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tlWRl-0007Wa-5X; Fri, 21 Feb 2025 12:04:17 -0500 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 1tlWRi-0007H0-7G for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:14 -0500 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 1tlWRg-0001TU-20 for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1740157451; 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=ptln7kC4VQ55Kh7p6OYpuJx9dpz1kCK9KqyudGJngSI=; b=LEIdMg34iOcZ7RGUDOwuVdUI+6guYG8Gt4MtjfGJ/Q3yNo6NcV3TD8NoKGit+LKJuyAyiL J1khO2HzPDZAYNqiyh7iRsBjbXK6R6fOiKK76+wnEvFQ5varO34LK35oJG5kssGgRENmPQ eenOsR7aT3gY0ctJ1/rBq2Aw0qKIc4A= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-592-9XF-9xH5MmK7xmNNdEl6BA-1; Fri, 21 Feb 2025 12:04:09 -0500 X-MC-Unique: 9XF-9xH5MmK7xmNNdEl6BA-1 X-Mimecast-MFC-AGG-ID: 9XF-9xH5MmK7xmNNdEl6BA_1740157448 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-43942e82719so15904815e9.2 for ; Fri, 21 Feb 2025 09:04:09 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740157447; x=1740762247; 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=ptln7kC4VQ55Kh7p6OYpuJx9dpz1kCK9KqyudGJngSI=; b=tCyBFzzdzz7lxpscndfjbTr/TxHqRTytR+VQJcTkRRESeA6uGwy9IMy2F5g1xl/R5o OIp0vrE5rRovZzPPCJrCLJSP05tNQxhU8aAmiYQgnMhJI3Wv9ntHmRI7yxtTaOH6Okia PTqFxBjxq4+3/FuAWzU8no2eMy5xg3Nm7tzYLtVRBGcF/EWOf8ArhU4W/b6o4XrV57qZ dfyAYgdDo8HCvDHU3e5gYGF3jgWnDdxGUXI8J1pn9feUZEK3OYMOl6IUOUbJasCc8mT1 3zRGH8dyd+KvvU3GD9hVTP5urIa7xFjK90lQitoWQ41C0YpIXwncGxvvEc4aEYlmGBDH YJ4g== X-Gm-Message-State: AOJu0YwiH8ZHB7aQQLn3o8tnFjAvODDZeAFpsf0UIiVsiNuNA7otpTns zM4t7DHYWLCJ732/xKcqEugQpFOTfKTOuEiGlk8v2CZcnhcL4NJlgj1g3HYtsxb1u073xJvlNFg jEaRVOTESFo3t4/ygu49yWiOmnfl56kdbGp5AxPSHN0We2gBmRgcRarIssxBrmu9W48mDLFsLAP zRRdl/3P8tHK3OQJEHTgXIM/Xx3eRs4TGonO4Q2a8= X-Gm-Gg: ASbGncuv1vfKkyrhocRmNq5FAiaefExgIeQnIHQgc6JJsJqAfthPCrGhFZkaPXFlruJ 79Qs8NfjTigwl5aEcPpp/YhyQzrXBugoXvk8oyyf4n5GH0kWPJJQ0J1k10bL5MdILwPNzZwsIRL ywoFdRpC8enSeiLfUy8XKE0+VmgF4UsdUnQhUJNqwQysCxP41DuSpwoMyjjnijFfPLHwZG1qrtV OaaapK+2SyZRYmZqxb3MzpwYk64Jt0EwgyR9RPqFHTxbVD7XcxBL6rwR5fgxETE5+u/iGg+ctbs IkeubuSURQZrhHHq34s= X-Received: by 2002:a05:600c:1c9d:b0:439:88bb:d02f with SMTP id 5b1f17b1804b1-439b1b7fdfamr27090305e9.5.1740157446934; Fri, 21 Feb 2025 09:04:06 -0800 (PST) X-Google-Smtp-Source: AGHT+IE5lQklDkjGCKQ5dzNMU7dIqrOWUiGmo7zLHwx/J7q+hv1FUD3/VB0Q4LzK4MqDgH6vbWTClQ== X-Received: by 2002:a05:600c:1c9d:b0:439:88bb:d02f with SMTP id 5b1f17b1804b1-439b1b7fdfamr27089635e9.5.1740157446414; Fri, 21 Feb 2025 09:04:06 -0800 (PST) Received: from [192.168.10.48] ([151.95.61.185]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f258b44b2sm23583763f8f.20.2025.02.21.09.04.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Feb 2025 09:04:01 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: qemu-rust@nongnu.org Subject: [PATCH 09/15] rust: irq: wrap IRQState with Opaque<> Date: Fri, 21 Feb 2025 18:03:36 +0100 Message-ID: <20250221170342.63591-10-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250221170342.63591-1-pbonzini@redhat.com> References: <20250221170342.63591-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.424, 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 Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/irq.rs | 15 ++++++++++----- rust/qemu-api/src/sysbus.rs | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/rust/qemu-api/src/irq.rs b/rust/qemu-api/src/irq.rs index d1c9dc96eff..aec2825b2f9 100644 --- a/rust/qemu-api/src/irq.rs +++ b/rust/qemu-api/src/irq.rs @@ -9,10 +9,16 @@ use crate::{ bindings::{self, qemu_set_irq}, + cell::Opaque, prelude::*, qom::ObjectClass, }; +/// An opaque wrapper around [`bindings::IRQState`]. +#[repr(transparent)] +#[derive(Debug, qemu_api_macros::Wrapper)] +pub struct IRQState(Opaque); + /// Interrupt sources are used by devices to pass changes to a value (typically /// a boolean). The interrupt sink is usually an interrupt controller or /// GPIO controller. @@ -22,8 +28,7 @@ /// method sends a `true` value to the sink. If the guest has to see a /// different polarity, that change is performed by the board between the /// device and the interrupt controller. -pub type IRQState = bindings::IRQState; - +/// /// Interrupts are implemented as a pointer to the interrupt "sink", which has /// type [`IRQState`]. A device exposes its source as a QOM link property using /// a function such as [`SysBusDeviceMethods::init_irq`], and @@ -41,7 +46,7 @@ pub struct InterruptSource where c_int: From, { - cell: BqlCell<*mut IRQState>, + cell: BqlCell<*mut bindings::IRQState>, _marker: PhantomData, } @@ -80,11 +85,11 @@ pub fn set(&self, level: T) { } } - pub(crate) const fn as_ptr(&self) -> *mut *mut IRQState { + pub(crate) const fn as_ptr(&self) -> *mut *mut bindings::IRQState { self.cell.as_ptr() } - pub(crate) const fn slice_as_ptr(slice: &[Self]) -> *mut *mut IRQState { + pub(crate) const fn slice_as_ptr(slice: &[Self]) -> *mut *mut bindings::IRQState { assert!(!slice.is_empty()); slice[0].as_ptr() } diff --git a/rust/qemu-api/src/sysbus.rs b/rust/qemu-api/src/sysbus.rs index 04821a2b9b3..48803a655f9 100644 --- a/rust/qemu-api/src/sysbus.rs +++ b/rust/qemu-api/src/sysbus.rs @@ -79,6 +79,7 @@ fn mmio_map(&self, id: u32, addr: u64) { fn connect_irq(&self, id: u32, irq: &Owned) { assert!(bql_locked()); let id: i32 = id.try_into().unwrap(); + let irq: &IRQState = irq; unsafe { bindings::sysbus_connect_irq(self.as_mut_ptr(), id, irq.as_mut_ptr()); } From patchwork Fri Feb 21 17:03:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13986075 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 73851C021B3 for ; Fri, 21 Feb 2025 17:05:56 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tlWRs-0007sz-ON; Fri, 21 Feb 2025 12:04:24 -0500 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 1tlWRp-0007jr-IP for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:21 -0500 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 1tlWRn-0001VO-N3 for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:21 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1740157459; 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=kC/cNDLMmEH0ht1LPa/Se/Yyc16GMQBcm6b3VMIbeso=; b=Z+ulD5XSI+eNOMzYptlWidcyL+9bYvE8aqvemWjRWFiD9a/yoaxgYli1k/bXVJ/V8e/EDk dSE5sZOz4h6Of1Q1kVz2r8d6d+LKRPmWgpAQPqFX2X/KN6e7VvtnTeUo2gNDebiO3g1JoF 6W00n6lnXeK4zJg9wcsveON9LZCprL8= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-62-UZzRcB0INhKVk8Ab_QCzNg-1; Fri, 21 Feb 2025 12:04:11 -0500 X-MC-Unique: UZzRcB0INhKVk8Ab_QCzNg-1 X-Mimecast-MFC-AGG-ID: UZzRcB0INhKVk8Ab_QCzNg_1740157451 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-38f36f03312so1130611f8f.3 for ; Fri, 21 Feb 2025 09:04:11 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740157450; x=1740762250; 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=kC/cNDLMmEH0ht1LPa/Se/Yyc16GMQBcm6b3VMIbeso=; b=LRcEaPxKHWBfnH3yheDXxmcrXfg3ajCH4PivSOxAZzG5xMj9Dlzxxidckqq7uhvudd XZw8L3R2vl5vSsjLScyazL4Zmr9UKcx+RsqWK7WERqlZpBxWRM78Bv6uU7pgbq5tizX5 4DPU/a8eJQKF0UW0TjxpB0fHbnnWPjwT76kOYuWg7b0Lun/zgajqF8T9bda7dUDjxhAz r8MQq/JxOZaacZ0b493OcDZyg6RmhjruuOavEOhybBV4+e91v5orb6nYVAqz9Ef4kRJw dGVPa8pcucKlufE2wXYwH3NzZnSP/o4hiM1zetW8w4kdh94kmd2+qwphf9iaKosr5m43 96NQ== X-Gm-Message-State: AOJu0Yx1j5pEzHRulP1ezxUsJ2LB25cY8zwfcE2P2k4ZgjPRIwmRtKx9 caKjIEjclISNIJl4ng2jjZzPBkBTkOVY9ksr2JOA5KTQ8LHBin8z9enBuaz9BwHz1LZ6uBxxY/u QWKQPbRz2vWWrwDMz2n9WxS3Oon69MkJCKY7paYGxbIawM5ldgaJqDnhKipju67C+a6hP2CSxSQ JhUrEVdpyMxnOd8ELyaA9wAqn+ivjeFe5GtxWvca0= X-Gm-Gg: ASbGncvJi4HYpq/M4ooyCLcjemZz4m3nJLTdB174sCzeAojcad2h3w4w04d8uxdaC32 h9iAI5w61GAtZsfFNeq/efJMkdMGwKDqX8ddC5JPexsOuD4cvF0g2X8eyvO/ylwrY6jzGj7hBrG EstopXOEULX2YgHkds6r63LTij5WlVvipqSfXnRfZ4i0TnJK8evvjExl6/3CFlBrPxd8S6S9Rv2 wqggGN0GkU4zotxURpEH73hqeYiUV6RZn0qTlElXMW41cRk25JRp3GIemqLGPlaXu85CN6vEux7 Gf8l/JXzsBvVzIhrLjw= X-Received: by 2002:a5d:4e87:0:b0:38d:a879:4778 with SMTP id ffacd0b85a97d-38f6f0529bbmr3686934f8f.33.1740157450029; Fri, 21 Feb 2025 09:04:10 -0800 (PST) X-Google-Smtp-Source: AGHT+IGB0ekFJz+EyjHY94kBqvTTV49d3AiJxMXN0S82AGo5gezpgP14Ud1X2XRcHXYdQ3+tgA1y1A== X-Received: by 2002:a5d:4e87:0:b0:38d:a879:4778 with SMTP id ffacd0b85a97d-38f6f0529bbmr3686832f8f.33.1740157449232; Fri, 21 Feb 2025 09:04:09 -0800 (PST) Received: from [192.168.10.48] ([151.95.61.185]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f258b44b2sm23583955f8f.20.2025.02.21.09.04.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Feb 2025 09:04:07 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: qemu-rust@nongnu.org Subject: [PATCH 10/15] rust: qom: wrap Object with Opaque<> Date: Fri, 21 Feb 2025 18:03:37 +0100 Message-ID: <20250221170342.63591-11-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250221170342.63591-1-pbonzini@redhat.com> References: <20250221170342.63591-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.424, 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=unavailable 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 Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/bindings.rs | 3 --- rust/qemu-api/src/memory.rs | 2 +- rust/qemu-api/src/qdev.rs | 6 +++--- rust/qemu-api/src/qom.rs | 35 ++++++++++++++++++++++------------- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs index d2868639ff6..be6dd68c09c 100644 --- a/rust/qemu-api/src/bindings.rs +++ b/rust/qemu-api/src/bindings.rs @@ -46,9 +46,6 @@ unsafe impl Sync for MemoryRegion {} unsafe impl Send for ObjectClass {} unsafe impl Sync for ObjectClass {} -unsafe impl Send for Object {} -unsafe impl Sync for Object {} - unsafe impl Send for SysBusDevice {} unsafe impl Sync for SysBusDevice {} diff --git a/rust/qemu-api/src/memory.rs b/rust/qemu-api/src/memory.rs index 682951ab44e..713c494ca2e 100644 --- a/rust/qemu-api/src/memory.rs +++ b/rust/qemu-api/src/memory.rs @@ -157,7 +157,7 @@ unsafe fn do_init_io( let cstr = CString::new(name).unwrap(); memory_region_init_io( slot, - owner.cast::(), + owner.cast::(), ops, owner.cast::(), cstr.as_ptr(), diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs index c136457090c..1a4d1f38762 100644 --- a/rust/qemu-api/src/qdev.rs +++ b/rust/qemu-api/src/qdev.rs @@ -52,7 +52,7 @@ pub trait ResettablePhasesImpl { /// can be downcasted to type `T`. We also expect the device is /// readable/writeable from one thread at any time. unsafe extern "C" fn rust_resettable_enter_fn( - obj: *mut Object, + obj: *mut bindings::Object, typ: ResetType, ) { let state = NonNull::new(obj).unwrap().cast::(); @@ -65,7 +65,7 @@ pub trait ResettablePhasesImpl { /// can be downcasted to type `T`. We also expect the device is /// readable/writeable from one thread at any time. unsafe extern "C" fn rust_resettable_hold_fn( - obj: *mut Object, + obj: *mut bindings::Object, typ: ResetType, ) { let state = NonNull::new(obj).unwrap().cast::(); @@ -78,7 +78,7 @@ pub trait ResettablePhasesImpl { /// can be downcasted to type `T`. We also expect the device is /// readable/writeable from one thread at any time. unsafe extern "C" fn rust_resettable_exit_fn( - obj: *mut Object, + obj: *mut bindings::Object, typ: ResetType, ) { let state = NonNull::new(obj).unwrap().cast::(); diff --git a/rust/qemu-api/src/qom.rs b/rust/qemu-api/src/qom.rs index 5488643a2fd..0bca36336ba 100644 --- a/rust/qemu-api/src/qom.rs +++ b/rust/qemu-api/src/qom.rs @@ -101,16 +101,24 @@ ptr::NonNull, }; -pub use bindings::{Object, ObjectClass}; +pub use bindings::ObjectClass; use crate::{ bindings::{ self, object_class_dynamic_cast, object_dynamic_cast, object_get_class, object_get_typename, object_new, object_ref, object_unref, TypeInfo, }, - cell::bql_locked, + cell::{bql_locked, Opaque}, }; +/// A safe wrapper around [`bindings::Object`]. +#[repr(transparent)] +#[derive(Debug, qemu_api_macros::Wrapper)] +pub struct Object(Opaque); + +unsafe impl Send for Object {} +unsafe impl Sync for Object {} + /// Marker trait: `Self` can be statically upcasted to `P` (i.e. `P` is a direct /// or indirect parent of `Self`). /// @@ -199,7 +207,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { } } -unsafe extern "C" fn rust_instance_init(obj: *mut Object) { +unsafe extern "C" fn rust_instance_init(obj: *mut bindings::Object) { let mut state = NonNull::new(obj).unwrap().cast::(); // SAFETY: obj is an instance of T, since rust_instance_init // is called from QOM core as the instance_init function @@ -209,7 +217,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { } } -unsafe extern "C" fn rust_instance_post_init(obj: *mut Object) { +unsafe extern "C" fn rust_instance_post_init(obj: *mut bindings::Object) { let state = NonNull::new(obj).unwrap().cast::(); // SAFETY: obj is an instance of T, since rust_instance_post_init // is called from QOM core as the instance_post_init function @@ -230,7 +238,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { ::CLASS_INIT(unsafe { klass.as_mut() }) } -unsafe extern "C" fn drop_object(obj: *mut Object) { +unsafe extern "C" fn drop_object(obj: *mut bindings::Object) { // SAFETY: obj is an instance of T, since drop_object is called // from the QOM core function object_deinit() as the instance_finalize // function for class T. Note that while object_deinit() will drop the @@ -280,14 +288,14 @@ pub unsafe trait ObjectType: Sized { /// Return the receiver as an Object. This is always safe, even /// if this type represents an interface. fn as_object(&self) -> &Object { - unsafe { &*self.as_object_ptr() } + unsafe { &*self.as_ptr().cast() } } /// Return the receiver as a const raw pointer to Object. /// This is preferrable to `as_object_mut_ptr()` if a C /// function only needs a `const Object *`. - fn as_object_ptr(&self) -> *const Object { - self.as_ptr().cast() + fn as_object_ptr(&self) -> *const bindings::Object { + self.as_object().as_ptr() } /// Return the receiver as a mutable raw pointer to Object. @@ -297,8 +305,8 @@ fn as_object_ptr(&self) -> *const Object { /// This cast is always safe, but because the result is mutable /// and the incoming reference is not, this should only be used /// for calls to C functions, and only if needed. - unsafe fn as_object_mut_ptr(&self) -> *mut Object { - self.as_object_ptr() as *mut _ + unsafe fn as_object_mut_ptr(&self) -> *mut bindings::Object { + self.as_object().as_mut_ptr() } } @@ -621,7 +629,7 @@ pub trait ObjectImpl: ObjectType + IsA { /// We expect the FFI user of this function to pass a valid pointer that /// can be downcasted to type `T`. We also expect the device is /// readable/writeable from one thread at any time. -unsafe extern "C" fn rust_unparent_fn(dev: *mut Object) { +unsafe extern "C" fn rust_unparent_fn(dev: *mut bindings::Object) { let state = NonNull::new(dev).unwrap().cast::(); T::UNPARENT.unwrap()(unsafe { state.as_ref() }); } @@ -796,8 +804,9 @@ fn new() -> Owned { // SAFETY: the object created by object_new is allocated on // the heap and has a reference count of 1 unsafe { - let obj = &*object_new(Self::TYPE_NAME.as_ptr()); - Owned::from_raw(obj.unsafe_cast::()) + let obj = object_new(Self::TYPE_NAME.as_ptr()); + let obj = Object::from_raw(obj).unsafe_cast::(); + Owned::from_raw(obj) } } } From patchwork Fri Feb 21 17:03:38 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13986064 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 38CD1C021B3 for ; Fri, 21 Feb 2025 17:05:26 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tlWRu-0007yu-4U; Fri, 21 Feb 2025 12:04:26 -0500 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 1tlWRq-0007kW-2K for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:22 -0500 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 1tlWRn-0001VI-3z for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:21 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1740157458; 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=2qAjDlzrSY64BqeVItW5GYtRjxGE8Q/k4KYQ6izQmD4=; b=E8I2nmR72heNeVFs9yMELoDmmIyXjYVgsHFMJKZ0Zd0rGnd9R7xCU3ZtKn+zue+jt/zT/D 0HkyKtQwhF1EetEOcv8GFN3nJvBbY4spclKJajLzwPcykFnu2miu0bebpY0Oi5CN+KH/dO zbres3/+QthDAhQgHmEPS3/CU3y8VI4= Received: from mail-ed1-f69.google.com (mail-ed1-f69.google.com [209.85.208.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-655-WwGzz0EAP--jzrpca_zL8g-1; Fri, 21 Feb 2025 12:04:16 -0500 X-MC-Unique: WwGzz0EAP--jzrpca_zL8g-1 X-Mimecast-MFC-AGG-ID: WwGzz0EAP--jzrpca_zL8g_1740157455 Received: by mail-ed1-f69.google.com with SMTP id 4fb4d7f45d1cf-5e08dfe2283so2137128a12.2 for ; Fri, 21 Feb 2025 09:04:16 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740157455; x=1740762255; 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=2qAjDlzrSY64BqeVItW5GYtRjxGE8Q/k4KYQ6izQmD4=; b=wLcpiycyxEN+W27T8E/rpfJA6ONXnLMKMMPASCmSOofG7p8sqaMnsVVEUlIRrFdWMn WAZC46KBFW8swpjGoDeWPUrpYkAju662xFW92dCMQeLg78idtE3Ml2soqCvrWTGjFE+e +ugWIc6/b3Xn2qYuGCmwyUWbFC9X7hOgRdo5r7XaxDHHeCQvqNKdqlY2mBnS96d2/19/ pgsNTV100vVCIfyKx7JbrTpcFUwl+8l8FKIRIgxcQ0LpquIbtdV+nYjZWe0bWZ+ZMw9c 27ZbxVfxOpw+45158qObX1VVE5maRTlrmA0O1+TSgf0zbh7NNcKpdCLC6SaHc11n5AyD UGjA== X-Gm-Message-State: AOJu0YxkVH1pHs4MdQ4OzkAmAIGo2kXhNYDTICwlUhPilbJJW957JOao DLHx474voANZYbQvuKpfdmRLqkLCvhU8BtZ2zz3Rq9ieHfrO4uLytzo14nKUVk1ZP+Gbed2YGti AC4/tEoy/18zZ7v7r5Fd+1NvmgDWqDifD/4WI6a+JbgiCeCEYMkd6z1PYhMulN+HF447a9KlHnx oo7A/8azdCetWEO5s/Fw0GLOnNumLRzYGkZY90MM4= X-Gm-Gg: ASbGncuhSUlrdLn3yJlxKn2AuFBeFxjCCPNVgbBmr5ttaDGbn9RhLU0FIUjIb4V5wtu 6BXRx/qvW+EGSP1jICP0JZR7OZergliZINF6xPOrKD/AL7hTRwFz1blkWAzW1/JVca+AgtpcogS dz9k9K+D6SVtGQrTSJkeJ454CkTrDHutDzTiP3aWWaEqADxzRvBT9tXefiuz/rjnw1JGvafxrLe cJSu9u5mbRPigHx1Wm+yTBPmqgpp8vK7A6GPDbpNA+QyCXpEynMKHW1Sl7bXvPupn98adq5ZHrG rh/Hp9w+KoX1uDUEzt4= X-Received: by 2002:a05:6402:388c:b0:5e0:7cc4:ec57 with SMTP id 4fb4d7f45d1cf-5e0b7266ba5mr7393983a12.31.1740157454375; Fri, 21 Feb 2025 09:04:14 -0800 (PST) X-Google-Smtp-Source: AGHT+IF33QoOqgmxmc8LVsNCqEn91wuWdiLttrFTLkpybIl0dvb1Oxi7pSLekqxSW/N32BQEskDCgw== X-Received: by 2002:a05:6402:388c:b0:5e0:7cc4:ec57 with SMTP id 4fb4d7f45d1cf-5e0b7266ba5mr7393701a12.31.1740157452298; Fri, 21 Feb 2025 09:04:12 -0800 (PST) Received: from [192.168.10.48] ([151.95.61.185]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5e07464bcc7sm6856043a12.33.2025.02.21.09.04.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Feb 2025 09:04:11 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: qemu-rust@nongnu.org Subject: [PATCH 11/15] rust: qdev: wrap Clock and DeviceState with Opaque<> Date: Fri, 21 Feb 2025 18:03:38 +0100 Message-ID: <20250221170342.63591-12-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250221170342.63591-1-pbonzini@redhat.com> References: <20250221170342.63591-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.424, 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_H5=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 Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/bindings.rs | 6 ---- rust/qemu-api/src/qdev.rs | 68 ++++++++++++++++++++++++----------- rust/qemu-api/src/vmstate.rs | 2 +- 3 files changed, 49 insertions(+), 27 deletions(-) diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs index be6dd68c09c..6e70a75a0e6 100644 --- a/rust/qemu-api/src/bindings.rs +++ b/rust/qemu-api/src/bindings.rs @@ -34,12 +34,6 @@ unsafe impl Sync for CharBackend {} unsafe impl Send for Chardev {} unsafe impl Sync for Chardev {} -unsafe impl Send for Clock {} -unsafe impl Sync for Clock {} - -unsafe impl Send for DeviceState {} -unsafe impl Sync for DeviceState {} - unsafe impl Send for MemoryRegion {} unsafe impl Sync for MemoryRegion {} diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs index 1a4d1f38762..ed5dce08216 100644 --- a/rust/qemu-api/src/qdev.rs +++ b/rust/qemu-api/src/qdev.rs @@ -10,12 +10,12 @@ ptr::NonNull, }; -pub use bindings::{Clock, ClockEvent, DeviceClass, DeviceState, Property, ResetType}; +pub use bindings::{ClockEvent, DeviceClass, Property, ResetType}; use crate::{ bindings::{self, qdev_init_gpio_in, qdev_init_gpio_out, Error, ResettableClass}, callbacks::FnCall, - cell::bql_locked, + cell::{bql_locked, Opaque}, chardev::Chardev, irq::InterruptSource, prelude::*, @@ -23,6 +23,22 @@ vmstate::VMStateDescription, }; +/// A safe wrapper around [`bindings::Clock`]. +#[repr(transparent)] +#[derive(Debug, qemu_api_macros::Wrapper)] +pub struct Clock(Opaque); + +unsafe impl Send for Clock {} +unsafe impl Sync for Clock {} + +/// A safe wrapper around [`bindings::DeviceState`]. +#[repr(transparent)] +#[derive(Debug, qemu_api_macros::Wrapper)] +pub struct DeviceState(Opaque); + +unsafe impl Send for DeviceState {} +unsafe impl Sync for DeviceState {} + /// Trait providing the contents of the `ResettablePhases` struct, /// which is part of the QOM `Resettable` interface. pub trait ResettablePhasesImpl { @@ -117,7 +133,10 @@ fn vmsd() -> Option<&'static VMStateDescription> { /// We expect the FFI user of this function to pass a valid pointer that /// can be downcasted to type `T`. We also expect the device is /// readable/writeable from one thread at any time. -unsafe extern "C" fn rust_realize_fn(dev: *mut DeviceState, _errp: *mut *mut Error) { +unsafe extern "C" fn rust_realize_fn( + dev: *mut bindings::DeviceState, + _errp: *mut *mut Error, +) { let state = NonNull::new(dev).unwrap().cast::(); T::REALIZE.unwrap()(unsafe { state.as_ref() }); } @@ -251,7 +270,7 @@ fn init_clock_in FnCall<(&'a Self::Target, ClockEvent)>>( events: ClockEvent, ) -> Owned { fn do_init_clock_in( - dev: *mut DeviceState, + dev: &DeviceState, name: &str, cb: Option, events: ClockEvent, @@ -265,14 +284,15 @@ fn do_init_clock_in( unsafe { let cstr = CString::new(name).unwrap(); let clk = bindings::qdev_init_clock_in( - dev, + dev.0.as_mut_ptr(), cstr.as_ptr(), cb, - dev.cast::(), + dev.0.as_void_ptr(), events.0, ); - Owned::from(&*clk) + let clk: &Clock = Clock::from_raw(clk); + Owned::from(clk) } } @@ -289,7 +309,7 @@ fn do_init_clock_in( None }; - do_init_clock_in(self.as_mut_ptr(), name, cb, events) + do_init_clock_in(self.upcast(), name, cb, events) } /// Add an output clock named `name`. @@ -304,9 +324,10 @@ fn do_init_clock_in( fn init_clock_out(&self, name: &str) -> Owned { unsafe { let cstr = CString::new(name).unwrap(); - let clk = bindings::qdev_init_clock_out(self.as_mut_ptr(), cstr.as_ptr()); + let clk = bindings::qdev_init_clock_out(self.upcast().as_mut_ptr(), cstr.as_ptr()); - Owned::from(&*clk) + let clk: &Clock = Clock::from_raw(clk); + Owned::from(clk) } } @@ -314,7 +335,11 @@ fn prop_set_chr(&self, propname: &str, chr: &Owned) { assert!(bql_locked()); let c_propname = CString::new(propname).unwrap(); unsafe { - bindings::qdev_prop_set_chr(self.as_mut_ptr(), c_propname.as_ptr(), chr.as_mut_ptr()); + bindings::qdev_prop_set_chr( + self.upcast().as_mut_ptr(), + c_propname.as_ptr(), + chr.as_mut_ptr(), + ); } } @@ -323,8 +348,17 @@ fn init_gpio_in FnCall<(&'a Self::Target, u32, u32)>>( num_lines: u32, _cb: F, ) { - let _: () = F::ASSERT_IS_SOME; + fn do_init_gpio_in( + dev: &DeviceState, + num_lines: u32, + gpio_in_cb: unsafe extern "C" fn(*mut c_void, c_int, c_int), + ) { + unsafe { + qdev_init_gpio_in(dev.as_mut_ptr(), Some(gpio_in_cb), num_lines as c_int); + } + } + let _: () = F::ASSERT_IS_SOME; unsafe extern "C" fn rust_irq_handler FnCall<(&'a T, u32, u32)>>( opaque: *mut c_void, line: c_int, @@ -337,19 +371,13 @@ fn init_gpio_in FnCall<(&'a Self::Target, u32, u32)>>( let gpio_in_cb: unsafe extern "C" fn(*mut c_void, c_int, c_int) = rust_irq_handler::; - unsafe { - qdev_init_gpio_in( - self.as_mut_ptr::(), - Some(gpio_in_cb), - num_lines as c_int, - ); - } + do_init_gpio_in(self.upcast(), num_lines, gpio_in_cb); } fn init_gpio_out(&self, pins: &[InterruptSource]) { unsafe { qdev_init_gpio_out( - self.as_mut_ptr::(), + self.upcast().as_mut_ptr(), InterruptSource::slice_as_ptr(pins), pins.len() as c_int, ); diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 24a4dc81e7f..b115d1f8742 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -469,7 +469,7 @@ macro_rules! vmstate_clock { $crate::assert_field_type!( $struct_name, $field_name, - $crate::qom::Owned<$crate::bindings::Clock> + $crate::qom::Owned<$crate::qdev::Clock> ); $crate::offset_of!($struct_name, $field_name) }, From patchwork Fri Feb 21 17:03:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13986079 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 3410DC021B6 for ; Fri, 21 Feb 2025 17:06:42 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tlWRx-0008D6-8A; Fri, 21 Feb 2025 12:04:29 -0500 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 1tlWRr-0007ml-4r for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:23 -0500 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 1tlWRp-0001Vr-30 for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1740157460; 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=wrxstZfwC92BCL08iYO3tMXByMssL0Rad+3hL3bRI4k=; b=XKAldwQb/0l/S6I+LX9a86GkDjihruQLqrVM43wFz/W0MEeox8PdRGiyizStmu3Ydhl/NR mmYDMVIav6TA2FE4I5dpswGPAaZ4Fvyk3tVlKtFppZik3nUtVgvPWmkAPdKqKaJgdU1xEQ Cpqk5qqsBq3NvdfLWUxwf1oY72aooCo= Received: from mail-ed1-f71.google.com (mail-ed1-f71.google.com [209.85.208.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-658-vmo46GzqO_mRVpvHyEddow-1; Fri, 21 Feb 2025 12:04:18 -0500 X-MC-Unique: vmo46GzqO_mRVpvHyEddow-1 X-Mimecast-MFC-AGG-ID: vmo46GzqO_mRVpvHyEddow_1740157458 Received: by mail-ed1-f71.google.com with SMTP id 4fb4d7f45d1cf-5da03762497so2320560a12.1 for ; Fri, 21 Feb 2025 09:04:18 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740157456; x=1740762256; 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=wrxstZfwC92BCL08iYO3tMXByMssL0Rad+3hL3bRI4k=; b=kNDJ32XcE6EQ8OXGsydDlK7pMAORdVo+zJrhWQnKzKbAkDxfS5xZ7e/FQFn+3hXrbB S+C+XLWSKQK9kk+yh1szNRub/whoLXEY0SFfQocdLYSced0+WfKQWXkRF1VDVEaNuQ4u +FymBlDgCEkzppiCc62MnyN5bzE3wX8C2RrrXQ86ejMcIOQO77ibJKgi48WOxmnLsgPK hrjVcdzmO1qlMQVx0FMzMDOAJWVXPu79ElhhfUiJumRRaSU+rMJxQ7r8QYi91ae8amYP HHrTaATXB/Xhje2H90Fr0q9hkxsLLNKeUwMXEXog+JXWqYLVjEHmE/v3GTXr0buFsi2H UfJQ== X-Gm-Message-State: AOJu0YwIgWcZEaPsQjQ4gQ/X/0h4KKUTLL7a1FQ3sdcyBN8Bed8YRhVU 6ARPNWahNULIy+fxfAVCqzXW4+ScCn6o8gPPfKg6P6pmqdG28ptfoc0IrnwPiiIa0GvfzfUzobO Debwk2skKkrbAjBwy8yxk24GtjZH45JS2E6rKIP5fz9yn05X1ZBoj21s8PuWY6CDL4wdAK0i/i8 juYd7N5NKzfa+6zaCqnEgta6GZ8JM8vVo7jXqcKUI= X-Gm-Gg: ASbGncuneDe5Hb9lg/T33RLap7qp/bGscHixcN4A7GhpjMtZS1lSpLM1m4A2I8as6b9 hJaa5w/da08k4AWPxEtyfAra/KJ4jCjl72+uvgj6ZVyNQiRdcKUNu1JFOVmETF4WikOSK+wFYOR 72qmf7BZb1+XMkpOnIEgkLTdVHpDSyWbGrb1ORFceCTfcpJDXoy0sv9z9tDW7M20Hivx4F6uVJi UaFu16I9WiKr/kAaAiJbirPn4+fnGKYODtytBbQhYmEvk8zlkUyLyfuHGrbdomyt338alfqwO9/ Rb+pq0UQn8bzCq3lVN0= X-Received: by 2002:a05:6402:1ecf:b0:5e0:8a3f:ef65 with SMTP id 4fb4d7f45d1cf-5e0b62f9bbdmr4044712a12.7.1740157456163; Fri, 21 Feb 2025 09:04:16 -0800 (PST) X-Google-Smtp-Source: AGHT+IExONKfMjCtfDcseZA+TksGC0DWhptB5rhNYjv195XCgFnxhHIkfqbSWPIwA2s61byRocY23g== X-Received: by 2002:a05:6402:1ecf:b0:5e0:8a3f:ef65 with SMTP id 4fb4d7f45d1cf-5e0b62f9bbdmr4044457a12.7.1740157454033; Fri, 21 Feb 2025 09:04:14 -0800 (PST) Received: from [192.168.10.48] ([151.95.61.185]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5e09072247esm4486329a12.51.2025.02.21.09.04.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Feb 2025 09:04:13 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: qemu-rust@nongnu.org Subject: [PATCH 12/15] rust: sysbus: wrap SysBusDevice with Opaque<> Date: Fri, 21 Feb 2025 18:03:39 +0100 Message-ID: <20250221170342.63591-13-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250221170342.63591-1-pbonzini@redhat.com> References: <20250221170342.63591-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.424, 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=unavailable 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 Signed-off-by: Paolo Bonzini --- rust/hw/timer/hpet/src/hpet.rs | 2 +- rust/qemu-api/src/bindings.rs | 3 --- rust/qemu-api/src/sysbus.rs | 25 ++++++++++++++++++------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/rust/hw/timer/hpet/src/hpet.rs b/rust/hw/timer/hpet/src/hpet.rs index be27eb0eff4..19e63465cff 100644 --- a/rust/hw/timer/hpet/src/hpet.rs +++ b/rust/hw/timer/hpet/src/hpet.rs @@ -741,7 +741,7 @@ fn reset_hold(&self, _type: ResetType) { HPETFwConfig::update_hpet_cfg( self.hpet_id.get(), self.capability.get() as u32, - sbd.mmio[0].addr, + unsafe { *sbd.as_ptr() }.mmio[0].addr, ); // to document that the RTC lowers its output on reset as well diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs index 6e70a75a0e6..b791ca6d87f 100644 --- a/rust/qemu-api/src/bindings.rs +++ b/rust/qemu-api/src/bindings.rs @@ -40,9 +40,6 @@ unsafe impl Sync for MemoryRegion {} unsafe impl Send for ObjectClass {} unsafe impl Sync for ObjectClass {} -unsafe impl Send for SysBusDevice {} -unsafe impl Sync for SysBusDevice {} - // SAFETY: this is a pure data struct unsafe impl Send for CoalescedMemoryRange {} unsafe impl Sync for CoalescedMemoryRange {} diff --git a/rust/qemu-api/src/sysbus.rs b/rust/qemu-api/src/sysbus.rs index 48803a655f9..78909fb9931 100644 --- a/rust/qemu-api/src/sysbus.rs +++ b/rust/qemu-api/src/sysbus.rs @@ -6,11 +6,11 @@ use std::{ffi::CStr, ptr::addr_of_mut}; -pub use bindings::{SysBusDevice, SysBusDeviceClass}; +pub use bindings::SysBusDeviceClass; use crate::{ bindings, - cell::bql_locked, + cell::{bql_locked, Opaque}, irq::{IRQState, InterruptSource}, memory::MemoryRegion, prelude::*, @@ -18,6 +18,14 @@ qom::Owned, }; +/// A safe wrapper around [`bindings::SysBusDevice`]. +#[repr(transparent)] +#[derive(Debug, qemu_api_macros::Wrapper)] +pub struct SysBusDevice(Opaque); + +unsafe impl Send for SysBusDevice {} +unsafe impl Sync for SysBusDevice {} + unsafe impl ObjectType for SysBusDevice { type Class = SysBusDeviceClass; const TYPE_NAME: &'static CStr = @@ -49,7 +57,7 @@ pub trait SysBusDeviceMethods: ObjectDeref fn init_mmio(&self, iomem: &MemoryRegion) { assert!(bql_locked()); unsafe { - bindings::sysbus_init_mmio(self.as_mut_ptr(), iomem.as_mut_ptr()); + bindings::sysbus_init_mmio(self.upcast().as_mut_ptr(), iomem.as_mut_ptr()); } } @@ -60,7 +68,7 @@ fn init_mmio(&self, iomem: &MemoryRegion) { fn init_irq(&self, irq: &InterruptSource) { assert!(bql_locked()); unsafe { - bindings::sysbus_init_irq(self.as_mut_ptr(), irq.as_ptr()); + bindings::sysbus_init_irq(self.upcast().as_mut_ptr(), irq.as_ptr()); } } @@ -69,7 +77,7 @@ fn mmio_map(&self, id: u32, addr: u64) { assert!(bql_locked()); let id: i32 = id.try_into().unwrap(); unsafe { - bindings::sysbus_mmio_map(self.as_mut_ptr(), id, addr); + bindings::sysbus_mmio_map(self.upcast().as_mut_ptr(), id, addr); } } @@ -81,7 +89,7 @@ fn connect_irq(&self, id: u32, irq: &Owned) { let id: i32 = id.try_into().unwrap(); let irq: &IRQState = irq; unsafe { - bindings::sysbus_connect_irq(self.as_mut_ptr(), id, irq.as_mut_ptr()); + bindings::sysbus_connect_irq(self.upcast().as_mut_ptr(), id, irq.as_mut_ptr()); } } @@ -89,7 +97,10 @@ fn sysbus_realize(&self) { // TODO: return an Error assert!(bql_locked()); unsafe { - bindings::sysbus_realize(self.as_mut_ptr(), addr_of_mut!(bindings::error_fatal)); + bindings::sysbus_realize( + self.upcast().as_mut_ptr(), + addr_of_mut!(bindings::error_fatal), + ); } } } From patchwork Fri Feb 21 17:03:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13986080 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 C4237C021B8 for ; Fri, 21 Feb 2025 17:06:42 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tlWRx-0008Bc-4B; Fri, 21 Feb 2025 12:04:29 -0500 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 1tlWRu-00080s-95 for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:26 -0500 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 1tlWRs-0001Wz-DY for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:25 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1740157463; 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=tF++Gjxl8qlA5pYY+tAt3HrugPJ8B0H6ljBKbOe9dP8=; b=N82HjQemBZDpKvcdUViHpsw1iJ8B9Dz+GrUvsc+rTAeEFiVAoJ/NHCJT7uMYmnQiW6I477 xxTZmAV9d2g0TZh8h0CYu8WuYPNccUvS3zDC8f9TiuaSnfeU8RSWpDmeQMb5VVcgckA4MH afjEcOrj8FRfHzltviYnTnyu1PY99BQ= Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-513-zKVvDBAzOOuf5Ai86YFTzA-1; Fri, 21 Feb 2025 12:04:21 -0500 X-MC-Unique: zKVvDBAzOOuf5Ai86YFTzA-1 X-Mimecast-MFC-AGG-ID: zKVvDBAzOOuf5Ai86YFTzA_1740157460 Received: by mail-ej1-f72.google.com with SMTP id a640c23a62f3a-abba4c6d9ddso265312966b.1 for ; Fri, 21 Feb 2025 09:04:20 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740157457; x=1740762257; 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=tF++Gjxl8qlA5pYY+tAt3HrugPJ8B0H6ljBKbOe9dP8=; b=IAkV8TVUXb0LA8dQb1Gc9MdokxS+HmGT4f8f+RKTucaB5PptxuImU3dp0eb5bBzrys 95bTGbinxluM9PH1V7cezlPeePm0mJtFgsV338QmAFxUNhEuGvSimfLnUrgCBUz0dd2H AAvcfSHOCG5iWf/c1gjBpjAsDYvcCC9ffZlTikMkd50nkGczt0HIqM+bB4/9rVQ7a+72 stoGbC+wxPyOlsQRp0nnY5w8cJaq/THaSuT1jzyuD7e4l1cOXGY4axFaB2PQ5QPjbgDs //wP6mjprZN5ISGOuRQyo/eekg/kILqoNYM9Miw+ZHmFWBGTvpl6dNt3g9oYizWIooq5 A7mA== X-Gm-Message-State: AOJu0YwT3ONaIAYyRci7FujyGjanoeJoWrjUZf2sRi+2nxlhvLvmDQ31 pwEweZ+E17McEoHzcyd1CIBbeqE7QU2ZloGjrmJC8o29Y7VzDwZocDLzRrF5x6am1LU1P+eIgTg qAcmjgGbLvLbotxtD7S5lTD7zHSnlyLzjAHzNoj3qB6ZDkKXcP3H+l4MsPL5LqbRQ+GsrgIhYiV ep08NcoMALLN8HXlMHFYpywWI2U/NSaCJeTsRK1TY= X-Gm-Gg: ASbGncvIbcOgmTLthBgBJiB5koNdcqT94nx//Licy26pxjhRU4cG1e5AbW6VZ3ZesgF i+zotrygJ7CgkX4dEqKu2Q/RHCyP+GhroszSx9UejPcGGs0qwJlHe+fCMEBNANTPITFL7/aIrIz OcjmGb9LW7WqnaDJDjmMjikAAP+zSOn6XhFe0LY840/9m1cSQ6v/HaQy3f+eODwSEU3oZgsCgRl E4624aPqPNWN7RK/MYlWSWNGtYDplyzuM3UpgOJIx3luZzGf9P/UIYRa5yZUJbIlIC9gjscgVms WNLz0cxoBx1pu2yNBrw= X-Received: by 2002:a17:907:d16:b0:aa6:b63a:4521 with SMTP id a640c23a62f3a-abc0d9dd9ecmr343454566b.15.1740157457287; Fri, 21 Feb 2025 09:04:17 -0800 (PST) X-Google-Smtp-Source: AGHT+IHlGheNS8hhPmT17THOlcjVYtIbDYCcx1/8bOp+Nm/X18M30oIRTJKprBJsZsTUU4Ax0giO3Q== X-Received: by 2002:a17:907:d16:b0:aa6:b63a:4521 with SMTP id a640c23a62f3a-abc0d9dd9ecmr343447666b.15.1740157456472; Fri, 21 Feb 2025 09:04:16 -0800 (PST) Received: from [192.168.10.48] ([151.95.61.185]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-aba9cf8a262sm1389156466b.22.2025.02.21.09.04.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Feb 2025 09:04:15 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: qemu-rust@nongnu.org Subject: [PATCH 13/15] rust: memory: wrap MemoryRegion with Opaque<> Date: Fri, 21 Feb 2025 18:03:40 +0100 Message-ID: <20250221170342.63591-14-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250221170342.63591-1-pbonzini@redhat.com> References: <20250221170342.63591-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.424, 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_H5=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=unavailable 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 Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/bindings.rs | 3 --- rust/qemu-api/src/memory.rs | 30 ++++++++++++++++-------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs index b791ca6d87f..26cc8de0cf2 100644 --- a/rust/qemu-api/src/bindings.rs +++ b/rust/qemu-api/src/bindings.rs @@ -34,9 +34,6 @@ unsafe impl Sync for CharBackend {} unsafe impl Send for Chardev {} unsafe impl Sync for Chardev {} -unsafe impl Send for MemoryRegion {} -unsafe impl Sync for MemoryRegion {} - unsafe impl Send for ObjectClass {} unsafe impl Sync for ObjectClass {} diff --git a/rust/qemu-api/src/memory.rs b/rust/qemu-api/src/memory.rs index 713c494ca2e..fdb1ea11fcf 100644 --- a/rust/qemu-api/src/memory.rs +++ b/rust/qemu-api/src/memory.rs @@ -6,9 +6,8 @@ use std::{ ffi::{CStr, CString}, - marker::{PhantomData, PhantomPinned}, + marker::PhantomData, os::raw::{c_uint, c_void}, - ptr::addr_of, }; pub use bindings::{hwaddr, MemTxAttrs}; @@ -16,6 +15,7 @@ use crate::{ bindings::{self, device_endian, memory_region_init_io}, callbacks::FnCall, + cell::Opaque, prelude::*, zeroable::Zeroable, }; @@ -132,13 +132,13 @@ fn default() -> Self { } } -/// A safe wrapper around [`bindings::MemoryRegion`]. Compared to the -/// underlying C struct it is marked as pinned because the QOM tree -/// contains a pointer to it. -pub struct MemoryRegion { - inner: bindings::MemoryRegion, - _pin: PhantomPinned, -} +/// A safe wrapper around [`bindings::MemoryRegion`]. +#[repr(transparent)] +#[derive(qemu_api_macros::Wrapper)] +pub struct MemoryRegion(Opaque); + +unsafe impl Send for MemoryRegion {} +unsafe impl Sync for MemoryRegion {} impl MemoryRegion { // inline to ensure that it is not included in tests, which only @@ -174,13 +174,15 @@ pub fn init_io>( size: u64, ) { unsafe { - Self::do_init_io(&mut self.inner, owner.cast::(), &ops.0, name, size); + Self::do_init_io( + self.0.as_mut_ptr(), + owner.cast::(), + &ops.0, + name, + size, + ); } } - - pub(crate) const fn as_mut_ptr(&self) -> *mut bindings::MemoryRegion { - addr_of!(self.inner) as *mut _ - } } unsafe impl ObjectType for MemoryRegion { From patchwork Fri Feb 21 17:03:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13986061 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 4867EC021B5 for ; Fri, 21 Feb 2025 17:04:48 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tlWRz-0008S9-R1; Fri, 21 Feb 2025 12:04:32 -0500 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 1tlWRw-0008Ck-NA for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:29 -0500 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 1tlWRu-0001Xe-64 for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:28 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1740157465; 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=gITORNAi3idPJ7f7HHnX56O6J1H0hwCpHvwebA0yrfA=; b=TWqImNhRgjI0EEqsovcpEuJtdP9sxKfHpFb8AP3k24iU5kYbNqg1pRXzXMD4JG/bh7ZvNB r1RflNVCGAnjcKcs4/iJzATKVcBc9KKhAlZbzpYevDYFoFTGj8NEvAmvOiVUWMGoQYfJhj ARsiqOJ2ADx6wJrnsHR2558P+87/qro= Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-426-YyB2QBF7OkGk8KTeyiTe_w-1; Fri, 21 Feb 2025 12:04:24 -0500 X-MC-Unique: YyB2QBF7OkGk8KTeyiTe_w-1 X-Mimecast-MFC-AGG-ID: YyB2QBF7OkGk8KTeyiTe_w_1740157463 Received: by mail-ej1-f72.google.com with SMTP id a640c23a62f3a-ab7f6f6cd96so64125966b.2 for ; Fri, 21 Feb 2025 09:04:24 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740157462; x=1740762262; 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=gITORNAi3idPJ7f7HHnX56O6J1H0hwCpHvwebA0yrfA=; b=kXmUnNO0+VK9GtRo9xmxRfX64XOC4YS55cr+HM+WlskNjM4/CLKNno72ZU8J5Qh3Z2 UGQWbR9d51J+m8wQYU3m6iWWspbCLR573uiwtX5fhU5HwcrGPByAbesP1JJ5rrFEqFk2 XAhGnuio6uTTVXA64+jBcj1+Tb2CpmyqvFk09AWYEAJK2X/zZAkIKT9bwOHvoNyLYk8I wbOeEdkZ+3O/4Em45LOSyl46cjtKNhdnujyX6kik+Lx/s2AcpKgSgR5FIftBDTVpDnd3 XujwhyW2IcemG3LLQoihTMSIGI2XynpzWw1i6ezLZ3HD+/bTiK3burakwKLGfX745VXM cIiA== X-Gm-Message-State: AOJu0Yy6/DfL8pNMkgLVAScB/hZTpkAiMeFXR4lD1kEJzfcjuPsw3Lz/ 5QLe90fs6f6vp2FcQe7GbVz0oFuyXXywyucYEAy2cgxXu+Lni/SljQnB4xcLEcLv8Qz9hYKNpBG MbOfwubET/rTPZGsZXQWLAXTIZPOu6A4rZnOY3aQCETgWTTyH7VTddgC+2Od0XKktwwFP6rEo4b G0sZasSKT/DvWpyByXJKxosE5HHTPHMrWju2A+sZs= X-Gm-Gg: ASbGnct1JTupu8y7k4jnRksSBar+W93t8REbxunlj15+eDt1igJ9ivJs+GEtTZPjC40 F+r6xD3AGVGuINpc81aykNT7Dtf8oJfAE6r3Hs3XsJo/eZtHVBSgiJ5HBmlgx1YMLjwPeUdeGWf Sf6fNXCxbEsGfDrkdJapcDkC7WyYAAHIomYQFd2KRYqJby7LFZYkauAyTCsABB7SraK4DKdRCe0 U6MUuMQDoo44Uijan4AVus4NEp8mDmGVsaczUid6JoU57Pa15MxsURGNOGMcHHoZSmiz0ZWCn+V J7LDBcl+wd1zKNjNWG8= X-Received: by 2002:a17:907:d204:b0:ab9:63bd:91be with SMTP id a640c23a62f3a-abc099b3911mr472630166b.3.1740157462312; Fri, 21 Feb 2025 09:04:22 -0800 (PST) X-Google-Smtp-Source: AGHT+IHh3OiPvtScaPUKA6oR2syBGUS8aeCMOzQAoTZ6jAjPhsuT4a36zKEOsBZELst31y+ZScBTgg== X-Received: by 2002:a17:907:d204:b0:ab9:63bd:91be with SMTP id a640c23a62f3a-abc099b3911mr472617766b.3.1740157461568; Fri, 21 Feb 2025 09:04:21 -0800 (PST) Received: from [192.168.10.48] ([151.95.61.185]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-abbda707e3dsm535043666b.106.2025.02.21.09.04.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Feb 2025 09:04:17 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: qemu-rust@nongnu.org Subject: [PATCH 14/15] rust: chardev: wrap Chardev with Opaque<> Date: Fri, 21 Feb 2025 18:03:41 +0100 Message-ID: <20250221170342.63591-15-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250221170342.63591-1-pbonzini@redhat.com> References: <20250221170342.63591-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.424, 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=unavailable 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 Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/bindings.rs | 3 --- rust/qemu-api/src/chardev.rs | 8 ++++++-- rust/qemu-api/src/qdev.rs | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs index 26cc8de0cf2..c3f36108bd5 100644 --- a/rust/qemu-api/src/bindings.rs +++ b/rust/qemu-api/src/bindings.rs @@ -31,9 +31,6 @@ unsafe impl Sync for BusState {} unsafe impl Send for CharBackend {} unsafe impl Sync for CharBackend {} -unsafe impl Send for Chardev {} -unsafe impl Sync for Chardev {} - unsafe impl Send for ObjectClass {} unsafe impl Sync for ObjectClass {} diff --git a/rust/qemu-api/src/chardev.rs b/rust/qemu-api/src/chardev.rs index 74cfb634e5f..a35b9217e90 100644 --- a/rust/qemu-api/src/chardev.rs +++ b/rust/qemu-api/src/chardev.rs @@ -6,9 +6,13 @@ use std::ffi::CStr; -use crate::{bindings, prelude::*}; +use crate::{bindings, cell::Opaque, prelude::*}; + +/// A safe wrapper around [`bindings::Chardev`]. +#[repr(transparent)] +#[derive(qemu_api_macros::Wrapper)] +pub struct Chardev(Opaque); -pub type Chardev = bindings::Chardev; pub type ChardevClass = bindings::ChardevClass; unsafe impl ObjectType for Chardev { diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs index ed5dce08216..1ff6c1ca7c2 100644 --- a/rust/qemu-api/src/qdev.rs +++ b/rust/qemu-api/src/qdev.rs @@ -334,6 +334,7 @@ fn init_clock_out(&self, name: &str) -> Owned { fn prop_set_chr(&self, propname: &str, chr: &Owned) { assert!(bql_locked()); let c_propname = CString::new(propname).unwrap(); + let chr: &Chardev = chr; unsafe { bindings::qdev_prop_set_chr( self.upcast().as_mut_ptr(), From patchwork Fri Feb 21 17:03:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13986077 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 C451BC021B5 for ; Fri, 21 Feb 2025 17:06:40 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tlWS2-0000A4-0N; Fri, 21 Feb 2025 12:04:34 -0500 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 1tlWRy-0008My-QT for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:30 -0500 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 1tlWRw-0001YS-Vh for qemu-devel@nongnu.org; Fri, 21 Feb 2025 12:04:30 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1740157468; 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=hGeedFex4hwcA+4WKc4T7rcitnlGc1D0mCRSihvSmdw=; b=UN4FwTxyQAfMZt/YZQPiWuznipXqMrgdJRTBYOKqzRsOxl+BideIXVrZLp9MGhFCOBAKqw mdjAfKzzjkMJGLXa5Fk1WePbBNXICVS/kJsCLdjQt+MfZxRuMVele4UVQOYOojclCZMjvu kW7AlEgKY4Xxq3jb1lw5BQNDYW0Q4CY= Received: from mail-ej1-f70.google.com (mail-ej1-f70.google.com [209.85.218.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-329-l6xVWyGvPgyPd7DDnFshQQ-1; Fri, 21 Feb 2025 12:04:26 -0500 X-MC-Unique: l6xVWyGvPgyPd7DDnFshQQ-1 X-Mimecast-MFC-AGG-ID: l6xVWyGvPgyPd7DDnFshQQ_1740157465 Received: by mail-ej1-f70.google.com with SMTP id a640c23a62f3a-ab397fff5a3so266944066b.1 for ; Fri, 21 Feb 2025 09:04:26 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740157465; x=1740762265; 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=hGeedFex4hwcA+4WKc4T7rcitnlGc1D0mCRSihvSmdw=; b=lKNidc+bu2yv22KpCu0IVz/DvfFGSWm2pYfH692qsSXj0+lkLr4n0tzH7+MwzKsMQQ eUaT9ZiRXre4pDvbbug57rPBJrNqfEsULlmURqJzIHaHF/pjc2tC5vAU+mI013Ngau/r Twg1bsjX4ShT7NrBQNqGjmJpQLr3/RYHl1uzBLiKRfVQhLWsE9gTYGjsFHJgoKHVNflj gDuJidpbdxFN39+Dy/bXoG2vhIsEW8cibeOhtlCGG0by5vxW00RrcZT0JnRzkarY57Hm rWvU3pVt15CRfTYvlnzeqQ8uu/2kqCmKvbp3kp5IiC38KqiBTnLrcHk+t4mIF6RO87EJ GiVQ== X-Gm-Message-State: AOJu0Yxu+Ph+grPDGO8DU2LWBviM54CTqfgx2X9NJlUC2mQqpKYHdT1S YiQr+UQYavxqMvegB7ALwMsZYVmE/UHFbGJlQ0yohrZk47JyKZZP+0aJ9KoUJS5Rxr2BclUm+qB hLLkm/im2xSmW6828ppe2tFTWhrXxGIwaLQiAIuB2yPWoA8/aj+bSLRi2gJZ4l1sczM6ZxDBI1R 2y+0p2qVh2AzbH6tEyytE4chuxkidNMyRV4mw/01I= X-Gm-Gg: ASbGncujMUDZ6hQC9PJ0fgREwP/HmCQS5WP/R4Z22LYkna/5UGHHnzfoFew3nH63dPr HDRRWUY/t3lcX0QJCB24gdfZOhbU2Ij4Iu0vuz/NwBKg52thPcrZ4BNUKeGgm6OUgq2gclDSaU/ 5oLuFLp1blxFBfdbteaRkHE8WaGP1sIRzlJwmtIercx371xW5a4TpHAQGE5Rmze/8lQHP/FSx0Q tlgcqNRtpr1s9Y8s1KkbGTQcDkARwtC+hPDF6zejnfZ6Aqp/gWyd6ZEGDuqSvkF4600ha2VbTKU NyxW3hjadxMmn83X+So= X-Received: by 2002:a17:907:1686:b0:abb:dbc2:bfb6 with SMTP id a640c23a62f3a-abbedd4df55mr796077266b.10.1740157464644; Fri, 21 Feb 2025 09:04:24 -0800 (PST) X-Google-Smtp-Source: AGHT+IEECFPHS+8PObVyoFvxy1YQzPxv9V7w9Vt4je3ICUJK7nFtqsY2CGp21/qsO3xZ0JJk5hx44Q== X-Received: by 2002:a17:907:1686:b0:abb:dbc2:bfb6 with SMTP id a640c23a62f3a-abbedd4df55mr796070266b.10.1740157464045; Fri, 21 Feb 2025 09:04:24 -0800 (PST) Received: from [192.168.10.48] ([151.95.61.185]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-aba910e8b11sm1394251366b.21.2025.02.21.09.04.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Feb 2025 09:04:22 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: qemu-rust@nongnu.org Subject: [PATCH 15/15] rust: bindings: remove more unnecessary Send/Sync impls Date: Fri, 21 Feb 2025 18:03:42 +0100 Message-ID: <20250221170342.63591-16-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250221170342.63591-1-pbonzini@redhat.com> References: <20250221170342.63591-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.424, 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_H5=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=unavailable 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 Send and Sync are now implemented on the opaque wrappers. Remove them from the bindings module, unless the structs are pure data containers and/or have no C functions defined on them. Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/bindings.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs index c3f36108bd5..3c1d297581e 100644 --- a/rust/qemu-api/src/bindings.rs +++ b/rust/qemu-api/src/bindings.rs @@ -25,15 +25,11 @@ // SAFETY: these are implemented in C; the bindings need to assert that the // BQL is taken, either directly or via `BqlCell` and `BqlRefCell`. -unsafe impl Send for BusState {} -unsafe impl Sync for BusState {} - +// When bindings for character devices are introduced, this can be +// moved to the Opaque<> wrapper in src/chardev.rs. unsafe impl Send for CharBackend {} unsafe impl Sync for CharBackend {} -unsafe impl Send for ObjectClass {} -unsafe impl Sync for ObjectClass {} - // SAFETY: this is a pure data struct unsafe impl Send for CoalescedMemoryRange {} unsafe impl Sync for CoalescedMemoryRange {}