summary refs log tree commit diff stats
path: root/rust/hw/core/src/qdev.rs
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2025-09-24 12:04:18 -0700
committerRichard Henderson <richard.henderson@linaro.org>2025-09-24 12:04:18 -0700
commit95b9e0d2ade5d633fd13ffba96a54e87c65baf39 (patch)
treef94d1493977dc2457608abeab74c549da6b01a06 /rust/hw/core/src/qdev.rs
parent687a9b83833cda591a04f997a5260f85bd0c5e44 (diff)
parentcd64320e1e27168d3796a847bbfde66c8b1116f9 (diff)
downloadfocaccia-qemu-95b9e0d2ade5d633fd13ffba96a54e87c65baf39.tar.gz
focaccia-qemu-95b9e0d2ade5d633fd13ffba96a54e87c65baf39.zip
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging
* qom: Do not unparent in instance_finalize
* linux-user: avoid -Werror=int-in-bool-context
* docs: use the pyvenv version of Meson
* rust: parse attributes using the attrs crate
* rust: complete conversion of qdev properties to proc macro
* docs: clarify AI-generated content policy

# -----BEGIN PGP SIGNATURE-----
#
# iQFIBAABCgAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmjTnTgUHHBib256aW5p
# QHJlZGhhdC5jb20ACgkQv/vSX3jHroNYUwf9EpJbiCN8Qif9JU3XQEaOMDGTDO07
# nMvn6RnRTFyn4iYzCc+pn6GFKWfJGZ6/cD9Qby7lyi3lHlhW8fLYbAcTXn1HoLNk
# lr/Ibmyaa8U2WP5u/QG+3dwn9zTgNFza3BFLguKrOhWjbv3ZL85xez29yChGgtYq
# sTUTigtl261JF4SvtOhzCMqUPo4wzqD0m0Vc/pjxrlgpHAb3rKf32Y6xPkNMVN84
# 81egbF0ZRtUbubjvGzPFstMdRcVBdrac5wnFPWum9GazuWwB4K8p2iBFdmuXMOhy
# NW6M8HP516zhoNk7bA5zQghxmhPWLXah4iA7MflAzLTI30s23TNIMCeJRw==
# =ug+J
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 24 Sep 2025 12:26:48 AM PDT
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [unknown]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [unknown]
# gpg: WARNING: The key's User ID is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* tag 'for-upstream' of https://gitlab.com/bonzini/qemu: (29 commits)
  docs/code-provenance: AI exceptions are in addition to DCO
  docs/code-provenance: make the exception process more prominent
  docs/code-provenance: clarify scope very early
  hw/xen: Do not unparent in instance_finalize()
  vfio: Do not unparent in instance_finalize()
  hw/sd/sdhci: Do not unparent in instance_finalize()
  hv-balloon: hw/core/register: Do not unparent in instance_finalize()
  hw/core/register: Do not unparent in instance_finalize()
  vfio/pci: Do not unparent in instance_finalize()
  docs/devel: Do not unparent in instance_finalize()
  linux-user: avoid -Werror=int-in-bool-context
  rust/qdev: Drop declare_properties & define_property macros
  rust/hpet: Convert qdev properties to #property macro
  rust/hpet: Clean up type mismatch for num_timers property
  rust/qdev: Test bit property for #property
  rust/qdev: Support bit property in #property macro
  rust/qdev: Support property info for more common types
  rust/qdev: Refine the documentation for QDevProp trait
  rust/qdev: use addr_of! in QDevProp
  rust/common/uninit: Fix Clippy's complaints about lifetime
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'rust/hw/core/src/qdev.rs')
-rw-r--r--rust/hw/core/src/qdev.rs105
1 files changed, 34 insertions, 71 deletions
diff --git a/rust/hw/core/src/qdev.rs b/rust/hw/core/src/qdev.rs
index 71b9ef141c..a4493dbf01 100644
--- a/rust/hw/core/src/qdev.rs
+++ b/rust/hw/core/src/qdev.rs
@@ -6,7 +6,7 @@
 
 use std::{
     ffi::{c_int, c_void, CStr, CString},
-    ptr::NonNull,
+    ptr::{addr_of, NonNull},
 };
 
 use chardev::Chardev;
