From patchwork Thu Feb 13 16:00: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: 13973579 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 788DFC021A0 for ; Thu, 13 Feb 2025 16:13:38 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tiber-0000vt-0H; Thu, 13 Feb 2025 11:01:45 -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 1tibeJ-0000op-JW for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:18 -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 1tibeD-0005PM-JT for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:10 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462464; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WszW0NxKZSYHFFSiUB5cJcU961As2uXrLrk50UN0l2U=; b=ZL92n1OJJupYecXua3K6tOmQDfE1EBXS/9Egz5xhhZTmGj4FjMWUcXs9U4lyrMdgxTc+Zd kszC4U6QeMTD9Jd5KaWnJNLz+w7f/zZ5EOIR8PMdkZov+tmq3jYXhx0VUzwKLmXmL2HoZC EKSoWqCwwemRRa/nE8hyPT1mwyrjdAY= 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-549-vHSMizb1NX6hT6xb5joKng-1; Thu, 13 Feb 2025 11:01:02 -0500 X-MC-Unique: vHSMizb1NX6hT6xb5joKng-1 X-Mimecast-MFC-AGG-ID: vHSMizb1NX6hT6xb5joKng Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-43941ad86d4so8422565e9.2 for ; Thu, 13 Feb 2025 08:01:02 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462461; x=1740067261; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=WszW0NxKZSYHFFSiUB5cJcU961As2uXrLrk50UN0l2U=; b=uyHngAvOp/AcAyKb3Iwh2mgORbmH/85dRKXAwqh47UrZ3hpLOOFUOstylkcC8jwGW5 9Cg5MLSOJ2B+8HTBJH0VOf+A7/b4T0AnPAkFgO9H8cYvQDwGU6RVQRYSnECUJzktzR6V C1rSBpx6xWDoYClp5Hitluinek4cp1+t8FCGjbJVPBeTe4YnWeo/QhKn++cZl+83Fanh 1/VIYerzEr/t/x2pwg8GX9cHXs8dBJpI873Q86/Bx+Hu/iS9aXEzTyU1yL61opB84Nsz HzuaDyKJpihWe1qUoYmgUCOQq3VQfMfgHvT6OdfZQgL+NbsW78tMfALLi3ajH+kpBZEQ I2Hw== X-Gm-Message-State: AOJu0Yx6lztEu+OuW3G1acnmfovlWyzOvQMfy+VDLHe4dm/fD27D0TNl hAtTwdUaL9zVVQ4s24d2ea1HxWAJQvriAQTKTSaKlheqmGtRR5d1NmBocblHp3Dw8wjC1kpLq2T OGZOWMeDy4iSc7s8DVROdzz5dwEwGAG2y4u91T5Id3mSg6JgbF4TZEqFCnRrCv/P+dRpS55zj6E YVa02MTthQLPgL75HniypraHehn5YgPVra7Ls8FjA= X-Gm-Gg: ASbGncu9XeXH1nfQ5c+1IisnsXOMn988Go0v9orxuxOWRA320clSVGngRHGjCXGinQf 3Hj1fyicCTCCZ7vKvP9Gj+pmgm+OmxCiuHBAb8T6klw8RNibWwUorVQ2sh92jGWJ4uzFX62JroM vL1H83CqaeCbFNIv862mpJZqgu6GhM2lhOkJwKT++bF+6EfjaLr+xzuN+52ZTZ7tmHc5CQvlaU5 xavVr723WLYsit3SSxoiFrZSVN69gFuiPtESee2MnnH8pJzaO6OxoZ93fuE+uTu7JNJgVYBWpcW TqGOHx2OydkTQSF5nIgzZNtaRcpo5Ews4Br87uJbGVacIw== X-Received: by 2002:a5d:598e:0:b0:38f:21ce:aa28 with SMTP id ffacd0b85a97d-38f21ceb0famr6167230f8f.36.1739462460311; Thu, 13 Feb 2025 08:01:00 -0800 (PST) X-Google-Smtp-Source: AGHT+IGV2iV679sLK2Kn6isMwwx8W+PjBeaDA8rvAcFeN/A8HvlbVfbSMlvN/1+ih+wfA+QMrBd4FQ== X-Received: by 2002:a5d:598e:0:b0:38f:21ce:aa28 with SMTP id ffacd0b85a97d-38f21ceb0famr6167121f8f.36.1739462459383; Thu, 13 Feb 2025 08:00:59 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f258ccd2csm2318611f8f.30.2025.02.13.08.00.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:00:58 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 01/27] rust: docs: document naming convention Date: Thu, 13 Feb 2025 17:00:28 +0100 Message-ID: <20250213160054.3937012-2-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 As agreed in the "vtables and procedural macros" thread on the mailing list. Signed-off-by: Paolo Bonzini --- docs/devel/rust.rst | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/docs/devel/rust.rst b/docs/devel/rust.rst index 390aae43866..8cccca7a734 100644 --- a/docs/devel/rust.rst +++ b/docs/devel/rust.rst @@ -194,6 +194,50 @@ module status interface either. Also, ``unsafe`` interfaces may be replaced by safe interfaces later. +Naming convention +''''''''''''''''' + +C function names usually are prefixed according to the data type that they +apply to, for example ``timer_mod`` or ``sysbus_connect_irq``. Furthermore, +both function and structs sometimes have a ``qemu_`` or ``QEMU`` prefix. +Generally speaking, these are all removed in the corresponding Rust functions: +``QEMUTimer`` becomes ``timer::Timer``, ``timer_mod`` becomes ``Timer::modify``, +``sysbus_connect_irq`` becomes ``SysBusDeviceMethods::connect_irq``. + +Sometimes however a name appears multiple times in the QOM class hierarchy, +and the only difference is in the prefix. An example is ``qdev_realize`` and +``sysbus_realize``. In such cases, whenever a name is not unique in +the hierarchy, always add the prefix to the classes that are lower in +the hierarchy; for the top class, decide on a case by case basis. + +For example: + +========================== ========================================= +``device_cold_reset()`` ``DeviceMethods::cold_reset()`` +``pci_device_reset()`` ``PciDeviceMethods::pci_device_reset()`` +``pci_bridge_reset()`` ``PciBridgeMethods::pci_bridge_reset()`` +========================== ========================================= + +Here, the name is not exactly the same, but nevertheless ``PciDeviceMethods`` +adds the prefix to avoid confusion, because the functionality of +``device_cold_reset()`` and ``pci_device_reset()`` is subtly different. + +In this case, however, no prefix is needed: + +========================== ========================================= +``device_realize()`` ``DeviceMethods::realize()`` +``sysbus_realize()`` ``SysbusDeviceMethods::sysbus_realize()`` +``pci_realize()`` ``PciDeviceMethods::pci_realize()`` +========================== ========================================= + +Here, the lower classes do not add any functionality, and mostly +provide extra compile-time checking; the basic *realize* functionality +is the same for all devices. Therefore, ``DeviceMethods`` does not +add the prefix. + +Whenever a name is unique in the hierarchy, instead, you should +always remove the class name prefix. + Common pitfalls ''''''''''''''' From patchwork Thu Feb 13 16:00: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: 13973557 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 0DBF0C021A4 for ; Thu, 13 Feb 2025 16:10:16 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibey-0000yO-4K; Thu, 13 Feb 2025 11:01:52 -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 1tibeO-0000pM-89 for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:22 -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 1tibeH-0005QB-AZ for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:12 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462467; 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=JDXDdyrYu8aqHcWMZRgkJHUGkK2ZXNisxDcxlPZPe2o=; b=BAzJLnBhgKGQa/1LuvWU3i8rtscGkgrJEO7QCjTNif0je/0amUOflPV23jQ6XubPro4vL5 h1/CaoOYxyCMFQltE336sWmWlG3yOnwPcjtXY5N5niLqvpS4jjjXi2lBsp8WJeqJTvuqGJ o2WYR7Kt6WMJOuXZgVPq+9uiSoMhDUg= 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-444-Ej5S0OsBPlOBgsZQd1dktA-1; Thu, 13 Feb 2025 11:01:06 -0500 X-MC-Unique: Ej5S0OsBPlOBgsZQd1dktA-1 X-Mimecast-MFC-AGG-ID: Ej5S0OsBPlOBgsZQd1dktA Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-43941ad86d4so8423055e9.2 for ; Thu, 13 Feb 2025 08:01:06 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462464; x=1740067264; 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=JDXDdyrYu8aqHcWMZRgkJHUGkK2ZXNisxDcxlPZPe2o=; b=N3TxvArPe+fyTyFanreowuZXmAr6ye0zUlCcC95FQqyRNPktGhrqwlAecOaIzf+1Z8 sQ0cLvjEH2uTdQN0fdeW2BI7tHH1yeFThfAvD5G0MjR01cN70R7PRRNdZKbPGBiOf9Nh HYmL/Img45BeUAZZdERvJeMLxulOOWzxsRH1SOcrrSAC1FqHQLo1O168gCn4avAfh39R JVyLJh5e3O4H7ji5CEyo0shjNMj744+dtI1ElXetGuj0k+CwfdwKouBcDop28Jb4iy44 e8vwa7x+0OKnR2on64nryvAYleQNKNUW60HUkHxzpVa2btbVF3MCjSNbFeLXqW4muieU WwSQ== X-Gm-Message-State: AOJu0YxDVv84hfO/0UAeMUBC3T0TRkGcvnUiNZmtLolZkYh3xtulceGO AbPtnNJblHv8ZzBNRoEp9yhrKpeNGAnDXcecQXtSRqqAZbw8ZugYnHcAtF58T2NqU7Inlp63DaQ 2DgpsDynp7kOkOqTnaBc4cxL7CzZvUVpIxduTpv1OgNKTDcb5RnLGv80jl2jwzorUd6/Pxxi4k6 XlV1taj5uX2qui4bHyaZOB1+eo9feEuoHDyGpTuM0= X-Gm-Gg: ASbGncsj7t5MaRwAs6Ax4dCRALMh8Ka1aulYFu1DMfnre6FGBwZ2k7kPEMl2zQpDA9t zpirpNK/6caKhS7WTpvSOTOZLE0hLxpLjMjvzo5UulRGKlgHbNO2n94Y+TOo/64DMdC1EgxS58q +6ZgYi5a+GI0DN9G+onEf+gfkl+oxFemSpzlbCss7fQdkY6oUkCsbHMEBm16lEPiE0WAhNwLnbj 7XRrhLsLpF7l37oAo+F89UP6gEcPFkSotzp4dZdhqsEVfj36NMp+FKkPNg6BFbbGAJLvqCslExE 9daw8RQn1dbEyH2hSKJlJj3XKKbRzn8e1NAv8GiD4RFo9w== X-Received: by 2002:a05:600c:3d86:b0:439:61cd:4fc0 with SMTP id 5b1f17b1804b1-43961cd5298mr33511495e9.24.1739462462661; Thu, 13 Feb 2025 08:01:02 -0800 (PST) X-Google-Smtp-Source: AGHT+IF1ICZNqoM/P1kZwMj/1G6bY681Fn1W5wEmVRPxCx1xxpyfCFbfvEla+EjI3eVBVTH+Dh+05w== X-Received: by 2002:a05:600c:3d86:b0:439:61cd:4fc0 with SMTP id 5b1f17b1804b1-43961cd5298mr33510335e9.24.1739462461482; Thu, 13 Feb 2025 08:01:01 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4395a04ee48sm53074745e9.3.2025.02.13.08.01.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:00 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 02/27] rust: qom: add reference counting functionality Date: Thu, 13 Feb 2025 17:00:29 +0100 Message-ID: <20250213160054.3937012-3-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 Add a smart pointer that allows to add and remove references from QOM objects. It's important to note that while all QOM objects have a reference count, in practice not all of them have their lifetime guarded by it. Embedded objects, specifically, are confined to the lifetime of the owner. When writing Rust bindings this is important, because embedded objects are *never* used through the "Owned<>" smart pointer that is introduced here. Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/qom.rs | 166 +++++++++++++++++++++++++++++++++-- rust/qemu-api/src/vmstate.rs | 6 +- rust/qemu-api/tests/tests.rs | 13 ++- 3 files changed, 178 insertions(+), 7 deletions(-) diff --git a/rust/qemu-api/src/qom.rs b/rust/qemu-api/src/qom.rs index f50ee371aac..404446d57fc 100644 --- a/rust/qemu-api/src/qom.rs +++ b/rust/qemu-api/src/qom.rs @@ -56,6 +56,7 @@ use std::{ ffi::CStr, fmt, + mem::ManuallyDrop, ops::{Deref, DerefMut}, os::raw::c_void, ptr::NonNull, @@ -63,7 +64,13 @@ pub use bindings::{Object, ObjectClass}; -use crate::bindings::{self, object_dynamic_cast, object_get_class, object_get_typename, TypeInfo}; +use crate::{ + bindings::{ + self, object_dynamic_cast, object_get_class, object_get_typename, object_ref, object_unref, + TypeInfo, + }, + cell::bql_locked, +}; /// Marker trait: `Self` can be statically upcasted to `P` (i.e. `P` is a direct /// or indirect parent of `Self`). @@ -280,10 +287,10 @@ fn as_ptr(&self) -> *const U /// /// # Safety /// - /// This method is unsafe because it overrides const-ness of `&self`. - /// Bindings to C APIs will use it a lot, but otherwise it should not - /// be necessary. - unsafe fn as_mut_ptr(&self) -> *mut U + /// This method is safe because only the actual dereference of the pointer + /// has to be unsafe. Bindings to C APIs will use it a lot, but care has + /// to be taken because it overrides the const-ness of `&self`. + fn as_mut_ptr(&self) -> *mut U where Self::Target: IsA, { @@ -610,6 +617,148 @@ unsafe impl ObjectType for Object { unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_OBJECT) }; } +/// A reference-counted pointer to a QOM object. +/// +/// `Owned` wraps `T` with automatic reference counting. It increases the +/// reference count when created via [`Owned::from`] or cloned, and decreases +/// it when dropped. This ensures that the reference count remains elevated +/// as long as any `Owned` references to it exist. +/// +/// `Owned` can be used for two reasons: +/// * because the lifetime of the QOM object is unknown and someone else could +/// take a reference (similar to `Arc`, for example): in this case, the +/// object can escape and outlive the Rust struct that contains the `Owned` +/// field; +/// +/// * to ensure that the object stays alive until after `Drop::drop` is called +/// on the Rust struct: in this case, the object will always die together with +/// the Rust struct that contains the `Owned` field. +/// +/// Child properties are an example of the second case: in C, an object that +/// is created with `object_initialize_child` will die *before* +/// `instance_finalize` is called, whereas Rust expects the struct to have valid +/// contents when `Drop::drop` is called. Therefore Rust structs that have +/// child properties need to keep a reference to the child object. Right now +/// this can be done with `Owned`; in the future one might have a separate +/// `Child<'parent, T>` smart pointer that keeps a reference to a `T`, like +/// `Owned`, but does not allow cloning. +/// +/// Note that dropping an `Owned` requires the big QEMU lock to be taken. +#[repr(transparent)] +#[derive(PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct Owned(NonNull); + +// The following rationale for safety is taken from Linux's kernel::sync::Arc. + +// SAFETY: It is safe to send `Owned` to another thread when the underlying +// `T` is `Sync` because it effectively means sharing `&T` (which is safe +// because `T` is `Sync`); additionally, it needs `T` to be `Send` because any +// thread that has an `Owned` may ultimately access `T` using a +// mutable reference when the reference count reaches zero and `T` is dropped. +unsafe impl Send for Owned {} + +// SAFETY: It is safe to send `&Owned` to another thread when the underlying +// `T` is `Sync` because it effectively means sharing `&T` (which is safe +// because `T` is `Sync`); additionally, it needs `T` to be `Send` because any +// thread that has a `&Owned` may clone it and get an `Owned` on that +// thread, so the thread may ultimately access `T` using a mutable reference +// when the reference count reaches zero and `T` is dropped. +unsafe impl Sync for Owned {} + +impl Owned { + /// Convert a raw C pointer into an owned reference to the QOM + /// object it points to. The object's reference count will be + /// decreased when the `Owned` is dropped. + /// + /// # Panics + /// + /// Panics if `ptr` is NULL. + /// + /// # Safety + /// + /// The caller must indeed own a reference to the QOM object. + /// The object must not be embedded in another unless the outer + /// object is guaranteed to have a longer lifetime. + /// + /// A raw pointer obtained via [`Owned::into_raw()`] can always be passed + /// back to `from_raw()` (assuming the original `Owned` was valid!), + /// since the owned reference remains there between the calls to + /// `into_raw()` and `from_raw()`. + pub unsafe fn from_raw(ptr: *const T) -> Self { + // SAFETY NOTE: while NonNull requires a mutable pointer, only + // Deref is implemented so the pointer passed to from_raw + // remains const + Owned(NonNull::new(ptr as *mut T).unwrap()) + } + + /// Obtain a raw C pointer from a reference. `src` is consumed + /// and the reference is leaked. + #[allow(clippy::missing_const_for_fn)] + pub fn into_raw(src: Owned) -> *mut T { + let src = ManuallyDrop::new(src); + src.0.as_ptr() + } + + /// Increase the reference count of a QOM object and return + /// a new owned reference to it. + /// + /// # Safety + /// + /// The object must not be embedded in another, unless the outer + /// object is guaranteed to have a longer lifetime. + pub unsafe fn from(obj: &T) -> Self { + unsafe { + object_ref(obj.as_object_mut_ptr().cast::()); + + // SAFETY NOTE: while NonNull requires a mutable pointer, only + // Deref is implemented so the reference passed to from_raw + // remains shared + Owned(NonNull::new_unchecked(obj.as_mut_ptr())) + } + } +} + +impl Clone for Owned { + fn clone(&self) -> Self { + // SAFETY: creation method is unsafe; whoever calls it has + // responsibility that the pointer is valid, and remains valid + // throughout the lifetime of the `Owned` and its clones. + unsafe { Owned::from(self.deref()) } + } +} + +impl Deref for Owned { + type Target = T; + + fn deref(&self) -> &Self::Target { + // SAFETY: creation method is unsafe; whoever calls it has + // responsibility that the pointer is valid, and remains valid + // throughout the lifetime of the `Owned` and its clones. + // With that guarantee, reference counting ensures that + // the object remains alive. + unsafe { &*self.0.as_ptr() } + } +} +impl ObjectDeref for Owned {} + +impl Drop for Owned { + fn drop(&mut self) { + assert!(bql_locked()); + // SAFETY: creation method is unsafe, and whoever calls it has + // responsibility that the pointer is valid, and remains valid + // throughout the lifetime of the `Owned` and its clones. + unsafe { + object_unref(self.as_object_mut_ptr().cast::()); + } + } +} + +impl> fmt::Debug for Owned { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.deref().debug_fmt(f) + } +} + /// Trait for methods exposed by the Object class. The methods can be /// called on all objects that have the trait `IsA`. /// @@ -641,6 +790,13 @@ fn get_class(&self) -> &'static ::Class { klass } + + /// Convenience function for implementing the Debug trait + fn debug_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple(&self.typename()) + .field(&(self as *const Self)) + .finish() + } } impl ObjectMethods for R where R::Target: IsA {} diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 6ac432cf52f..11d21b8791c 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -29,6 +29,8 @@ pub use crate::bindings::{VMStateDescription, VMStateField}; use crate::{ bindings::{self, VMStateFlags}, + prelude::*, + qom::Owned, zeroable::Zeroable, }; @@ -191,7 +193,8 @@ pub const fn vmstate_varray_flag(_: PhantomData) -> VMStateFlags /// * a transparent wrapper for any of the above (`Cell`, `UnsafeCell`, /// [`BqlCell`](crate::cell::BqlCell), [`BqlRefCell`](crate::cell::BqlRefCell) /// * a raw pointer to any of the above -/// * a `NonNull` pointer or a `Box` for any of the above +/// * a `NonNull` pointer, a `Box` or an [`Owned`](crate::qom::Owned) for any of +/// the above /// * an array of any of the above /// /// In order to support other types, the trait `VMState` must be implemented @@ -398,6 +401,7 @@ unsafe impl<$base> VMState for $type where $base: VMState $($where)* { // Unlike C pointers, Box is always non-null therefore there is no need // to specify VMS_ALLOC. impl_vmstate_pointer!(Box where T: VMState); +impl_vmstate_pointer!(Owned where T: VMState + ObjectType); // Arrays using the underlying type's VMState plus // VMS_ARRAY/VMS_ARRAY_OF_POINTER diff --git a/rust/qemu-api/tests/tests.rs b/rust/qemu-api/tests/tests.rs index 5c3e75ed3d5..5f6096a572e 100644 --- a/rust/qemu-api/tests/tests.rs +++ b/rust/qemu-api/tests/tests.rs @@ -15,7 +15,7 @@ declare_properties, define_property, prelude::*, qdev::{DeviceClass, DeviceImpl, DeviceState, Property}, - qom::{ClassInitImpl, ObjectImpl, ParentField}, + qom::{ClassInitImpl, ObjectImpl, Owned, ParentField}, vmstate::VMStateDescription, zeroable::Zeroable, }; @@ -138,6 +138,17 @@ fn test_object_new() { } } +#[test] +#[allow(clippy::redundant_clone)] +/// Create, clone and then drop an instance. +fn test_clone() { + init_qom(); + let p: *mut DummyState = unsafe { object_new(DummyState::TYPE_NAME.as_ptr()).cast() }; + let p = unsafe { Owned::from_raw(p) }; + assert_eq!(p.clone().typename(), "dummy"); + drop(p); +} + #[test] /// Try invoking a method on an object. fn test_typename() { From patchwork Thu Feb 13 16:00: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: 13973526 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 4D4CBC021A0 for ; Thu, 13 Feb 2025 16:02:33 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibey-0000yw-Tt; Thu, 13 Feb 2025 11:01:52 -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 1tibeQ-0000pc-0D for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:22 -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 1tibeO-0005Rc-12 for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462474; 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=p4TsCALrwmKkF6xOTgGrMRoSliyIjrnUML60NrYfbfc=; b=T7Rwr3GKve12IgiJtWvVgHTRvTnba2hDqMOKKbYHRyxNAPFsttDHV+8/rNTcR+f79aZmOj DOOc4qLPeM/Z+QH4gzzV9ew7AEXhRkNEIpr8879MJn4CZArmU3HE9SoYh6rVKV3MrOljhf P4YEFboRCWJmsdXsepo6QoHk2byT/4g= 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-6-MOvkylzPMtunqmV7OtXFjQ-1; Thu, 13 Feb 2025 11:01:13 -0500 X-MC-Unique: MOvkylzPMtunqmV7OtXFjQ-1 X-Mimecast-MFC-AGG-ID: MOvkylzPMtunqmV7OtXFjQ_1739462472 Received: by mail-ej1-f70.google.com with SMTP id a640c23a62f3a-ab7e9f7381cso119694566b.2 for ; Thu, 13 Feb 2025 08:01:13 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462472; x=1740067272; 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=p4TsCALrwmKkF6xOTgGrMRoSliyIjrnUML60NrYfbfc=; b=m3ri6TBm6fTullz74GPqaEm1YGtrkIbswlgJ/kW8NDVMy/kqMS7cxvRs4B9+YhvtJu geWysC0oqmZ7xT/oAeclTML7hdZ/gNwiK9JN06HCgpnlq7paVfmt8Ks9O/JLu3C2gHlB tETAT0mfH5zFV5d1AIxalQnsyB15OC7PcxmAlnczkeI2vwRwxjR8ZR1Ues4HUdjrC5Qr rVjMymlxWamDkFTaTMllPZQlucIHW6txDDCxXaXFbVO3PU/CHd+z+TVv/7mtk9PwxInC gWfH8lgj+5V1lqGuxOBjna0RyMvZBw485tc4jw6rywGbc1uHAwGO46oXzE8jDyVd3lqp Y+pQ== X-Gm-Message-State: AOJu0Yzm4fDtjOhQ6kezwyr1UA/oc+OXS1A2w2DJ3Go7dePZlFpc7Iea bRoIAU0NlReI/4SQR2+43ZwyJCwRdh7dPAntN1oQv/UAvm5kAJhXecDD5sAZaR/4GTES+94VmOG kfHkr3i5Ks1l06UiN+28BzMmD0qUZFlTaj07kWEX1wnX+UOzZ0h2oyC20rjKNb9Qfl3CcMR+7MT zET13U2TeIM3RqTHrSM5LM57lq/bbZHdEaEDm2DiU= X-Gm-Gg: ASbGncuYDLGtmI5pdl+w7GjvI/gXKqUDYHWOk3/O9PmSGvloKyWMJY2CTQRP9DkOPjn R+PQfnkluDMqjvdQFsKOiVFUyPR92kPn0wkyfMWA0/E99+cav8fTKFxPxSlsVwfKygvxsCRGpXw srjbH20vkQGcbAoe/DmZCokgl43mackLvyUHNSiuAYxDvQ5d88vZBBMt5fURWhmH4ijBIEjdPFW OZWLO2DPYh8kqtKyCq9rVVdhuaCeCRgUpFWQQKw/4Updy/QmLJdN4YXWK9Hi/V5zabMtqrm8yqH i0xWtoJrJlBMFQA5QFjONU1K9p0SPVvm433XPDycQfINfg== X-Received: by 2002:a17:907:2d0c:b0:ab7:f2da:8125 with SMTP id a640c23a62f3a-aba4ebca817mr435292066b.27.1739462469966; Thu, 13 Feb 2025 08:01:09 -0800 (PST) X-Google-Smtp-Source: AGHT+IHugt1Thz3R1hT0Ofwk6m+PP3dolqfTTzoxNHJK/Vt8RDldRhVy1m6VXZ9RwtuoNSQhjZi93g== X-Received: by 2002:a17:907:2d0c:b0:ab7:f2da:8125 with SMTP id a640c23a62f3a-aba4ebca817mr435204566b.27.1739462463300; Thu, 13 Feb 2025 08:01:03 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4396180f199sm21157805e9.15.2025.02.13.08.01.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:02 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 03/27] rust: qom: add object creation functionality Date: Thu, 13 Feb 2025 17:00:30 +0100 Message-ID: <20250213160054.3937012-4-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 The basic object lifecycle test can now be implemented using safe code! Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- rust/hw/char/pl011/src/device.rs | 23 ++++++++++++--------- rust/qemu-api/src/prelude.rs | 1 + rust/qemu-api/src/qom.rs | 23 +++++++++++++++++++-- rust/qemu-api/tests/tests.rs | 35 ++++++++++++-------------------- 4 files changed, 48 insertions(+), 34 deletions(-) diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index 8050ede9c85..f5db114b0c7 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -10,11 +10,11 @@ use qemu_api::{ bindings::{ - error_fatal, hwaddr, memory_region_init_io, qdev_init_clock_in, qdev_new, - qdev_prop_set_chr, qemu_chr_fe_accept_input, qemu_chr_fe_ioctl, qemu_chr_fe_set_handlers, - qemu_chr_fe_write_all, qemu_irq, sysbus_connect_irq, sysbus_mmio_map, - sysbus_realize_and_unref, CharBackend, Chardev, Clock, ClockEvent, MemoryRegion, - QEMUChrEvent, CHR_IOCTL_SERIAL_SET_BREAK, + error_fatal, hwaddr, memory_region_init_io, qdev_init_clock_in, qdev_prop_set_chr, + qemu_chr_fe_accept_input, qemu_chr_fe_ioctl, qemu_chr_fe_set_handlers, + qemu_chr_fe_write_all, qemu_irq, sysbus_connect_irq, sysbus_mmio_map, sysbus_realize, + CharBackend, Chardev, Clock, ClockEvent, MemoryRegion, QEMUChrEvent, + CHR_IOCTL_SERIAL_SET_BREAK, }, c_str, impl_vmstate_forward, irq::InterruptSource, @@ -705,15 +705,18 @@ pub fn post_load(&self, _version_id: u32) -> Result<(), ()> { irq: qemu_irq, chr: *mut Chardev, ) -> *mut DeviceState { + let pl011 = PL011State::new(); unsafe { - let dev: *mut DeviceState = qdev_new(PL011State::TYPE_NAME.as_ptr()); - let sysbus: *mut SysBusDevice = dev.cast::(); - + let dev = pl011.as_mut_ptr::(); qdev_prop_set_chr(dev, c_str!("chardev").as_ptr(), chr); - sysbus_realize_and_unref(sysbus, addr_of_mut!(error_fatal)); + + let sysbus = pl011.as_mut_ptr::(); + sysbus_realize(sysbus, addr_of_mut!(error_fatal)); sysbus_mmio_map(sysbus, 0, addr); sysbus_connect_irq(sysbus, 0, irq); - dev + + // return the pointer, which is kept alive by the QOM tree; drop owned ref + pl011.as_mut_ptr() } } diff --git a/rust/qemu-api/src/prelude.rs b/rust/qemu-api/src/prelude.rs index 2dc86e19b29..3df6a5c21ec 100644 --- a/rust/qemu-api/src/prelude.rs +++ b/rust/qemu-api/src/prelude.rs @@ -12,6 +12,7 @@ pub use crate::qom::ObjectCast; pub use crate::qom::ObjectCastMut; pub use crate::qom::ObjectDeref; +pub use crate::qom::ObjectClassMethods; pub use crate::qom::ObjectMethods; pub use crate::qom::ObjectType; diff --git a/rust/qemu-api/src/qom.rs b/rust/qemu-api/src/qom.rs index 404446d57fc..3e63cb30ca6 100644 --- a/rust/qemu-api/src/qom.rs +++ b/rust/qemu-api/src/qom.rs @@ -66,8 +66,8 @@ use crate::{ bindings::{ - self, object_dynamic_cast, object_get_class, object_get_typename, object_ref, object_unref, - TypeInfo, + self, object_dynamic_cast, object_get_class, object_get_typename, object_new, object_ref, + object_unref, TypeInfo, }, cell::bql_locked, }; @@ -759,6 +759,24 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } +/// Trait for class methods exposed by the Object class. The methods can be +/// called on all objects that have the trait `IsA`. +/// +/// The trait should only be used through the blanket implementation, +/// which guarantees safety via `IsA` +pub trait ObjectClassMethods: IsA { + /// Return a new reference counted instance of this class + fn new() -> Owned { + assert!(bql_locked()); + // 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::()) + } + } +} + /// Trait for methods exposed by the Object class. The methods can be /// called on all objects that have the trait `IsA`. /// @@ -799,4 +817,5 @@ fn debug_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } +impl ObjectClassMethods for T where T: IsA {} impl ObjectMethods for R where R::Target: IsA {} diff --git a/rust/qemu-api/tests/tests.rs b/rust/qemu-api/tests/tests.rs index 5f6096a572e..10748fba197 100644 --- a/rust/qemu-api/tests/tests.rs +++ b/rust/qemu-api/tests/tests.rs @@ -3,8 +3,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later use std::{ - ffi::CStr, - os::raw::c_void, + ffi::{c_void, CStr}, ptr::{addr_of, addr_of_mut}, }; @@ -15,7 +14,7 @@ declare_properties, define_property, prelude::*, qdev::{DeviceClass, DeviceImpl, DeviceState, Property}, - qom::{ClassInitImpl, ObjectImpl, Owned, ParentField}, + qom::{ClassInitImpl, ObjectImpl, ParentField}, vmstate::VMStateDescription, zeroable::Zeroable, }; @@ -132,10 +131,8 @@ fn init_qom() { /// Create and immediately drop an instance. fn test_object_new() { init_qom(); - unsafe { - object_unref(object_new(DummyState::TYPE_NAME.as_ptr()).cast()); - object_unref(object_new(DummyChildState::TYPE_NAME.as_ptr()).cast()); - } + drop(DummyState::new()); + drop(DummyChildState::new()); } #[test] @@ -143,8 +140,7 @@ fn test_object_new() { /// Create, clone and then drop an instance. fn test_clone() { init_qom(); - let p: *mut DummyState = unsafe { object_new(DummyState::TYPE_NAME.as_ptr()).cast() }; - let p = unsafe { Owned::from_raw(p) }; + let p = DummyState::new(); assert_eq!(p.clone().typename(), "dummy"); drop(p); } @@ -153,12 +149,8 @@ fn test_clone() { /// Try invoking a method on an object. fn test_typename() { init_qom(); - let p: *mut DummyState = unsafe { object_new(DummyState::TYPE_NAME.as_ptr()).cast() }; - let p_ref: &DummyState = unsafe { &*p }; - assert_eq!(p_ref.typename(), "dummy"); - unsafe { - object_unref(p_ref.as_object_mut_ptr().cast::()); - } + let p = DummyState::new(); + assert_eq!(p.typename(), "dummy"); } // a note on all "cast" tests: usually, especially for downcasts the desired @@ -173,24 +165,23 @@ fn test_typename() { /// Test casts on shared references. fn test_cast() { init_qom(); - let p: *mut DummyState = unsafe { object_new(DummyState::TYPE_NAME.as_ptr()).cast() }; + let p = DummyState::new(); + let p_ptr: *mut DummyState = p.as_mut_ptr(); + let p_ref: &mut DummyState = unsafe { &mut *p_ptr }; - let p_ref: &DummyState = unsafe { &*p }; let obj_ref: &Object = p_ref.upcast(); - assert_eq!(addr_of!(*obj_ref), p.cast()); + assert_eq!(addr_of!(*obj_ref), p_ptr.cast()); let sbd_ref: Option<&SysBusDevice> = obj_ref.dynamic_cast(); assert!(sbd_ref.is_none()); let dev_ref: Option<&DeviceState> = obj_ref.downcast(); - assert_eq!(addr_of!(*dev_ref.unwrap()), p.cast()); + assert_eq!(addr_of!(*dev_ref.unwrap()), p_ptr.cast()); // SAFETY: the cast is wrong, but the value is only used for comparison unsafe { let sbd_ref: &SysBusDevice = obj_ref.unsafe_cast(); - assert_eq!(addr_of!(*sbd_ref), p.cast()); - - object_unref(p_ref.as_object_mut_ptr().cast::()); + assert_eq!(addr_of!(*sbd_ref), p_ptr.cast()); } } From patchwork Thu Feb 13 16:00: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: 13973549 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 E8BE9C021A4 for ; Thu, 13 Feb 2025 16:07:56 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibf0-0000zP-Fs; Thu, 13 Feb 2025 11:01:54 -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 1tibeP-0000pZ-Td for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:22 -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 1tibeJ-0005Qg-An for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462470; 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=XCiret68kVy9ikx7EXAg8zqFJuISRQAId/mthV/wRgU=; b=XgcurFbPdmzgJ0/5iSsekPbNAzSsl652rMlmauCTkuseVsn/2i5ULz4eeqwZHJUvvHiiJK Yjbb8U5migkLUnhrsUjLWfurcVAh0g+fCB5TMByxcbMziR/qjuMfgwbFOJJ8kB2IPGXPCN 4423LekppT7/RG8/aKY3tdxvoSP7v3M= 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-584-WnNe7Cg7M9iqwkBoBwqgPw-1; Thu, 13 Feb 2025 11:01:08 -0500 X-MC-Unique: WnNe7Cg7M9iqwkBoBwqgPw-1 X-Mimecast-MFC-AGG-ID: WnNe7Cg7M9iqwkBoBwqgPw Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-4394040fea1so6230615e9.0 for ; Thu, 13 Feb 2025 08:01:08 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462467; x=1740067267; 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=XCiret68kVy9ikx7EXAg8zqFJuISRQAId/mthV/wRgU=; b=GQiPBkFTOMKXQlLMcmJheVW75Y46Ec6ESKjmGv4f/9mKrdpYqEpcc+F/mEIjOKKkKk khyIkjsD5MORIRMaNUvuiCkkxoovDTbIkLyuRR6E9V97ejUa5FWLC6dNfdpm53bxPCwg M0KHHBDmkSk/Kcgzm7DAeceX0yEB1OovLPTvYswcW8s74IGX/Qy2a2dxPHuSKycqfzMO VjRGbjLGrRFoxSG7CniRe+sD7kNUyeNaGByhfa5aJhGzeHY8oK4iBTnn8Q0iI/UOOGhS NlDA3sC3Y11aa/J6MIvCczn+cPLlTu5O5M/Qw7/D1i6PSJWdaEXMbwd99U7vR5I6UXrh HhAw== X-Gm-Message-State: AOJu0YzDF/q5JyndmA1V7APyfo0XfNLoS6odbPRVTzl/U2vGiwu1sxHR oQKoy3JRPm9v3JLIZjC4XEwBdvx1fsQ6a3WcZIq1NcnNiL/ZLl3H7+bu6cbrIGzxNr03e/bAaR2 3QgL34leLt/ERjYsz21drDlNBaXRZzE6QtLU3bhNYiNpRsq77no9QLzuPVeCrsR74kPv/Cwy1V9 TedV4ib/J5+GMrBltWiiDSHJpVHkjHbGdZewf9RqA= X-Gm-Gg: ASbGncsaGwyXKp+OdIM4F+QG2McRg3+SBLHe5gCmocRHD6PtpdvMd4NadwZK3J0Ackb gC43/xwumo9davQDBI5wX3hlG4RvcA5eDn7jRmx92hkJ6tXgLYbDwe8/gtzwy6FwNMLY3WitvBl 9jXf1xBV5cV7OdyY/V6+7aV5e7sspJjjSQAAsmnkqhTeSDueJ2c5kJcIC5eS7/oXelYpTzMmfDe HexWKAWZQ543nuMmUQSta00Phv6fGfzdxoT/B5N741DpRwWYQjR4EsipgDtLVkZp1rHXhr/aP5K 5VR5Js4kyEKfxR8pBKzq//VvskSb/HHi14hk4kmys/G0Zg== X-Received: by 2002:a05:600c:6a15:b0:439:5cf6:ec3 with SMTP id 5b1f17b1804b1-43960bca41fmr36849645e9.4.1739462466989; Thu, 13 Feb 2025 08:01:06 -0800 (PST) X-Google-Smtp-Source: AGHT+IGG3n03WFGaiuZw0EnXX+R1paGlqFU+k8lMKVxHFMd2DuUvGuhBZ/lD9G6tiTSkOKQg1UbtZA== X-Received: by 2002:a05:600c:6a15:b0:439:5cf6:ec3 with SMTP id 5b1f17b1804b1-43960bca41fmr36848945e9.4.1739462466314; Thu, 13 Feb 2025 08:01:06 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4395a1b824dsm52248675e9.34.2025.02.13.08.01.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:05 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 04/27] rust: callbacks: allow passing optional callbacks as () Date: Thu, 13 Feb 2025 17:00:31 +0100 Message-ID: <20250213160054.3937012-5-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 In some cases, callbacks are optional. Using "Some(function)" and "None" does not work well, because when someone writes "None" the compiler does not know what to use for "F" in "Option". Therefore, adopt () to mean a "null" callback. It is possible to enforce that a callback is valid by adding a "let _: () = F::ASSERT_IS_SOME" before the invocation of F::call. Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/callbacks.rs | 97 ++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/rust/qemu-api/src/callbacks.rs b/rust/qemu-api/src/callbacks.rs index 314f9dce962..9642a16eb89 100644 --- a/rust/qemu-api/src/callbacks.rs +++ b/rust/qemu-api/src/callbacks.rs @@ -79,6 +79,31 @@ /// call_it(&move |_| String::from(x), "hello workd"); /// ``` /// +/// `()` can be used to indicate "no function": +/// +/// ``` +/// # use qemu_api::callbacks::FnCall; +/// fn optional FnCall<(&'a str,), String>>(_f: &F, s: &str) -> Option { +/// if F::IS_SOME { +/// Some(F::call((s,))) +/// } else { +/// None +/// } +/// } +/// +/// assert!(optional(&(), "hello world").is_none()); +/// ``` +/// +/// Invoking `F::call` will then be a run-time error. +/// +/// ```should_panic +/// # use qemu_api::callbacks::FnCall; +/// # fn call_it FnCall<(&'a str,), String>>(_f: &F, s: &str) -> String { +/// # F::call((s,)) +/// # } +/// let s: String = call_it(&(), "hello world"); // panics +/// ``` +/// /// # Safety /// /// Because `Self` is a zero-sized type, all instances of the type are @@ -93,10 +118,70 @@ pub unsafe trait FnCall: 'static + Sync + Sized { /// Rust 1.79.0+. const ASSERT_ZERO_SIZED: () = { assert!(mem::size_of::() == 0) }; + /// Referring to this constant asserts that the `Self` type is an actual + /// function type, which can be used to catch incorrect use of `()` + /// at compile time. + /// + /// # Examples + /// + /// ```compile_fail + /// # use qemu_api::callbacks::FnCall; + /// fn call_it FnCall<(&'a str,), String>>(_f: &F, s: &str) -> String { + /// let _: () = F::ASSERT_IS_SOME; + /// F::call((s,)) + /// } + /// + /// let s: String = call_it((), "hello world"); // does not compile + /// ``` + /// + /// Note that this can be more simply `const { assert!(F::IS_SOME) }` in + /// Rust 1.79.0 or newer. + const ASSERT_IS_SOME: () = { assert!(Self::IS_SOME) }; + + /// `true` if `Self` is an actual function type and not `()`. + /// + /// # Examples + /// + /// You can use `IS_SOME` to catch this at compile time: + /// + /// ```compile_fail + /// # use qemu_api::callbacks::FnCall; + /// fn call_it FnCall<(&'a str,), String>>(_f: &F, s: &str) -> String { + /// const { assert!(F::IS_SOME) } + /// F::call((s,)) + /// } + /// + /// let s: String = call_it((), "hello world"); // does not compile + /// ``` + const IS_SOME: bool; + + /// `false` if `Self` is an actual function type, `true` if it is `()`. + fn is_none() -> bool { + !Self::IS_SOME + } + + /// `true` if `Self` is an actual function type, `false` if it is `()`. + fn is_some() -> bool { + Self::IS_SOME + } + /// Call the function with the arguments in args. fn call(a: Args) -> R; } +/// `()` acts as a "null" callback. Using `()` and `function` is nicer +/// than `None` and `Some(function)`, because the compiler is unable to +/// infer the type of just `None`. Therefore, the trait itself acts as the +/// option type, with functions [`FnCall::is_some`] and [`FnCall::is_none`]. +unsafe impl FnCall for () { + const IS_SOME: bool = false; + + /// Call the function with the arguments in args. + fn call(_a: Args) -> R { + panic!("callback not specified") + } +} + macro_rules! impl_call { ($($args:ident,)* ) => ( // SAFETY: because each function is treated as a separate type, @@ -106,6 +191,8 @@ unsafe impl FnCall<($($args,)*), R> for F where F: 'static + Sync + Sized + Fn($($args, )*) -> R, { + const IS_SOME: bool = true; + #[inline(always)] fn call(a: ($($args,)*)) -> R { let _: () = Self::ASSERT_ZERO_SIZED; @@ -141,4 +228,14 @@ fn do_test_call<'a, F: FnCall<(&'a str,), String>>(_f: &F) -> String { fn test_call() { assert_eq!(do_test_call(&str::to_owned), "hello world") } + + // The `_f` parameter is unused but it helps the compiler infer `F`. + fn do_test_is_some<'a, F: FnCall<(&'a str,), String>>(_f: &F) { + assert!(F::is_some()); + } + + #[test] + fn test_is_some() { + do_test_is_some(&str::to_owned); + } } From patchwork Thu Feb 13 16:00: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: 13973550 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 89E6CC021A0 for ; Thu, 13 Feb 2025 16:08:55 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibeu-0000x5-0H; Thu, 13 Feb 2025 11:01:48 -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 1tibeW-0000r2-T7 for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:31 -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 1tibeS-0005Sg-2k for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:23 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462479; 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=fpScOGuqkkpqCWAGOqG2RKOLu/MENt6Jr9VwylD8zsA=; b=YQVim5+vwK7FurL4lX8TXoDQKzQPJ+YPvDIXkwK4ZNyR6Sj+OHD+mp02AKd/2yL9ZIrcVg MQNiawc5maa5XZO6G66NxYeWsGWSwjRnkT88fAnJ05AaAcLB0frVm+SCCFWhb/Oxei9PF1 kDv+lDSUubDrKLA1Wcpppag1GoT+6Mw= 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-55-Fx7r2193O8yqK6WS-m0rZQ-1; Thu, 13 Feb 2025 11:01:17 -0500 X-MC-Unique: Fx7r2193O8yqK6WS-m0rZQ-1 X-Mimecast-MFC-AGG-ID: Fx7r2193O8yqK6WS-m0rZQ_1739462475 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-38dd533dad0so1177929f8f.0 for ; Thu, 13 Feb 2025 08:01:16 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462474; x=1740067274; 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=fpScOGuqkkpqCWAGOqG2RKOLu/MENt6Jr9VwylD8zsA=; b=eEcefMFlV3x0O7ltfekewHCIr5H3GwN42aK+OstelaInwomejnrpoolQy+FUP79X8Q f+THu8/wI1VFXByy/I7Tl9YoJVm+STAbecIga1pW/iv8Q3TDm5JofDJhuHDZ4s9azYt8 /s47mgqNJMBdBfvUKz1/SnCb+g64WDkv+W9NY/jUIZeBDCvINsP/gIANEx20jAZZ7JIK wKQHMgJv9YvkWHqOztfXungrAi5qAAoF6HgtR1DgiM3NfK/oqP9aUUsq9v7QS80KHgNx qSCbwXCnIQeCM8yJdJypTMtOvW/nj3leEwUPkmQz7hvgLZkg5jXzILRQUp8joExBbjKP ZMVw== X-Gm-Message-State: AOJu0YxH2vdlo4C2J2qa5fftPczSupSzERXAvkK1vvQcY/nZbBqGyyPt FQqJ1oHxCZbjL3DDy0XcuY0dSKQK/FwrevOIa1GLDkuPeghsrXdLiB2M6KBdcBxlDpuvXrpwjUx jGDJRGgtQPDaCXzJ4GE5/j8GLwSz7UkbyPcrWJ3bMkZndc1X+t5cWLdFkmesPsZ1jmtEaSYfyot eHeEDJu5eL4mpz7mo6RDk8qNwI7RAIAVaWmQcsiQg= X-Gm-Gg: ASbGnctcxgtyper5aSXlQhYUOk86ggOzumu4bmNp6wLTN4ByMEDzBWdLDWZoLnpVPj9 R8FsrjCaEFMfLNAjDHl2LD4ZbgSvTp8xU/HnBO3q7OmCzeaFr+tjQC03cV1gFdi1RPyDVzS+iQT 5NmI5AahPrg8gARORRcsW3k0cDpEdVw4HO6bxgdIOwsi0DoqopneB17PrVCt33c/c73C4Y47qGf nu5l5tpIcq84Ne/qLfnCJGTjVzS6G8y7FjK423pH4Z6O5gn3C1f7BP9mZelhroh0dooeW9yPGnH OBNXHXwqcChnbD8058ZmevjDONpHwM/kyJ7os0BoQBxtwA== X-Received: by 2002:a05:6000:18a7:b0:38d:dfb8:368d with SMTP id ffacd0b85a97d-38dea2f76ddmr7278923f8f.50.1739462469856; Thu, 13 Feb 2025 08:01:09 -0800 (PST) X-Google-Smtp-Source: AGHT+IE46/BxU0Ec0C8ZUXM85fjiiS60CRxllE+fBxQR+rHcorVSs5iz/bMommZ1x7vXRCkm1tzo7A== X-Received: by 2002:a05:6000:18a7:b0:38d:dfb8:368d with SMTP id ffacd0b85a97d-38dea2f76ddmr7278847f8f.50.1739462469042; Thu, 13 Feb 2025 08:01:09 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f258b4123sm2319261f8f.17.2025.02.13.08.01.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:08 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 05/27] rust: qdev: add clock creation Date: Thu, 13 Feb 2025 17:00:32 +0100 Message-ID: <20250213160054.3937012-6-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 Add a Rust version of qdev_init_clock_in, which can be used in instance_init. There are a couple differences with the C version: - in Rust the object keeps its own reference to the clock (in addition to the one embedded in the NamedClockList), and the reference is dropped automatically by instance_finalize(); this is encoded in the signature of DeviceClassMethods::init_clock_in, which makes the lifetime of the clock independent of that of the object it holds. This goes unnoticed in the C version and is due to the existence of aliases. - also, anything that happens during instance_init uses the pinned_init framework to operate on a partially initialized object, and is done through class methods (i.e. through DeviceClassMethods rather than DeviceMethods) because the device does not exist yet. Therefore, Rust code *must* create clocks from instance_init, which is stricter than C. Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- rust/hw/char/pl011/src/device.rs | 43 +++++-------- rust/qemu-api/src/prelude.rs | 2 + rust/qemu-api/src/qdev.rs | 107 ++++++++++++++++++++++++++++++- rust/qemu-api/src/vmstate.rs | 4 +- 4 files changed, 125 insertions(+), 31 deletions(-) diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index f5db114b0c7..37936a328b8 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -10,17 +10,16 @@ use qemu_api::{ bindings::{ - error_fatal, hwaddr, memory_region_init_io, qdev_init_clock_in, qdev_prop_set_chr, - qemu_chr_fe_accept_input, qemu_chr_fe_ioctl, qemu_chr_fe_set_handlers, - qemu_chr_fe_write_all, qemu_irq, sysbus_connect_irq, sysbus_mmio_map, sysbus_realize, - CharBackend, Chardev, Clock, ClockEvent, MemoryRegion, QEMUChrEvent, - CHR_IOCTL_SERIAL_SET_BREAK, + error_fatal, hwaddr, memory_region_init_io, qdev_prop_set_chr, qemu_chr_fe_accept_input, + qemu_chr_fe_ioctl, qemu_chr_fe_set_handlers, qemu_chr_fe_write_all, qemu_irq, + sysbus_connect_irq, sysbus_mmio_map, sysbus_realize, CharBackend, Chardev, MemoryRegion, + QEMUChrEvent, CHR_IOCTL_SERIAL_SET_BREAK, }, c_str, impl_vmstate_forward, irq::InterruptSource, prelude::*, - qdev::{DeviceImpl, DeviceState, Property}, - qom::{ClassInitImpl, ObjectImpl, ParentField}, + qdev::{Clock, ClockEvent, DeviceImpl, DeviceState, Property}, + qom::{ClassInitImpl, ObjectImpl, Owned, ParentField}, sysbus::{SysBusDevice, SysBusDeviceClass}, vmstate::VMStateDescription, }; @@ -131,7 +130,7 @@ pub struct PL011State { #[doc(alias = "irq")] pub interrupts: [InterruptSource; IRQMASK.len()], #[doc(alias = "clk")] - pub clock: NonNull, + pub clock: Owned, #[doc(alias = "migrate_clk")] pub migrate_clock: bool, } @@ -485,8 +484,6 @@ impl PL011State { /// location/instance. All its fields are expected to hold unitialized /// values with the sole exception of `parent_obj`. unsafe fn init(&mut self) { - const CLK_NAME: &CStr = c_str!("clk"); - // SAFETY: // // self and self.iomem are guaranteed to be valid at this point since callers @@ -506,22 +503,16 @@ unsafe fn init(&mut self) { // SAFETY: // - // self.clock is not initialized at this point; but since `NonNull<_>` is Copy, - // we can overwrite the undefined value without side effects. This is - // safe since all PL011State instances are created by QOM code which - // calls this function to initialize the fields; therefore no code is - // able to access an invalid self.clock value. - unsafe { - let dev: &mut DeviceState = self.upcast_mut(); - self.clock = NonNull::new(qdev_init_clock_in( - dev, - CLK_NAME.as_ptr(), - None, /* pl011_clock_update */ - addr_of_mut!(*self).cast::(), - ClockEvent::ClockUpdate.0, - )) - .unwrap(); - } + // self.clock is not initialized at this point; but since `Owned<_>` is + // not Drop, we can overwrite the undefined value without side effects; + // it's not sound but, because for all PL011State instances are created + // by QOM code which calls this function to initialize the fields, at + // leastno code is able to access an invalid self.clock value. + self.clock = self.init_clock_in("clk", &Self::clock_update, ClockEvent::ClockUpdate); + } + + const fn clock_update(&self, _event: ClockEvent) { + /* pl011_trace_baudrate_change(s); */ } fn post_init(&self) { diff --git a/rust/qemu-api/src/prelude.rs b/rust/qemu-api/src/prelude.rs index 3df6a5c21ec..87e3ce90f26 100644 --- a/rust/qemu-api/src/prelude.rs +++ b/rust/qemu-api/src/prelude.rs @@ -7,6 +7,8 @@ pub use crate::cell::BqlCell; pub use crate::cell::BqlRefCell; +pub use crate::qdev::DeviceMethods; + pub use crate::qom::IsA; pub use crate::qom::Object; pub use crate::qom::ObjectCast; diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs index f4c75c752f1..176c69a5600 100644 --- a/rust/qemu-api/src/qdev.rs +++ b/rust/qemu-api/src/qdev.rs @@ -4,14 +4,20 @@ //! Bindings to create devices and access device functionality from Rust. -use std::{ffi::CStr, ptr::NonNull}; +use std::{ + ffi::{CStr, CString}, + os::raw::c_void, + ptr::NonNull, +}; -pub use bindings::{DeviceClass, DeviceState, Property}; +pub use bindings::{Clock, ClockEvent, DeviceClass, DeviceState, Property}; use crate::{ bindings::{self, Error}, + callbacks::FnCall, + cell::bql_locked, prelude::*, - qom::{ClassInitImpl, ObjectClass}, + qom::{ClassInitImpl, ObjectClass, Owned}, vmstate::VMStateDescription, }; @@ -143,3 +149,98 @@ unsafe impl ObjectType for DeviceState { unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_DEVICE) }; } qom_isa!(DeviceState: Object); + +/// Trait for methods exposed by the [`DeviceState`] class. The methods can be +/// called on all objects that have the trait `IsA`. +/// +/// The trait should only be used through the blanket implementation, +/// which guarantees safety via `IsA`. +pub trait DeviceMethods: ObjectDeref +where + Self::Target: IsA, +{ + /// Add an input clock named `name`. Invoke the callback with + /// `self` as the first parameter for the events that are requested. + /// + /// The resulting clock is added as a child of `self`, but it also + /// stays alive until after `Drop::drop` is called because C code + /// keeps an extra reference to it until `device_finalize()` calls + /// `qdev_finalize_clocklist()`. Therefore (unlike most cases in + /// which Rust code has a reference to a child object) it would be + /// possible for this function to return a `&Clock` too. + #[inline] + fn init_clock_in FnCall<(&'a Self::Target, ClockEvent)>>( + &self, + name: &str, + _cb: &F, + events: ClockEvent, + ) -> Owned { + fn do_init_clock_in( + dev: *mut DeviceState, + name: &str, + cb: Option, + events: ClockEvent, + ) -> Owned { + assert!(bql_locked()); + + // SAFETY: the clock is heap allocated, but qdev_init_clock_in() + // does not gift the reference to its caller; so use Owned::from to + // add one. The callback is disabled automatically when the clock + // is unparented, which happens before the device is finalized. + unsafe { + let cstr = CString::new(name).unwrap(); + let clk = bindings::qdev_init_clock_in( + dev, + cstr.as_ptr(), + cb, + dev.cast::(), + events.0, + ); + + Owned::from(&*clk) + } + } + + let cb: Option = if F::is_some() { + unsafe extern "C" fn rust_clock_cb FnCall<(&'a T, ClockEvent)>>( + opaque: *mut c_void, + event: ClockEvent, + ) { + // SAFETY: the opaque is "this", which is indeed a pointer to T + F::call((unsafe { &*(opaque.cast::()) }, event)) + } + Some(rust_clock_cb::) + } else { + None + }; + + do_init_clock_in(self.as_mut_ptr(), name, cb, events) + } + + /// Add an output clock named `name`. + /// + /// The resulting clock is added as a child of `self`, but it also + /// stays alive until after `Drop::drop` is called because C code + /// keeps an extra reference to it until `device_finalize()` calls + /// `qdev_finalize_clocklist()`. Therefore (unlike most cases in + /// which Rust code has a reference to a child object) it would be + /// possible for this function to return a `&Clock` too. + #[inline] + 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()); + + Owned::from(&*clk) + } + } +} + +impl DeviceMethods for R where R::Target: IsA {} + +unsafe impl ObjectType for Clock { + type Class = ObjectClass; + const TYPE_NAME: &'static CStr = + unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_CLOCK) }; +} +qom_isa!(Clock: Object); diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 11d21b8791c..164effc6553 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -470,11 +470,11 @@ macro_rules! vmstate_clock { $crate::assert_field_type!( $struct_name, $field_name, - core::ptr::NonNull<$crate::bindings::Clock> + $crate::qom::Owned<$crate::bindings::Clock> ); $crate::offset_of!($struct_name, $field_name) }, - size: ::core::mem::size_of::<*const $crate::bindings::Clock>(), + size: ::core::mem::size_of::<*const $crate::qdev::Clock>(), flags: VMStateFlags(VMStateFlags::VMS_STRUCT.0 | VMStateFlags::VMS_POINTER.0), vmsd: unsafe { ::core::ptr::addr_of!($crate::bindings::vmstate_clock) }, ..$crate::zeroable::Zeroable::ZERO From patchwork Thu Feb 13 16:00: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: 13973532 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 D5461C021A0 for ; Thu, 13 Feb 2025 16:03:26 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibeq-0000vu-Vg; Thu, 13 Feb 2025 11:01:45 -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 1tibeU-0000pv-Qf for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:22 -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 1tibeR-0005SQ-7G for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:20 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462478; 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=KJKsboCr/rz3b2EwIlGZQLj7iVI/rClT9i/wfrBfAQo=; b=g4VgqoMUvBIy7yO+lSvwgjAqoPpdP2tJ6w8++pwL4+uJXe4WxIZSGHzeXwEfbCoWRICDxP PptYD6sv8+X8QDNreRlP1FRW+8JtyQdUfTjtzKkYd6nQAaIVH1YmQnoWCihugHA0kMFZNn ghpnedpXjV4XuEMEbYNqgd6TYTgbCVM= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-284-cN9ZZz2ZPtGDHb5iij73hg-1; Thu, 13 Feb 2025 11:01:15 -0500 X-MC-Unique: cN9ZZz2ZPtGDHb5iij73hg-1 X-Mimecast-MFC-AGG-ID: cN9ZZz2ZPtGDHb5iij73hg_1739462474 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-4394b2c19ccso8356655e9.1 for ; Thu, 13 Feb 2025 08:01:15 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462473; x=1740067273; 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=KJKsboCr/rz3b2EwIlGZQLj7iVI/rClT9i/wfrBfAQo=; b=qkQ40+zvVe066GdnFq1Twk2g20AZhexutJWxw5nif4DZnsFfDWzQjYSJt6fOchVOP3 UNR5V4IrhVD/Pv6UqM3J+lxsCMPJ47aiophkDhm9XP2Ql593bgAvtEC3liKnS5fydWUb GMrdnMGyI/c6jQKtOjPJOlZ/IA05ApyWB+oqN9IghlPrOPOnzQH466ZVTdgSwPen83TX OXXEVl5R67jR8WUjdO900rt2Nc9eiVnHx0OiuRFWwqegHAgN2UbPkAO5nCfDZRAy14Wy SAgX7kKIN3x1Pp3+iwvbh9lUIpA2dof0RV90z9wfy98TYTx8+1Ie/+O272Ocyc8g1i4V XLyQ== X-Gm-Message-State: AOJu0YyJsjU7nFJADCChUXmvdiqNGzjo6p5rD4KPRQdnYDqZus+n9MWc oRiQSa3geHHXdHEET4fjSlkhzB2CVR1rpnVv9r2Un0eXHzpjjHqu73yDsqHmP6UFxmad/JUBfI6 nONrJw6HVGX8ZgEotGLqez0FpVwYPnRZweutGHDqflqqv76yqhTMPSHqfMV3Lkmr/kOoEtbpQAb 4eujITzZAnsIubqZ/viJA6rP6UaxIv01U3zMQf53U= X-Gm-Gg: ASbGncsTUZZC8nY+v6uBacrYU5JeUZV0CIL/TYiVoWyfcCJb9ZcHonxVDsCLybsKpub 6lFh8R07qxRX8rx7TiMi+a2LQ5c6kGoixdAIhy9fp6c/Wdw6rpA8VBKgO719Jqj6WanI9nVz707 5ZPxso1nuOy/X5dBuXjl2fUPRFC/Pa4r1GXu3vKSEnBWJcJEaYIOgkqZewmEYHo6UF1Uchb4XFT Gbs7DncrxFVhVVsXgU54lwIyU/BcWzLZmVtbUFTAQwU06XA9PW5a7ELjfyqJkAE/UVSBxkQjT41 PVRvgFnvbR3qVgAoJblLBY3B3Fs89i1IdAlN0fW1WLaj2Q== X-Received: by 2002:a05:600c:c8c:b0:439:31e0:d9a4 with SMTP id 5b1f17b1804b1-4396018a6ccmr56667245e9.10.1739462472874; Thu, 13 Feb 2025 08:01:12 -0800 (PST) X-Google-Smtp-Source: AGHT+IFRHUW8qwvjg/1btvDVyIM03bqYSZSR0qlQmqgXiFpx3SPgXfRfBHXL6+K61nXB+LRTqcPg0g== X-Received: by 2002:a05:600c:c8c:b0:439:31e0:d9a4 with SMTP id 5b1f17b1804b1-4396018a6ccmr56665135e9.10.1739462470816; Thu, 13 Feb 2025 08:01:10 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43961885077sm21118335e9.25.2025.02.13.08.01.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:10 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 06/27] rust: qom: allow initializing interface vtables Date: Thu, 13 Feb 2025 17:00:33 +0100 Message-ID: <20250213160054.3937012-7-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 Unlike regular classes, interface vtables can only be obtained via object_class_dynamic_cast. Provide a wrapper that allows accessing the vtable and pass it to a ClassInitImpl implementation, for example ClassInitImpl. Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/prelude.rs | 1 + rust/qemu-api/src/qom.rs | 45 ++++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/rust/qemu-api/src/prelude.rs b/rust/qemu-api/src/prelude.rs index 87e3ce90f26..254edb476dd 100644 --- a/rust/qemu-api/src/prelude.rs +++ b/rust/qemu-api/src/prelude.rs @@ -9,6 +9,7 @@ pub use crate::qdev::DeviceMethods; +pub use crate::qom::InterfaceType; pub use crate::qom::IsA; pub use crate::qom::Object; pub use crate::qom::ObjectCast; diff --git a/rust/qemu-api/src/qom.rs b/rust/qemu-api/src/qom.rs index 3e63cb30ca6..3d5ab2d9018 100644 --- a/rust/qemu-api/src/qom.rs +++ b/rust/qemu-api/src/qom.rs @@ -66,8 +66,8 @@ use crate::{ bindings::{ - self, object_dynamic_cast, object_get_class, object_get_typename, object_new, object_ref, - object_unref, TypeInfo, + self, object_class_dynamic_cast, object_dynamic_cast, object_get_class, + object_get_typename, object_new, object_ref, object_unref, TypeInfo, }, cell::bql_locked, }; @@ -263,6 +263,47 @@ unsafe fn as_object_mut_ptr(&self) -> *mut Object { } } +/// Trait exposed by all structs corresponding to QOM interfaces. +/// Unlike `ObjectType`, it is implemented on the class type (which provides +/// the vtable for the interfaces). +/// +/// # Safety +/// +/// `TYPE` must match the contents of the `TypeInfo` as found in the C code; +/// right now, interfaces can only be declared in C. +pub unsafe trait InterfaceType: Sized { + /// The name of the type, which can be passed to + /// `object_class_dynamic_cast()` to obtain the pointer to the vtable + /// 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 + /// lists the interface in its `TypeInfo`. + /// + /// # 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, + ) { + unsafe { + // SAFETY: upcasting to ObjectClass is always valid, and the + // return type is either NULL or the argument itself + let result: *mut Self = object_class_dynamic_cast( + (klass as *mut U::Class).cast(), + Self::TYPE_NAME.as_ptr(), + ) + .cast(); + + >::class_init(result.as_mut().unwrap()) + } + } +} + /// This trait provides safe casting operations for QOM objects to raw pointers, /// to be used for example for FFI. The trait can be applied to any kind of /// reference or smart pointers, and enforces correctness through the [`IsA`] From patchwork Thu Feb 13 16:00: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: 13973577 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 C1BF0C021A4 for ; Thu, 13 Feb 2025 16:13:15 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibet-0000wg-0c; Thu, 13 Feb 2025 11:01:47 -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 1tibeW-0000r1-So for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01: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 1tibeU-0005TU-JS for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:24 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462481; 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=jBfwZaRGoXfvVuthcliDjzbUe37ctGojDr1s126k8vs=; b=Op26xkEnLRNgCuQvfXPYYldZmAZUb/yVSh1wUbuaxDPuM1Hk75aCWWChHvVIOFgbSvS6oc Iu0FFMdik8JIKu6Lkv0ycuL8bC4TVaoAxympqTd6z0UvaxNQoMA1RtfwMWcToNy/1GmHLu i1wGgaRYKBUpRKjJ076N0q+fvKpt86Q= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-401-2jVJbnYvPT6KolWcah_PzA-1; Thu, 13 Feb 2025 11:01:19 -0500 X-MC-Unique: 2jVJbnYvPT6KolWcah_PzA-1 X-Mimecast-MFC-AGG-ID: 2jVJbnYvPT6KolWcah_PzA Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-43943bd1409so8455865e9.3 for ; Thu, 13 Feb 2025 08:01:18 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462477; x=1740067277; 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=jBfwZaRGoXfvVuthcliDjzbUe37ctGojDr1s126k8vs=; b=GMDYnTx8JFHfo9+yFTRHPWR1AndHasUZy1t47XaS1un8+GYcoB9LC1mOBcmdVVKXD2 CVRZC7k5i2RhA8DBjqhdYbElNnCBYGLYLkjfOqZLTc0IMr1AbV9mQ1oek1l3tbldpglk E868+E8eS+9fyjqjn8Su/BlxRPq+/kV99syJbRx44IYOUrQtzqIiwi8RIBr9COz/J1M5 YdWGpgBNPPbqqv/5kpFrE8+hTww1DF2HRJzI8rF0qj+sE/rei3GH4PzoPnTyybHZS0k7 V4SMyEjDUDbjxDqamohwu1quaDuCO9YALBhWv8/9aIh4PDuG7uDZKTntZ16rBziKFzYc r1Hg== X-Gm-Message-State: AOJu0YwKiGzdWSfpBHAgJMsNL/cSdC9awtJPvzAzuTrGscLL5kg0kAyG Yl7JbcgmGbiAVHjmSj3NAzYr/CUNHqaRZ5kK5Pvi6Hjyw2R3b7DPhwKZ5XnrlFnByuocEROUwXb PXVc4CyHxWyvrGxwFvYDNWQCm9+y8IUXEDIeuPjMByj9L9a6WGOWm9yNtnnhaPiWIC0ZrJN+EME zsydyHMetdLk1vsifmk8euVYoSE3haxHouWBNcpy4= X-Gm-Gg: ASbGncuBmTuYr3oq7fpVvE41UNsyxWe9SIik6kS5sT0VqHMAtB45xqQT8TlFHS1D+6P TG2dIDWPOcuiLKrQyzFPDk00VgXNT3JWzgm3N++tBY9W9iN0u1K2cNi/JU0VHnQdU0xRB5SGV+S MFKHi/QIUorTjtmVCkP11vRE/RXiDZY0hQm+tdPmNieI69JOjuNJ29ECCJqAWo+7cJ51RFCjSxO 3Edkemqs3GJkR4JQ41aW87if1FW6wumBlkPTdo6B5mIJG+CkbK9XcmG1nTpBeoBQNpncpLy99fg rFQlbC1pu+xhEST/V1tWbtir+pVXcz7YWrLIWEHlkOmdZA== X-Received: by 2002:a05:600c:4710:b0:439:3e9e:929a with SMTP id 5b1f17b1804b1-439581b1d5cmr82746735e9.24.1739462477349; Thu, 13 Feb 2025 08:01:17 -0800 (PST) X-Google-Smtp-Source: AGHT+IFACEKZpCfHplS5eVb49/yLPM4PLR132kFx+SfkXcxWtBlsWsmPZ3pOin1yz6YQlax/3r/Rqw== X-Received: by 2002:a05:600c:4710:b0:439:3e9e:929a with SMTP id 5b1f17b1804b1-439581b1d5cmr82745875e9.24.1739462476498; Thu, 13 Feb 2025 08:01:16 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4395a1b83a3sm51981295e9.33.2025.02.13.08.01.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:12 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 07/27] rust: qdev: make ObjectImpl a supertrait of DeviceImpl Date: Thu, 13 Feb 2025 17:00:34 +0100 Message-ID: <20250213160054.3937012-8-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 In practice it has to be implemented always in order to access an implementation of ClassInitImpl. Make the relationship explicit in the code. Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/qdev.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs index 176c69a5600..34d24da4b63 100644 --- a/rust/qemu-api/src/qdev.rs +++ b/rust/qemu-api/src/qdev.rs @@ -17,12 +17,12 @@ callbacks::FnCall, cell::bql_locked, prelude::*, - qom::{ClassInitImpl, ObjectClass, Owned}, + qom::{ClassInitImpl, ObjectClass, ObjectImpl, Owned}, vmstate::VMStateDescription, }; /// Trait providing the contents of [`DeviceClass`]. -pub trait DeviceImpl { +pub trait DeviceImpl: ObjectImpl { /// _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). From patchwork Thu Feb 13 16:00: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: 13973546 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 A6AF5C021A0 for ; Thu, 13 Feb 2025 16:06:58 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibf1-0000zq-80; Thu, 13 Feb 2025 11:01:55 -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 1tibeY-0000r7-LH for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:31 -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 1tibeW-0005UG-8j for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:26 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462483; 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=U5PgGVHnFw25YamWWjyXuJxRbq8ocW+EGCTnABnLuhE=; b=QF5wnS8Lqw0FAkeZIgGyMatbwOKjf/bVDtm6rRZg11y8ZUxZqwwW5NIbirVC+6Gl+QeFah uMr12QvcPKSJ3b71o7smDDZ5Voacz643ixWXBQoHB0cDJx5OdIh4uCEMlNu0uChmzhxg+v r7EgE9IdxiZBTNlkBkIGx1sT9gWbBMA= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-650-NL5AhxH9N2yCwNjoXHosuw-1; Thu, 13 Feb 2025 11:01:22 -0500 X-MC-Unique: NL5AhxH9N2yCwNjoXHosuw-1 X-Mimecast-MFC-AGG-ID: NL5AhxH9N2yCwNjoXHosuw Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-38dcc9653a7so553469f8f.0 for ; Thu, 13 Feb 2025 08:01:21 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462480; x=1740067280; 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=U5PgGVHnFw25YamWWjyXuJxRbq8ocW+EGCTnABnLuhE=; b=NRsFNm0UKX0Vl6L2XbLniKJVou+vjMLVuD1QY5oDOiFCuNKTkigQvIUhdkSTK7IWnF z7MrRI+HEvRrslFqPXg+xTcm3c4yUUtI6IbCbQ5R4UHnLSwndovBGIFMTyoeQUckwDzw R27NHitrHJ3+U/8bZvpSmkhONNy/pa26Ul20/JRZkwGBXhEWsC0c7DRyeRCc/kK4f/i5 jIUIfBrjXLC4gN3O0BEhy43reef5lJH5MUonrFCz+WnAcRj9P9T69/fSn1go1qbC/7XN 175YP1NWLBomzjyVH9tBWYD5pytD2iWTl3LNBPlQ6gMigWrLHvmV1s/pvOQ2ic9lVOJn NnNA== X-Gm-Message-State: AOJu0YwlH9OlNDw/YXQRg/8bBaSjNzFEnciO9yKp85a+ZgwRCvFPOLkK tC9ysBwHoZDUCmRjSlOayusYMb7qJoV0sqS75cffyP3Ye70Uou3jDJsiH4Si70ncML8yKHPyJOU tdOdhLerj0zf4P/BtlYbg7lYZ6YjS6oaiG9+a4Z6PiQRTbEan6+NSaH1ZGAAs6FPDPT5xJtpy4j 1W9G5HdClxgMBXEJaOS5Urtkk7CAFbjZcVDEKqsgw= X-Gm-Gg: ASbGncvMrH5FIBAr5exx5O/O7sL/9+/2Yt1aARyaiieJ5q9m6rYVi6MNRfV829PT7jz FpcHc7Y2/0B7R+1auEvwbjY+V0YgL15Jg/wM8pH0ETq/JvfH+dQ7OtbQH07uZ3vUTLurgc6Rjyj 0wSeOkf5ksvzMG0bvQYKykQQG8Zp4g0ukD5W+hjCQEoxUbMgrRICBqadmbSqmpMO4H8i7M9fHPV bOW78qBZkSNaoHLmkPuqmNnay5Kk4tkVAx19SyOSDialQv48FDSPGg/KalqccsD1kKR0zGPINnr /4EXy8PQRU0X2+Ins6G0QgKEPtUMDmF/4qmBkiBYUSAo0w== X-Received: by 2002:a7b:cbc7:0:b0:439:65c5:f28a with SMTP id 5b1f17b1804b1-43965c5f2f4mr10437425e9.16.1739462479628; Thu, 13 Feb 2025 08:01:19 -0800 (PST) X-Google-Smtp-Source: AGHT+IHI/OtkM4KzRpkrEmA5gaL8NEPd8+zDRB23sLWWWDgbMUquXcu+YggW9qr4BYDWdT6pEbsDOQ== X-Received: by 2002:a7b:cbc7:0:b0:439:65c5:f28a with SMTP id 5b1f17b1804b1-43965c5f2f4mr10436655e9.16.1739462478813; Thu, 13 Feb 2025 08:01:18 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-439617ffa28sm21270095e9.14.2025.02.13.08.01.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:18 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 08/27] rust: qdev: switch from legacy reset to Resettable Date: Thu, 13 Feb 2025 17:00:35 +0100 Message-ID: <20250213160054.3937012-9-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- meson.build | 1 + rust/hw/char/pl011/src/device.rs | 10 ++- rust/qemu-api/src/qdev.rs | 111 ++++++++++++++++++++++++------- rust/qemu-api/tests/tests.rs | 5 +- 4 files changed, 99 insertions(+), 28 deletions(-) diff --git a/meson.build b/meson.build index 18cf9e2913b..16c76c493f3 100644 --- a/meson.build +++ b/meson.build @@ -4073,6 +4073,7 @@ if have_rust 'MigrationPriority', 'QEMUChrEvent', 'QEMUClockType', + 'ResetType', 'device_endian', 'module_init_type', ] diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index 37936a328b8..1d0390b4fbe 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -18,7 +18,7 @@ c_str, impl_vmstate_forward, irq::InterruptSource, prelude::*, - qdev::{Clock, ClockEvent, DeviceImpl, DeviceState, Property}, + qdev::{Clock, ClockEvent, DeviceImpl, DeviceState, Property, ResetType, ResettablePhasesImpl}, qom::{ClassInitImpl, ObjectImpl, Owned, ParentField}, sysbus::{SysBusDevice, SysBusDeviceClass}, vmstate::VMStateDescription, @@ -171,7 +171,10 @@ fn vmsd() -> Option<&'static VMStateDescription> { Some(&device_class::VMSTATE_PL011) } const REALIZE: Option = Some(Self::realize); - const RESET: Option = Some(Self::reset); +} + +impl ResettablePhasesImpl for PL011State { + const HOLD: Option = Some(Self::reset_hold); } impl PL011Registers { @@ -622,7 +625,7 @@ pub fn realize(&self) { } } - pub fn reset(&self) { + pub fn reset_hold(&self, _type: ResetType) { self.regs.borrow_mut().reset(); } @@ -737,3 +740,4 @@ impl ObjectImpl for PL011Luminary { } impl DeviceImpl for PL011Luminary {} +impl ResettablePhasesImpl for PL011Luminary {} diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs index 34d24da4b63..64ba3d90981 100644 --- a/rust/qemu-api/src/qdev.rs +++ b/rust/qemu-api/src/qdev.rs @@ -10,10 +10,10 @@ ptr::NonNull, }; -pub use bindings::{Clock, ClockEvent, DeviceClass, DeviceState, Property}; +pub use bindings::{Clock, ClockEvent, DeviceClass, DeviceState, Property, ResetType}; use crate::{ - bindings::{self, Error}, + bindings::{self, Error, ResettableClass}, callbacks::FnCall, cell::bql_locked, prelude::*, @@ -21,8 +21,70 @@ vmstate::VMStateDescription, }; +/// Trait providing the contents of the `ResettablePhases` struct, +/// which is part of the QOM `Resettable` interface. +pub trait ResettablePhasesImpl { + /// If not None, this is called when the object enters reset. It + /// can reset local state of the object, but it must not do anything that + /// has a side-effect on other objects, such as raising or lowering an + /// [`InterruptSource`](crate::irq::InterruptSource), or reading or + /// writing guest memory. It takes the reset's type as argument. + const ENTER: Option = None; + + /// If not None, this is called when the object for entry into reset, once + /// every object in the system which is being reset has had its + /// `ResettablePhasesImpl::ENTER` method called. At this point devices + /// can do actions that affect other objects. + /// + /// If in doubt, implement this method. + const HOLD: Option = None; + + /// If not None, this phase is called when the object leaves the reset + /// state. Actions affecting other objects are permitted. + const EXIT: Option = None; +} + +/// # Safety +/// +/// 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_resettable_enter_fn( + obj: *mut Object, + typ: ResetType, +) { + let state = NonNull::new(obj).unwrap().cast::(); + T::ENTER.unwrap()(unsafe { state.as_ref() }, typ); +} + +/// # Safety +/// +/// 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_resettable_hold_fn( + obj: *mut Object, + typ: ResetType, +) { + let state = NonNull::new(obj).unwrap().cast::(); + T::HOLD.unwrap()(unsafe { state.as_ref() }, typ); +} + +/// # Safety +/// +/// 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_resettable_exit_fn( + obj: *mut Object, + typ: ResetType, +) { + let state = NonNull::new(obj).unwrap().cast::(); + T::EXIT.unwrap()(unsafe { state.as_ref() }, typ); +} + /// Trait providing the contents of [`DeviceClass`]. -pub trait DeviceImpl: ObjectImpl { +pub trait DeviceImpl: ObjectImpl + ResettablePhasesImpl { /// _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). @@ -31,13 +93,6 @@ pub trait DeviceImpl: ObjectImpl { /// with the function pointed to by `REALIZE`. const REALIZE: Option = None; - /// If not `None`, the parent class's `reset` method is overridden - /// with the function pointed to by `RESET`. - /// - /// Rust does not yet support the three-phase reset protocol; this is - /// usually okay for leaf classes. - const RESET: Option = None; - /// An array providing the properties that the user can set on the /// device. Not a `const` because referencing statics in constants /// is unstable until Rust 1.83.0. @@ -65,29 +120,36 @@ fn vmsd() -> Option<&'static VMStateDescription> { T::REALIZE.unwrap()(unsafe { state.as_ref() }); } -/// # Safety -/// -/// 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_reset_fn(dev: *mut DeviceState) { - let mut state = NonNull::new(dev).unwrap().cast::(); - T::RESET.unwrap()(unsafe { state.as_mut() }); +unsafe impl InterfaceType for ResettableClass { + const TYPE_NAME: &'static CStr = + unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_RESETTABLE_INTERFACE) }; +} + +impl ClassInitImpl for T +where + T: ResettablePhasesImpl, +{ + fn class_init(rc: &mut ResettableClass) { + if ::ENTER.is_some() { + rc.phases.enter = Some(rust_resettable_enter_fn::); + } + if ::HOLD.is_some() { + rc.phases.hold = Some(rust_resettable_hold_fn::); + } + if ::EXIT.is_some() { + rc.phases.exit = Some(rust_resettable_exit_fn::); + } + } } impl ClassInitImpl for T where - T: ClassInitImpl + DeviceImpl, + T: ClassInitImpl + ClassInitImpl + DeviceImpl, { fn class_init(dc: &mut DeviceClass) { if ::REALIZE.is_some() { dc.realize = Some(rust_realize_fn::); } - if ::RESET.is_some() { - unsafe { - bindings::device_class_set_legacy_reset(dc, Some(rust_reset_fn::)); - } - } if let Some(vmsd) = ::vmsd() { dc.vmsd = vmsd; } @@ -98,6 +160,7 @@ fn class_init(dc: &mut DeviceClass) { } } + ResettableClass::interface_init::(dc); >::class_init(&mut dc.parent_class); } } diff --git a/rust/qemu-api/tests/tests.rs b/rust/qemu-api/tests/tests.rs index 10748fba197..92dbfb8a0c8 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}, + qdev::{DeviceClass, DeviceImpl, DeviceState, Property, ResettablePhasesImpl}, qom::{ClassInitImpl, ObjectImpl, ParentField}, vmstate::VMStateDescription, zeroable::Zeroable, @@ -61,6 +61,8 @@ impl ObjectImpl for DummyState { const ABSTRACT: bool = false; } +impl ResettablePhasesImpl for DummyState {} + impl DeviceImpl for DummyState { fn properties() -> &'static [Property] { &DUMMY_PROPERTIES @@ -101,6 +103,7 @@ impl ObjectImpl for DummyChildState { const ABSTRACT: bool = false; } +impl ResettablePhasesImpl for DummyChildState {} impl DeviceImpl for DummyChildState {} impl ClassInitImpl for DummyChildState { From patchwork Thu Feb 13 16:00: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: 13973529 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 CDF22C021A0 for ; Thu, 13 Feb 2025 16:03:03 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibey-0000ys-T1; Thu, 13 Feb 2025 11:01:52 -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 1tibei-0000sb-Fc for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:42 -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 1tibee-0005W1-1m for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:34 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462491; 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=TjaNShE0GYpF6KF1Wxl7XEXpF6pZfvD+oUSQf7rKQdY=; b=VFuMITx5N6RXVxdudLuL6NQb5P0dvPAi+zr8YkkQUw2gUeid9KvIBkPrBN38j84SkNpQJ6 M70xhH70ap/D5yiBjkjfnBFHepa1e5OjWhFJ04mejgnMMt9tXWLkdv5PwPAywRrVNvoxI8 PIMTpRODTdGAqHH51+QMOfOL7CaF4DA= 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-615-EExo55gHMhGJdRKV9yLThQ-1; Thu, 13 Feb 2025 11:01:28 -0500 X-MC-Unique: EExo55gHMhGJdRKV9yLThQ-1 X-Mimecast-MFC-AGG-ID: EExo55gHMhGJdRKV9yLThQ Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-4394b2c19ccso8359735e9.1 for ; Thu, 13 Feb 2025 08:01:28 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462486; x=1740067286; 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=TjaNShE0GYpF6KF1Wxl7XEXpF6pZfvD+oUSQf7rKQdY=; b=RCC2dM3BwDbMERS7bCFYAgZ55a7MqoyxWqVPBynAyfmR29CJ0ggowGxrSm2Q0j5Y9g ovXdQ/ujxwnFu2+XEJoo7ebaUU9ziwwh8MriFFgzYaPuK2F6+Rn5O9A555oAi0IOo0rf VqXZDSUcVCyQm4TQHZGGKxKvv9UkgYVjdhhNggS63lDm2sTQMxrNZ4DxiMBeaNQjJ3sl RFFIQ5RsfwELGdmOFRj16grJ0+hEkCz5/shKRr8IPrC9ynyG15JUUBZLlFNTCEQGMSxE mvVivRYELBoRXJtwnFpNpT7PhH2uq7Ti7wG23lspRsmclgCAdeOkP2mYC0W899Mm/DSY amsw== X-Gm-Message-State: AOJu0YyW66m5G+60ls+MHLnMRWZjnmFn8pxrzoIOUZST3RXyUM/bdHVd OX0edMriHLz4OstDK3QiXrN0KyjD4HGDqu+7K1W1jORJPiCwWEriSKzHf5GnxR9pqj06YbJkqWM ZkQFeoG/cAwsJUVfCLtnSWxKMlMnRyTU1rlu1AH9lN9CIbMGjuJUWOTHUjAHFZ4+hFRpa0u5sMD 0O+5OXdzvXP49ttN6MF2snJpjdTK6Q09ZFbdXABgE= X-Gm-Gg: ASbGnct/Kebr06yzTO+8YRcUf1XblGaKwi53lya5M92m+mwa7skkjKuz01FLL/gSrIl xRYuXTLAgPdb2zyS9GSBZfrQBmrbV/jnmX46mYUhbwG41xo7V0Kagy2Pw4TM5G4CysdRoAaxsIY U7Rxv+hGpF+tpZNy1YbLJtWbjM+GDIp7wtfrIcKzTGicYR+dmjakp6ex7SpsH9YzMWjpGDjykzQ 85sCLlzJJc28fCK0yfaE88ev2fD1fbnHrDHFgmRJRXSrlbd0OnXS9p4iqR0GhLnEErlqhmcm+0R MP3y7uFVqZ0VjAlxODuNDXpDAAt4YdUum45RaqZMI8tUeg== X-Received: by 2002:a05:600c:6986:b0:439:4700:9eba with SMTP id 5b1f17b1804b1-43960185ed6mr51795515e9.2.1739462484175; Thu, 13 Feb 2025 08:01:24 -0800 (PST) X-Google-Smtp-Source: AGHT+IGm8uVhA9hdM53H9GG/NzdknnS4BRr+dYopbimP7mYSDM/NQiZVZ5Z+N6J0R2xcVa0IJfR/yA== X-Received: by 2002:a05:600c:6986:b0:439:4700:9eba with SMTP id 5b1f17b1804b1-43960185ed6mr51793375e9.2.1739462481813; Thu, 13 Feb 2025 08:01:21 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43961e07252sm20137425e9.14.2025.02.13.08.01.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:20 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 09/27] rust: bindings: add Send and Sync markers for types that have bindings Date: Thu, 13 Feb 2025 17:00:36 +0100 Message-ID: <20250213160054.3937012-10-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 This is needed for the MemoryRegionOps to be declared as static; Rust requires static elements to be Sync. Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/bindings.rs | 46 +++++++++++++++++++++++++++++++++++ rust/qemu-api/src/irq.rs | 3 +++ 2 files changed, 49 insertions(+) diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs index 8a9b821bb91..b71220113ef 100644 --- a/rust/qemu-api/src/bindings.rs +++ b/rust/qemu-api/src/bindings.rs @@ -21,9 +21,55 @@ #[cfg(not(MESON))] include!(concat!(env!("OUT_DIR"), "/bindings.inc.rs")); +// 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 {} + +unsafe impl Send for CharBackend {} +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 {} + +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 {} + +// SAFETY: this is a pure data struct +unsafe impl Send for CoalescedMemoryRange {} +unsafe impl Sync for CoalescedMemoryRange {} + +// SAFETY: these are constants and vtables; the Send and Sync requirements +// are deferred to the unsafe callbacks that they contain +unsafe impl Send for MemoryRegionOps {} +unsafe impl Sync for MemoryRegionOps {} + unsafe impl Send for Property {} unsafe impl Sync for Property {} + +unsafe impl Send for TypeInfo {} unsafe impl Sync for TypeInfo {} + +unsafe impl Send for VMStateDescription {} unsafe impl Sync for VMStateDescription {} + +unsafe impl Send for VMStateField {} unsafe impl Sync for VMStateField {} + +unsafe impl Send for VMStateInfo {} unsafe impl Sync for VMStateInfo {} diff --git a/rust/qemu-api/src/irq.rs b/rust/qemu-api/src/irq.rs index 378e5202951..638545c3a64 100644 --- a/rust/qemu-api/src/irq.rs +++ b/rust/qemu-api/src/irq.rs @@ -43,6 +43,9 @@ pub struct InterruptSource _marker: PhantomData, } +// SAFETY: the implementation asserts via `BqlCell` that the BQL is taken +unsafe impl Sync for InterruptSource where c_int: From {} + impl InterruptSource { /// Send a low (`false`) value to the interrupt sink. pub fn lower(&self) { From patchwork Thu Feb 13 16:00: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: 13973578 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 C45B4C021A0 for ; Thu, 13 Feb 2025 16:13:27 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tiber-0000wM-9d; Thu, 13 Feb 2025 11:01:45 -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 1tibel-0000sq-Dc for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:42 -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 1tibeg-0005WB-1M for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:36 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462492; 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=TjWIFBZVobxAu7MHNKyQ3KXgW2OoUY+xqs67zS21jZg=; b=a7ONeRIQsy32JzwPU5Qszsxxes3z9xOYGkIdmuCDcCXUXb/EP013gcnbsg9Lah9LfQApKZ PLfhoh/sI303wIrH6EvBS6i+ewDYkHNeEUS0Tc79akvNVwKp2ToKC5OBA84Xvsdr3EVVX5 maHGsSURhmGJ1P/MuRHcf76yCm1iT+M= 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-19-sMDtEJqaOieWz89vQdeecg-1; Thu, 13 Feb 2025 11:01:29 -0500 X-MC-Unique: sMDtEJqaOieWz89vQdeecg-1 X-Mimecast-MFC-AGG-ID: sMDtEJqaOieWz89vQdeecg_1739462487 Received: by mail-ej1-f72.google.com with SMTP id a640c23a62f3a-ab7fa2b5be0so129839066b.3 for ; Thu, 13 Feb 2025 08:01:28 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462485; x=1740067285; 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=TjWIFBZVobxAu7MHNKyQ3KXgW2OoUY+xqs67zS21jZg=; b=K9kVxbiyzPr9HUDs/+cYLQROmKUv3IKhksdRw5zmBLhZXwfzCQ7bDnvQLDi4nBlfxZ MAE89+7ydpOFu+X7V/iZt77zNrio57bCpdAmKuucuEo0angMcEQJAxM7GVkLBdU2UcOq hIivUXVkqwQTufTlEB0Qp/vk528rQZU3JbrN6iMbArpORbFIdDspXjEUNQeRRJe6hebx idTMNGCNSjgH9Hmn6nznnzkftTEcTApAl21/y6ZPCisbbC2s3hLf05UIqp+/XyLxdqO6 xWL/SkVfYljuuIe/3frCy2y0XsxMl8XMICywBNeDfMmfBa3zgeYVddjHBUpEYqBpomt9 k4YQ== X-Gm-Message-State: AOJu0Yy18he95j2zNbvbxV+7En6YAPXhrJioCM7gGq7QN3zNn3wxzLty VhZAOlkIA9NTJRtcTLOK8hSrKstOXSOMcgeDKgo8gypY3bCDBjq9ke4xTgv0s+O9x6008mWKNlQ yjYjwPS/mRU4Lh7yth1VD/XuOFtzmYW9rggI2TqR+S3TajljEsC2pMp9JAl4mKj1B+akUkffi9u UTeCJR0FXMgghSLj2wl7DQhU6idO34yLB8B4VQhq4= X-Gm-Gg: ASbGnct2BU0yaM6OZNulqAnGwYhhoXCf8qlpCIeOMk61F8+POkLVI9EvqlqcNW7erw2 dAlXK4s8KkE/ioHn2DiJ6clGzHhF3v3G9fK7Bc4aUnH7ln6cdgziCFB2J8rzt0RGPqImEoc3NOL atuavv2dxuyrLbKvc5PJvESK0nJg5hK12hRLc/xWN4zec2UL2DIc6BUruktwYUixaFSHUe5KiRq ojtwI66IzVK0+xcqLD19UpK8oqV/s2itaqoWcwlPZ5AgMxoTnbizFEmlIVoOO0QuTrgHVglC4pp nBAxy/wd+0wT6SiW2DyaF7BzlxDKgteXppGIK/ZbeZl+AA== X-Received: by 2002:a17:907:9619:b0:ab7:e41d:34b6 with SMTP id a640c23a62f3a-ab7f33c5c4amr605754166b.28.1739462484858; Thu, 13 Feb 2025 08:01:24 -0800 (PST) X-Google-Smtp-Source: AGHT+IHXJTVJzOEmETWcQ9b8hSsnrclJ20lGCr5ARB1w7AaQlxeMSi0A+nRNsHdMI9Qcx5rdPX2f0w== X-Received: by 2002:a17:907:9619:b0:ab7:e41d:34b6 with SMTP id a640c23a62f3a-ab7f33c5c4amr605747566b.28.1739462484183; Thu, 13 Feb 2025 08:01:24 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4395a1b8443sm52978195e9.35.2025.02.13.08.01.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:23 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 10/27] rust: bindings for MemoryRegionOps Date: Thu, 13 Feb 2025 17:00:37 +0100 Message-ID: <20250213160054.3937012-11-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- docs/devel/rust.rst | 1 + rust/hw/char/pl011/src/device.rs | 51 +++---- rust/hw/char/pl011/src/lib.rs | 1 - rust/hw/char/pl011/src/memory_ops.rs | 34 ----- rust/qemu-api/meson.build | 1 + rust/qemu-api/src/lib.rs | 1 + rust/qemu-api/src/memory.rs | 191 +++++++++++++++++++++++++++ rust/qemu-api/src/sysbus.rs | 7 +- rust/qemu-api/src/zeroable.rs | 1 + 9 files changed, 227 insertions(+), 61 deletions(-) delete mode 100644 rust/hw/char/pl011/src/memory_ops.rs create mode 100644 rust/qemu-api/src/memory.rs diff --git a/docs/devel/rust.rst b/docs/devel/rust.rst index 8cccca7a734..a5399db50b5 100644 --- a/docs/devel/rust.rst +++ b/docs/devel/rust.rst @@ -180,6 +180,7 @@ module status ``cell`` stable ``c_str`` complete ``irq`` complete +``memory`` stable ``module`` complete ``offset_of`` stable ``qdev`` stable diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index 1d0390b4fbe..5e4e75133c8 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -10,13 +10,14 @@ use qemu_api::{ bindings::{ - error_fatal, hwaddr, memory_region_init_io, qdev_prop_set_chr, qemu_chr_fe_accept_input, - qemu_chr_fe_ioctl, qemu_chr_fe_set_handlers, qemu_chr_fe_write_all, qemu_irq, - sysbus_connect_irq, sysbus_mmio_map, sysbus_realize, CharBackend, Chardev, MemoryRegion, - QEMUChrEvent, CHR_IOCTL_SERIAL_SET_BREAK, + error_fatal, qdev_prop_set_chr, qemu_chr_fe_accept_input, qemu_chr_fe_ioctl, + qemu_chr_fe_set_handlers, qemu_chr_fe_write_all, qemu_irq, sysbus_connect_irq, + sysbus_mmio_map, sysbus_realize, CharBackend, Chardev, QEMUChrEvent, + CHR_IOCTL_SERIAL_SET_BREAK, }, c_str, impl_vmstate_forward, irq::InterruptSource, + memory::{hwaddr, MemoryRegion, MemoryRegionOps, MemoryRegionOpsBuilder}, prelude::*, qdev::{Clock, ClockEvent, DeviceImpl, DeviceState, Property, ResetType, ResettablePhasesImpl}, qom::{ClassInitImpl, ObjectImpl, Owned, ParentField}, @@ -26,7 +27,6 @@ use crate::{ device_class, - memory_ops::PL011_OPS, registers::{self, Interrupt}, RegisterOffset, }; @@ -487,20 +487,24 @@ impl PL011State { /// location/instance. All its fields are expected to hold unitialized /// values with the sole exception of `parent_obj`. unsafe fn init(&mut self) { + static PL011_OPS: MemoryRegionOps = MemoryRegionOpsBuilder::::new() + .read(&PL011State::read) + .write(&PL011State::write) + .native_endian() + .impl_sizes(4, 4) + .build(); + // SAFETY: // // self and self.iomem are guaranteed to be valid at this point since callers // must make sure the `self` reference is valid. - unsafe { - memory_region_init_io( - addr_of_mut!(self.iomem), - addr_of_mut!(*self).cast::(), - &PL011_OPS, - addr_of_mut!(*self).cast::(), - Self::TYPE_NAME.as_ptr(), - 0x1000, - ); - } + MemoryRegion::init_io( + unsafe { &mut *addr_of_mut!(self.iomem) }, + addr_of_mut!(*self), + &PL011_OPS, + "pl011", + 0x1000, + ); self.regs = Default::default(); @@ -525,7 +529,7 @@ fn post_init(&self) { } } - pub fn read(&mut self, offset: hwaddr, _size: u32) -> u64 { + pub fn read(&self, offset: hwaddr, _size: u32) -> u64 { match RegisterOffset::try_from(offset) { Err(v) if (0x3f8..0x400).contains(&(v >> 2)) => { let device_id = self.get_class().device_id; @@ -540,7 +544,7 @@ pub fn read(&mut self, offset: hwaddr, _size: u32) -> u64 { if update_irq { self.update(); unsafe { - qemu_chr_fe_accept_input(&mut self.char_backend); + qemu_chr_fe_accept_input(addr_of!(self.char_backend) as *mut _); } } result.into() @@ -548,7 +552,7 @@ pub fn read(&mut self, offset: hwaddr, _size: u32) -> u64 { } } - pub fn write(&mut self, offset: hwaddr, value: u64) { + pub fn write(&self, offset: hwaddr, value: u64, _size: u32) { let mut update_irq = false; if let Ok(field) = RegisterOffset::try_from(offset) { // qemu_chr_fe_write_all() calls into the can_receive @@ -561,14 +565,15 @@ pub fn write(&mut self, offset: hwaddr, value: u64) { // XXX this blocks entire thread. Rewrite to use // qemu_chr_fe_write and background I/O callbacks unsafe { - qemu_chr_fe_write_all(&mut self.char_backend, &ch, 1); + qemu_chr_fe_write_all(addr_of!(self.char_backend) as *mut _, &ch, 1); } } - update_irq = self - .regs - .borrow_mut() - .write(field, value as u32, &mut self.char_backend); + update_irq = self.regs.borrow_mut().write( + field, + value as u32, + addr_of!(self.char_backend) as *mut _, + ); } else { eprintln!("write bad offset {offset} value {value}"); } diff --git a/rust/hw/char/pl011/src/lib.rs b/rust/hw/char/pl011/src/lib.rs index 3c72f1221ff..1bf46c65af2 100644 --- a/rust/hw/char/pl011/src/lib.rs +++ b/rust/hw/char/pl011/src/lib.rs @@ -18,7 +18,6 @@ mod device; mod device_class; -mod memory_ops; pub use device::pl011_create; diff --git a/rust/hw/char/pl011/src/memory_ops.rs b/rust/hw/char/pl011/src/memory_ops.rs deleted file mode 100644 index 432d3263898..00000000000 --- a/rust/hw/char/pl011/src/memory_ops.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2024, Linaro Limited -// Author(s): Manos Pitsidianakis -// SPDX-License-Identifier: GPL-2.0-or-later - -use core::ptr::NonNull; -use std::os::raw::{c_uint, c_void}; - -use qemu_api::{bindings::*, zeroable::Zeroable}; - -use crate::device::PL011State; - -pub static PL011_OPS: MemoryRegionOps = MemoryRegionOps { - read: Some(pl011_read), - write: Some(pl011_write), - read_with_attrs: None, - write_with_attrs: None, - endianness: device_endian::DEVICE_NATIVE_ENDIAN, - valid: Zeroable::ZERO, - impl_: MemoryRegionOps__bindgen_ty_2 { - min_access_size: 4, - max_access_size: 4, - ..Zeroable::ZERO - }, -}; - -unsafe extern "C" fn pl011_read(opaque: *mut c_void, addr: hwaddr, size: c_uint) -> u64 { - let mut state = NonNull::new(opaque).unwrap().cast::(); - unsafe { state.as_mut() }.read(addr, size) -} - -unsafe extern "C" fn pl011_write(opaque: *mut c_void, addr: hwaddr, data: u64, _size: c_uint) { - let mut state = NonNull::new(opaque).unwrap().cast::(); - unsafe { state.as_mut() }.write(addr, data); -} diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build index 60944a657de..80eafc7f6bd 100644 --- a/rust/qemu-api/meson.build +++ b/rust/qemu-api/meson.build @@ -22,6 +22,7 @@ _qemu_api_rs = static_library( 'src/cell.rs', 'src/c_str.rs', 'src/irq.rs', + 'src/memory.rs', 'src/module.rs', 'src/offset_of.rs', 'src/prelude.rs', diff --git a/rust/qemu-api/src/lib.rs b/rust/qemu-api/src/lib.rs index 3cf9371cff0..e4316b21cf2 100644 --- a/rust/qemu-api/src/lib.rs +++ b/rust/qemu-api/src/lib.rs @@ -19,6 +19,7 @@ pub mod callbacks; pub mod cell; pub mod irq; +pub mod memory; pub mod module; pub mod offset_of; pub mod qdev; diff --git a/rust/qemu-api/src/memory.rs b/rust/qemu-api/src/memory.rs new file mode 100644 index 00000000000..963d689c27d --- /dev/null +++ b/rust/qemu-api/src/memory.rs @@ -0,0 +1,191 @@ +// Copyright 2024 Red Hat, Inc. +// Author(s): Paolo Bonzini +// SPDX-License-Identifier: GPL-2.0-or-later + +//! Bindings for `MemoryRegion` and `MemoryRegionOps` + +use std::{ + ffi::{CStr, CString}, + marker::{PhantomData, PhantomPinned}, + os::raw::{c_uint, c_void}, + ptr::addr_of, +}; + +pub use bindings::hwaddr; + +use crate::{ + bindings::{self, device_endian, memory_region_init_io}, + callbacks::FnCall, + prelude::*, + zeroable::Zeroable, +}; + +pub struct MemoryRegionOps( + bindings::MemoryRegionOps, + // Note: quite often you'll see PhantomData mentioned when discussing + // covariance and contravariance; you don't need any of those to understand + // this usage of PhantomData. Quite simply, MemoryRegionOps *logically* + // holds callbacks that take an argument of type &T, except the type is erased + // before the callback is stored in the bindings::MemoryRegionOps field. + // The argument of PhantomData is a function pointer in order to represent + // that relationship; while that will also provide desirable and safe variance + // for T, variance is not the point but just a consequence. + PhantomData, +); + +// SAFETY: When a *const T is passed to the callbacks, the call itself +// is done in a thread-safe manner. The invocation is okay as long as +// T itself is `Sync`. +unsafe impl Sync for MemoryRegionOps {} + +#[derive(Clone)] +pub struct MemoryRegionOpsBuilder(bindings::MemoryRegionOps, PhantomData); + +unsafe extern "C" fn memory_region_ops_read_cb FnCall<(&'a T, hwaddr, u32), u64>>( + opaque: *mut c_void, + addr: hwaddr, + size: c_uint, +) -> u64 { + F::call((unsafe { &*(opaque.cast::()) }, addr, size)) +} + +unsafe extern "C" fn memory_region_ops_write_cb FnCall<(&'a T, hwaddr, u64, u32)>>( + opaque: *mut c_void, + addr: hwaddr, + data: u64, + size: c_uint, +) { + F::call((unsafe { &*(opaque.cast::()) }, addr, data, size)) +} + +impl MemoryRegionOpsBuilder { + #[must_use] + pub const fn read FnCall<(&'a T, hwaddr, u32), u64>>(mut self, _f: &F) -> Self { + self.0.read = Some(memory_region_ops_read_cb::); + self + } + + #[must_use] + pub const fn write FnCall<(&'a T, hwaddr, u64, u32)>>(mut self, _f: &F) -> Self { + self.0.write = Some(memory_region_ops_write_cb::); + self + } + + #[must_use] + pub const fn big_endian(mut self) -> Self { + self.0.endianness = device_endian::DEVICE_BIG_ENDIAN; + self + } + + #[must_use] + pub const fn little_endian(mut self) -> Self { + self.0.endianness = device_endian::DEVICE_LITTLE_ENDIAN; + self + } + + #[must_use] + pub const fn native_endian(mut self) -> Self { + self.0.endianness = device_endian::DEVICE_NATIVE_ENDIAN; + self + } + + #[must_use] + pub const fn valid_sizes(mut self, min: u32, max: u32) -> Self { + self.0.valid.min_access_size = min; + self.0.valid.max_access_size = max; + self + } + + #[must_use] + pub const fn valid_unaligned(mut self) -> Self { + self.0.valid.unaligned = true; + self + } + + #[must_use] + pub const fn impl_sizes(mut self, min: u32, max: u32) -> Self { + self.0.impl_.min_access_size = min; + self.0.impl_.max_access_size = max; + self + } + + #[must_use] + pub const fn impl_unaligned(mut self) -> Self { + self.0.impl_.unaligned = true; + self + } + + #[must_use] + pub const fn build(self) -> MemoryRegionOps { + MemoryRegionOps::(self.0, PhantomData) + } + + #[must_use] + pub const fn new() -> Self { + Self(bindings::MemoryRegionOps::ZERO, PhantomData) + } +} + +impl Default for MemoryRegionOpsBuilder { + fn default() -> Self { + Self::new() + } +} + +/// 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, +} + +impl MemoryRegion { + // inline to ensure that it is not included in tests, which only + // link to hwcore and qom. FIXME: inlining is actually the opposite + // of what we want, since this is the type-erased version of the + // init_io function below. Look into splitting the qemu_api crate. + #[inline(always)] + unsafe fn do_init_io( + slot: *mut bindings::MemoryRegion, + owner: *mut Object, + ops: &'static bindings::MemoryRegionOps, + name: &'static str, + size: u64, + ) { + unsafe { + let cstr = CString::new(name).unwrap(); + memory_region_init_io( + slot, + owner.cast::(), + ops, + owner.cast::(), + cstr.as_ptr(), + size, + ); + } + } + + pub fn init_io>( + &mut self, + owner: *mut T, + ops: &'static MemoryRegionOps, + name: &'static str, + size: u64, + ) { + unsafe { + Self::do_init_io(&mut self.inner, 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 { + type Class = bindings::MemoryRegionClass; + const TYPE_NAME: &'static CStr = + unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_MEMORY_REGION) }; +} +qom_isa!(MemoryRegion: Object); diff --git a/rust/qemu-api/src/sysbus.rs b/rust/qemu-api/src/sysbus.rs index e6762b5c145..c27dbf79e43 100644 --- a/rust/qemu-api/src/sysbus.rs +++ b/rust/qemu-api/src/sysbus.rs @@ -2,7 +2,7 @@ // Author(s): Paolo Bonzini // SPDX-License-Identifier: GPL-2.0-or-later -use std::{ffi::CStr, ptr::addr_of}; +use std::ffi::CStr; pub use bindings::{SysBusDevice, SysBusDeviceClass}; @@ -10,6 +10,7 @@ bindings, cell::bql_locked, irq::InterruptSource, + memory::MemoryRegion, prelude::*, qdev::{DeviceClass, DeviceState}, qom::ClassInitImpl, @@ -42,10 +43,10 @@ pub trait SysBusDeviceMethods: ObjectDeref /// important, since whoever creates the sysbus device will refer to the /// region with a number that corresponds to the order of calls to /// `init_mmio`. - fn init_mmio(&self, iomem: &bindings::MemoryRegion) { + fn init_mmio(&self, iomem: &MemoryRegion) { assert!(bql_locked()); unsafe { - bindings::sysbus_init_mmio(self.as_mut_ptr(), addr_of!(*iomem) as *mut _); + bindings::sysbus_init_mmio(self.as_mut_ptr(), iomem.as_mut_ptr()); } } diff --git a/rust/qemu-api/src/zeroable.rs b/rust/qemu-api/src/zeroable.rs index 7b04947cb6c..75742b50d4e 100644 --- a/rust/qemu-api/src/zeroable.rs +++ b/rust/qemu-api/src/zeroable.rs @@ -100,3 +100,4 @@ fn default() -> Self { impl_zeroable!(crate::bindings::VMStateDescription); impl_zeroable!(crate::bindings::MemoryRegionOps__bindgen_ty_1); impl_zeroable!(crate::bindings::MemoryRegionOps__bindgen_ty_2); +impl_zeroable!(crate::bindings::MemoryRegionOps); From patchwork Thu Feb 13 16:00: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: 13973552 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 AF772C021A6 for ; Thu, 13 Feb 2025 16:09:26 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibf0-0000zS-GS; Thu, 13 Feb 2025 11:01:54 -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 1tibem-0000su-NC for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:42 -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 1tibek-0005XK-D3 for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462495; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2zMrreiA6fXml/tyoB0xwdzip2po3nTWUJjLq04bCbM=; b=itf1G/ncKn6Rm4YOxyg9FLIzatHiW5ZqZ98RWIl6yHodf8+KBf8wQUSZ/wfzR2OqGbUdkw zhWSb1KkTmzHjqlj0leIXrqaw5P67/D/AI2oL8u++6qO2kNbicRSkPbVEFpvuyKI8Q7C2w tZlIKBnrb+AfXZmzXbZhXxXfINTm2iI= 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-679-30kFj1oXMUaBlEa3nqhMQg-1; Thu, 13 Feb 2025 11:01:29 -0500 X-MC-Unique: 30kFj1oXMUaBlEa3nqhMQg-1 X-Mimecast-MFC-AGG-ID: 30kFj1oXMUaBlEa3nqhMQg Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-4393535043bso6150155e9.1 for ; Thu, 13 Feb 2025 08:01:29 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462487; x=1740067287; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2zMrreiA6fXml/tyoB0xwdzip2po3nTWUJjLq04bCbM=; b=TFN4LTrYX3Td9gK/z/EnzQ+z7ElWi1hd/hOA8cvU/7RF+voIPFWXWOAwoTifBf63ML yA7GZTn9kNVZzYDnWNcOToyo3lJXgOlXQVuv232BjZyF+Huo+4Msdh6dyrZCQ44MmoST Po1z0ZBigOyZ9sNfeW0mUaF7feMzAcoAXv1evF8mvkoqZO3rkh81G/ahOX3LUXjfj/yj lyUmiFIUqkLZ7PX3ZHR3wmPDZvoUgijmdxRWnvegyJ8YMMV2wPUrkre4ZImcj5hyz9ui bhDBvBDfwEeXbksoN6MDL7xN9P+n9afDamVDqoQOeTcxueXGbwhM40sPrb2vYdaDHgxf CG5Q== X-Gm-Message-State: AOJu0YxhAcV21V3b024dLflVPpBNdAZKpmxhH1QNGRpbthJaniTs/ksJ leYyVrgbtnZ+8IbUUqbBTQ1jrwVKAh9EkfiPrc/uf/mloNMze6j4Id0IsybjqTFRbhxyL720/yY gc7B9O4ljfhmGim6l2pTDdcwdy7CY0H/49Oa1Dz70vppTrelLw1EyPMBKy5oxnbwHCjX6SB1xSy 1pf+G8t+k065QmcWVOhjKmC3SB5/V1do5Tc7jj3Dk= X-Gm-Gg: ASbGncvS25PBpuQYrrxPCUEnuJwFYII6u2z+n4Zg650Ni0DrzZM3FhP3wWyRn2QnnU6 xDyWtXHZaR/V8Wg6n7V1rn/en49nz2V57ZwnPp064qb4f5G2vkvCouroRE5tUsf2YMLjRa6pWrH ilZw1jHH1LDdJE6W1nHwYOJEOMsS5WwJTtKMbj2ldrek6S4PhKAwmrEuAoLHelK7RjbRl7vsLM2 sAu2tZisohiCMZwThdzg09Ht4W1/gtvGe+mjZB/2GfRTLWiXvw93DgzTFXSixe3mCb2oNVnSZeY HnKJjJu5hvWfjCItEQiYodWpUiJoS9URKYfRVgztS3/twQ== X-Received: by 2002:a05:600c:1784:b0:439:5fa1:af56 with SMTP id 5b1f17b1804b1-43960bbfd9fmr40320075e9.2.1739462486802; Thu, 13 Feb 2025 08:01:26 -0800 (PST) X-Google-Smtp-Source: AGHT+IEb22ek4gAyWo8DumBxedsHT7YsZjI5woIb02D0k81UFNRgaJD1el82dfCWNaim7qA0aZ5Gog== X-Received: by 2002:a05:600c:1784:b0:439:5fa1:af56 with SMTP id 5b1f17b1804b1-43960bbfd9fmr40319395e9.2.1739462486088; Thu, 13 Feb 2025 08:01:26 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4395a1b83a3sm51986045e9.33.2025.02.13.08.01.25 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:25 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 11/27] rust: irq: define ObjectType for IRQState Date: Thu, 13 Feb 2025 17:00:38 +0100 Message-ID: <20250213160054.3937012-12-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 This is a small preparation in order to use an Owned for the argument to sysbus_connect_irq. Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/irq.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/rust/qemu-api/src/irq.rs b/rust/qemu-api/src/irq.rs index 638545c3a64..835b027d5e5 100644 --- a/rust/qemu-api/src/irq.rs +++ b/rust/qemu-api/src/irq.rs @@ -5,11 +5,12 @@ //! Bindings for interrupt sources use core::ptr; -use std::{marker::PhantomData, os::raw::c_int}; +use std::{ffi::CStr, marker::PhantomData, os::raw::c_int}; use crate::{ - bindings::{qemu_set_irq, IRQState}, + bindings::{self, qemu_set_irq}, prelude::*, + qom::ObjectClass, }; /// Interrupt sources are used by devices to pass changes to a value (typically @@ -21,7 +22,8 @@ /// 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 @@ -91,3 +93,10 @@ fn default() -> Self { } } } + +unsafe impl ObjectType for IRQState { + type Class = ObjectClass; + const TYPE_NAME: &'static CStr = + unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_IRQ) }; +} +qom_isa!(IRQState: Object); From patchwork Thu Feb 13 16:00: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: 13973576 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 BBFB4C021A0 for ; Thu, 13 Feb 2025 16:12:59 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibey-0000yv-TE; Thu, 13 Feb 2025 11:01:52 -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 1tibeo-0000uC-V2 for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:43 -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 1tibel-0005XQ-4a for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:42 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462496; 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=S+SMasJt000rT1ae4EhUEs5xt45LQa6MMA6T4RmgKLs=; b=NQFnqXED52jLMFsn1QZhh+SYL1Y+9DG9qjPaUugWWBmpkvLSP3j1J/GjKRr1qa3NR7ouNB L0XzApyNKk/GwVTZcQcrleSTTOJ61w9fVzm0lDkcPT6u5s9REacmEB1X9mk9vv9T060m0h zBHwzLCV+lg20fF+isSUrqg2sTFoVKU= 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-634-f2meafQUNS-3l7Hzskm6Tw-1; Thu, 13 Feb 2025 11:01:34 -0500 X-MC-Unique: f2meafQUNS-3l7Hzskm6Tw-1 X-Mimecast-MFC-AGG-ID: f2meafQUNS-3l7Hzskm6Tw Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-38f28a4647eso341220f8f.1 for ; Thu, 13 Feb 2025 08:01:33 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462492; x=1740067292; 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=S+SMasJt000rT1ae4EhUEs5xt45LQa6MMA6T4RmgKLs=; b=jGRNLN8XdaFSh0hPFD0OfW4GcEcwiyDLqTQveIRTXjF0i5bqqJcyGfkqSyaMLH7Yts goralXXDqRGYaYQAbVrqg5UdF0kPukgLI0xAHixkm+P0kL5fF6a9e7fTAaWJWHS02o1W r3oVvFO+gvbMmi50VFq9llQfs61sACSRpoG6awAxGJuyEPHPwVMIo4Y/VqEPurmmSqZR 9HBYb8HMnTnnTHNRPgtexvE+hjCNdEDu2Yne+zIZsOHXanyWvi2vSjfe0sqLJSXAUlef /gzCj/lQROe1j01duYTwtCXoOkXUnbAPONTUDY/A3HiJ3mtBBzIoOornnJ0NaNGepto7 w8gg== X-Gm-Message-State: AOJu0YwX5EOsxRtA8QJ166kPP61LlNFHSR21UabJVvYDRdnm32IyFk9t GrEGRa46b8cGSN8Bo6vN01t6Gq13tBgK3anaua+C0q97REnio9/OD2sxm71ebePxGhXkUZfeDO1 bBTi2JlBFgnsu2jX3BxH5f7p0I4zmneoucb3g5Tn0/lOldK3tlzEEL0TYZpJGQF4V5+lOoYv4GY GC2kC7pHSJlbVg3rGeD3JgOZrg5T+s67yHMU8tq84= X-Gm-Gg: ASbGnct526d/tWWkkZlL+0kMzaK8iHQgAad1W7w6zD7qtUfgADjeTsI/pj1ZAa9pwgM kDSamiBQ0tW2NqPEIT+RT/LlEZj6CaljOCoX2KxIdUlZovH9QHH6pUvijLb27f5ZyVlQdq7TVUk TPjvXvPyA/enExIhrPlCvrAoeaNAV77/hsqb7TuXu4KpZjOGcIvYFz8pUwVp1HSUzKRg2Z5BlzK Ae0+JKtH6ROKHOeZ0CsJd6+TkZhVYgD5DnDuzMsnQ3WRwpQkjQQ3JWwQQ3VJB/j4WzyVsoRAfjZ mO/dtghkJN3yuUdPCEzsy+JZxsh8xAbPk4J8sFp/5UmYTQ== X-Received: by 2002:a5d:47af:0:b0:38d:de45:bf98 with SMTP id ffacd0b85a97d-38f244d6481mr4693589f8f.8.1739462492186; Thu, 13 Feb 2025 08:01:32 -0800 (PST) X-Google-Smtp-Source: AGHT+IGFwGxN7AEXtFao+iZL6ulae/eZoNGoDW+fdOz5CHBb1iLUDoq6Y+EfHKr41tk5ixLrU/unVg== X-Received: by 2002:a5d:47af:0:b0:38d:de45:bf98 with SMTP id ffacd0b85a97d-38f244d6481mr4693419f8f.8.1739462490087; Thu, 13 Feb 2025 08:01:30 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f258b432asm2207575f8f.6.2025.02.13.08.01.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:27 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 12/27] rust: chardev, qdev: add bindings to qdev_prop_set_chr Date: Thu, 13 Feb 2025 17:00:39 +0100 Message-ID: <20250213160054.3937012-13-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 Because the argument to the function is an Owned, this also adds an ObjectType implementation to Chardev. Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- rust/hw/char/pl011/src/device.rs | 3 ++- rust/qemu-api/meson.build | 1 + rust/qemu-api/src/chardev.rs | 19 +++++++++++++++++++ rust/qemu-api/src/lib.rs | 1 + rust/qemu-api/src/qdev.rs | 9 +++++++++ 5 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 rust/qemu-api/src/chardev.rs diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index 5e4e75133c8..4e959073711 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -12,9 +12,10 @@ bindings::{ error_fatal, qdev_prop_set_chr, qemu_chr_fe_accept_input, qemu_chr_fe_ioctl, qemu_chr_fe_set_handlers, qemu_chr_fe_write_all, qemu_irq, sysbus_connect_irq, - sysbus_mmio_map, sysbus_realize, CharBackend, Chardev, QEMUChrEvent, + sysbus_mmio_map, sysbus_realize, CharBackend, QEMUChrEvent, CHR_IOCTL_SERIAL_SET_BREAK, }, + chardev::Chardev, c_str, impl_vmstate_forward, irq::InterruptSource, memory::{hwaddr, MemoryRegion, MemoryRegionOps, MemoryRegionOpsBuilder}, diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build index 80eafc7f6bd..45e30324b29 100644 --- a/rust/qemu-api/meson.build +++ b/rust/qemu-api/meson.build @@ -20,6 +20,7 @@ _qemu_api_rs = static_library( 'src/bitops.rs', 'src/callbacks.rs', 'src/cell.rs', + 'src/chardev.rs', 'src/c_str.rs', 'src/irq.rs', 'src/memory.rs', diff --git a/rust/qemu-api/src/chardev.rs b/rust/qemu-api/src/chardev.rs new file mode 100644 index 00000000000..74cfb634e5f --- /dev/null +++ b/rust/qemu-api/src/chardev.rs @@ -0,0 +1,19 @@ +// Copyright 2024 Red Hat, Inc. +// Author(s): Paolo Bonzini +// SPDX-License-Identifier: GPL-2.0-or-later + +//! Bindings for character devices + +use std::ffi::CStr; + +use crate::{bindings, prelude::*}; + +pub type Chardev = bindings::Chardev; +pub type ChardevClass = bindings::ChardevClass; + +unsafe impl ObjectType for Chardev { + type Class = ChardevClass; + const TYPE_NAME: &'static CStr = + unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_CHARDEV) }; +} +qom_isa!(Chardev: Object); diff --git a/rust/qemu-api/src/lib.rs b/rust/qemu-api/src/lib.rs index e4316b21cf2..2a338a888a0 100644 --- a/rust/qemu-api/src/lib.rs +++ b/rust/qemu-api/src/lib.rs @@ -18,6 +18,7 @@ pub mod c_str; pub mod callbacks; pub mod cell; +pub mod chardev; pub mod irq; pub mod memory; pub mod module; diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs index 64ba3d90981..73343e10b96 100644 --- a/rust/qemu-api/src/qdev.rs +++ b/rust/qemu-api/src/qdev.rs @@ -16,6 +16,7 @@ bindings::{self, Error, ResettableClass}, callbacks::FnCall, cell::bql_locked, + chardev::Chardev, prelude::*, qom::{ClassInitImpl, ObjectClass, ObjectImpl, Owned}, vmstate::VMStateDescription, @@ -297,6 +298,14 @@ fn init_clock_out(&self, name: &str) -> Owned { Owned::from(&*clk) } } + + 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()); + } + } } impl DeviceMethods for R where R::Target: IsA {} From patchwork Thu Feb 13 16:00: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: 13973533 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 9A4EDC021A0 for ; Thu, 13 Feb 2025 16:03:45 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibes-0000wf-VU; Thu, 13 Feb 2025 11:01:46 -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 1tibeo-0000u4-CU for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:43 -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 1tibel-0005Xu-9A for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:42 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462497; 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=w/1RoRTf0RRS0LThHHY7f3sZLW21yJAIxZIiCZP4N+g=; b=WJw1rHk463BkfuMLxVocAYoMBN/Qs19NhLDh1AZnH8Ydy1TLR1yEMu2rw7eeyDlncjfE8/ hA7Kg/edPrSe3T9elRSSuzzEStenkkQa8h1JvBCOrnWnrqkWROzZnkigSmKspFgc5ia6zY TR8qxHsqM2LzMXX5Rz6yiITIASpPtO4= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-26-2bQRzlyoN6GuTIBHPKwZ6w-1; Thu, 13 Feb 2025 11:01:35 -0500 X-MC-Unique: 2bQRzlyoN6GuTIBHPKwZ6w-1 X-Mimecast-MFC-AGG-ID: 2bQRzlyoN6GuTIBHPKwZ6w_1739462494 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-43935bcec74so6051025e9.3 for ; Thu, 13 Feb 2025 08:01:34 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462493; x=1740067293; 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=w/1RoRTf0RRS0LThHHY7f3sZLW21yJAIxZIiCZP4N+g=; b=lDzEH7H8d4tHnzB4ZbpjBsvPN/G2aOx0JTHxm+LcH7kqN29K/7ntuKEarWoSFziWut M288eQrdQAnfKRBYjqk139eg5gEcL1lqkZ0Hj89hhU0zTmvOh4ICjnnwfhAGNut9XCKu +tzifV3gEBFamF+yNiONfTI70dwo+cb4GQ/PiKPAlKneb6eLjjMatWVV3eBHmEsd0amw Q/1/MuTuX4ZBiRcefyIifQgM3cdeXVR6xjWPw8tjlZQ2rwvcU+jV7MhFIoVOSnw4afhN SHs3ZR65AOIffPZ6TbF1xjb15LQR44HcAFW/4nHEN+bzzdfTg9RtYeQZVkjCZa1FBSdv z7Vw== X-Gm-Message-State: AOJu0Yw3thAYlHL9mwN5OrFy6J6JMEENyXhrHrRx4A/p2zqSZKr26SXV kGFjIosA+/uQuwZ7LrSOsATHq2ndPDtvWz3c+fJ/AxM/QAhN4cHjFUYB93xe0hzGSwxZXC/mCp/ QkwMU+L6LyKmxoyziFSVkiI2jUBmtRz5B35Yu8lW1benXXz6J9FBsNa8gRGmLKNJXu5lkiclrV6 im8A1libvG+MRZq57K0B4Tc2A3Pd+Gc3m5m8fnWzI= X-Gm-Gg: ASbGncuxsuAqCRMsCirb5qfEvxXbBQmzfiUfmZETEcx0eqfPwXxBTHezVkZRrOFiW0n anJpkkuiveimV6VpdQQQupBQpZ29/X/AvQZeFbEWKlZDKVNFr2/umsmdqrUuW6Pk2PgKsxokFD0 L4YcUze49zKIrEuhFz3tac8wJ3uyGZw4rSomMzFJ3Q+auP08azfFu/IfolWL+01emOpP858Cc80 4tUFaINOAbFAsjN67YAcy7fGshqUV1dsoXhUYPdXjR13hLbnxJ3aikV7NrRbXnwXdHWiLOeqdV8 dQnCp3bYk2AEFlnIoXpSo8Ai7K7JLPbWCwy9X6I+CEWmhA== X-Received: by 2002:a05:600c:1c82:b0:439:5803:414f with SMTP id 5b1f17b1804b1-43959925af0mr84072585e9.5.1739462492977; Thu, 13 Feb 2025 08:01:32 -0800 (PST) X-Google-Smtp-Source: AGHT+IE2EOwQd0ZXPwQhvNrZMUC/5MaOesFDyO0rSKolEYfI3nA9g633cMsov/u/9oYw9nPKETliKQ== X-Received: by 2002:a05:600c:1c82:b0:439:5803:414f with SMTP id 5b1f17b1804b1-43959925af0mr84071735e9.5.1739462491899; Thu, 13 Feb 2025 08:01:31 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f258b4344sm2299200f8f.13.2025.02.13.08.01.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:31 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 13/27] rust: pl011: convert pl011_create to safe Rust Date: Thu, 13 Feb 2025 17:00:40 +0100 Message-ID: <20250213160054.3937012-14-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 Not a major change but, as a small but significant step in creating qdev bindings, show how pl011_create can be written without "unsafe" calls (apart from converting pointers to references). This also provides a starting point for creating Error** bindings. Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- rust/hw/char/pl011/src/device.rs | 37 ++++++++++++++++---------------- rust/qemu-api/src/sysbus.rs | 34 ++++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index 4e959073711..fe73771021e 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -10,14 +10,12 @@ use qemu_api::{ bindings::{ - error_fatal, qdev_prop_set_chr, qemu_chr_fe_accept_input, qemu_chr_fe_ioctl, - qemu_chr_fe_set_handlers, qemu_chr_fe_write_all, qemu_irq, sysbus_connect_irq, - sysbus_mmio_map, sysbus_realize, CharBackend, QEMUChrEvent, - CHR_IOCTL_SERIAL_SET_BREAK, + qemu_chr_fe_accept_input, qemu_chr_fe_ioctl, qemu_chr_fe_set_handlers, + qemu_chr_fe_write_all, CharBackend, QEMUChrEvent, CHR_IOCTL_SERIAL_SET_BREAK, }, chardev::Chardev, - c_str, impl_vmstate_forward, - irq::InterruptSource, + impl_vmstate_forward, + irq::{IRQState, InterruptSource}, memory::{hwaddr, MemoryRegion, MemoryRegionOps, MemoryRegionOpsBuilder}, prelude::*, qdev::{Clock, ClockEvent, DeviceImpl, DeviceState, Property, ResetType, ResettablePhasesImpl}, @@ -698,26 +696,27 @@ pub fn post_load(&self, _version_id: u32) -> Result<(), ()> { /// # Safety /// -/// We expect the FFI user of this function to pass a valid pointer for `chr`. +/// We expect the FFI user of this function to pass a valid pointer for `chr` +/// and `irq`. #[no_mangle] pub unsafe extern "C" fn pl011_create( addr: u64, - irq: qemu_irq, + irq: *mut IRQState, chr: *mut Chardev, ) -> *mut DeviceState { - let pl011 = PL011State::new(); - unsafe { - let dev = pl011.as_mut_ptr::(); - qdev_prop_set_chr(dev, c_str!("chardev").as_ptr(), chr); + // SAFETY: The callers promise that they have owned references. + // They do not gift them to pl011_create, so use `Owned::from`. + let irq = unsafe { Owned::::from(&*irq) }; + let chr = unsafe { Owned::::from(&*chr) }; - let sysbus = pl011.as_mut_ptr::(); - sysbus_realize(sysbus, addr_of_mut!(error_fatal)); - sysbus_mmio_map(sysbus, 0, addr); - sysbus_connect_irq(sysbus, 0, irq); + let dev = PL011State::new(); + dev.prop_set_chr("chardev", &chr); + dev.sysbus_realize(); + dev.mmio_map(0, addr); + dev.connect_irq(0, &irq); - // return the pointer, which is kept alive by the QOM tree; drop owned ref - pl011.as_mut_ptr() - } + // The pointer is kept alive by the QOM tree; drop the owned ref + dev.as_mut_ptr() } #[repr(C)] diff --git a/rust/qemu-api/src/sysbus.rs b/rust/qemu-api/src/sysbus.rs index c27dbf79e43..1f66a5f1e09 100644 --- a/rust/qemu-api/src/sysbus.rs +++ b/rust/qemu-api/src/sysbus.rs @@ -2,18 +2,18 @@ // Author(s): Paolo Bonzini // SPDX-License-Identifier: GPL-2.0-or-later -use std::ffi::CStr; +use std::{ffi::CStr, ptr::addr_of_mut}; pub use bindings::{SysBusDevice, SysBusDeviceClass}; use crate::{ bindings, cell::bql_locked, - irq::InterruptSource, + irq::{IRQState, InterruptSource}, memory::MemoryRegion, prelude::*, qdev::{DeviceClass, DeviceState}, - qom::ClassInitImpl, + qom::{ClassInitImpl, Owned}, }; unsafe impl ObjectType for SysBusDevice { @@ -60,6 +60,34 @@ fn init_irq(&self, irq: &InterruptSource) { bindings::sysbus_init_irq(self.as_mut_ptr(), irq.as_ptr()); } } + + // TODO: do we want a type like GuestAddress here? + 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); + } + } + + // Owned<> is used here because sysbus_connect_irq (via + // object_property_set_link) adds a reference to the IRQState, + // which can prolong its life + fn connect_irq(&self, id: u32, irq: &Owned) { + assert!(bql_locked()); + let id: i32 = id.try_into().unwrap(); + unsafe { + bindings::sysbus_connect_irq(self.as_mut_ptr(), id, irq.as_mut_ptr()); + } + } + + 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)); + } + } } impl SysBusDeviceMethods for R where R::Target: IsA {} From patchwork Thu Feb 13 16:00: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: 13973528 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 A3D18C021A0 for ; Thu, 13 Feb 2025 16:02:51 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibfB-00010t-7z; Thu, 13 Feb 2025 11:02:05 -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 1tibep-0000uk-KP for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:43 -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 1tiben-0005Yd-8k for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:43 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462500; 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=Tt5qLjgDkzgeWvrd3siaS5OYB5bi/JKRwTeutA8JPDs=; b=HxoSqHhgGPA0tdtCLxjRsrPZC/EGgDbY+P/7GuofRNl+/mX+nMSVkdYhjRZRpv832pagF9 fZ3KdmWhFN5K9owD3mRfHebiqCVYvNwZGy05Dpl5CFuBBoV7Gb/j28EnFtxDr+gQo5/coI +Vk05zBOdvLuztX75C95/2qHKiD6ieo= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-541-MyoQmwq9N9GYK3iHDwzLxA-1; Thu, 13 Feb 2025 11:01:39 -0500 X-MC-Unique: MyoQmwq9N9GYK3iHDwzLxA-1 X-Mimecast-MFC-AGG-ID: MyoQmwq9N9GYK3iHDwzLxA Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-4395586f952so5401285e9.2 for ; Thu, 13 Feb 2025 08:01:38 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462497; x=1740067297; 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=Tt5qLjgDkzgeWvrd3siaS5OYB5bi/JKRwTeutA8JPDs=; b=jRXaKmRFncAmmEnB7nGa1PMRYevkcuRnYPk/sH9ub8O0RBCtiSndS/DBVk2yJbVf0f nnLAAo8F4m9e8YYZnYXqzeWu8WN+xIcCnsOqrwwpHDn2RGEcwykjlKM7fB9GfHGmLwva WIPbifMYu+wf/VbnK1n4xjkDnK1ylZaYstcNfvVceVshkcytEV4ePNM3MM24OSnxIjcP y/Gx7m9omwYwSIFMhxguHs4YoRwH/yNRZajgy/y8TzIDrslAZTz3NQrFvvLFgfIK7nsT mmXFOOplDa4RMfHdFsAn5DYoDVSWC/83Zz1pdErw6wKr6sWHpB/x0KJsnk6SLI8Bxt3v IleA== X-Gm-Message-State: AOJu0Yx77PK23PQT7B2YQrJ7rgZgvcV4M3CJUvAox6o1Nw+LHn2XX8Cu O4iIe5YakWm6CFoerBoysIbPbtWXnzJekRYmxWAqVXooBxLfborwDLFJB5ok4zmIQwInM+O/IWM g2WYIDUnQNa99uB/FLQYYtClwh1nyaUTJvBNOPzkqZCG1gz/RUiJ2fgt1QFhxthk38mF0b+LYOu cWr4yjKdAHKICIrEZSk0SgqLtByBmJWg6aHlBY7Ys= X-Gm-Gg: ASbGnctq4T3a48PFD6VHxzUP9vhlipE0ZfeACbO3qH5CaXSjWn8uIILbGeejbns4Zv3 rIUzPY5QoBzwH0GGL+p2GxOcahPslGLKyB6w3WIZ/RrhUX5hRaKAJ1ypBs8XTcI4TB56457i3TL mxuDn4m++pliLCwwyBnQ8g+AERFTazM+QNz6rLABP2+fUmG7MWcTJWgY5kiJoa+0ZQhbaNsRfUH n9rcdbclOtUrcxFPxUIj6YXPKDkG8T661Lr0AgQ6oinN4IT7woYyzCHZs2boIlsPq0cXMR90IXO ceoN8kBviMqpzE5SLy+9jvK0KJsA8xcCbpCQnXH1+8OOdQ== X-Received: by 2002:a05:600c:4fc6:b0:434:a734:d268 with SMTP id 5b1f17b1804b1-43960185baemr53667795e9.14.1739462497285; Thu, 13 Feb 2025 08:01:37 -0800 (PST) X-Google-Smtp-Source: AGHT+IFwKGPXT5gHUdEmjdR6lkKJRyUOwEe0aqs6m32ToYFsCbVjYOVebAqe87dOi3od8vOfT+b3pg== X-Received: by 2002:a05:600c:4fc6:b0:434:a734:d268 with SMTP id 5b1f17b1804b1-43960185baemr53665375e9.14.1739462495153; Thu, 13 Feb 2025 08:01:35 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4395a04f217sm51970905e9.1.2025.02.13.08.01.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:33 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 14/27] i386/fw_cfg: move hpet_cfg definition to hpet.c Date: Thu, 13 Feb 2025 17:00:41 +0100 Message-ID: <20250213160054.3937012-15-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 From: Zhao Liu HPET device needs to access and update hpet_cfg variable, but now it is defined in hw/i386/fw_cfg.c and Rust code can't access it. Move hpet_cfg definition to hpet.c (and rename it to hpet_fw_cfg). This allows Rust HPET device implements its own global hpet_fw_cfg variable, and will further reduce the use of unsafe C code access and calls in the Rust HPET implementation. Signed-off-by: Zhao Liu Link: https://lore.kernel.org/r/20250210030051.2562726-2-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- include/hw/timer/hpet.h | 2 +- hw/i386/fw_cfg.c | 6 ++++-- hw/timer/hpet.c | 16 +++++++++------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/hw/timer/hpet.h b/include/hw/timer/hpet.h index 71e8c62453d..c2656f7f0be 100644 --- a/include/hw/timer/hpet.h +++ b/include/hw/timer/hpet.h @@ -73,7 +73,7 @@ struct hpet_fw_config struct hpet_fw_entry hpet[8]; } QEMU_PACKED; -extern struct hpet_fw_config hpet_cfg; +extern struct hpet_fw_config hpet_fw_cfg; #define TYPE_HPET "hpet" diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c index 91bf1df0f2e..d08aefa0291 100644 --- a/hw/i386/fw_cfg.c +++ b/hw/i386/fw_cfg.c @@ -26,7 +26,9 @@ #include CONFIG_DEVICES #include "target/i386/cpu.h" -struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; +#if !defined(CONFIG_HPET) && !defined(CONFIG_X_HPET_RUST) +struct hpet_fw_config hpet_fw_cfg = {.count = UINT8_MAX}; +#endif const char *fw_cfg_arch_key_name(uint16_t key) { @@ -149,7 +151,7 @@ FWCfgState *fw_cfg_arch_create(MachineState *ms, #endif fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, 1); - fw_cfg_add_bytes(fw_cfg, FW_CFG_HPET, &hpet_cfg, sizeof(hpet_cfg)); + fw_cfg_add_bytes(fw_cfg, FW_CFG_HPET, &hpet_fw_cfg, sizeof(hpet_fw_cfg)); /* allocate memory for the NUMA channel: one (64bit) word for the number * of nodes, one word for each VCPU->node and one word for each node to * hold the amount of memory. diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index 1c8c6c69ef5..dcff18a9871 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -40,6 +40,8 @@ #include "qom/object.h" #include "trace.h" +struct hpet_fw_config hpet_fw_cfg = {.count = UINT8_MAX}; + #define HPET_MSI_SUPPORT 0 OBJECT_DECLARE_SIMPLE_TYPE(HPETState, HPET) @@ -278,7 +280,7 @@ static int hpet_post_load(void *opaque, int version_id) /* Push number of timers into capability returned via HPET_ID */ s->capability &= ~HPET_ID_NUM_TIM_MASK; s->capability |= (s->num_timers - 1) << HPET_ID_NUM_TIM_SHIFT; - hpet_cfg.hpet[s->hpet_id].event_timer_block_id = (uint32_t)s->capability; + hpet_fw_cfg.hpet[s->hpet_id].event_timer_block_id = (uint32_t)s->capability; /* Derive HPET_MSI_SUPPORT from the capability of the first timer. */ s->flags &= ~(1 << HPET_MSI_SUPPORT); @@ -665,8 +667,8 @@ static void hpet_reset(DeviceState *d) s->hpet_counter = 0ULL; s->hpet_offset = 0ULL; s->config = 0ULL; - hpet_cfg.hpet[s->hpet_id].event_timer_block_id = (uint32_t)s->capability; - hpet_cfg.hpet[s->hpet_id].address = sbd->mmio[0].addr; + hpet_fw_cfg.hpet[s->hpet_id].event_timer_block_id = (uint32_t)s->capability; + hpet_fw_cfg.hpet[s->hpet_id].address = sbd->mmio[0].addr; /* to document that the RTC lowers its output on reset as well */ s->rtc_irq_level = 0; @@ -708,17 +710,17 @@ static void hpet_realize(DeviceState *dev, Error **errp) if (!s->intcap) { warn_report("Hpet's intcap not initialized"); } - if (hpet_cfg.count == UINT8_MAX) { + if (hpet_fw_cfg.count == UINT8_MAX) { /* first instance */ - hpet_cfg.count = 0; + hpet_fw_cfg.count = 0; } - if (hpet_cfg.count == 8) { + if (hpet_fw_cfg.count == 8) { error_setg(errp, "Only 8 instances of HPET is allowed"); return; } - s->hpet_id = hpet_cfg.count++; + s->hpet_id = hpet_fw_cfg.count++; for (i = 0; i < HPET_NUM_IRQ_ROUTES; i++) { sysbus_init_irq(sbd, &s->irqs[i]); From patchwork Thu Feb 13 16:00: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: 13973553 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 3CDE2C021A4 for ; Thu, 13 Feb 2025 16:09:32 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibeu-0000xf-W2; Thu, 13 Feb 2025 11:01:49 -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 1tiber-0000wX-It for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:45 -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 1tibep-0005ZW-VW for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:45 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462503; 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=3iw0/AYRBwPsktKL9Xh//wvj/8ASNqeRu9rzaypgjUY=; b=EJ5xrA0xS8EogMElYHF5sREooP5ln+I3wx5t3UHbRC9hIXUxVzCdZ8kqkmJ84nsTZk/Wkn 4B8vdsvMciWQpj9yS89EwMtFKhO/0LeoBaoHifp3zX/qoPb4nJAVUDfXft2KpwsRGIYc4V fw7saj7TfPkQQULUdYe8/3syiYbWSQ0= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-127-RyL3zWVEN4eNHjGr66Nt-A-1; Thu, 13 Feb 2025 11:01:41 -0500 X-MC-Unique: RyL3zWVEN4eNHjGr66Nt-A-1 X-Mimecast-MFC-AGG-ID: RyL3zWVEN4eNHjGr66Nt-A_1739462500 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-4393e89e910so5890815e9.0 for ; Thu, 13 Feb 2025 08:01:41 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462499; x=1740067299; 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=3iw0/AYRBwPsktKL9Xh//wvj/8ASNqeRu9rzaypgjUY=; b=HijHu3CWJaJXJpyr3sP9rgtLfjifzvUe9vaRikAokJWNAa+vuPPaj93AOWGPF9aSND 7L7PFPSPrjo63Bz3vBZO9qx2b/xhbPIa52ry2O+HX2d5C1J9gg7m7Z0eKxVKxiVcwtN8 N2prIkuYhJvfjItbTjA7ibImWbtct/oaAiT+qB/Xlj7kUswA+YSHWuV71tn3yJE6ZJCQ PCBPK2xBlcTaloLsRmiFDzOzmmKCC0YS86azgBsQmup4kxffh7Kjur01GQxZcd6JhOx/ ZmLhno2DQGLYus9jVAnSK31KxhrmycYXxZfWTRjIOxghZVv1twTk7/FcSCHtuR0y4TXl LRkA== X-Gm-Message-State: AOJu0YzDQxXB9MEFBfnDT5cD7xHlXPP1YIkvPQ9xACk77M6BiUeBMC8i 5vXMR+0m8v4s0sP6UqATk2AE7QgeFf8YpL/uWrqfiqRMKjCx532KiUXfiYkdnaG0KG/idpYNGXF ttq3i5ZxWbNC8cv/2hoBkkRIJTb6u/vcG/W6WpENbdmhI/oTCTp8vNL3QqLWh+AC0BxRzTiX/N2 IoKihyBDeg83DRn8bSFcI9uZYaWZ9Ce7bwZNR31bU= X-Gm-Gg: ASbGncvt2bbHHJ4SdA6WwvUU0JKgIedhVDb1I5u+wvraFEvC/l8ULlmVSi/NreBvuyv uMlW3RJsl0OR9tUI6bVZq3iMBa8ip/dIZFFjItqTozip2pKK9iNRKGe1x/11sB0xe4MAjiMA2FX 49900pvrtsJCUD0d0GxI7mA3Qag0P2intFJd7QjC//MhvQr0RmlMOajerK/jeCgVqF5sakUDXZx B1ccnAEdFe97FW4DMjJ/pa4GNbyvYSh6N7MI8tFyWBMDMhPE1hGehRNvL1SSSKXA7IPmYPplS+m KgqwAUwi2GXpsnWB3sf0RZXyxmOOExAxGGxojJdTvjsICg== X-Received: by 2002:a05:600c:a4a:b0:439:57b5:f8a0 with SMTP id 5b1f17b1804b1-439601ab838mr46795955e9.24.1739462499065; Thu, 13 Feb 2025 08:01:39 -0800 (PST) X-Google-Smtp-Source: AGHT+IHvGzqzxxPcE5zcFqijbmOw3CsFbgwzv0DTWm3ckR5l3JzPJTy4VDMg7p4dX1e8bkrzGBrqGA== X-Received: by 2002:a05:600c:a4a:b0:439:57b5:f8a0 with SMTP id 5b1f17b1804b1-439601ab838mr46793975e9.24.1739462496944; Thu, 13 Feb 2025 08:01:36 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-439617fc885sm21272335e9.9.2025.02.13.08.01.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:36 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 15/27] rust/qdev: add the macro to define bit property Date: Thu, 13 Feb 2025 17:00:42 +0100 Message-ID: <20250213160054.3937012-16-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 From: Zhao Liu HPET device (Rust device) needs to define the bit type property. Add a variant of define_property macro to define bit type property. Signed-off-by: Zhao Liu Link: https://lore.kernel.org/r/20250210030051.2562726-3-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/qdev.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs index 73343e10b96..c44a22876b9 100644 --- a/rust/qemu-api/src/qdev.rs +++ b/rust/qemu-api/src/qdev.rs @@ -168,6 +168,18 @@ fn class_init(dc: &mut DeviceClass) { #[macro_export] macro_rules! define_property { + ($name:expr, $state:ty, $field:ident, $prop:expr, $type:ty, bit = $bitnr:expr, default = $defval:expr$(,)*) => { + $crate::bindings::Property { + // use associated function syntax for type checking + name: ::std::ffi::CStr::as_ptr($name), + info: $prop, + offset: $crate::offset_of!($state, $field) as isize, + bitnr: $bitnr, + set_default: true, + defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval as u64 }, + ..$crate::zeroable::Zeroable::ZERO + } + }; ($name:expr, $state:ty, $field:ident, $prop:expr, $type:ty, default = $defval:expr$(,)*) => { $crate::bindings::Property { // use associated function syntax for type checking From patchwork Thu Feb 13 16:00:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13973535 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 A88A8C021A0 for ; Thu, 13 Feb 2025 16:05:18 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibfK-00015R-2u; Thu, 13 Feb 2025 11:02:14 -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 1tibf7-00010q-9i for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:01 -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 1tibf5-0005cA-Eb for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462518; 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=ahr6D3HUwH5Ls6hZQSV3hmahhoExY6Sc6jHH3fVS+DM=; b=GOsZv6EAT6tKR5w0tQFwIt518cajyqyQu/k8ip2fDzBxbqehj3OHs8pOG5sKZ6jbiX32YH 5XpH42QgSxi33v/C6LlAtu83jMAYyTXS/IBQ2W1p1CfjRo5E0FVdSqPzv/+Wlle38w9j7S 1ADTGXsccxmNeWPZ4zIV8blr3Zyv/4A= Received: from mail-ej1-f69.google.com (mail-ej1-f69.google.com [209.85.218.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-31-lvsxE0-JM0yqr6Uy7HQ-Uw-1; Thu, 13 Feb 2025 11:01:56 -0500 X-MC-Unique: lvsxE0-JM0yqr6Uy7HQ-Uw-1 X-Mimecast-MFC-AGG-ID: lvsxE0-JM0yqr6Uy7HQ-Uw_1739462515 Received: by mail-ej1-f69.google.com with SMTP id a640c23a62f3a-ab39f65dc10so129435166b.1 for ; Thu, 13 Feb 2025 08:01:55 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462514; x=1740067314; 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=ahr6D3HUwH5Ls6hZQSV3hmahhoExY6Sc6jHH3fVS+DM=; b=Vw/77RgbqvReO07kyZUYNpvP9LycpJS12izD/oBloYABl/DxqHBPZOHcYVe0gy/d9i QPrBlTxQv/nySsCWOXRfLhKsjCqRgCKeD4DJkngndsTMj2dj/7Mo86Csddx4eiuqyfdD pS4AcNoaDk9yzJkRd1A7tKnUqUt7GxObywrt3Zrgjc99MQlhxqIHDkCzBKgIfKkfQTmP g0BQ8k6W5I7j+2Oya95TycJltkLc3GCsksTCScV9pWr+W+F1A4qTahgRaoIRy/O0Cpg3 X3+gelMBB+ECEbMTx7erEeG2P+jqikb8ALn4k0F1y4eYjALwKF7pB1aoY8QOFlp+mwAe apTA== X-Gm-Message-State: AOJu0YyN0cTGHsxn4RjJDkXvvMEHOoUq20iQKutezetW4lCWFA2FMDDW FdhLPgbTfW8hpOOhmTVDkRthwjY6E3y49fYKMKAV9DK9e2wGLO+6fgzTTcRrwQRzpX7f+W2hjWN eCk7ur/+62669dFxtuB7ifDWgnV7Ya68jFhVPLYzXbqG6sdvYEYhYJ5YObR5r1mKDuLRvnCug+8 yRsYx/jg4qJ5IUaizWME83NgMiASDzFs674sqpbRA= X-Gm-Gg: ASbGncvwHPuvUch5YbGUKCy4fIsEUK4Rx2dId2/XUbPfKQQjEaMV4uk8zJD7h8zg7SQ wrHem6cwSdP4pOcQouFeJG3MQnYIevnKBP+PqFIIW8cij7WOp8nciHd5LzDxe7pMJd90V5PrsGx fcRgfcTWggQaEaBXidITHwl0tSPvNj72iVopNA8FscjvSTSCWs2eF4lRWn6v8FBqQYhKAQHEmSl a6SJWsDa97ZCmP48t9sagSgH8KZZSOc4LbSGpOVd1tPRO/Q/6cKXc0lI4lCjiU6xvUzz4bH/y3G XlH+a/u3+YC61eQcGIHnwdu9soQC7wXE12ax4cBrXBLzAA== X-Received: by 2002:a17:907:2d11:b0:ab7:e451:4834 with SMTP id a640c23a62f3a-aba4ebabfc9mr346470166b.19.1739462502956; Thu, 13 Feb 2025 08:01:42 -0800 (PST) X-Google-Smtp-Source: AGHT+IFNvV97dF43opM9yfLujDXJ6CvLH+bFhvdySbv+SmPuX/q+COo5fvb83yYz/+ReN62RjvIVXQ== X-Received: by 2002:a17:907:2d11:b0:ab7:e451:4834 with SMTP id a640c23a62f3a-aba4ebabfc9mr346414666b.19.1739462498935; Thu, 13 Feb 2025 08:01:38 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4396180f7d6sm21327345e9.17.2025.02.13.08.01.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:38 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 16/27] rust/irq: Add a helper to convert [InterruptSource] to pointer Date: Thu, 13 Feb 2025 17:00:43 +0100 Message-ID: <20250213160054.3937012-17-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 From: Zhao Liu This is useful when taking an InterruptSource slice and passing it to C function. Suggested-by: Paolo Bonzini Signed-off-by: Zhao Liu Link: https://lore.kernel.org/r/20250210030051.2562726-4-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/irq.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rust/qemu-api/src/irq.rs b/rust/qemu-api/src/irq.rs index 835b027d5e5..672eec1430f 100644 --- a/rust/qemu-api/src/irq.rs +++ b/rust/qemu-api/src/irq.rs @@ -83,6 +83,12 @@ pub fn set(&self, level: T) { pub(crate) const fn as_ptr(&self) -> *mut *mut IRQState { self.cell.as_ptr() } + + #[allow(dead_code)] + pub(crate) const fn slice_as_ptr(slice: &[Self]) -> *mut *mut IRQState { + assert!(!slice.is_empty()); + slice[0].as_ptr() + } } impl Default for InterruptSource { From patchwork Thu Feb 13 16:00:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13973527 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 759BEC021A4 for ; Thu, 13 Feb 2025 16:02:37 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibfB-00010s-86; Thu, 13 Feb 2025 11:02:05 -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 1tibez-0000zC-MS for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:54 -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 1tibex-0005bF-Oj for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:53 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462511; 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=mivfeOqK0XtIeqrjyFn8pgXSCxXVOfe1ZMdvogAVIRk=; b=K+dC8Mfl8WFnbb7OpWsqX1E8PAknXxFJgf73eMv4GXR8tfoIoXpj2+C06ROjj3flDT6FnK oBjuDdwkWa3p78t1w0bFM7XrYA8sT+WrWlRgl+pk1WQOpCIvpy54toZO5nI7UmWouWBM3P sSbMVFxprP3Z0efYe5enisT8eAWtYsE= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-644-ggKGpwhWNCS7I1FbHFrR-Q-1; Thu, 13 Feb 2025 11:01:47 -0500 X-MC-Unique: ggKGpwhWNCS7I1FbHFrR-Q-1 X-Mimecast-MFC-AGG-ID: ggKGpwhWNCS7I1FbHFrR-Q Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-38f20b530dfso1060679f8f.3 for ; Thu, 13 Feb 2025 08:01:47 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462506; x=1740067306; 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=mivfeOqK0XtIeqrjyFn8pgXSCxXVOfe1ZMdvogAVIRk=; b=t3exQYQc3bBpUeFoZKR/TwstEfAti2sRph5YycGly2Wg2uvORZUbcUKPFZH0MX2ReF r8Ns4f6aJ1UHmj3F7wVh0h/YY3aPC80f3d0QpMapFijZP4nfK3meEETa6P9Qm1NJoMYt p6hjOUQgSrTN1JBk64764c6TN7+gopsaEX7SDT5Wm7Cok1dYvftd/qhzUiu8CBEPaACx eYHPIdlM2rSyIcfRlWt5yh8dTSHWP2sgMRkaZJs7TVYjS9S7PWXdi5CmHTFLQQ7/XI/H m1TTOqzpWF+iZsEPH5D5SGK+L/6avBjGZSPwVl4/fafNwGuvznVBm3BLPzGtfTAjAya/ 7ANg== X-Gm-Message-State: AOJu0YyhWLmxUGhIbCYqe5TCjRsf6xegUb1jaBuIq4b9iG7QJjU79tbo Hm7jJqur2PxgnXYs9trNsPU19qdo0SrRv1TA4nHh8000w/uHBFoUfSI0vNWGwtXGgKytFkc0sVA /Zki+t5ffXKn21fuI0yWHw5gFwQZQ/gr8IF4aZOsb3tjHlvNLFqwL05Dvex3ui5mRP0RYMGf7Wg JbAHT4Mmwc+WRt8QGpOXNI8QBuqTMFf5usSiQPoOY= X-Gm-Gg: ASbGncuG9p6ewG/PotJMnG3chsaFB+WAJ4RGTJfPfQWAf+H7g8R1NWpG/ih9D+Ncmct BsSSnEH7GbsjKY7wdYRPP8EYzh03hVS1P5bnNeEu8r4F8O9wS50iwnRG4JtnN0bhktnkMZgxGW+ c3BJ/+obKHth2mM45XFfUy/6yrtKYE8MF0x7pLriDvXwVpCt3CZbQTgse3G4LhacFUvijna0COP XWbjX1rB1CoL12m3oaPVogyasq45c9CMUs/i4JHngPbqDcQx3Q2MPWdQeBBfT3etRPktnySIFzn yzJ/R1Qu0uDhJKFitZvP0nmc3x3WDkImLRa2u4yMnIeESg== X-Received: by 2002:a05:6000:1868:b0:38d:e0be:71a3 with SMTP id ffacd0b85a97d-38dea2fa9fdmr8502046f8f.54.1739462504860; Thu, 13 Feb 2025 08:01:44 -0800 (PST) X-Google-Smtp-Source: AGHT+IFBZ0AJzJ6RThTRI63zaw+dhT6Wid1pjduAqrAQms4tBdlrua7qdRZ9GTkWn/cP39VTWBz7GA== X-Received: by 2002:a05:6000:1868:b0:38d:e0be:71a3 with SMTP id ffacd0b85a97d-38dea2fa9fdmr8501970f8f.54.1739462504225; Thu, 13 Feb 2025 08:01:44 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43961826cd4sm21228355e9.24.2025.02.13.08.01.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:43 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 17/27] rust: add bindings for gpio_{in|out} initialization Date: Thu, 13 Feb 2025 17:00:44 +0100 Message-ID: <20250213160054.3937012-18-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 From: Zhao Liu Wrap qdev_init_gpio_{in|out} as methods in DeviceMethods. And for qdev_init_gpio_in, based on FnCall, it can support idiomatic Rust callback without the need for C style wrapper. Signed-off-by: Zhao Liu Link: https://lore.kernel.org/r/20250210030051.2562726-5-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/irq.rs | 1 - rust/qemu-api/src/qdev.rs | 47 +++++++++++++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/rust/qemu-api/src/irq.rs b/rust/qemu-api/src/irq.rs index 672eec1430f..d1c9dc96eff 100644 --- a/rust/qemu-api/src/irq.rs +++ b/rust/qemu-api/src/irq.rs @@ -84,7 +84,6 @@ pub(crate) const fn as_ptr(&self) -> *mut *mut IRQState { self.cell.as_ptr() } - #[allow(dead_code)] pub(crate) const fn slice_as_ptr(slice: &[Self]) -> *mut *mut IRQState { assert!(!slice.is_empty()); slice[0].as_ptr() diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs index c44a22876b9..3a7aa4def62 100644 --- a/rust/qemu-api/src/qdev.rs +++ b/rust/qemu-api/src/qdev.rs @@ -6,17 +6,18 @@ use std::{ ffi::{CStr, CString}, - os::raw::c_void, + os::raw::{c_int, c_void}, ptr::NonNull, }; pub use bindings::{Clock, ClockEvent, DeviceClass, DeviceState, Property, ResetType}; use crate::{ - bindings::{self, Error, ResettableClass}, + bindings::{self, qdev_init_gpio_in, qdev_init_gpio_out, Error, ResettableClass}, callbacks::FnCall, cell::bql_locked, chardev::Chardev, + irq::InterruptSource, prelude::*, qom::{ClassInitImpl, ObjectClass, ObjectImpl, Owned}, vmstate::VMStateDescription, @@ -28,8 +29,8 @@ pub trait ResettablePhasesImpl { /// If not None, this is called when the object enters reset. It /// can reset local state of the object, but it must not do anything that /// has a side-effect on other objects, such as raising or lowering an - /// [`InterruptSource`](crate::irq::InterruptSource), or reading or - /// writing guest memory. It takes the reset's type as argument. + /// [`InterruptSource`], or reading or writing guest memory. It takes the + /// reset's type as argument. const ENTER: Option = None; /// If not None, this is called when the object for entry into reset, once @@ -318,6 +319,44 @@ fn prop_set_chr(&self, propname: &str, chr: &Owned) { bindings::qdev_prop_set_chr(self.as_mut_ptr(), c_propname.as_ptr(), chr.as_mut_ptr()); } } + + fn init_gpio_in FnCall<(&'a Self::Target, u32, u32)>>( + &self, + num_lines: u32, + _cb: F, + ) { + let _: () = F::ASSERT_IS_SOME; + + unsafe extern "C" fn rust_irq_handler FnCall<(&'a T, u32, u32)>>( + opaque: *mut c_void, + line: c_int, + level: c_int, + ) { + // SAFETY: the opaque was passed as a reference to `T` + F::call((unsafe { &*(opaque.cast::()) }, line as u32, level as 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, + ); + } + } + + fn init_gpio_out(&self, pins: &[InterruptSource]) { + unsafe { + qdev_init_gpio_out( + self.as_mut_ptr::(), + InterruptSource::slice_as_ptr(pins), + pins.len() as c_int, + ); + } + } } impl DeviceMethods for R where R::Target: IsA {} From patchwork Thu Feb 13 16:00:45 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13973554 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 7CE67C021A0 for ; Thu, 13 Feb 2025 16:09:34 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibfM-000179-CZ; Thu, 13 Feb 2025 11:02:16 -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 1tibfC-00012M-5X for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02: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 1tibfA-0005cb-Ab for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462519; 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=5kzmkIRqhlXbqWGVMFyokXMxq1ViMc/6BtpuRSbbCnU=; b=Uexvsv3PblcoFvZKKkcziASuzYltgcFT549Ngjop5g+HnBpVxUxLQIdsaWTV3tvYg3/Mji Z80ROy4YamXd5Xw20jyUp1G3Lmybb6mhzqcWI39TiiGvPbg4xhQuCVE5CgcEpd4M+mMoBV gp9Es2z3UxFfjIu9u41EwL+7F0P91kI= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-224-hUt8jtLBOQ2zEOngkyubBQ-1; Thu, 13 Feb 2025 11:01:51 -0500 X-MC-Unique: hUt8jtLBOQ2zEOngkyubBQ-1 X-Mimecast-MFC-AGG-ID: hUt8jtLBOQ2zEOngkyubBQ_1739462509 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-439622e9113so5914185e9.3 for ; Thu, 13 Feb 2025 08:01:50 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462508; x=1740067308; 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=5kzmkIRqhlXbqWGVMFyokXMxq1ViMc/6BtpuRSbbCnU=; b=dt6+ZifajCedv5Ltpl34SnegJTCqGV08PfL61jZX4KiJ+LHsfiTztVqWvc/ybXAsSJ xFh+V719K0UgI1on2847JiPDKo/1+NZqPEiFmjL7zhzIs+ThRkWZ4pvK4QALKFn/OmBB DMbF0tqLajzsrcWqYGf9NyFd2qNY6LPLfNSzGjKPoJYxCfawQhvZJvqFAhhE87QfWjg2 4KHv1XKSKC/y/DpSU5R+jAwPafyJnH4a8PempFPS3ImTEkyMMglFs2vLn7G73ucBrijo baI1pMHHTh5i4EBcUkAjGMRthBAqRqhCJC2D4xLC0KQHNOHXMDMJUB5brRSKTNSX36Mf +2rw== X-Gm-Message-State: AOJu0Yyw0bw8xw6CIIznktP2vi9pr3UuJvFKjeg4zINqrRgDIMe+Sn2S weqctJ8LwnRWGanvbLKCbLng9zz2CavUwj7q+aUaofxDy4kqxugl1Ksilau+1ihSmaiHplylzNR 6unaXvu9Zi91JU6bm9vKL3lHKG6DsxlIzTnLlDdHpO3vhb9VVlSJFKsuOgctJD0FqY5qZYlFEUO KcuvpI2/tt8rnf0QRCnUkuH3zMnSH+P9KSxLhrihA= X-Gm-Gg: ASbGnct6PHV6hSaEJYZ3M4DMvAlaae4jRhvQiMO2mMVRwOwM06dGDxdxBk53L1l9K7W ODx0yt5Kqc2CBOpNkMUsYeXpu4Req4tS6aOfXYwemixsbPIpPNJq0Knhj/S8MqqYwRBP3UXZsjC RUqaslQtj9QinHmfgCm5PdXRPLpv34MZOsynDFV07YrzRZref/zGba9j+OfWHVB56SdoT1O1y9x p0mfWXksXssPMWidIglESl3W+80pS3l1U3eN3bwM1wJzfndUyAI5EdYomEFAyNhNnL6P0S0dR56 31WDrVGw/53zig+XRVWCQSHvBzrPbG+Qa6qeBcD8ZI7S9A== X-Received: by 2002:a05:600c:46ce:b0:439:4706:ae04 with SMTP id 5b1f17b1804b1-43958183d00mr88069365e9.16.1739462507973; Thu, 13 Feb 2025 08:01:47 -0800 (PST) X-Google-Smtp-Source: AGHT+IF5P3usQFM4sw99zeLXuofbTil4WiHincDNIFVauGcj8cqp1Jakn1BBYgPpx8TugeF/JE3PXw== X-Received: by 2002:a05:600c:46ce:b0:439:4706:ae04 with SMTP id 5b1f17b1804b1-43958183d00mr88068625e9.16.1739462507437; Thu, 13 Feb 2025 08:01:47 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259d5b40sm2266095f8f.68.2025.02.13.08.01.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:46 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 18/27] rust: add bindings for memattrs Date: Thu, 13 Feb 2025 17:00:45 +0100 Message-ID: <20250213160054.3937012-19-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 From: Zhao Liu The MemTxAttrs structure contains bitfield members, and bindgen is unable to generate an equivalent macro definition for MEMTXATTRS_UNSPECIFIED. Therefore, manually define a global constant variable MEMTXATTRS_UNSPECIFIED to support calls from Rust code. Signed-off-by: Zhao Liu Link: https://lore.kernel.org/r/20250125125137.1223277-6-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/wrapper.h | 1 + rust/qemu-api/src/memory.rs | 16 ++++++++++++++-- rust/qemu-api/src/zeroable.rs | 1 + 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/rust/wrapper.h b/rust/wrapper.h index a9bc67af0d5..54839ce0f51 100644 --- a/rust/wrapper.h +++ b/rust/wrapper.h @@ -62,3 +62,4 @@ typedef enum memory_order { #include "qapi/error.h" #include "migration/vmstate.h" #include "chardev/char-serial.h" +#include "exec/memattrs.h" diff --git a/rust/qemu-api/src/memory.rs b/rust/qemu-api/src/memory.rs index 963d689c27d..682951ab44e 100644 --- a/rust/qemu-api/src/memory.rs +++ b/rust/qemu-api/src/memory.rs @@ -2,7 +2,7 @@ // Author(s): Paolo Bonzini // SPDX-License-Identifier: GPL-2.0-or-later -//! Bindings for `MemoryRegion` and `MemoryRegionOps` +//! Bindings for `MemoryRegion`, `MemoryRegionOps` and `MemTxAttrs` use std::{ ffi::{CStr, CString}, @@ -11,7 +11,7 @@ ptr::addr_of, }; -pub use bindings::hwaddr; +pub use bindings::{hwaddr, MemTxAttrs}; use crate::{ bindings::{self, device_endian, memory_region_init_io}, @@ -189,3 +189,15 @@ unsafe impl ObjectType for MemoryRegion { unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_MEMORY_REGION) }; } qom_isa!(MemoryRegion: Object); + +/// A special `MemTxAttrs` constant, used to indicate that no memory +/// attributes are specified. +/// +/// Bus masters which don't specify any attributes will get this, +/// which has all attribute bits clear except the topmost one +/// (so that we can distinguish "all attributes deliberately clear" +/// from "didn't specify" if necessary). +pub const MEMTXATTRS_UNSPECIFIED: MemTxAttrs = MemTxAttrs { + unspecified: true, + ..Zeroable::ZERO +}; diff --git a/rust/qemu-api/src/zeroable.rs b/rust/qemu-api/src/zeroable.rs index 75742b50d4e..9f009606b1a 100644 --- a/rust/qemu-api/src/zeroable.rs +++ b/rust/qemu-api/src/zeroable.rs @@ -101,3 +101,4 @@ fn default() -> Self { impl_zeroable!(crate::bindings::MemoryRegionOps__bindgen_ty_1); impl_zeroable!(crate::bindings::MemoryRegionOps__bindgen_ty_2); impl_zeroable!(crate::bindings::MemoryRegionOps); +impl_zeroable!(crate::bindings::MemTxAttrs); From patchwork Thu Feb 13 16:00:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13973555 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 88080C021A0 for ; Thu, 13 Feb 2025 16:10:10 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibfK-00015P-0z; Thu, 13 Feb 2025 11:02:14 -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 1tibf6-00010C-7W for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:00 -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 1tibf3-0005bz-9b for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:01:59 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462516; 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=cnt5OnVQ+l+gmS65l633q8WW3swGA/w0Xihg0kZvStU=; b=cQSmG2c8L72ceo42l/1oB05RVO1HqK0YTs5RJm/3bm42F4kos2AdW59JmQgjPR13GDVNCD 8Pmj0GR60tfk8yHKZ7gB0ISqyjB+wZfaatm5skW/aGj9/7dAGa4c73xSr+jmw5ptnU52iw FgOd2pc4cB+sP43WkaGJiEfSkzYjtb0= 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-3-X8cjJkbFMWGzg1d6QV3x9Q-1; Thu, 13 Feb 2025 11:01:54 -0500 X-MC-Unique: X8cjJkbFMWGzg1d6QV3x9Q-1 X-Mimecast-MFC-AGG-ID: X8cjJkbFMWGzg1d6QV3x9Q_1739462514 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-38dd8d11139so912476f8f.1 for ; Thu, 13 Feb 2025 08:01:54 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462513; x=1740067313; 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=cnt5OnVQ+l+gmS65l633q8WW3swGA/w0Xihg0kZvStU=; b=I95GBcvdmUT+u/DqRE9wvM3K6qrqLQoV4XzL3T+28ZM+Wqg6NMapO2Q6aI2p2b13xU zbpKvOnKqm5YxKDuF73qYZbISVEjB5ldMwtdzb+6dyExYS7OLa1s/i9d8MCA+dtZPnz+ Io7CJX7Icjc+UteJc3wMYOxRTW1hlT5Sr4v4JZ/TETZ2cFmHwPQpuXm3UVdgVNxt2AkS rHrjOy4OzoJjPXr+AEqezSSQm2FekkteSOpfb5wR3NWd/+XXLOAJMfItKHTZRguV9ovF 7RpEpz4HBX0axkNOf7xKZ4yyyu99bo0Pnt+IcnhQzcBqu79OI2+S3d0uFDW5y/5vlvpK /YFw== X-Gm-Message-State: AOJu0YxZuZ/cOI4wno/FFWANjkXggDlGbOrhI4Mf2krHuJyyfdgJxowB QDKqbCn92EmjbVf3Mr7m3oyaFfUkvD6Df+ngtz2YcvcFJSTZhQyq1hzGHHmVJ8XLu2ojMpfokjh zgcrIuUq0BC3EQbS2IDJ0uU3dEILCaxWwNIHPoM4K09khLgGA+XKY5W7/J2i5z2JF8TPKc6m9TW NZvDfyP2ome+kAsy5ylwFsl52TvEP+ZzyJnwCRjas= X-Gm-Gg: ASbGncujge+IeL4ziNERc9CiwBntsGXTFm5b7Lri8PXaAIlIzu1U79tK+hKBovVe7CJ OS4ZmhYkrkQDWdOjhTGoYFp6nYT2uSLvl+YCa9Tu33Xst6UfAN1koG11tGEO1Mm3ZI2g/nRpF84 Pzva19OYxaU8Oxy6NAme8Eppr18hDFoUiaB/tt/Tng1wI7KK/ABRFnx0qworLrkPlrbPwvyH1du j0ke0BvhAZuPZu0z6uDQf6h1SDDVSFPjMjTcbQZfmeO14asajMLCY3nWEihNl0XjgOqpkIkaOmb Q0BNjniLp5/pTD9PhDw8yxooKXNuR8lmFI+byJm/ffBW+A== X-Received: by 2002:a05:6000:18ab:b0:38f:276a:1662 with SMTP id ffacd0b85a97d-38f276a1705mr3405677f8f.13.1739462511457; Thu, 13 Feb 2025 08:01:51 -0800 (PST) X-Google-Smtp-Source: AGHT+IHVSQh0DLrXYu8O4DuxNCMUcLqamW/yKRgbf0WcvUWqkNdOO+vq/t+rZqjBW0+OfHavVyM9lg== X-Received: by 2002:a05:6000:18ab:b0:38f:276a:1662 with SMTP id ffacd0b85a97d-38f276a1705mr3405579f8f.13.1739462510554; Thu, 13 Feb 2025 08:01:50 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f25913f5asm2280440f8f.52.2025.02.13.08.01.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:49 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 19/27] rust: add bindings for timer Date: Thu, 13 Feb 2025 17:00:46 +0100 Message-ID: <20250213160054.3937012-20-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 From: Zhao Liu Add timer bindings to help handle idiomatic Rust callbacks. Additionally, wrap QEMUClockType in ClockType binding to avoid unsafe calls in device code. Signed-off-by: Zhao Liu Link: https://lore.kernel.org/r/20250210030051.2562726-7-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- docs/devel/rust.rst | 1 + meson.build | 7 +++ rust/wrapper.h | 1 + rust/qemu-api/meson.build | 1 + rust/qemu-api/src/lib.rs | 1 + rust/qemu-api/src/timer.rs | 98 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 109 insertions(+) create mode 100644 rust/qemu-api/src/timer.rs diff --git a/docs/devel/rust.rst b/docs/devel/rust.rst index a5399db50b5..90958e5a306 100644 --- a/docs/devel/rust.rst +++ b/docs/devel/rust.rst @@ -186,6 +186,7 @@ module status ``qdev`` stable ``qom`` stable ``sysbus`` stable +``timer`` stable ``vmstate`` proof of concept ``zeroable`` stable ================ ====================== diff --git a/meson.build b/meson.build index 16c76c493f3..8ed10b6624e 100644 --- a/meson.build +++ b/meson.build @@ -4087,6 +4087,13 @@ 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/wrapper.h b/rust/wrapper.h index 54839ce0f51..a35bfbd1760 100644 --- a/rust/wrapper.h +++ b/rust/wrapper.h @@ -63,3 +63,4 @@ typedef enum memory_order { #include "migration/vmstate.h" #include "chardev/char-serial.h" #include "exec/memattrs.h" +#include "qemu/timer.h" diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build index 45e30324b29..2e9c1078b9b 100644 --- a/rust/qemu-api/meson.build +++ b/rust/qemu-api/meson.build @@ -30,6 +30,7 @@ _qemu_api_rs = static_library( 'src/qdev.rs', 'src/qom.rs', 'src/sysbus.rs', + 'src/timer.rs', 'src/vmstate.rs', 'src/zeroable.rs', ], diff --git a/rust/qemu-api/src/lib.rs b/rust/qemu-api/src/lib.rs index 2a338a888a0..ed1a8f9a2b4 100644 --- a/rust/qemu-api/src/lib.rs +++ b/rust/qemu-api/src/lib.rs @@ -26,6 +26,7 @@ pub mod qdev; pub mod qom; pub mod sysbus; +pub mod timer; pub mod vmstate; pub mod zeroable; diff --git a/rust/qemu-api/src/timer.rs b/rust/qemu-api/src/timer.rs new file mode 100644 index 00000000000..a593538917a --- /dev/null +++ b/rust/qemu-api/src/timer.rs @@ -0,0 +1,98 @@ +// Copyright (C) 2024 Intel Corporation. +// Author(s): Zhao Liu +// SPDX-License-Identifier: GPL-2.0-or-later + +use std::os::raw::{c_int, c_void}; + +use crate::{ + bindings::{self, qemu_clock_get_ns, timer_del, timer_init_full, timer_mod, QEMUClockType}, + callbacks::FnCall, +}; + +pub type Timer = bindings::QEMUTimer; +pub type TimerListGroup = bindings::QEMUTimerListGroup; + +impl Timer { + pub const MS: u32 = bindings::SCALE_MS; + pub const US: u32 = bindings::SCALE_US; + pub const NS: u32 = bindings::SCALE_NS; + + 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>, + clk_type: ClockType, + scale: u32, + attributes: u32, + _cb: F, + opaque: &'opaque T, + ) where + F: for<'a> FnCall<(&'a T,)>, + { + let _: () = F::ASSERT_IS_SOME; + + /// timer expiration callback + unsafe extern "C" fn rust_timer_handler FnCall<(&'a T,)>>( + opaque: *mut c_void, + ) { + // SAFETY: the opaque was passed as a reference to `T`. + F::call((unsafe { &*(opaque.cast::()) },)) + } + + let timer_cb: unsafe extern "C" fn(*mut c_void) = rust_timer_handler::; + + // SAFETY: the opaque outlives the timer + unsafe { + timer_init_full( + self, + if let Some(g) = timer_list_group { + g as *const TimerListGroup as *mut _ + } else { + ::core::ptr::null_mut() + }, + clk_type.id, + scale as c_int, + attributes as c_int, + Some(timer_cb), + (opaque as *const T).cast::() as *mut c_void, + ) + } + } + + pub fn modify(&self, expire_time: u64) { + unsafe { timer_mod(self.as_mut_ptr(), expire_time as i64) } + } + + pub fn delete(&self) { + unsafe { timer_del(self.as_mut_ptr()) } + } +} + +impl Drop for Timer { + fn drop(&mut self) { + self.delete() + } +} + +pub struct ClockType { + id: QEMUClockType, +} + +impl ClockType { + pub fn get_ns(&self) -> u64 { + // SAFETY: cannot be created outside this module, therefore id + // is valid + (unsafe { qemu_clock_get_ns(self.id) }) as u64 + } +} + +pub const CLOCK_VIRTUAL: ClockType = ClockType { + id: QEMUClockType::QEMU_CLOCK_VIRTUAL, +}; From patchwork Thu Feb 13 16:00:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13973534 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 0D977C021A0 for ; Thu, 13 Feb 2025 16:04:04 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibfJ-00015M-Gy; Thu, 13 Feb 2025 11:02: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 1tibf7-000117-QR for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:04 -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 1tibf5-0005c8-EX for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:01 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462518; 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=B9eIPT4SqTnanKoz0+BJuTe5SIxIAvdPZ6BH+2W1Vt4=; b=Lj4rXuBs+/0xA2bV6J6bmZNnoQxzDRlMj5Cnhnn0ozxvXDwpK+kQtG+NFwhtL4sL5qu4ED R91AXRpfgfyJ8a+gHyf1ye+TLRAal9jy23qUdBfLtffIV/S2DZBulywpDstrfGOu8pf02h ZrENYfIF9ieRk35EyIUDP+3Ff4Wgwfo= 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-57-PqNQ5l7JPl-Usg-sK9FBAA-1; Thu, 13 Feb 2025 11:01:56 -0500 X-MC-Unique: PqNQ5l7JPl-Usg-sK9FBAA-1 X-Mimecast-MFC-AGG-ID: PqNQ5l7JPl-Usg-sK9FBAA_1739462515 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-43935bcec79so8421605e9.3 for ; Thu, 13 Feb 2025 08:01:56 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462514; x=1740067314; 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=B9eIPT4SqTnanKoz0+BJuTe5SIxIAvdPZ6BH+2W1Vt4=; b=V9DfWwP7mZ7WLeyX2itUT4KPEKH8LGNgtq7jEmqnnEYMcI9p4mHzlaymXNQWds3RLO OI8UGni9E3jnx8PoezO+0b4BWpTvpK3AEaYN+OC6ZWZlMDHOu41rIU1Grce0vrKE4C3q EEOgHsgSKowE0dHzbX/trlke+hsAquR4Emo2fL6WTiUO2YuEepMXjHRYylToKj1LhYJ/ 1Vpbk1vKnLHCFg48fyrsVQat2UYTin/4DgfyVGODUjA/JJKO60OuA5pSlsPxRzQ6QTWB KufhZrS8+STJvMVO59wdrA6O3pk4lhwda6b7P4stiFZfLW6tzmZ4Gtg1vwBxK9rb35mT bb0g== X-Gm-Message-State: AOJu0Yz3qkXGqAFX4GbqfvInm+5VM7a0JpcyzSKgeSYbe60WjC85ap+n ZIRE00XZXOni2MB5OO1Dl7Yi90pv4Xqz8GTGZFjhpxgychk/sbqRRhVmmad6RsnLg9KsoACZLxy SXql8rFHgeQ18wGXRc8v8XaA8tM4S3OITNPwUbMTfYtegwl2smFu5gxyqQLly9kwJgYEWiW20Vg AmSQNC8NEvTh1si6NxfVe63DIsyse9iPt/DLMddZE= X-Gm-Gg: ASbGncu4ZKWZiP+AESY1HzpURqov+RDKY2jc/AkyRFX5LYwaZE9wIDqoeYJZE9CPOBf SQOvPpA5XiZ1Kf56JsrAvAlqi7eLlApCiK5LwA+DYvRKSH8e5Z61nZEDKilVp7yXVyvy5fjNHIJ ijsNXlQPCmvPIhVF0GMN7gjA5vChC72a2PQrrAGhnW6Z35DexsOLuriE+rwe1Jdy04cpUzj3M/c EaS5M3HhDNkvPIazQNQDrBNOLNdFNQjgJmV6JFgnJWEH/PYyG+hrgk0SLoJPWDp5LzV+UIGO3dj HaM2t4ajQe1J+Sc3PlgtANjwL+2Fp5Elu2I8CFNRSI2Kww== X-Received: by 2002:a05:6000:1a8b:b0:38d:d8b2:cf14 with SMTP id ffacd0b85a97d-38dea28cffemr7631072f8f.30.1739462513856; Thu, 13 Feb 2025 08:01:53 -0800 (PST) X-Google-Smtp-Source: AGHT+IHu7ftjSrsulhgq/qsGntZ/7C+sn6rupvgD/hZR4vjcYcRQY9CJb7o0IN+g4uvK43nd+dC5sA== X-Received: by 2002:a05:6000:1a8b:b0:38d:d8b2:cf14 with SMTP id ffacd0b85a97d-38dea28cffemr7630980f8f.30.1739462513012; Thu, 13 Feb 2025 08:01:53 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4395a055859sm52907205e9.10.2025.02.13.08.01.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:52 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 20/27] rust/timer/hpet: define hpet_fw_cfg Date: Thu, 13 Feb 2025 17:00:47 +0100 Message-ID: <20250213160054.3937012-21-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 From: Zhao Liu Define HPETFwEntry structure with the same memory layout as hpet_fw_entry in C. Further, define the global hpet_cfg variable in Rust which is the same as the C version. This hpet_cfg variable in Rust will replace the C version one and allows both Rust code and C code to access it. The Rust version of hpet_cfg is self-contained, avoiding unsafe access to C code. Signed-off-by: Zhao Liu Link: https://lore.kernel.org/r/20250210030051.2562726-8-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/Cargo.lock | 8 ++++ rust/Cargo.toml | 1 + rust/hw/meson.build | 1 + rust/hw/timer/hpet/Cargo.toml | 18 ++++++++ rust/hw/timer/hpet/meson.build | 18 ++++++++ rust/hw/timer/hpet/src/fw_cfg.rs | 71 ++++++++++++++++++++++++++++++++ rust/hw/timer/hpet/src/lib.rs | 10 +++++ rust/hw/timer/meson.build | 1 + rust/qemu-api/src/zeroable.rs | 6 ++- 9 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 rust/hw/timer/hpet/Cargo.toml create mode 100644 rust/hw/timer/hpet/meson.build create mode 100644 rust/hw/timer/hpet/src/fw_cfg.rs create mode 100644 rust/hw/timer/hpet/src/lib.rs create mode 100644 rust/hw/timer/meson.build diff --git a/rust/Cargo.lock b/rust/Cargo.lock index c0c6069247a..79e142723b8 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -37,6 +37,14 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +[[package]] +name = "hpet" +version = "0.1.0" +dependencies = [ + "qemu_api", + "qemu_api_macros", +] + [[package]] name = "itertools" version = "0.11.0" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 5b0cb559286..5041d6291fd 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -4,6 +4,7 @@ members = [ "qemu-api-macros", "qemu-api", "hw/char/pl011", + "hw/timer/hpet", ] [workspace.lints.rust] diff --git a/rust/hw/meson.build b/rust/hw/meson.build index 860196645e7..9749d4adfc9 100644 --- a/rust/hw/meson.build +++ b/rust/hw/meson.build @@ -1 +1,2 @@ subdir('char') +subdir('timer') diff --git a/rust/hw/timer/hpet/Cargo.toml b/rust/hw/timer/hpet/Cargo.toml new file mode 100644 index 00000000000..147f216e725 --- /dev/null +++ b/rust/hw/timer/hpet/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "hpet" +version = "0.1.0" +edition = "2021" +authors = ["Zhao Liu "] +license = "GPL-2.0-or-later" +description = "IA-PC High Precision Event Timer emulation in Rust" +rust-version = "1.63.0" + +[lib] +crate-type = ["staticlib"] + +[dependencies] +qemu_api = { path = "../../../qemu-api" } +qemu_api_macros = { path = "../../../qemu-api-macros" } + +[lints] +workspace = true diff --git a/rust/hw/timer/hpet/meson.build b/rust/hw/timer/hpet/meson.build new file mode 100644 index 00000000000..c2d7c0532ca --- /dev/null +++ b/rust/hw/timer/hpet/meson.build @@ -0,0 +1,18 @@ +_libhpet_rs = static_library( + 'hpet', + files('src/lib.rs'), + override_options: ['rust_std=2021', 'build.rust_std=2021'], + rust_abi: 'rust', + dependencies: [ + qemu_api, + qemu_api_macros, + ], +) + +rust_devices_ss.add(when: 'CONFIG_X_HPET_RUST', if_true: [declare_dependency( + link_whole: [_libhpet_rs], + # Putting proc macro crates in `dependencies` is necessary for Meson to find + # them when compiling the root per-target static rust lib. + dependencies: [qemu_api_macros], + variables: {'crate': 'hpet'}, +)]) diff --git a/rust/hw/timer/hpet/src/fw_cfg.rs b/rust/hw/timer/hpet/src/fw_cfg.rs new file mode 100644 index 00000000000..849e277d483 --- /dev/null +++ b/rust/hw/timer/hpet/src/fw_cfg.rs @@ -0,0 +1,71 @@ +// Copyright (C) 2024 Intel Corporation. +// Author(s): Zhao Liu +// SPDX-License-Identifier: GPL-2.0-or-later + +#![allow(dead_code)] + +use std::ptr::addr_of_mut; + +use qemu_api::{cell::bql_locked, impl_zeroable, zeroable::Zeroable}; + +/// Each `HPETState` represents a Event Timer Block. The v1 spec supports +/// up to 8 blocks. QEMU only uses 1 block (in PC machine). +const HPET_MAX_NUM_EVENT_TIMER_BLOCK: usize = 8; + +#[repr(C, packed)] +#[derive(Copy, Clone, Default)] +pub struct HPETFwEntry { + pub event_timer_block_id: u32, + pub address: u64, + pub min_tick: u16, + pub page_prot: u8, +} +impl_zeroable!(HPETFwEntry); + +#[repr(C, packed)] +#[derive(Copy, Clone, Default)] +pub struct HPETFwConfig { + pub count: u8, + pub hpet: [HPETFwEntry; HPET_MAX_NUM_EVENT_TIMER_BLOCK], +} +impl_zeroable!(HPETFwConfig); + +#[allow(non_upper_case_globals)] +#[no_mangle] +pub static mut hpet_fw_cfg: HPETFwConfig = HPETFwConfig { + count: u8::MAX, + ..Zeroable::ZERO +}; + +impl HPETFwConfig { + pub(crate) fn assign_hpet_id() -> usize { + assert!(bql_locked()); + // SAFETY: all accesses go through these methods, which guarantee + // that the accesses are protected by the BQL. + let mut fw_cfg = unsafe { *addr_of_mut!(hpet_fw_cfg) }; + + if fw_cfg.count == u8::MAX { + // first instance + fw_cfg.count = 0; + } + + if fw_cfg.count == 8 { + // TODO: Add error binding: error_setg() + panic!("Only 8 instances of HPET is allowed"); + } + + let id: usize = fw_cfg.count.into(); + fw_cfg.count += 1; + id + } + + pub(crate) fn update_hpet_cfg(hpet_id: usize, timer_block_id: u32, address: u64) { + assert!(bql_locked()); + // SAFETY: all accesses go through these methods, which guarantee + // that the accesses are protected by the BQL. + let mut fw_cfg = unsafe { *addr_of_mut!(hpet_fw_cfg) }; + + fw_cfg.hpet[hpet_id].event_timer_block_id = timer_block_id; + fw_cfg.hpet[hpet_id].address = address; + } +} diff --git a/rust/hw/timer/hpet/src/lib.rs b/rust/hw/timer/hpet/src/lib.rs new file mode 100644 index 00000000000..44e9f3fb8ab --- /dev/null +++ b/rust/hw/timer/hpet/src/lib.rs @@ -0,0 +1,10 @@ +// Copyright (C) 2024 Intel Corporation. +// Author(s): Zhao Liu +// SPDX-License-Identifier: GPL-2.0-or-later + +//! # HPET QEMU Device Model +//! +//! This library implements a device model for the IA-PC HPET (High +//! Precision Event Timers) device in QEMU. + +pub mod fw_cfg; diff --git a/rust/hw/timer/meson.build b/rust/hw/timer/meson.build new file mode 100644 index 00000000000..22a84f15536 --- /dev/null +++ b/rust/hw/timer/meson.build @@ -0,0 +1 @@ +subdir('hpet') diff --git a/rust/qemu-api/src/zeroable.rs b/rust/qemu-api/src/zeroable.rs index 9f009606b1a..cd424e6ea05 100644 --- a/rust/qemu-api/src/zeroable.rs +++ b/rust/qemu-api/src/zeroable.rs @@ -56,6 +56,7 @@ pub unsafe trait Zeroable: Default { /// ## Differences with `core::mem::zeroed` /// /// `const_zero` zeroes padding bits, while `core::mem::zeroed` doesn't +#[macro_export] macro_rules! const_zero { // This macro to produce a type-generic zero constant is taken from the // const_zero crate (v0.1.1): @@ -77,10 +78,11 @@ union TypeAsBytes { } /// A wrapper to implement the `Zeroable` trait through the `const_zero` macro. +#[macro_export] macro_rules! impl_zeroable { ($type:ty) => { - unsafe impl Zeroable for $type { - const ZERO: Self = unsafe { const_zero!($type) }; + unsafe impl $crate::zeroable::Zeroable for $type { + const ZERO: Self = unsafe { $crate::const_zero!($type) }; } }; } From patchwork Thu Feb 13 16:00:48 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13973548 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 5CA92C021A6 for ; Thu, 13 Feb 2025 16:07:54 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibfP-00018i-GH; Thu, 13 Feb 2025 11:02:19 -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 1tibfF-000141-Gg for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:12 -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 1tibfB-0005dW-Ai for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:08 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462523; 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=wmFwjn7DirEUg9I0UDe0I1UL7FmQO7ZwjSM+vupQK5I=; b=dW+yrK2xClUFXl+84AyqvgwNF2qHDgmrhr5OQA9bPG+ppUcJlhIL00K0ijwe0UurulF1cl Flm9J/WfCzwlhVNvrzdtf3oBVgjqLvKNpwRg3kv7Kgmdb4MOruqRnqoKt/du/V8kLgt1UW AOX9wC02lAv7I3xgZ20bhIc6824UKXM= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-653-FxFGmBtMPOi7IluTsWwwAA-1; Thu, 13 Feb 2025 11:02:00 -0500 X-MC-Unique: FxFGmBtMPOi7IluTsWwwAA-1 X-Mimecast-MFC-AGG-ID: FxFGmBtMPOi7IluTsWwwAA Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-43933b8d9b1so5800975e9.3 for ; Thu, 13 Feb 2025 08:02:00 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462519; x=1740067319; 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=wmFwjn7DirEUg9I0UDe0I1UL7FmQO7ZwjSM+vupQK5I=; b=eq7c6rQH1q3qCdXgD1Ifbw0bnbY8dGFWwcW5B1bxVcDxQnfUmDB6AYMC4+isaw8Sng n/EQnlCo3bhHo9c5+k7AUNvyzRcXlSPdArQHlNPN3tY2M559C/vNkJGJGlE2xfuT02ri 6wVTy6unzUkCg5ZRHJgUkl91h08F82DhHq4dz6Hre7k34mgeqkbU5azaqAVd+EYRV5d/ 1c+VHWxg1brPDiRUVvQDUM1lURvlKVySmglPYWagS6gDoQ3yk0T1+cE0AnHv/Hb5a+cp HvGBYtjJ0/DEhxLMoy6oeJ+Gyy9l7yxh2K4QNUSntS0qdF+ePNz0e8tGEnpgPIqXp9zN YlZw== X-Gm-Message-State: AOJu0YwNALyFWXdZexCaH4Fl/kqqqOhFhqbvqms0cCtNmS9Ze17L7cAR cJ6tpA/Scv7UhYlJrZeGiOcQO83ccDWOak6kztUZ4C//iFSLv0aKNRJM6WSyshDBgHRTae7wC63 v9ass381UQuUM2MIvN669bFoDUkJTo7IYw8SVyz7PX0bjN7dWHk1+2opxnzMyZnAZjAIedaOADc IoTJz8vS5DvpiwHaUPmw3n5sdR5vlCb0Ro3miZvy0= X-Gm-Gg: ASbGncs0OG5NnF965NYY9C6s8wHykTY8qw9BFxhZlG1Lfs7mRJAGB+4Q2f9zVJ5EpwT 9xNMO9Rx2u3yVntlQZnEC6ghzKyhkiCXJmawVG3rRs5bjn6Nd4BR77HL2t/hJQ9zV0b4t6un1wX cbOmP+m8sDEBBAwsArlKKXJL1v6iyhys2OujUK1sA2WjcEn50q0Hh4pzkKpvbJ8HlLc7wgoi8tV BQGNEYDXpowge0llGXhnrlZ0LXpeCzXDIYKnuJS4t/DuRfm9+Jk+60Tcem72DOm+JHpYEo8FZIQ S0v0gwchtRIORCOqaZET2bGvW/Fv3bjugSEDIL6JCMWjgg== X-Received: by 2002:a05:600c:1d92:b0:439:5a37:815f with SMTP id 5b1f17b1804b1-439601b92e9mr55558475e9.30.1739462518343; Thu, 13 Feb 2025 08:01:58 -0800 (PST) X-Google-Smtp-Source: AGHT+IHEjQwvPfitfdSbmdTYVmH+Tl581LLKnhVsjw8LNp9rd0RISbqRIv1Ums3Fl8t+yp91Y9qTTw== X-Received: by 2002:a05:600c:1d92:b0:439:5a37:815f with SMTP id 5b1f17b1804b1-439601b92e9mr55556405e9.30.1739462516846; Thu, 13 Feb 2025 08:01:56 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f258b4123sm2320983f8f.17.2025.02.13.08.01.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:54 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 21/27] rust/timer/hpet: add basic HPET timer and HPETState Date: Thu, 13 Feb 2025 17:00:48 +0100 Message-ID: <20250213160054.3937012-22-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 From: Zhao Liu Add the HPETTimer and HPETState (HPET timer block), along with their basic methods and register definitions. This is in preparation for supporting the QAPI interfaces. Note, wrap all items in HPETState that may be changed in the callback called by C code into the BqlCell/BqlRefCell. Signed-off-by: Zhao Liu Link: https://lore.kernel.org/r/20250210030051.2562726-9-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/wrapper.h | 1 + rust/hw/timer/hpet/src/hpet.rs | 629 +++++++++++++++++++++++++++++++++ rust/hw/timer/hpet/src/lib.rs | 1 + 3 files changed, 631 insertions(+) create mode 100644 rust/hw/timer/hpet/src/hpet.rs diff --git a/rust/wrapper.h b/rust/wrapper.h index a35bfbd1760..d927ad6799d 100644 --- a/rust/wrapper.h +++ b/rust/wrapper.h @@ -64,3 +64,4 @@ typedef enum memory_order { #include "chardev/char-serial.h" #include "exec/memattrs.h" #include "qemu/timer.h" +#include "exec/address-spaces.h" diff --git a/rust/hw/timer/hpet/src/hpet.rs b/rust/hw/timer/hpet/src/hpet.rs new file mode 100644 index 00000000000..795610f8e88 --- /dev/null +++ b/rust/hw/timer/hpet/src/hpet.rs @@ -0,0 +1,629 @@ +// Copyright (C) 2024 Intel Corporation. +// Author(s): Zhao Liu +// SPDX-License-Identifier: GPL-2.0-or-later + +#![allow(dead_code)] + +use std::ptr::{addr_of_mut, null_mut, NonNull}; + +use qemu_api::{ + bindings::{address_space_memory, address_space_stl_le}, + cell::{BqlCell, BqlRefCell}, + irq::InterruptSource, + memory::{MemoryRegion, MEMTXATTRS_UNSPECIFIED}, + prelude::*, + qom::ParentField, + sysbus::SysBusDevice, + timer::{Timer, CLOCK_VIRTUAL}, +}; + +/// Register space for each timer block (`HPET_BASE` is defined in hpet.h). +const HPET_REG_SPACE_LEN: u64 = 0x400; // 1024 bytes + +/// Minimum recommended hardware implementation. +const HPET_MIN_TIMERS: usize = 3; +/// Maximum timers in each timer block. +const HPET_MAX_TIMERS: usize = 32; + +/// Flags that HPETState.flags supports. +const HPET_FLAG_MSI_SUPPORT_SHIFT: usize = 0; + +const HPET_NUM_IRQ_ROUTES: usize = 32; +const HPET_LEGACY_PIT_INT: u32 = 0; // HPET_LEGACY_RTC_INT isn't defined here. +const RTC_ISA_IRQ: usize = 8; + +const HPET_CLK_PERIOD: u64 = 10; // 10 ns +const FS_PER_NS: u64 = 1000000; // 1000000 femtoseconds == 1 ns + +/// General Capabilities and ID Register +const HPET_CAP_REG: u64 = 0x000; +/// Revision ID (bits 0:7). Revision 1 is implemented (refer to v1.0a spec). +const HPET_CAP_REV_ID_VALUE: u64 = 0x1; +const HPET_CAP_REV_ID_SHIFT: usize = 0; +/// Number of Timers (bits 8:12) +const HPET_CAP_NUM_TIM_SHIFT: usize = 8; +/// Counter Size (bit 13) +const HPET_CAP_COUNT_SIZE_CAP_SHIFT: usize = 13; +/// Legacy Replacement Route Capable (bit 15) +const HPET_CAP_LEG_RT_CAP_SHIFT: usize = 15; +/// Vendor ID (bits 16:31) +const HPET_CAP_VENDER_ID_VALUE: u64 = 0x8086; +const HPET_CAP_VENDER_ID_SHIFT: usize = 16; +/// Main Counter Tick Period (bits 32:63) +const HPET_CAP_CNT_CLK_PERIOD_SHIFT: usize = 32; + +/// General Configuration Register +const HPET_CFG_REG: u64 = 0x010; +/// Overall Enable (bit 0) +const HPET_CFG_ENABLE_SHIFT: usize = 0; +/// Legacy Replacement Route (bit 1) +const HPET_CFG_LEG_RT_SHIFT: usize = 1; +/// Other bits are reserved. +const HPET_CFG_WRITE_MASK: u64 = 0x003; + +/// General Interrupt Status Register +const HPET_INT_STATUS_REG: u64 = 0x020; + +/// Main Counter Value Register +const HPET_COUNTER_REG: u64 = 0x0f0; + +/// Timer N Configuration and Capability Register (masked by 0x18) +const HPET_TN_CFG_REG: u64 = 0x000; +/// bit 0, 7, and bits 16:31 are reserved. +/// bit 4, 5, 15, and bits 32:64 are read-only. +const HPET_TN_CFG_WRITE_MASK: u64 = 0x7f4e; +/// Timer N Interrupt Type (bit 1) +const HPET_TN_CFG_INT_TYPE_SHIFT: usize = 1; +/// Timer N Interrupt Enable (bit 2) +const HPET_TN_CFG_INT_ENABLE_SHIFT: usize = 2; +/// Timer N Type (Periodic enabled or not, bit 3) +const HPET_TN_CFG_PERIODIC_SHIFT: usize = 3; +/// Timer N Periodic Interrupt Capable (support Periodic or not, bit 4) +const HPET_TN_CFG_PERIODIC_CAP_SHIFT: usize = 4; +/// Timer N Size (timer size is 64-bits or 32 bits, bit 5) +const HPET_TN_CFG_SIZE_CAP_SHIFT: usize = 5; +/// Timer N Value Set (bit 6) +const HPET_TN_CFG_SETVAL_SHIFT: usize = 6; +/// Timer N 32-bit Mode (bit 8) +const HPET_TN_CFG_32BIT_SHIFT: usize = 8; +/// Timer N Interrupt Rout (bits 9:13) +const HPET_TN_CFG_INT_ROUTE_MASK: u64 = 0x3e00; +const HPET_TN_CFG_INT_ROUTE_SHIFT: usize = 9; +/// Timer N FSB Interrupt Enable (bit 14) +const HPET_TN_CFG_FSB_ENABLE_SHIFT: usize = 14; +/// Timer N FSB Interrupt Delivery (bit 15) +const HPET_TN_CFG_FSB_CAP_SHIFT: usize = 15; +/// Timer N Interrupt Routing Capability (bits 32:63) +const HPET_TN_CFG_INT_ROUTE_CAP_SHIFT: usize = 32; + +/// Timer N Comparator Value Register (masked by 0x18) +const HPET_TN_CMP_REG: u64 = 0x008; + +/// Timer N FSB Interrupt Route Register (masked by 0x18) +const HPET_TN_FSB_ROUTE_REG: u64 = 0x010; + +const fn hpet_next_wrap(cur_tick: u64) -> u64 { + (cur_tick | 0xffffffff) + 1 +} + +const fn hpet_time_after(a: u64, b: u64) -> bool { + ((b - a) as i64) < 0 +} + +const fn ticks_to_ns(value: u64) -> u64 { + value * HPET_CLK_PERIOD +} + +const fn ns_to_ticks(value: u64) -> u64 { + value / HPET_CLK_PERIOD +} + +// Avoid touching the bits that cannot be written. +const fn hpet_fixup_reg(new: u64, old: u64, mask: u64) -> u64 { + (new & mask) | (old & !mask) +} + +const fn activating_bit(old: u64, new: u64, shift: usize) -> bool { + let mask: u64 = 1 << shift; + (old & mask == 0) && (new & mask != 0) +} + +const fn deactivating_bit(old: u64, new: u64, shift: usize) -> bool { + let mask: u64 = 1 << shift; + (old & mask != 0) && (new & mask == 0) +} + +fn timer_handler(timer_cell: &BqlRefCell) { + timer_cell.borrow_mut().callback() +} + +/// HPET Timer Abstraction +#[repr(C)] +#[derive(Debug, Default)] +#[cfg_attr(has_offset_of, derive(qemu_api_macros::offsets))] +pub struct HPETTimer { + /// timer N index within the timer block (`HPETState`) + #[doc(alias = "tn")] + index: usize, + qemu_timer: Option>, + /// timer block abstraction containing this timer + state: Option>, + + // Memory-mapped, software visible timer registers + /// Timer N Configuration and Capability Register + config: u64, + /// Timer N Comparator Value Register + cmp: u64, + /// Timer N FSB Interrupt Route Register + fsb: u64, + + // Hidden register state + /// comparator (extended to counter width) + cmp64: u64, + /// Last value written to comparator + period: u64, + /// timer pop will indicate wrap for one-shot 32-bit + /// mode. Next pop will be actual timer expiration. + wrap_flag: u8, + /// last value armed, to avoid timer storms + last: u64, +} + +impl HPETTimer { + fn init(&mut self, index: usize, state_ptr: *mut HPETState) -> &mut Self { + *self = HPETTimer::default(); + self.index = index; + self.state = NonNull::new(state_ptr); + self + } + + fn init_timer_with_state(&mut self) { + self.qemu_timer = Some(Box::new({ + let mut t = Timer::new(); + t.init_full( + None, + CLOCK_VIRTUAL, + Timer::NS, + 0, + timer_handler, + &self.get_state().timers[self.index], + ); + t + })); + } + + fn get_state(&self) -> &HPETState { + // SAFETY: + // the pointer is convertible to a reference + unsafe { self.state.unwrap().as_ref() } + } + + fn is_int_active(&self) -> bool { + self.get_state().is_timer_int_active(self.index) + } + + const fn is_fsb_route_enabled(&self) -> bool { + self.config & (1 << HPET_TN_CFG_FSB_ENABLE_SHIFT) != 0 + } + + const fn is_periodic(&self) -> bool { + self.config & (1 << HPET_TN_CFG_PERIODIC_SHIFT) != 0 + } + + const fn is_int_enabled(&self) -> bool { + self.config & (1 << HPET_TN_CFG_INT_ENABLE_SHIFT) != 0 + } + + const fn is_32bit_mod(&self) -> bool { + self.config & (1 << HPET_TN_CFG_32BIT_SHIFT) != 0 + } + + const fn is_valset_enabled(&self) -> bool { + self.config & (1 << HPET_TN_CFG_SETVAL_SHIFT) != 0 + } + + fn clear_valset(&mut self) { + self.config &= !(1 << HPET_TN_CFG_SETVAL_SHIFT); + } + + /// True if timer interrupt is level triggered; otherwise, edge triggered. + const fn is_int_level_triggered(&self) -> bool { + self.config & (1 << HPET_TN_CFG_INT_TYPE_SHIFT) != 0 + } + + /// calculate next value of the general counter that matches the + /// target (either entirely, or the low 32-bit only depending on + /// the timer mode). + fn calculate_cmp64(&self, cur_tick: u64, target: u64) -> u64 { + if self.is_32bit_mod() { + let mut result: u64 = cur_tick.deposit(0, 32, target); + if result < cur_tick { + result += 0x100000000; + } + result + } else { + target + } + } + + const fn get_individual_route(&self) -> usize { + ((self.config & HPET_TN_CFG_INT_ROUTE_MASK) >> HPET_TN_CFG_INT_ROUTE_SHIFT) as usize + } + + fn get_int_route(&self) -> usize { + if self.index <= 1 && self.get_state().is_legacy_mode() { + // If LegacyReplacement Route bit is set, HPET specification requires + // timer0 be routed to IRQ0 in NON-APIC or IRQ2 in the I/O APIC, + // timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC. + // + // If the LegacyReplacement Route bit is set, the individual routing + // bits for timers 0 and 1 (APIC or FSB) will have no impact. + // + // FIXME: Consider I/O APIC case. + if self.index == 0 { + 0 + } else { + RTC_ISA_IRQ + } + } else { + // (If the LegacyReplacement Route bit is set) Timer 2-n will be + // routed as per the routing in the timer n config registers. + // ... + // If the LegacyReplacement Route bit is not set, the individual + // routing bits for each of the timers are used. + self.get_individual_route() + } + } + + fn set_irq(&mut self, set: bool) { + let route = self.get_int_route(); + + if set && self.is_int_enabled() && self.get_state().is_hpet_enabled() { + if self.is_fsb_route_enabled() { + // SAFETY: + // the parameters are valid. + unsafe { + address_space_stl_le( + addr_of_mut!(address_space_memory), + self.fsb >> 32, // Timer N FSB int addr + self.fsb as u32, // Timer N FSB int value, truncate! + MEMTXATTRS_UNSPECIFIED, + null_mut(), + ); + } + } else if self.is_int_level_triggered() { + self.get_state().irqs[route].raise(); + } else { + self.get_state().irqs[route].pulse(); + } + } else if !self.is_fsb_route_enabled() { + self.get_state().irqs[route].lower(); + } + } + + fn update_irq(&mut self, set: bool) { + // If Timer N Interrupt Enable bit is 0, "the timer will + // still operate and generate appropriate status bits, but + // will not cause an interrupt" + self.get_state() + .update_int_status(self.index as u32, set && self.is_int_level_triggered()); + self.set_irq(set); + } + + fn arm_timer(&mut self, tick: u64) { + let mut ns = self.get_state().get_ns(tick); + + // Clamp period to reasonable min value (1 us) + if self.is_periodic() && ns - self.last < 1000 { + ns = self.last + 1000; + } + + self.last = ns; + self.qemu_timer.as_ref().unwrap().modify(self.last); + } + + fn set_timer(&mut self) { + let cur_tick: u64 = self.get_state().get_ticks(); + + self.wrap_flag = 0; + self.cmp64 = self.calculate_cmp64(cur_tick, self.cmp); + if self.is_32bit_mod() { + // HPET spec says in one-shot 32-bit mode, generate an interrupt when + // counter wraps in addition to an interrupt with comparator match. + if !self.is_periodic() && self.cmp64 > hpet_next_wrap(cur_tick) { + self.wrap_flag = 1; + self.arm_timer(hpet_next_wrap(cur_tick)); + return; + } + } + self.arm_timer(self.cmp64); + } + + fn del_timer(&mut self) { + // Just remove the timer from the timer_list without destroying + // this timer instance. + self.qemu_timer.as_ref().unwrap().delete(); + + if self.is_int_active() { + // For level-triggered interrupt, this leaves interrupt status + // register set but lowers irq. + self.update_irq(true); + } + } + + /// Configuration and Capability Register + fn set_tn_cfg_reg(&mut self, shift: u32, len: u32, val: u64) { + // TODO: Add trace point - trace_hpet_ram_write_tn_cfg(addr & 4) + let old_val: u64 = self.config; + let mut new_val: u64 = old_val.deposit(shift, len, val); + new_val = hpet_fixup_reg(new_val, old_val, HPET_TN_CFG_WRITE_MASK); + + // Switch level-type interrupt to edge-type. + if deactivating_bit(old_val, new_val, HPET_TN_CFG_INT_TYPE_SHIFT) { + // Do this before changing timer.config; otherwise, if + // HPET_TN_FSB is set, update_irq will not lower the qemu_irq. + self.update_irq(false); + } + + self.config = new_val; + + if activating_bit(old_val, new_val, HPET_TN_CFG_INT_ENABLE_SHIFT) && self.is_int_active() { + self.update_irq(true); + } + + if self.is_32bit_mod() { + self.cmp = u64::from(self.cmp as u32); // truncate! + self.period = u64::from(self.period as u32); // truncate! + } + + if self.get_state().is_hpet_enabled() { + self.set_timer(); + } + } + + /// Comparator Value Register + fn set_tn_cmp_reg(&mut self, shift: u32, len: u32, val: u64) { + let mut length = len; + let mut value = val; + + // TODO: Add trace point - trace_hpet_ram_write_tn_cmp(addr & 4) + if self.is_32bit_mod() { + // High 32-bits are zero, leave them untouched. + if shift != 0 { + // TODO: Add trace point - trace_hpet_ram_write_invalid_tn_cmp() + return; + } + length = 64; + value = u64::from(value as u32); // truncate! + } + + if !self.is_periodic() || self.is_valset_enabled() { + self.cmp = self.cmp.deposit(shift, length, value); + } + + if self.is_periodic() { + self.period = self.period.deposit(shift, length, value); + } + + self.clear_valset(); + if self.get_state().is_hpet_enabled() { + self.set_timer(); + } + } + + /// FSB Interrupt Route Register + fn set_tn_fsb_route_reg(&mut self, shift: u32, len: u32, val: u64) { + self.fsb = self.fsb.deposit(shift, len, val); + } + + fn reset(&mut self) { + self.del_timer(); + self.cmp = u64::MAX; // Comparator Match Registers reset to all 1's. + self.config = (1 << HPET_TN_CFG_PERIODIC_CAP_SHIFT) | (1 << HPET_TN_CFG_SIZE_CAP_SHIFT); + if self.get_state().has_msi_flag() { + self.config |= 1 << HPET_TN_CFG_FSB_CAP_SHIFT; + } + // advertise availability of ioapic int + self.config |= + (u64::from(self.get_state().int_route_cap)) << HPET_TN_CFG_INT_ROUTE_CAP_SHIFT; + self.period = 0; + self.wrap_flag = 0; + } + + /// timer expiration callback + fn callback(&mut self) { + let period: u64 = self.period; + let cur_tick: u64 = self.get_state().get_ticks(); + + if self.is_periodic() && period != 0 { + while hpet_time_after(cur_tick, self.cmp64) { + self.cmp64 += period; + } + if self.is_32bit_mod() { + self.cmp = u64::from(self.cmp64 as u32); // truncate! + } else { + self.cmp = self.cmp64; + } + self.arm_timer(self.cmp64); + } else if self.wrap_flag != 0 { + self.wrap_flag = 0; + self.arm_timer(self.cmp64); + } + self.update_irq(true); + } +} + +/// HPET Event Timer Block Abstraction +#[repr(C)] +#[derive(qemu_api_macros::offsets)] +pub struct HPETState { + parent_obj: ParentField, + iomem: MemoryRegion, + + // HPET block Registers: Memory-mapped, software visible registers + /// General Capabilities and ID Register + capability: BqlCell, + /// General Configuration Register + config: BqlCell, + /// General Interrupt Status Register + #[doc(alias = "isr")] + int_status: BqlCell, + /// Main Counter Value Register + #[doc(alias = "hpet_counter")] + counter: BqlCell, + + // Internal state + /// Capabilities that QEMU HPET supports. + /// bit 0: MSI (or FSB) support. + flags: u32, + + /// Offset of main counter relative to qemu clock. + hpet_offset: BqlCell, + hpet_offset_saved: bool, + + irqs: [InterruptSource; HPET_NUM_IRQ_ROUTES], + rtc_irq_level: BqlCell, + pit_enabled: InterruptSource, + + /// Interrupt Routing Capability. + /// This field indicates to which interrupts in the I/O (x) APIC + /// the timers' interrupt can be routed, and is encoded in the + /// bits 32:64 of timer N's config register: + #[doc(alias = "intcap")] + int_route_cap: u32, + + /// HPET timer array managed by this timer block. + #[doc(alias = "timer")] + timers: [BqlRefCell; HPET_MAX_TIMERS], + num_timers: BqlCell, + + /// Instance id (HPET timer block ID). + hpet_id: BqlCell, +} + +impl HPETState { + const fn has_msi_flag(&self) -> bool { + self.flags & (1 << HPET_FLAG_MSI_SUPPORT_SHIFT) != 0 + } + + fn is_legacy_mode(&self) -> bool { + self.config.get() & (1 << HPET_CFG_LEG_RT_SHIFT) != 0 + } + + fn is_hpet_enabled(&self) -> bool { + self.config.get() & (1 << HPET_CFG_ENABLE_SHIFT) != 0 + } + + fn is_timer_int_active(&self, index: usize) -> bool { + self.int_status.get() & (1 << index) != 0 + } + + fn get_ticks(&self) -> u64 { + ns_to_ticks(CLOCK_VIRTUAL.get_ns() + self.hpet_offset.get()) + } + + fn get_ns(&self, tick: u64) -> u64 { + ticks_to_ns(tick) - self.hpet_offset.get() + } + + fn handle_legacy_irq(&self, irq: u32, level: u32) { + if irq == HPET_LEGACY_PIT_INT { + if !self.is_legacy_mode() { + self.irqs[0].set(level != 0); + } + } else { + self.rtc_irq_level.set(level); + if !self.is_legacy_mode() { + self.irqs[RTC_ISA_IRQ].set(level != 0); + } + } + } + + fn init_timer(&self) { + let raw_ptr: *mut HPETState = self as *const HPETState as *mut HPETState; + + for (index, timer) in self.timers.iter().enumerate() { + timer + .borrow_mut() + .init(index, raw_ptr) + .init_timer_with_state(); + } + } + + fn update_int_status(&self, index: u32, level: bool) { + self.int_status + .set(self.int_status.get().deposit(index, 1, u64::from(level))); + } + + /// General Configuration Register + fn set_cfg_reg(&self, shift: u32, len: u32, val: u64) { + let old_val = self.config.get(); + let mut new_val = old_val.deposit(shift, len, val); + + new_val = hpet_fixup_reg(new_val, old_val, HPET_CFG_WRITE_MASK); + self.config.set(new_val); + + if activating_bit(old_val, new_val, HPET_CFG_ENABLE_SHIFT) { + // Enable main counter and interrupt generation. + self.hpet_offset + .set(ticks_to_ns(self.counter.get()) - CLOCK_VIRTUAL.get_ns()); + + for timer in self.timers.iter().take(self.num_timers.get()) { + let mut t = timer.borrow_mut(); + + if t.is_int_enabled() && t.is_int_active() { + t.update_irq(true); + } + t.set_timer(); + } + } else if deactivating_bit(old_val, new_val, HPET_CFG_ENABLE_SHIFT) { + // Halt main counter and disable interrupt generation. + self.counter.set(self.get_ticks()); + + for timer in self.timers.iter().take(self.num_timers.get()) { + timer.borrow_mut().del_timer(); + } + } + + // i8254 and RTC output pins are disabled when HPET is in legacy mode + if activating_bit(old_val, new_val, HPET_CFG_LEG_RT_SHIFT) { + self.pit_enabled.set(false); + self.irqs[0].lower(); + self.irqs[RTC_ISA_IRQ].lower(); + } else if deactivating_bit(old_val, new_val, HPET_CFG_LEG_RT_SHIFT) { + // TODO: Add irq binding: qemu_irq_lower(s->irqs[0]) + self.irqs[0].lower(); + self.pit_enabled.set(true); + self.irqs[RTC_ISA_IRQ].set(self.rtc_irq_level.get() != 0); + } + } + + /// General Interrupt Status Register: Read/Write Clear + fn set_int_status_reg(&self, shift: u32, _len: u32, val: u64) { + let new_val = val << shift; + let cleared = new_val & self.int_status.get(); + + for (index, timer) in self.timers.iter().take(self.num_timers.get()).enumerate() { + if cleared & (1 << index) != 0 { + timer.borrow_mut().update_irq(false); + } + } + } + + /// Main Counter Value Register + fn set_counter_reg(&self, shift: u32, len: u32, val: u64) { + if self.is_hpet_enabled() { + // TODO: Add trace point - + // trace_hpet_ram_write_counter_write_while_enabled() + // + // HPET spec says that writes to this register should only be + // done while the counter is halted. So this is an undefined + // behavior. There's no need to forbid it, but when HPET is + // enabled, the changed counter value will not affect the + // tick count (i.e., the previously calculated offset will + // not be changed as well). + } + self.counter + .set(self.counter.get().deposit(shift, len, val)); + } +} diff --git a/rust/hw/timer/hpet/src/lib.rs b/rust/hw/timer/hpet/src/lib.rs index 44e9f3fb8ab..d6ac0b2521a 100644 --- a/rust/hw/timer/hpet/src/lib.rs +++ b/rust/hw/timer/hpet/src/lib.rs @@ -8,3 +8,4 @@ //! Precision Event Timers) device in QEMU. pub mod fw_cfg; +pub mod hpet; From patchwork Thu Feb 13 16:00:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13973556 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 E0D3DC021A0 for ; Thu, 13 Feb 2025 16:10:14 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibfM-000178-B3; Thu, 13 Feb 2025 11:02:16 -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 1tibfJ-00015E-20 for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:13 -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 1tibfG-0005ed-Dd for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:12 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462529; 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=AXSirWChTae0VbHv/LtCDoICPe1wlXJZ8L6gaZA9kvQ=; b=GTtyagnzIV4kxPdjXvMFqAjk1G4KE2TZFkaUBkXvuMBMuvofnn8eauFDe7kY6coB+Og7A4 cGcaMxfdAdeKw8EzqVL38WFKO/7iA0LQfqDszFxlI+l9Y/+bIP2z2wUHxQTvEHGJfHO5tY 92n5co5Ei1W6yR3yhb58b5SSW5FdMJs= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-619-MQnFB6lLMLOHUuYNj-toWg-1; Thu, 13 Feb 2025 11:02:05 -0500 X-MC-Unique: MQnFB6lLMLOHUuYNj-toWg-1 X-Mimecast-MFC-AGG-ID: MQnFB6lLMLOHUuYNj-toWg Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-439605aea5bso5745965e9.1 for ; Thu, 13 Feb 2025 08:02:04 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462523; x=1740067323; 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=AXSirWChTae0VbHv/LtCDoICPe1wlXJZ8L6gaZA9kvQ=; b=i1NsJoCNzNTTMq08VMJq9Mrb+0neEy3dr9dyc7z8l05T8AZHMEfDkyg7v2aPpsz963 jPrdzFFPWcJbhUWppimuW3v8ZMHs3AY4As7js1NEFUrcDeiFB4MqH2kxWAPsZwuWNL+S SuPW7bTVPazREpNkLn9GqCroB5eK4vrWGOdkF2A5mdeu7nto4Hxp4DmZYO6PD78PBGC+ SfydVfdEVTzdokaPYPT4vYC6/RBOe2XBiESejq+zvvxH0lap+vZ/ljmgTfcds6ZFUGtP tT1THEnZq2s31D7xsAZax48yXGUwpP1Nw45MgeoImuM8Po2vNe5q6zXiIXaiBufRiDQu f9GQ== X-Gm-Message-State: AOJu0Yy8A4fl9md2sCrzyWGuEba76KWCnyfdNLejtx5eyVrkRrTnS2sS ty/eU5oqvibme4prrAh4EgJWfrWuCUD4IuMsCfS02IoI4uF+gn882cHgmG0R2zgeM5M4I1fHuKP oHbJLqiUpANsDf1re+ALclU/mmDqMZ8Cg4OfV9Ee+b5+CdJm4DxIXhoxVys1dCBCMGIt5zemRle 7b+eCN3/5KOVPVbhsq/AgrrCP9dhuNDlsUq7TLpeA= X-Gm-Gg: ASbGncsTD0oabNXtTbpGb1AjnYO0MtlRVV83qB4XBNYaG9E1cBC7jIpnsEiEszEI6xx V/RUKB6TojM5R1Ldz2Gn+r8SAHsGq+MmLRONw27mz6k6RWoBNGjsqlF1zrL7e/vkQ9Wx0UNGU+V t0rgc2y4J7RBhYcDm/Eif8D8VConzv4L0dIqqfR7h86ZX+yIusR7T7fDx9ZVohjVKNy35oBg9Cx LexIfvAldqvhm9Gil6jYGmvXckb+FFIcwi8NzNlYr0Hgyt0fKf9vqqexQEJkVH3nAA615RDJ2Sg HmxRvBcsXjwi9efA12SS47FqN2X3nv40aQWt4UulJhOBcw== X-Received: by 2002:a05:600c:444d:b0:439:5529:33e0 with SMTP id 5b1f17b1804b1-439581bf09fmr74772315e9.27.1739462520985; Thu, 13 Feb 2025 08:02:00 -0800 (PST) X-Google-Smtp-Source: AGHT+IHy5z4A87oPWYlBQJfmcSJcYWVMoyMF4Lvtu+b8bgwzEYKYW2fgqP0WvUw1oZ86nj2SZZxeyQ== X-Received: by 2002:a05:600c:444d:b0:439:5529:33e0 with SMTP id 5b1f17b1804b1-439581bf09fmr74770295e9.27.1739462518680; Thu, 13 Feb 2025 08:01:58 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-439618a9421sm21146025e9.34.2025.02.13.08.01.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:01:58 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 22/27] rust/timer/hpet: add qom and qdev APIs support Date: Thu, 13 Feb 2025 17:00:49 +0100 Message-ID: <20250213160054.3937012-23-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 From: Zhao Liu Implement QOM & QAPI support for HPET device. Signed-off-by: Zhao Liu Link: https://lore.kernel.org/r/20250210030051.2562726-10-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/hw/timer/hpet/src/fw_cfg.rs | 2 - rust/hw/timer/hpet/src/hpet.rs | 278 ++++++++++++++++++++++++++++++- rust/hw/timer/hpet/src/lib.rs | 4 + 3 files changed, 273 insertions(+), 11 deletions(-) diff --git a/rust/hw/timer/hpet/src/fw_cfg.rs b/rust/hw/timer/hpet/src/fw_cfg.rs index 849e277d483..bef03727ea3 100644 --- a/rust/hw/timer/hpet/src/fw_cfg.rs +++ b/rust/hw/timer/hpet/src/fw_cfg.rs @@ -2,8 +2,6 @@ // Author(s): Zhao Liu // SPDX-License-Identifier: GPL-2.0-or-later -#![allow(dead_code)] - use std::ptr::addr_of_mut; use qemu_api::{cell::bql_locked, impl_zeroable, zeroable::Zeroable}; diff --git a/rust/hw/timer/hpet/src/hpet.rs b/rust/hw/timer/hpet/src/hpet.rs index 795610f8e88..75ff5b3e8d6 100644 --- a/rust/hw/timer/hpet/src/hpet.rs +++ b/rust/hw/timer/hpet/src/hpet.rs @@ -2,21 +2,33 @@ // Author(s): Zhao Liu // SPDX-License-Identifier: GPL-2.0-or-later -#![allow(dead_code)] - -use std::ptr::{addr_of_mut, null_mut, NonNull}; +use std::{ + ffi::CStr, + ptr::{addr_of_mut, null_mut, NonNull}, + slice::from_ref, +}; use qemu_api::{ - bindings::{address_space_memory, address_space_stl_le}, + bindings::{ + address_space_memory, address_space_stl_le, qdev_prop_bit, qdev_prop_bool, + qdev_prop_uint32, qdev_prop_uint8, + }, + c_str, cell::{BqlCell, BqlRefCell}, irq::InterruptSource, - memory::{MemoryRegion, MEMTXATTRS_UNSPECIFIED}, + memory::{ + hwaddr, MemoryRegion, MemoryRegionOps, MemoryRegionOpsBuilder, MEMTXATTRS_UNSPECIFIED, + }, prelude::*, - qom::ParentField, + qdev::{DeviceImpl, DeviceMethods, DeviceState, Property, ResetType, ResettablePhasesImpl}, + qom::{ObjectImpl, ObjectType, ParentField}, + qom_isa, sysbus::SysBusDevice, timer::{Timer, CLOCK_VIRTUAL}, }; +use crate::fw_cfg::HPETFwConfig; + /// Register space for each timer block (`HPET_BASE` is defined in hpet.h). const HPET_REG_SPACE_LEN: u64 = 0x400; // 1024 bytes @@ -139,8 +151,7 @@ fn timer_handler(timer_cell: &BqlRefCell) { /// HPET Timer Abstraction #[repr(C)] -#[derive(Debug, Default)] -#[cfg_attr(has_offset_of, derive(qemu_api_macros::offsets))] +#[derive(Debug, Default, qemu_api_macros::offsets)] pub struct HPETTimer { /// timer N index within the timer block (`HPETState`) #[doc(alias = "tn")] @@ -451,11 +462,41 @@ fn callback(&mut self) { } self.update_irq(true); } + + const fn read(&self, addr: hwaddr, _size: u32) -> u64 { + let shift: u64 = (addr & 4) * 8; + + match addr & !4 { + HPET_TN_CFG_REG => self.config >> shift, // including interrupt capabilities + HPET_TN_CMP_REG => self.cmp >> shift, // comparator register + HPET_TN_FSB_ROUTE_REG => self.fsb >> shift, + _ => { + // TODO: Add trace point - trace_hpet_ram_read_invalid() + // Reserved. + 0 + } + } + } + + fn write(&mut self, addr: hwaddr, value: u64, size: u32) { + let shift = ((addr & 4) * 8) as u32; + let len = std::cmp::min(size * 8, 64 - shift); + + match addr & !4 { + HPET_TN_CFG_REG => self.set_tn_cfg_reg(shift, len, value), + HPET_TN_CMP_REG => self.set_tn_cmp_reg(shift, len, value), + HPET_TN_FSB_ROUTE_REG => self.set_tn_fsb_route_reg(shift, len, value), + _ => { + // TODO: Add trace point - trace_hpet_ram_write_invalid() + // Reserved. + } + } + } } /// HPET Event Timer Block Abstraction #[repr(C)] -#[derive(qemu_api_macros::offsets)] +#[derive(qemu_api_macros::Object, qemu_api_macros::offsets)] pub struct HPETState { parent_obj: ParentField, iomem: MemoryRegion, @@ -626,4 +667,223 @@ fn set_counter_reg(&self, shift: u32, len: u32, val: u64) { self.counter .set(self.counter.get().deposit(shift, len, val)); } + + unsafe fn init(&mut self) { + static HPET_RAM_OPS: MemoryRegionOps = + MemoryRegionOpsBuilder::::new() + .read(&HPETState::read) + .write(&HPETState::write) + .native_endian() + .valid_sizes(4, 8) + .impl_sizes(4, 8) + .build(); + + // SAFETY: + // self and self.iomem are guaranteed to be valid at this point since callers + // must make sure the `self` reference is valid. + MemoryRegion::init_io( + unsafe { &mut *addr_of_mut!(self.iomem) }, + addr_of_mut!(*self), + &HPET_RAM_OPS, + "hpet", + HPET_REG_SPACE_LEN, + ); + } + + fn post_init(&self) { + self.init_mmio(&self.iomem); + for irq in self.irqs.iter() { + self.init_irq(irq); + } + } + + fn realize(&self) { + if self.int_route_cap == 0 { + // TODO: Add error binding: warn_report() + println!("Hpet's hpet-intcap property not initialized"); + } + + self.hpet_id.set(HPETFwConfig::assign_hpet_id()); + + if self.num_timers.get() < HPET_MIN_TIMERS { + self.num_timers.set(HPET_MIN_TIMERS); + } else if self.num_timers.get() > HPET_MAX_TIMERS { + self.num_timers.set(HPET_MAX_TIMERS); + } + + self.init_timer(); + // 64-bit General Capabilities and ID Register; LegacyReplacementRoute. + self.capability.set( + HPET_CAP_REV_ID_VALUE << HPET_CAP_REV_ID_SHIFT | + 1 << HPET_CAP_COUNT_SIZE_CAP_SHIFT | + 1 << HPET_CAP_LEG_RT_CAP_SHIFT | + HPET_CAP_VENDER_ID_VALUE << HPET_CAP_VENDER_ID_SHIFT | + ((self.num_timers.get() - 1) as u64) << HPET_CAP_NUM_TIM_SHIFT | // indicate the last timer + (HPET_CLK_PERIOD * FS_PER_NS) << HPET_CAP_CNT_CLK_PERIOD_SHIFT, // 10 ns + ); + + self.init_gpio_in(2, HPETState::handle_legacy_irq); + self.init_gpio_out(from_ref(&self.pit_enabled)); + } + + fn reset_hold(&self, _type: ResetType) { + let sbd = self.upcast::(); + + for timer in self.timers.iter().take(self.num_timers.get()) { + timer.borrow_mut().reset(); + } + + self.counter.set(0); + self.config.set(0); + self.pit_enabled.set(true); + self.hpet_offset.set(0); + + HPETFwConfig::update_hpet_cfg( + self.hpet_id.get(), + self.capability.get() as u32, + sbd.mmio[0].addr, + ); + + // to document that the RTC lowers its output on reset as well + self.rtc_irq_level.set(0); + } + + fn timer_and_addr(&self, addr: hwaddr) -> Option<(&BqlRefCell, hwaddr)> { + let timer_id: usize = ((addr - 0x100) / 0x20) as usize; + + // TODO: Add trace point - trace_hpet_ram_[read|write]_timer_id(timer_id) + if timer_id > self.num_timers.get() { + // TODO: Add trace point - trace_hpet_timer_id_out_of_range(timer_id) + None + } else { + // Keep the complete address so that HPETTimer's read and write could + // detect the invalid access. + Some((&self.timers[timer_id], addr & 0x1F)) + } + } + + fn read(&self, addr: hwaddr, size: u32) -> u64 { + let shift: u64 = (addr & 4) * 8; + + // address range of all TN regs + // TODO: Add trace point - trace_hpet_ram_read(addr) + if (0x100..=0x3ff).contains(&addr) { + match self.timer_and_addr(addr) { + None => 0, // Reserved, + Some((timer, tn_addr)) => timer.borrow_mut().read(tn_addr, size), + } + } else { + match addr & !4 { + HPET_CAP_REG => self.capability.get() >> shift, /* including HPET_PERIOD 0x004 */ + // (CNT_CLK_PERIOD field) + HPET_CFG_REG => self.config.get() >> shift, + HPET_COUNTER_REG => { + let cur_tick: u64 = if self.is_hpet_enabled() { + self.get_ticks() + } else { + self.counter.get() + }; + + // TODO: Add trace point - trace_hpet_ram_read_reading_counter(addr & 4, + // cur_tick) + cur_tick >> shift + } + HPET_INT_STATUS_REG => self.int_status.get() >> shift, + _ => { + // TODO: Add trace point- trace_hpet_ram_read_invalid() + // Reserved. + 0 + } + } + } + } + + fn write(&self, addr: hwaddr, value: u64, size: u32) { + let shift = ((addr & 4) * 8) as u32; + let len = std::cmp::min(size * 8, 64 - shift); + + // TODO: Add trace point - trace_hpet_ram_write(addr, value) + if (0x100..=0x3ff).contains(&addr) { + match self.timer_and_addr(addr) { + None => (), // Reserved. + Some((timer, tn_addr)) => timer.borrow_mut().write(tn_addr, value, size), + } + } else { + match addr & !0x4 { + HPET_CAP_REG => {} // General Capabilities and ID Register: Read Only + HPET_CFG_REG => self.set_cfg_reg(shift, len, value), + HPET_INT_STATUS_REG => self.set_int_status_reg(shift, len, value), + HPET_COUNTER_REG => self.set_counter_reg(shift, len, value), + _ => { + // TODO: Add trace point - trace_hpet_ram_write_invalid() + // Reserved. + } + } + } + } +} + +qom_isa!(HPETState: SysBusDevice, DeviceState, Object); + +unsafe impl ObjectType for HPETState { + // No need for HPETClass. Just like OBJECT_DECLARE_SIMPLE_TYPE in C. + type Class = ::Class; + const TYPE_NAME: &'static CStr = crate::TYPE_HPET; +} + +impl ObjectImpl for HPETState { + type ParentType = SysBusDevice; + + const INSTANCE_INIT: Option = Some(Self::init); + const INSTANCE_POST_INIT: Option = Some(Self::post_init); +} + +// TODO: Make these properties user-configurable! +qemu_api::declare_properties! { + HPET_PROPERTIES, + qemu_api::define_property!( + c_str!("timers"), + HPETState, + num_timers, + unsafe { &qdev_prop_uint8 }, + u8, + default = HPET_MIN_TIMERS + ), + qemu_api::define_property!( + c_str!("msi"), + HPETState, + flags, + unsafe { &qdev_prop_bit }, + u32, + bit = HPET_FLAG_MSI_SUPPORT_SHIFT as u8, + default = false, + ), + qemu_api::define_property!( + c_str!("hpet-intcap"), + HPETState, + int_route_cap, + unsafe { &qdev_prop_uint32 }, + u32, + default = 0 + ), + qemu_api::define_property!( + c_str!("hpet-offset-saved"), + HPETState, + hpet_offset_saved, + unsafe { &qdev_prop_bool }, + bool, + default = true + ), +} + +impl DeviceImpl for HPETState { + fn properties() -> &'static [Property] { + &HPET_PROPERTIES + } + + const REALIZE: Option = Some(Self::realize); +} + +impl ResettablePhasesImpl for HPETState { + const HOLD: Option = Some(Self::reset_hold); } diff --git a/rust/hw/timer/hpet/src/lib.rs b/rust/hw/timer/hpet/src/lib.rs index d6ac0b2521a..5e7c961c289 100644 --- a/rust/hw/timer/hpet/src/lib.rs +++ b/rust/hw/timer/hpet/src/lib.rs @@ -7,5 +7,9 @@ //! This library implements a device model for the IA-PC HPET (High //! Precision Event Timers) device in QEMU. +use qemu_api::c_str; + pub mod fw_cfg; pub mod hpet; + +pub const TYPE_HPET: &::std::ffi::CStr = c_str!("hpet"); From patchwork Thu Feb 13 16:00:50 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13973536 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 47E2EC021A0 for ; Thu, 13 Feb 2025 16:05:36 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibfL-000169-Bv; Thu, 13 Feb 2025 11:02: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 1tibfH-000149-3B for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:12 -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 1tibfF-0005eF-8H for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:10 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462527; 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=+gp7LPZ4z/UwRnFvmVqp2Msund5xUSnBQY80C+x5wKs=; b=gJqYcFx1nHrMkr/BzYwQ7caC2MyaASu8JTyg501Y6SefDpbHCV/T0fkV37Z4fSNsrQfLkV d8MgHTTEUxA7J4j0aB/cA8lz5Bndg/2v2dsvYoE/XvBMhjrN3Mx3C/JIDhlTeictQmlv0e rknbOiOCXu4ppFBL//xr6XF0sIUYs4Y= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-613-yHDJQ3Y0OY6giGBMUUtQ8A-1; Thu, 13 Feb 2025 11:02:05 -0500 X-MC-Unique: yHDJQ3Y0OY6giGBMUUtQ8A-1 X-Mimecast-MFC-AGG-ID: yHDJQ3Y0OY6giGBMUUtQ8A Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-438e4e9a53fso7823435e9.1 for ; Thu, 13 Feb 2025 08:02:05 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462523; x=1740067323; 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=+gp7LPZ4z/UwRnFvmVqp2Msund5xUSnBQY80C+x5wKs=; b=mvEPBs4rcS5wlYbGgv4u8jTj98Sx3XTQz6lfu2sxs1Cnt0fJe8tmwU7nHV6IBEGrGP c7T7eo35mzBzFoFoEOTl0ppPAL0jBcVdk9bxlTBsErkDBkFFR9e9p9WztdxScZ3l50CQ Tj0arJe8z8wk2X8QB6BSd+VJg+tmAQXiOQkB7DWs8LH5th2jiNo9KTvmfeoOpoESDURK W5AdYS8IRJizUxBMES6ZCNiGD9GRPVFr9ienJ/Qf7f5nPRejO2KoCrq1zyY5avewGKS0 lXxRmIZgRDG9/sh1l2J2sy/jxpWuKotL3ziTWlEFRZeSwmIPjk2KdJDodxwr8XeYVpxL +dEg== X-Gm-Message-State: AOJu0YzYk8cA6S+n7Ww3EC9JN0QHzFBdIc86j3w6u+tUFznpqi4NIKVF MKXdsukC1iuTnbycGq3XzE+g1vWCXMPU5y73X9ChZbn4fsb5ZPDZMzevGivjqbEHpfer5x8qPOf NSu5QmmOxQ6mZ+L5eDQMN4WP/d9gg5M4AzMyWe/spEN/Xc4Nvntzve0xbuXDoxACQK6YFna73lv GrTyDdhG8U5gV2VSQRPH74AvjeqY5HEPl3d3iePmg= X-Gm-Gg: ASbGncvmexV+FR+/gw8je3TumT/PSCo7hcnO9pG/2GcEPy+RTZ69+Q/Xzddq/ImJbgB GwHngGEK5OGyBaqRaX+eea8j+cA43Ow79GvyUwIOk0Yexoh5b8+2H2i1ab7qZ8T7QLrtB26gSgx 2JXpQwuBfiwYN4pAc5Rk4Qd9H8TdujXqwgm/0+jO+cTqxuzs6f5jnzE/yldqU6LN20sEi6Lk8vh ktERWOp4qM8dif4rBRHq3aErXWwekBPEThNqA3WlFE1is9vaZ0V/wdNAkwt30Qky+96s+XGEgf/ Me0pSaWYZz53troekQLUBBHyn+967cDdrGm3DkWEkGyd/w== X-Received: by 2002:a05:600c:46c7:b0:439:35bb:a5eb with SMTP id 5b1f17b1804b1-439581604d6mr85279095e9.4.1739462522528; Thu, 13 Feb 2025 08:02:02 -0800 (PST) X-Google-Smtp-Source: AGHT+IHFN2PdtHTwx8hF3F1lRnh6YMMkBV6sqm75V68yv3DjBOdEin5ZbzIpx7wuWzkR5mDbSxuoVw== X-Received: by 2002:a05:600c:46c7:b0:439:35bb:a5eb with SMTP id 5b1f17b1804b1-439581604d6mr85278345e9.4.1739462521908; Thu, 13 Feb 2025 08:02:01 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f258f5fb6sm2209597f8f.44.2025.02.13.08.02.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:02:01 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 23/27] i386: enable rust hpet for pc when rust is enabled Date: Thu, 13 Feb 2025 17:00:50 +0100 Message-ID: <20250213160054.3937012-24-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 From: Zhao Liu Add HPET configuration in PC's Kconfig options, and select HPET device (Rust version) if Rust is supported. Signed-off-by: Zhao Liu Link: https://lore.kernel.org/r/20250210030051.2562726-11-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- configs/devices/i386-softmmu/default.mak | 1 + hw/i386/pc.c | 2 +- hw/timer/Kconfig | 2 +- rust/hw/Kconfig | 1 + rust/hw/timer/Kconfig | 2 ++ tests/qtest/meson.build | 3 ++- 6 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 rust/hw/timer/Kconfig diff --git a/configs/devices/i386-softmmu/default.mak b/configs/devices/i386-softmmu/default.mak index 4faf2f0315e..9ef343cace0 100644 --- a/configs/devices/i386-softmmu/default.mak +++ b/configs/devices/i386-softmmu/default.mak @@ -6,6 +6,7 @@ #CONFIG_APPLESMC=n #CONFIG_FDC=n #CONFIG_HPET=n +#CONFIG_X_HPET_RUST=n #CONFIG_HYPERV=n #CONFIG_ISA_DEBUG=n #CONFIG_ISA_IPMI_BT=n diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 0eb52d315bb..22641e6ddca 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1701,7 +1701,7 @@ static void pc_machine_initfn(Object *obj) pcms->sata_enabled = true; pcms->i8042_enabled = true; pcms->max_fw_size = 8 * MiB; -#ifdef CONFIG_HPET +#if defined(CONFIG_HPET) || defined(CONFIG_X_HPET_RUST) pcms->hpet_enabled = true; #endif pcms->fd_bootchk = true; diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig index c96fd5d97ae..9ac00845340 100644 --- a/hw/timer/Kconfig +++ b/hw/timer/Kconfig @@ -11,7 +11,7 @@ config A9_GTIMER config HPET bool - default y if PC + default y if PC && !HAVE_RUST config I8254 bool diff --git a/rust/hw/Kconfig b/rust/hw/Kconfig index 4d934f30afe..36f92ec0287 100644 --- a/rust/hw/Kconfig +++ b/rust/hw/Kconfig @@ -1,2 +1,3 @@ # devices Kconfig source char/Kconfig +source timer/Kconfig diff --git a/rust/hw/timer/Kconfig b/rust/hw/timer/Kconfig new file mode 100644 index 00000000000..afd98033503 --- /dev/null +++ b/rust/hw/timer/Kconfig @@ -0,0 +1,2 @@ +config X_HPET_RUST + bool diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 68316dbdc1a..8a6243382a1 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -103,7 +103,8 @@ qtests_i386 = \ config_all_devices.has_key('CONFIG_VIRTIO_PCI') and \ slirp.found() ? ['virtio-net-failover'] : []) + \ (unpack_edk2_blobs and \ - config_all_devices.has_key('CONFIG_HPET') and \ + (config_all_devices.has_key('CONFIG_HPET') or \ + config_all_devices.has_key('CONFIG_X_HPET_RUST')) and \ config_all_devices.has_key('CONFIG_PARALLEL') ? ['bios-tables-test'] : []) + \ qtests_pci + \ qtests_cxl + \ From patchwork Thu Feb 13 16:00:51 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13973547 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 49A25C021A0 for ; Thu, 13 Feb 2025 16:07:54 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibfQ-00018w-8o; Thu, 13 Feb 2025 11:02: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 1tibfN-00017s-Ll for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:17 -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 1tibfL-0005fm-5o for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462534; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=l+aZANu1L4i2e4Tg4LUPUkh6vicaxG7hxdJp4ipBY0E=; b=ZteF7lwHkIzFBdxWwMewJRyPc9/y5ZaPVvTXbq9ymHb/Ol/LaWJ5zXIr/H84Kw3HDURDen qdIHJmKYCiT0rX/VtHExVt4Ia+yrsgygUnR/ZH1vk7YPiOSvr1VbCpkCTGUkLedfRabg5H AKPSIwQHCgbE0g6B1P53iGToyu4xVLM= 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-76-I-XlyBCVNxOGVByeqTx04A-1; Thu, 13 Feb 2025 11:02:13 -0500 X-MC-Unique: I-XlyBCVNxOGVByeqTx04A-1 X-Mimecast-MFC-AGG-ID: I-XlyBCVNxOGVByeqTx04A_1739462532 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-38de0a98043so614404f8f.3 for ; Thu, 13 Feb 2025 08:02:13 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462531; x=1740067331; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=l+aZANu1L4i2e4Tg4LUPUkh6vicaxG7hxdJp4ipBY0E=; b=Ah9XEoN5DojDq1LhHcUThNLdSg5e3X4u5JWBBS4SA/FTCNEWoa917N9lqyCnURDN0z 4SCYYRhBK/VC4U3QmY2iD4oJLTXpaycoiOHaQaqyF7IUnRYs6ePe3SXAB9dj8h2uKDrN ph3bbEIpKRq3IHAtiSP4/StoAS0xDjsSakkv/zIirgWl6xyNGV5ZJKxEyTDTWYxrhpqy LwJ+6UL1qaKqpGcIPzrxrlWvxlbbmXHFWXKzickpmNlzcBoWI+oS91PnEkFeRRzsFut+ 8OUSeqii8PqyY32iBTHMw1nsZdUna6pbDGOmQ8DVMD/+7MwNjZkDzor+mtfLQJ8VAoP4 nLVw== X-Gm-Message-State: AOJu0Yye7gRKfz/0G4aNFJn5V50yu7qqCJw++ota9tv1nN78iKJH7FXV Q3z1+1gvzO4wYld4mAOnuM6A66kdc1P4TnbP/IdDM7gZJO9+ezlSBUgFZ35xS7jg6co1mR6hkiF 1FZGNWtz6wlDAf7chY7PyuaPkIRjxHlnsDRlhT8iiNQCBV+5GNPCrun9TV4HJwuqHiELlSa3vE/ b4WEGCSlBE+ULJZEGagAqalYAJY/gfw2pC/3b70fU= X-Gm-Gg: ASbGncu9WhIzTrWSKj5fVdiEPdDuM819usQiiQBCZ3hA6aK+RBPeAsxB34qWuFRkMLZ 7Tp5x/Dv3jgMi1Ti8Rs7AAbofU6gPfIzMFKSKzDcLtICR2ou5ce8CHwZgFr7seUQ6itB2wZc+hA bo9OvQQGmMkfYrX1ldz0/jwaJTnHHuUFa2xnwuUYvyFo6mSG30+4Gmh7VJFL3sGYQW5p00rkUQk JDzigzo1rcqlrQQnkxtmYVBM2Z6OkWdMhYD1RQUMvw7E8+DvagLh7VlV4FRMp2UNw9liEZuy6Iq SlwQdCRh1ogETlGnxMEffccR6ErM32h5/dhNe2C+0MPM2A== X-Received: by 2002:a5d:52c8:0:b0:38d:e48b:1787 with SMTP id ffacd0b85a97d-38dea26c186mr6309492f8f.14.1739462528246; Thu, 13 Feb 2025 08:02:08 -0800 (PST) X-Google-Smtp-Source: AGHT+IE7exGDLDPu5qiGUy+vjCTWxO1dqlCumxmPQkRMu53nIW1zW59pb3bTc3TBOPwOj+bFx8MGtQ== X-Received: by 2002:a5d:52c8:0:b0:38d:e48b:1787 with SMTP id ffacd0b85a97d-38dea26c186mr6309282f8f.14.1739462525706; Thu, 13 Feb 2025 08:02:05 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f25a0fa1esm2208679f8f.100.2025.02.13.08.02.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:02:04 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 24/27] rust: qemu_api: add a documentation header for all modules Date: Thu, 13 Feb 2025 17:00:51 +0100 Message-ID: <20250213160054.3937012-25-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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/assertions.rs | 4 ++++ rust/qemu-api/src/bindings.rs | 2 ++ rust/qemu-api/src/c_str.rs | 8 ++++++++ rust/qemu-api/src/offset_of.rs | 7 +++++++ rust/qemu-api/src/prelude.rs | 2 ++ rust/qemu-api/src/sysbus.rs | 2 ++ rust/qemu-api/src/zeroable.rs | 2 ++ 7 files changed, 27 insertions(+) diff --git a/rust/qemu-api/src/assertions.rs b/rust/qemu-api/src/assertions.rs index 6e420469806..fa1a18de6fe 100644 --- a/rust/qemu-api/src/assertions.rs +++ b/rust/qemu-api/src/assertions.rs @@ -2,9 +2,13 @@ // Author(s): Paolo Bonzini // SPDX-License-Identifier: GPL-2.0-or-later +#![doc(hidden)] //! This module provides macros to check the equality of types and //! the type of `struct` fields. This can be useful to ensure that //! types match the expectations of C code. +//! +//! Documentation is hidden because it only exposes macros, which +//! are exported directly from `qemu_api`. // Based on https://stackoverflow.com/questions/64251852/x/70978292#70978292 // (stackoverflow answers are released under MIT license). diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs index b71220113ef..d2868639ff6 100644 --- a/rust/qemu-api/src/bindings.rs +++ b/rust/qemu-api/src/bindings.rs @@ -15,6 +15,8 @@ clippy::missing_safety_doc )] +//! `bindgen`-generated declarations. + #[cfg(MESON)] include!("bindings.inc.rs"); diff --git a/rust/qemu-api/src/c_str.rs b/rust/qemu-api/src/c_str.rs index 4cd96da0b45..3fa61b59c76 100644 --- a/rust/qemu-api/src/c_str.rs +++ b/rust/qemu-api/src/c_str.rs @@ -2,6 +2,14 @@ // Author(s): Paolo Bonzini // SPDX-License-Identifier: GPL-2.0-or-later +#![doc(hidden)] +//! This module provides a macro to define a constant of type +//! [`CStr`](std::ffi::CStr), for compatibility with versions of +//! Rust that lack `c""` literals. +//! +//! Documentation is hidden because it only exposes macros, which +//! are exported directly from `qemu_api`. + #[macro_export] /// Given a string constant _without_ embedded or trailing NULs, return /// a `CStr`. diff --git a/rust/qemu-api/src/offset_of.rs b/rust/qemu-api/src/offset_of.rs index 075e98f986b..373229bbde9 100644 --- a/rust/qemu-api/src/offset_of.rs +++ b/rust/qemu-api/src/offset_of.rs @@ -1,5 +1,12 @@ // SPDX-License-Identifier: MIT +#![doc(hidden)] +//! This module provides macros that emulate the functionality of +//! `core::mem::offset_of` on older versions of Rust. +//! +//! Documentation is hidden because it only exposes macros, which +//! are exported directly from `qemu_api`. + /// This macro provides the same functionality as `core::mem::offset_of`, /// except that only one level of field access is supported. The declaration /// of the struct must be wrapped with `with_offsets! { }`. diff --git a/rust/qemu-api/src/prelude.rs b/rust/qemu-api/src/prelude.rs index 254edb476dd..fbf0ee23e0b 100644 --- a/rust/qemu-api/src/prelude.rs +++ b/rust/qemu-api/src/prelude.rs @@ -2,6 +2,8 @@ // Author(s): Paolo Bonzini // SPDX-License-Identifier: GPL-2.0-or-later +//! Commonly used traits and types for QEMU. + pub use crate::bitops::IntegerExt; pub use crate::cell::BqlCell; diff --git a/rust/qemu-api/src/sysbus.rs b/rust/qemu-api/src/sysbus.rs index 1f66a5f1e09..fa36e12178f 100644 --- a/rust/qemu-api/src/sysbus.rs +++ b/rust/qemu-api/src/sysbus.rs @@ -2,6 +2,8 @@ // Author(s): Paolo Bonzini // SPDX-License-Identifier: GPL-2.0-or-later +//! Bindings to access `sysbus` functionality from Rust. + use std::{ffi::CStr, ptr::addr_of_mut}; pub use bindings::{SysBusDevice, SysBusDeviceClass}; diff --git a/rust/qemu-api/src/zeroable.rs b/rust/qemu-api/src/zeroable.rs index cd424e6ea05..a2356cb2f24 100644 --- a/rust/qemu-api/src/zeroable.rs +++ b/rust/qemu-api/src/zeroable.rs @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later +//! Defines a trait for structs that can be safely initialized with zero bytes. + /// Encapsulates the requirement that /// `MaybeUninit::::zeroed().assume_init()` does not cause undefined /// behavior. This trait in principle could be implemented as just: From patchwork Thu Feb 13 16:00:52 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13973530 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 B72EDC021A4 for ; Thu, 13 Feb 2025 16:03:22 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibfT-00019Q-Gg; Thu, 13 Feb 2025 11:02:23 -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 1tibfN-00017t-MQ for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:17 -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 1tibfK-0005fX-4n for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462533; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=flZ23sKzW+B6elEVxHhJ87AEPqM0mRFuz9sf5vBkc00=; b=c25duyDSk8oNRD2Dz3MYvsdtm50wu/n75CTHh6jt7Q0ELNSpjqB80E2qyu3BjbtOBHxORx X2IkeO9OX5gDbbmi3T758rvU0CiE2Z4kx1OirJYDU8W9rq9SQLr1gMlI8nvwEZHyPffxoe cJujd7yKoPT5ieYZyLhErPwVAImnLz0= 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-20-fIGJaf7OM12NsTmOWRJKbQ-1; Thu, 13 Feb 2025 11:02:12 -0500 X-MC-Unique: fIGJaf7OM12NsTmOWRJKbQ-1 X-Mimecast-MFC-AGG-ID: fIGJaf7OM12NsTmOWRJKbQ_1739462531 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-38dcc9653a7so554637f8f.0 for ; Thu, 13 Feb 2025 08:02:12 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462530; x=1740067330; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=flZ23sKzW+B6elEVxHhJ87AEPqM0mRFuz9sf5vBkc00=; b=WXOJQtQSLeVtLH/hOtoFvhI6TOG5cLhOGb5SYd3Ds9se3EkmQFO7tEk7M1RjzOUyhX RaXXj+cKJghPMxQO0bFZC6AnpeBCcPyYH9cy2nO6zMbQgFaKOMfQ0VkSeUoSbRptR7F/ RDyAvQiZzohsRbSO/FdjNdFIEo9rFWkig7TuR2jTcn3fPcdvoIOqWw8lDPgsCDOZtzo6 /DIgS1qJM60uObzZAYQSkbkoP4+Lfe49JXVAwPYJ1V+W9Ewc6CsUJbQPyNO4Wxd5CZ3h T+/9L1swxAt6LGhEFA2AWyPodILF0kguww+MZhac1L4d5p+p4lh2NnRu1hykVJ5Zru6z IaNg== X-Gm-Message-State: AOJu0YyZXevMNnWvCX8fJ3+rcHyO1TIRHDPPQka7UJGvWIzymkOIww11 7bROm0kdtAlgZdovcN2iJTDjoMxTagYGjOTyD94jxh8NXfXxvEkPjjKjAY+jRYKnhLLHHQ+jS/l C8DVD5GdLsxxNRciiraULzXBtKWwTvXpib9tkyv/V9ERSwBNBXvHkNvW7KZC8tAF5NiLWZo/ZZs XFE5fnGifoDGpEp4JVXetyvZxpE3IHefL4JSsPb04= X-Gm-Gg: ASbGncuBPi+EVagL/fudAkh33VXlvywIJSyt1L+cUCrYgUqRoacpXxXFgoO5nRWTF12 1LFalcMjprOlFHU7KX6kJml+TJLixpY8qsj9vVThinUdQV3d3YLMJ14sKyLCC+IcCTFrBw+SuHM SAKM2KyYmivSPJPsGTb7drAYPxSTAn+E7o34hWzkd2h8aar6zXGRX2cqT+uXKU5Jt/t/yU2RWAl PfzSm2tXB6DmrRV2KbtvekQZfXSz/ieJiu3Z5U0JzyYxLCb+SbLUuyES8DQCVtyVPzIma/36a45 wKe1tGIfE4TrxA3+KE3WnplWqQFiKnEuoXhVF+2ZukM3ig== X-Received: by 2002:a05:6000:2cf:b0:38c:5dcb:312e with SMTP id ffacd0b85a97d-38f2445d018mr5287761f8f.0.1739462529051; Thu, 13 Feb 2025 08:02:09 -0800 (PST) X-Google-Smtp-Source: AGHT+IEAuh4oKbmDkTcacFQwkdnf2a719fxZYLO2PbsTtJhqfR7ILUc3zxJIq318R89MRMTWGOcGkw== X-Received: by 2002:a05:6000:2cf:b0:38c:5dcb:312e with SMTP id ffacd0b85a97d-38f2445d018mr5287708f8f.0.1739462528561; Thu, 13 Feb 2025 08:02:08 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259d8f1csm2269535f8f.69.2025.02.13.08.02.07 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:02:07 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 25/27] rust: vmstate: remove redundant link targets Date: Thu, 13 Feb 2025 17:00:52 +0100 Message-ID: <20250213160054.3937012-26-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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/vmstate.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 164effc6553..c6dfb609356 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -191,10 +191,9 @@ pub const fn vmstate_varray_flag(_: PhantomData) -> VMStateFlags /// * scalar types (integer and `bool`) /// * the C struct `QEMUTimer` /// * a transparent wrapper for any of the above (`Cell`, `UnsafeCell`, -/// [`BqlCell`](crate::cell::BqlCell), [`BqlRefCell`](crate::cell::BqlRefCell) +/// [`BqlCell`], [`BqlRefCell`] /// * a raw pointer to any of the above -/// * a `NonNull` pointer, a `Box` or an [`Owned`](crate::qom::Owned) for any of -/// the above +/// * a `NonNull` pointer, a `Box` or an [`Owned`] for any of the above /// * an array of any of the above /// /// In order to support other types, the trait `VMState` must be implemented From patchwork Thu Feb 13 16:00:53 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13973575 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 51277C021A0 for ; Thu, 13 Feb 2025 16:11:25 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibfb-0001AE-N5; Thu, 13 Feb 2025 11:02:31 -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 1tibfT-00019P-EV for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:23 -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 1tibfL-0005fy-UR for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462535; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=FiozA6Zxf3TwsQBbLHJRuHW2pdcPG+mDIT1dc3xOVEE=; b=Ifa76a396QMDyY3giPeGSsfqNXsYBBzxnHda6MGKHu7pWIpqPyKkNO7FE/ONRsjE6N3pYQ Xr0Be01wTxG9FPH12FDulJCuZ5x93L0/Kmpy3X43Sv959od+b4wDPLgYAjIFswLxdmp9Ux cSTZtzEAGLnZzX+A+z2uNBPxqxjuVMM= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-445-3VerhEtrMCCVe-x2YRCjpw-1; Thu, 13 Feb 2025 11:02:12 -0500 X-MC-Unique: 3VerhEtrMCCVe-x2YRCjpw-1 X-Mimecast-MFC-AGG-ID: 3VerhEtrMCCVe-x2YRCjpw Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-38dc709f938so1255130f8f.0 for ; Thu, 13 Feb 2025 08:02:12 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462531; x=1740067331; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=FiozA6Zxf3TwsQBbLHJRuHW2pdcPG+mDIT1dc3xOVEE=; b=OtejCeB6cYvgm0MDwjBIfc/ODKsXfafGPKzFs/IuydY6SoDikyHYkWE7r0k6HLLfHc 4ZaVU9t9kUxK95FczpuZqHm3lV4UQjy1WaZSmVTHpGixFQwFfPR1/ZkMbj+tIuB1jZbV z923FfA9uVM2dv/iR74sIRgPqK4lYBMuXMAMNKZrmxGh+aPy9yh6PmdTJB/YLucJmEGm UT5N/zO5qok3VPvmAeUx9wHPLbTPEK2RkXDxjv3OQM1Xc9Hh9wFB8xyYeW3CL9beYJJU HiGf+Zt8iuqZxy7TO78DwEkV2tmJmesj+eU+T9TsW3vz/Zo/+rgHr5YjC1cxjAut9dkc poag== X-Gm-Message-State: AOJu0YzwmNnUN/xKTpwXqpf9TrVl2C5yriSg5RoZ7w8H8KpUFbJVuAEE iPXL3iVO5VodGDuLMOsQij7N/VJuqbzrvqb5o7Mx72wmMDKdkLwec53oIzYk9pby75Kl+YVrPWn +NJeXwpAetzxTBoDOXm7C1h27+K7gxaMq5gUl4s66Es26OHmxLPnZRe2kswvAADXOSr1vOFj24T HJXwOhp5qyTpPv8IWeEZH5b6xRKJ9qKYNmGSvcRN4= X-Gm-Gg: ASbGncsA5s9emdtykPTcMtga/WPwQD3kKRWmOTx80Ff+SgCOsPQF6Cmc6RtmG7zSCt3 00ud8A9PFhau17k7M7WJPuAn52veNysgflfXhgHSZqsBPg+f0ypdMKxhhvNcXfWiUez41tYqbdz pPDQeXFjMRm7NIWCWFGprppcIto3N59sScRg3KcGT3OMVoko8CAycaAX2NslP8NkyyqSs3yTJb1 3zgZNdFG9O4URF7AhN1CrjoFsGCNf/ANNKPFelXudN6Cgw+Fw0Jwb2NPi9i3L7vDBfJmGZGLd7T GcvoB4QVfrQPZBq7on0mMHcQzYbUY4TpinewcsPANiaOtQ== X-Received: by 2002:a05:6000:4024:b0:38d:afc8:954e with SMTP id ffacd0b85a97d-38f24cfa3dbmr4104954f8f.11.1739462530918; Thu, 13 Feb 2025 08:02:10 -0800 (PST) X-Google-Smtp-Source: AGHT+IEV4OUQ/3/DgIPhVyruiRKMRNKMkh6IS9gsA4K/+aJPxOSKPdA6FrwWqAUWbI/N2C4eqqxBRQ== X-Received: by 2002:a05:6000:4024:b0:38d:afc8:954e with SMTP id ffacd0b85a97d-38f24cfa3dbmr4104859f8f.11.1739462530162; Thu, 13 Feb 2025 08:02:10 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4395a06d1f2sm52061765e9.18.2025.02.13.08.02.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:02:09 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 26/27] rust: fix doctests Date: Thu, 13 Feb 2025 17:00:53 +0100 Message-ID: <20250213160054.3937012-27-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 Doctests were not being run by CI, and have broken. Fix them. Signed-off-by: Paolo Bonzini --- .gitlab-ci.d/buildtest.yml | 6 ++++++ rust/qemu-api/src/vmstate.rs | 2 +- rust/qemu-api/src/zeroable.rs | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml index 4265a577834..00f4bfcd9f3 100644 --- a/.gitlab-ci.d/buildtest.yml +++ b/.gitlab-ci.d/buildtest.yml @@ -131,6 +131,12 @@ build-system-fedora-rust-nightly: CONFIGURE_ARGS: --disable-docs --enable-rust --enable-strict-rust-lints TARGETS: aarch64-softmmu MAKE_CHECK_ARGS: check-build + after_script: + - source scripts/ci/gitlab-ci-section + - section_start test "Running Rust doctests" + - cd build + - pyvenv/bin/meson devenv -w ../rust ${CARGO-cargo} test --doc -p qemu_api + allow_failure: true check-system-fedora: diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index c6dfb609356..24a4dc81e7f 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -294,7 +294,7 @@ pub const fn with_varray_multiply(mut self, num: u32) -> VMStateField { /// # Examples /// /// ``` -/// # use qemu_api::vmstate::impl_vmstate_forward; +/// # use qemu_api::impl_vmstate_forward; /// pub struct Fifo([u8; 16]); /// impl_vmstate_forward!(Fifo); /// ``` diff --git a/rust/qemu-api/src/zeroable.rs b/rust/qemu-api/src/zeroable.rs index a2356cb2f24..47b6977828d 100644 --- a/rust/qemu-api/src/zeroable.rs +++ b/rust/qemu-api/src/zeroable.rs @@ -7,7 +7,7 @@ /// behavior. This trait in principle could be implemented as just: /// /// ``` -/// pub unsafe trait Zeroable { +/// pub unsafe trait Zeroable: Default { /// const ZERO: Self = unsafe { ::core::mem::MaybeUninit::::zeroed().assume_init() }; /// } /// ``` From patchwork Thu Feb 13 16:00:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 13973531 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 76458C021A4 for ; Thu, 13 Feb 2025 16:03:25 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tibfe-0001SK-TV; Thu, 13 Feb 2025 11:02:35 -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 1tibfU-00019R-Bl for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:27 -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 1tibfR-0005ga-5E for qemu-devel@nongnu.org; Thu, 13 Feb 2025 11:02:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739462540; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=kAa0SpJOhaviYKcQwZDtYWFA+1EBiCd0TLgglhF27bI=; b=fJxDxCMwUo+vESqIeRd3oiOI9dr45hC/9/oOL35EN+Y1KhY10mXp0H5F7fRcp6XdfvvGfL PRnupgglG21tlvePBtEs3rDjP3CKi2BfkVXWerps0cj4dsJ57GRiNynihy0Wn1DCR4mweN M1yBRKijbo66+jGi9EBlkBWeBBnoOJA= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-207-Y4heQnClOlG8JmTaVcZQrQ-1; Thu, 13 Feb 2025 11:02:18 -0500 X-MC-Unique: Y4heQnClOlG8JmTaVcZQrQ-1 X-Mimecast-MFC-AGG-ID: Y4heQnClOlG8JmTaVcZQrQ_1739462538 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-38dd533dae6so476084f8f.2 for ; Thu, 13 Feb 2025 08:02:18 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739462537; x=1740067337; 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=kAa0SpJOhaviYKcQwZDtYWFA+1EBiCd0TLgglhF27bI=; b=u+VORsuWz23HXTy4LwKjrJPYQBTpDPgx3TP1ACSQy0GB8wzNpbuZCAYtnlRcS8XW7Z QnP1N0MFurTWBNi5t6rJfSF0n5YbkLXJitU38GQGLCRXqIKPrJtVCtBOdEdQIChs5kMM oK+idBA1GsKkWrVYCJvzzGUI8GmHkK6BaiCaP6xO4YZ0bpDRVdR5nC2c5CT14vgyZz8X kWXuX2H3/96eOAwM/wL4SvjCJRC51q1lTJZhMAhdU/wwaufl81kN4HdB6Eo/tT4d2Wwb cjTe0/Yo5604lzx7OLthWYHQoEAwlL2CnKz8D9/WVp1FYecFE9wxDIF1jluNthXN0bKd DxLA== X-Gm-Message-State: AOJu0YyebYFHJBOVCLoGIiakMC02Rlw5zKeiMb77EtNLixV3pNBD4N1F Y9rMrPglS/qnCQrL4AX5bhkE73KiYg2UO93M4MchCchMYKfnuT7JYy0LqXuagVZvWsyWsWNd+PN dR2RYwFSGkh+l4nSD+grOTT1Huq3SU06mESF35+JWdjqWp+ssYeVug0Ljrk4nvs7lD+JM7opLjE RpSGEIbHjjCNIGjyME2gO7auywwQhpWraGXrT4SEk= X-Gm-Gg: ASbGncv78HtK7dqkqNGB+miA9mO3oQj2Vr/X13qcQw1swu/M35W8aBkaOqZcJ/Bp1Q5 FJCmY1vSDJhOrDdrH5J4RPC8Y3xhd1aBWuyGnmA30jeclHLqaXCd8hjlOe93rT2DedAo0x1a+Hi ysAOYJgjbQTdWiSsb7uMaX7fMSTbV8hgm3yRU1IDXaYlzChe/ConhK9y5Zgu0sF19P6cLE3Aoj4 3DI+QlwH7sS+VrrKEISTJRva8H3qWykv1j+6/zdtLi23EQDHWNMPDuevpNdmLgbAYUOa6jwk+lw 7oz4/UknaRTvXXaUXAP3dQcQ12CeNRqQF9a9MvxeDSSGRQ== X-Received: by 2002:a5d:5f55:0:b0:38d:b0fe:8c99 with SMTP id ffacd0b85a97d-38dea2ebbd1mr8558459f8f.48.1739462535699; Thu, 13 Feb 2025 08:02:15 -0800 (PST) X-Google-Smtp-Source: AGHT+IH05DZOGx7lO/0Wri7A8Tlyc31kB2zVkd29y1pQEpDWm9DlXIKKsWEZCIbncTUQp/sjVPKzQA== X-Received: by 2002:a5d:5f55:0:b0:38d:b0fe:8c99 with SMTP id ffacd0b85a97d-38dea2ebbd1mr8558151f8f.48.1739462533427; Thu, 13 Feb 2025 08:02:13 -0800 (PST) Received: from [192.168.126.123] (93-38-211-213.ip72.fastwebnet.it. [93.38.211.213]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259d8dd6sm2270907f8f.62.2025.02.13.08.02.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 08:02:11 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: =?utf-8?q?Volker_R=C3=BCmelin?= Subject: [PULL 27/27] ui/sdl2: reenable the SDL2 Windows keyboard hook procedure Date: Thu, 13 Feb 2025 17:00:54 +0100 Message-ID: <20250213160054.3937012-28-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250213160054.3937012-1-pbonzini@redhat.com> References: <20250213160054.3937012-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: -35 X-Spam_score: -3.6 X-Spam_bar: --- X-Spam_report: (-3.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.495, 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 From: Volker RĂ¼melin Windows only: The libSDL2 Windows message loop needs the libSDL2 Windows low level keyboard hook procedure to grab the left and right Windows keys correctly. Reenable the SDL2 Windows keyboard hook procedure. Since SDL2 2.30.4 the SDL2 keyboard hook procedure also filters out the special left Control key event for every Alt Gr key event on keyboards with an international layout. This means the QEMU low level keyboard hook procedure is no longer needed. Remove the QEMU Windows keyboard hook procedure. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2139 Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2323 Signed-off-by: Volker RĂ¼melin Link: https://lore.kernel.org/r/20241231115950.6732-1-vr_qemu@t-online.de Signed-off-by: Paolo Bonzini --- ui/sdl2.c | 26 -------------------------- ui/meson.build | 4 ---- 2 files changed, 30 deletions(-) diff --git a/ui/sdl2.c b/ui/sdl2.c index 445eb1dd9f9..cda4293a53e 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -32,7 +32,6 @@ #include "system/runstate.h" #include "system/runstate-action.h" #include "system/system.h" -#include "ui/win32-kbd-hook.h" #include "qemu/log.h" #include "qemu-main.h" @@ -263,7 +262,6 @@ static void sdl_grab_start(struct sdl2_console *scon) } SDL_SetWindowGrab(scon->real_window, SDL_TRUE); gui_grab = 1; - win32_kbd_set_grab(true); sdl_update_caption(scon); } @@ -271,7 +269,6 @@ static void sdl_grab_end(struct sdl2_console *scon) { SDL_SetWindowGrab(scon->real_window, SDL_FALSE); gui_grab = 0; - win32_kbd_set_grab(false); sdl_show_cursor(scon); sdl_update_caption(scon); } @@ -372,19 +369,6 @@ static int get_mod_state(void) } } -static void *sdl2_win32_get_hwnd(struct sdl2_console *scon) -{ -#ifdef CONFIG_WIN32 - SDL_SysWMinfo info; - - SDL_VERSION(&info.version); - if (SDL_GetWindowWMInfo(scon->real_window, &info)) { - return info.info.win.window; - } -#endif - return NULL; -} - static void handle_keydown(SDL_Event *ev) { int win; @@ -609,10 +593,6 @@ static void handle_windowevent(SDL_Event *ev) sdl2_redraw(scon); break; case SDL_WINDOWEVENT_FOCUS_GAINED: - win32_kbd_set_grab(gui_grab); - if (qemu_console_is_graphic(scon->dcl.con)) { - win32_kbd_set_window(sdl2_win32_get_hwnd(scon)); - } /* fall through */ case SDL_WINDOWEVENT_ENTER: if (!gui_grab && (qemu_input_is_absolute(scon->dcl.con) || absolute_enabled)) { @@ -628,9 +608,6 @@ static void handle_windowevent(SDL_Event *ev) scon->ignore_hotkeys = get_mod_state(); break; case SDL_WINDOWEVENT_FOCUS_LOST: - if (qemu_console_is_graphic(scon->dcl.con)) { - win32_kbd_set_window(NULL); - } if (gui_grab && !gui_fullscreen) { sdl_grab_end(scon); } @@ -870,10 +847,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o) #ifdef SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR /* only available since SDL 2.0.8 */ SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0"); #endif -#ifndef CONFIG_WIN32 - /* QEMU uses its own low level keyboard hook procedure on Windows */ SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "1"); -#endif #ifdef SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED SDL_SetHint(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, "0"); #endif diff --git a/ui/meson.build b/ui/meson.build index 28c7381dd10..35fb04cadf3 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -120,10 +120,6 @@ if gtk.found() endif if sdl.found() - if host_os == 'windows' - system_ss.add(files('win32-kbd-hook.c')) - endif - sdl_ss = ss.source_set() sdl_ss.add(sdl, sdl_image, pixman, glib, files( 'sdl2-2d.c',