@@ -109,9 +109,16 @@ unsafe extern "C" fn rust_resettable_exit_fn<T: ResettablePhasesImpl>(
 ///
 /// # Safety
 ///
-/// This trait is marked as `unsafe` because currently having a `const` refer to
-/// an `extern static` as a reference instead of a raw pointer results in this
-/// compiler error:
+/// This trait is marked as `unsafe` because `BASE_INFO` and `BIT_INFO` must be
+/// valid raw references to [`bindings::PropertyInfo`].
+///
+/// Note we could not use a regular reference:
+///
+/// ```text
+/// const VALUE: &bindings::PropertyInfo = ...
+/// ```
+///
+/// because this results in the following compiler error:
 ///
 /// ```text
 /// constructing invalid value: encountered reference to `extern` static in `const`
@@ -119,28 +126,37 @@ unsafe extern "C" fn rust_resettable_exit_fn<T: ResettablePhasesImpl>(
 ///
 /// This is because the compiler generally might dereference a normal reference
 /// during const evaluation, but not in this case (if it did, it'd need to
-/// dereference the raw pointer so this would fail to compile).
+/// dereference the raw pointer so using a `*const` would also fail to compile).
 ///
 /// It is the implementer's responsibility to provide a valid
 /// [`bindings::PropertyInfo`] pointer for the trait implementation to be safe.
 pub unsafe trait QDevProp {
-    const VALUE: *const bindings::PropertyInfo;
-}
-
-/// Use [`bindings::qdev_prop_bool`] for `bool`.
-unsafe impl QDevProp for bool {
-    const VALUE: *const bindings::PropertyInfo = unsafe { &bindings::qdev_prop_bool };
+    const BASE_INFO: *const bindings::PropertyInfo;
+    const BIT_INFO: *const bindings::PropertyInfo = {
+        panic!("invalid type for bit property");
+    };
 }
 
-/// Use [`bindings::qdev_prop_uint64`] for `u64`.
-unsafe impl QDevProp for u64 {
-    const VALUE: *const bindings::PropertyInfo = unsafe { &bindings::qdev_prop_uint64 };
+macro_rules! impl_qdev_prop {
+    ($type:ty,$info:ident$(, $bit_info:ident)?) => {
+        unsafe impl $crate::qdev::QDevProp for $type {
+            const BASE_INFO: *const $crate::bindings::PropertyInfo =
+                addr_of!($crate::bindings::$info);
+            $(const BIT_INFO: *const $crate::bindings::PropertyInfo =
+                addr_of!($crate::bindings::$bit_info);)?
+        }
+    };
 }
 
-/// Use [`bindings::qdev_prop_chr`] for [`chardev::CharBackend`].
-unsafe impl QDevProp for chardev::CharBackend {
-    const VALUE: *const bindings::PropertyInfo = unsafe { &bindings::qdev_prop_chr };
-}
+impl_qdev_prop!(bool, qdev_prop_bool);
+impl_qdev_prop!(u8, qdev_prop_uint8);
+impl_qdev_prop!(u16, qdev_prop_uint16);
+impl_qdev_prop!(u32, qdev_prop_uint32, qdev_prop_bit);
+impl_qdev_prop!(u64, qdev_prop_uint64, qdev_prop_bit64);
+impl_qdev_prop!(usize, qdev_prop_usize);
+impl_qdev_prop!(i32, qdev_prop_int32);
+impl_qdev_prop!(i64, qdev_prop_int64);
+impl_qdev_prop!(chardev::CharBackend, qdev_prop_chr);
 
 /// Trait to define device properties.
 ///
@@ -232,59 +248,6 @@ impl 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: ::std::mem::offset_of!($state, $field) as isize,
-            bitnr: $bitnr,
-            set_default: true,
-            defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval as u64 },
-            ..::common::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
-            name: ::std::ffi::CStr::as_ptr($name),
-            info: $prop,
-            offset: ::std::mem::offset_of!($state, $field) as isize,
-            set_default: true,
-            defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval as u64 },
-            ..::common::zeroable::Zeroable::ZERO
-        }
-    };
-    ($name:expr, $state:ty, $field:ident, $prop:expr, $type:ty$(,)*) => {
-        $crate::bindings::Property {
-            // use associated function syntax for type checking
-            name: ::std::ffi::CStr::as_ptr($name),
-            info: $prop,
-            offset: ::std::mem::offset_of!($state, $field) as isize,
-            set_default: false,
-            ..::common::zeroable::Zeroable::ZERO
-        }
-    };
-}
-
-#[macro_export]
-macro_rules! declare_properties {
-    ($ident:ident, $($prop:expr),*$(,)*) => {
-        pub static $ident: [$crate::bindings::Property; {
-            let mut len = 0;
-            $({
-                _ = stringify!($prop);
-                len += 1;
-            })*
-            len
-        }] = [
-            $($prop),*,
-        ];
-    };
-}
-
 unsafe impl ObjectType for DeviceState {
     type Class = DeviceClass;
     const TYPE_NAME: &'static CStr =