* [PATCH 00/13] rust: miscellaneous cleanups + QOM integration tests
@ 2024-10-18 14:42 Paolo Bonzini
2024-10-18 14:42 ` [PATCH 01/13] meson: import rust module into a global variable Paolo Bonzini
` (12 more replies)
0 siblings, 13 replies; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-18 14:42 UTC (permalink / raw)
To: qemu-devel; +Cc: Manos Pitsidianakis, Junjie Mao
This series integrates some of the observations from the MSRV patches at
https://lore.kernel.org/qemu-devel/20241015131735.518771-1-pbonzini@redhat.com/.
The main changes here are two: first, build an integration test that
actually tries to create a QOM object that is defined by Rust code;
second, make the properties array immutable so that declare_properties!
is enforced to use only const-friendly constructs. These are patches
6-11; the others consist of small cleanups.
Hidden in here is actually a C patch (#10) which makes the
bindgen-generated prototypes use "*const" instead of "*mut".
Tested with Rust nightly and (together with more patches from the
RFC), with Rust 1.63.0.
Unlike the MSRV patches, this should be ready for inclusion; the
changes should be mostly uncontroversial.
Paolo
Based-on: <20241018143334.949045-1-pbonzini@redhat.com>
Paolo Bonzini (13):
meson: import rust module into a global variable
meson: remove repeated search for rust_root_crate.sh
meson: pass rustc_args when building all crates
rust: do not use --no-size_t-is-usize
rust: remove uses of #[no_mangle]
rust: remove unused macro module_init!
rust: modernize #[derive(Object)] for ELF platforms
rust: build integration test for the qemu_api crate
rust: clean up define_property macro
qdev: make properties array "const"
rust: make properties array immutable
rust: provide safe wrapper for MaybeUninit::zeroed()
rust: do not use TYPE_CHARDEV unnecessarily
meson.build | 31 +++++++---
include/hw/qdev-core.h | 4 +-
include/hw/qdev-properties.h | 4 +-
hw/core/qdev-properties.c | 26 ++++----
system/qdev-monitor.c | 2 +-
rust/hw/char/pl011/src/device.rs | 7 +--
rust/hw/char/pl011/src/device_class.rs | 10 ++--
rust/hw/char/pl011/src/memory_ops.rs | 13 ++--
rust/qemu-api-macros/meson.build | 2 +-
rust/qemu-api-macros/src/lib.rs | 4 +-
rust/qemu-api/meson.build | 23 +++++--
rust/qemu-api/src/definitions.rs | 50 +---------------
rust/qemu-api/src/device_class.rs | 83 +++++++-------------------
rust/qemu-api/src/lib.rs | 1 +
rust/qemu-api/src/tests.rs | 49 ---------------
rust/qemu-api/src/zeroable.rs | 23 +++++++
rust/qemu-api/tests/tests.rs | 78 ++++++++++++++++++++++++
17 files changed, 201 insertions(+), 209 deletions(-)
delete mode 100644 rust/qemu-api/src/tests.rs
create mode 100644 rust/qemu-api/src/zeroable.rs
create mode 100644 rust/qemu-api/tests/tests.rs
--
2.46.2
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 01/13] meson: import rust module into a global variable
2024-10-18 14:42 [PATCH 00/13] rust: miscellaneous cleanups + QOM integration tests Paolo Bonzini
@ 2024-10-18 14:42 ` Paolo Bonzini
2024-10-18 14:42 ` [PATCH 02/13] meson: remove repeated search for rust_root_crate.sh Paolo Bonzini
` (11 subsequent siblings)
12 siblings, 0 replies; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-18 14:42 UTC (permalink / raw)
To: qemu-devel; +Cc: Manos Pitsidianakis, Junjie Mao
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
meson.build | 1 +
rust/qemu-api-macros/meson.build | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/meson.build b/meson.build
index d26690ce204..ffd78b6cbb3 100644
--- a/meson.build
+++ b/meson.build
@@ -15,6 +15,7 @@ meson.add_postconf_script(find_program('scripts/symlink-install-tree.py'))
not_found = dependency('', required: false)
keyval = import('keyval')
+rust = import('rust')
ss = import('sourceset')
fs = import('fs')
diff --git a/rust/qemu-api-macros/meson.build b/rust/qemu-api-macros/meson.build
index 517b9a4d2d5..24325dea5c2 100644
--- a/rust/qemu-api-macros/meson.build
+++ b/rust/qemu-api-macros/meson.build
@@ -2,7 +2,7 @@ quote_dep = dependency('quote-1-rs', native: true)
syn_dep = dependency('syn-2-rs', native: true)
proc_macro2_dep = dependency('proc-macro2-1-rs', native: true)
-_qemu_api_macros_rs = import('rust').proc_macro(
+_qemu_api_macros_rs = rust.proc_macro(
'qemu_api_macros',
files('src/lib.rs'),
override_options: ['rust_std=2021', 'build.rust_std=2021'],
--
2.46.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 02/13] meson: remove repeated search for rust_root_crate.sh
2024-10-18 14:42 [PATCH 00/13] rust: miscellaneous cleanups + QOM integration tests Paolo Bonzini
2024-10-18 14:42 ` [PATCH 01/13] meson: import rust module into a global variable Paolo Bonzini
@ 2024-10-18 14:42 ` Paolo Bonzini
2024-10-18 14:42 ` [PATCH 03/13] meson: pass rustc_args when building all crates Paolo Bonzini
` (10 subsequent siblings)
12 siblings, 0 replies; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-18 14:42 UTC (permalink / raw)
To: qemu-devel; +Cc: Manos Pitsidianakis, Junjie Mao
Avoid repeated lines of the form
Program scripts/rust/rust_root_crate.sh found: YES (/home/pbonzini/work/upstream/qemu/scripts/rust/rust_root_crate.sh)
in the meson logs.
Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
meson.build | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/meson.build b/meson.build
index ffd78b6cbb3..f85bc22fbdd 100644
--- a/meson.build
+++ b/meson.build
@@ -3977,6 +3977,7 @@ endif
feature_to_c = find_program('scripts/feature_to_c.py')
+rust_root_crate = find_program('scripts/rust/rust_root_crate.sh')
if host_os == 'darwin'
entitlement = find_program('scripts/entitlement.sh')
@@ -4078,7 +4079,7 @@ foreach target : target_dirs
if crates.length() > 0
rlib_rs = custom_target('rust_' + target.underscorify() + '.rs',
output: 'rust_' + target.underscorify() + '.rs',
- command: [find_program('scripts/rust/rust_root_crate.sh')] + crates,
+ command: [rust_root_crate, crates],
capture: true,
build_by_default: true,
build_always_stale: true)
--
2.46.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 03/13] meson: pass rustc_args when building all crates
2024-10-18 14:42 [PATCH 00/13] rust: miscellaneous cleanups + QOM integration tests Paolo Bonzini
2024-10-18 14:42 ` [PATCH 01/13] meson: import rust module into a global variable Paolo Bonzini
2024-10-18 14:42 ` [PATCH 02/13] meson: remove repeated search for rust_root_crate.sh Paolo Bonzini
@ 2024-10-18 14:42 ` Paolo Bonzini
2024-10-18 14:42 ` [PATCH 04/13] rust: do not use --no-size_t-is-usize Paolo Bonzini
` (9 subsequent siblings)
12 siblings, 0 replies; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-18 14:42 UTC (permalink / raw)
To: qemu-devel; +Cc: Manos Pitsidianakis, Junjie Mao
rustc_args is needed to smooth the difference in warnings between the various
versions of rustc. Always include those arguments.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
meson.build | 18 +++++++++++-------
rust/qemu-api/meson.build | 2 +-
rust/qemu-api/src/device_class.rs | 10 ++++++----
3 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/meson.build b/meson.build
index f85bc22fbdd..44f3bf34931 100644
--- a/meson.build
+++ b/meson.build
@@ -3317,6 +3317,17 @@ endif
genh += configure_file(output: 'config-host.h', configuration: config_host_data)
+if have_rust and have_system
+ rustc_args = run_command(
+ find_program('scripts/rust/rustc_args.py'),
+ '--config-headers', meson.project_build_root() / 'config-host.h',
+ capture : true,
+ check: true).stdout().strip().split()
+ rustc_args += ['-D', 'unsafe_op_in_unsafe_fn']
+ add_project_arguments(rustc_args, native: false, language: 'rust')
+ add_project_arguments(rustc_args, native: true, language: 'rust')
+endif
+
hxtool = find_program('scripts/hxtool')
shaderinclude = find_program('scripts/shaderinclude.py')
qapi_gen = find_program('scripts/qapi-gen.py')
@@ -3909,12 +3920,6 @@ common_all = static_library('common',
dependencies: common_ss.all_dependencies())
if have_rust and have_system
- rustc_args = run_command(
- find_program('scripts/rust/rustc_args.py'),
- '--config-headers', meson.project_build_root() / 'config-host.h',
- capture : true,
- check: true).stdout().strip().split()
- rustc_args += ['-D', 'unsafe_op_in_unsafe_fn']
bindgen_args = [
'--disable-header-comment',
'--raw-line', '// @generated',
@@ -4087,7 +4092,6 @@ foreach target : target_dirs
rlib_rs,
dependencies: target_rust.dependencies(),
override_options: ['rust_std=2021', 'build.rust_std=2021'],
- rust_args: rustc_args,
rust_abi: 'c')
arch_deps += declare_dependency(link_whole: [rlib])
endif
diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build
index c72d34b607d..42ea815fa5a 100644
--- a/rust/qemu-api/meson.build
+++ b/rust/qemu-api/meson.build
@@ -10,7 +10,7 @@ _qemu_api_rs = static_library(
),
override_options: ['rust_std=2021', 'build.rust_std=2021'],
rust_abi: 'rust',
- rust_args: rustc_args + [
+ rust_args: [
'--cfg', 'MESON',
# '--cfg', 'feature="allocator"',
],
diff --git a/rust/qemu-api/src/device_class.rs b/rust/qemu-api/src/device_class.rs
index 1ea95beb78d..b6b68cf9ce2 100644
--- a/rust/qemu-api/src/device_class.rs
+++ b/rust/qemu-api/src/device_class.rs
@@ -16,10 +16,12 @@ macro_rules! device_class_init {
) {
let mut dc =
::core::ptr::NonNull::new(klass.cast::<$crate::bindings::DeviceClass>()).unwrap();
- dc.as_mut().realize = $realize_fn;
- dc.as_mut().vmsd = &$vmsd;
- $crate::bindings::device_class_set_legacy_reset(dc.as_mut(), $legacy_reset_fn);
- $crate::bindings::device_class_set_props(dc.as_mut(), $props.as_mut_ptr());
+ unsafe {
+ dc.as_mut().realize = $realize_fn;
+ dc.as_mut().vmsd = &$vmsd;
+ $crate::bindings::device_class_set_legacy_reset(dc.as_mut(), $legacy_reset_fn);
+ $crate::bindings::device_class_set_props(dc.as_mut(), $props.as_mut_ptr());
+ }
}
};
}
--
2.46.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 04/13] rust: do not use --no-size_t-is-usize
2024-10-18 14:42 [PATCH 00/13] rust: miscellaneous cleanups + QOM integration tests Paolo Bonzini
` (2 preceding siblings ...)
2024-10-18 14:42 ` [PATCH 03/13] meson: pass rustc_args when building all crates Paolo Bonzini
@ 2024-10-18 14:42 ` Paolo Bonzini
2024-10-18 14:42 ` [PATCH 05/13] rust: remove uses of #[no_mangle] Paolo Bonzini
` (8 subsequent siblings)
12 siblings, 0 replies; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-18 14:42 UTC (permalink / raw)
To: qemu-devel; +Cc: Manos Pitsidianakis, Junjie Mao
This not necessary and makes it harder to write code that
is portable between 32- and 64-bit systems: it adds extra casts even
though size_of, align_of or offset_of already return the right type.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
meson.build | 1 -
rust/qemu-api/src/definitions.rs | 6 +++---
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/meson.build b/meson.build
index 44f3bf34931..48f82fd4ba6 100644
--- a/meson.build
+++ b/meson.build
@@ -3932,7 +3932,6 @@ if have_rust and have_system
'--no-doc-comments',
'--use-core',
'--with-derive-default',
- '--no-size_t-is-usize',
'--no-layout-tests',
'--no-prepend-enum-name',
'--allowlist-file', meson.project_source_root() + '/include/.*',
diff --git a/rust/qemu-api/src/definitions.rs b/rust/qemu-api/src/definitions.rs
index 60bd3f8aaa6..0b681c593f2 100644
--- a/rust/qemu-api/src/definitions.rs
+++ b/rust/qemu-api/src/definitions.rs
@@ -81,13 +81,13 @@ macro_rules! type_info {
} else {
::core::ptr::null_mut()
},
- instance_size: ::core::mem::size_of::<$t>() as $crate::bindings::size_t,
- instance_align: ::core::mem::align_of::<$t>() as $crate::bindings::size_t,
+ instance_size: ::core::mem::size_of::<$t>(),
+ instance_align: ::core::mem::align_of::<$t>(),
instance_init: <$t as $crate::definitions::ObjectImpl>::INSTANCE_INIT,
instance_post_init: <$t as $crate::definitions::ObjectImpl>::INSTANCE_POST_INIT,
instance_finalize: <$t as $crate::definitions::ObjectImpl>::INSTANCE_FINALIZE,
abstract_: <$t as $crate::definitions::ObjectImpl>::ABSTRACT,
- class_size: ::core::mem::size_of::<<$t as $crate::definitions::ObjectImpl>::Class>() as $crate::bindings::size_t,
+ class_size: ::core::mem::size_of::<<$t as $crate::definitions::ObjectImpl>::Class>(),
class_init: <<$t as $crate::definitions::ObjectImpl>::Class as $crate::definitions::Class>::CLASS_INIT,
class_base_init: <<$t as $crate::definitions::ObjectImpl>::Class as $crate::definitions::Class>::CLASS_BASE_INIT,
class_data: ::core::ptr::null_mut(),
--
2.46.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 05/13] rust: remove uses of #[no_mangle]
2024-10-18 14:42 [PATCH 00/13] rust: miscellaneous cleanups + QOM integration tests Paolo Bonzini
` (3 preceding siblings ...)
2024-10-18 14:42 ` [PATCH 04/13] rust: do not use --no-size_t-is-usize Paolo Bonzini
@ 2024-10-18 14:42 ` Paolo Bonzini
2024-10-21 10:07 ` Junjie Mao
2024-10-18 14:42 ` [PATCH 06/13] rust: remove unused macro module_init! Paolo Bonzini
` (7 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-18 14:42 UTC (permalink / raw)
To: qemu-devel; +Cc: Manos Pitsidianakis, Junjie Mao
Mangled symbols do not cause any issue; disabling mangling is only useful if
C headers reference the Rust function, which is not the case here.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
rust/hw/char/pl011/src/device.rs | 5 -----
rust/hw/char/pl011/src/device_class.rs | 2 --
rust/hw/char/pl011/src/memory_ops.rs | 2 --
rust/qemu-api/src/definitions.rs | 1 -
rust/qemu-api/src/device_class.rs | 2 --
5 files changed, 12 deletions(-)
diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs
index c7193b41bee..2b43f5e0939 100644
--- a/rust/hw/char/pl011/src/device.rs
+++ b/rust/hw/char/pl011/src/device.rs
@@ -514,7 +514,6 @@ pub fn update(&self) {
/// We expect the FFI user of this function to pass a valid pointer, that has
/// the same size as [`PL011State`]. We also expect the device is
/// readable/writeable from one thread at any time.
-#[no_mangle]
pub unsafe extern "C" fn pl011_can_receive(opaque: *mut c_void) -> c_int {
unsafe {
debug_assert!(!opaque.is_null());
@@ -530,7 +529,6 @@ pub fn update(&self) {
/// readable/writeable from one thread at any time.
///
/// The buffer and size arguments must also be valid.
-#[no_mangle]
pub unsafe extern "C" fn pl011_receive(
opaque: *mut core::ffi::c_void,
buf: *const u8,
@@ -554,7 +552,6 @@ pub fn update(&self) {
/// We expect the FFI user of this function to pass a valid pointer, that has
/// the same size as [`PL011State`]. We also expect the device is
/// readable/writeable from one thread at any time.
-#[no_mangle]
pub unsafe extern "C" fn pl011_event(opaque: *mut core::ffi::c_void, event: QEMUChrEvent) {
unsafe {
debug_assert!(!opaque.is_null());
@@ -566,7 +563,6 @@ pub fn update(&self) {
/// # Safety
///
/// We expect the FFI user of this function to pass a valid pointer for `chr`.
-#[no_mangle]
pub unsafe extern "C" fn pl011_create(
addr: u64,
irq: qemu_irq,
@@ -589,7 +585,6 @@ pub fn update(&self) {
/// We expect the FFI user of this function to pass a valid pointer, that has
/// the same size as [`PL011State`]. We also expect the device is
/// readable/writeable from one thread at any time.
-#[no_mangle]
pub unsafe extern "C" fn pl011_init(obj: *mut Object) {
unsafe {
debug_assert!(!obj.is_null());
diff --git a/rust/hw/char/pl011/src/device_class.rs b/rust/hw/char/pl011/src/device_class.rs
index b7ab31af02d..2ad80451e87 100644
--- a/rust/hw/char/pl011/src/device_class.rs
+++ b/rust/hw/char/pl011/src/device_class.rs
@@ -46,7 +46,6 @@
/// We expect the FFI user of this function to pass a valid pointer, that has
/// the same size as [`PL011State`]. We also expect the device is
/// readable/writeable from one thread at any time.
-#[no_mangle]
pub unsafe extern "C" fn pl011_realize(dev: *mut DeviceState, _errp: *mut *mut Error) {
unsafe {
assert!(!dev.is_null());
@@ -60,7 +59,6 @@
/// We expect the FFI user of this function to pass a valid pointer, that has
/// the same size as [`PL011State`]. We also expect the device is
/// readable/writeable from one thread at any time.
-#[no_mangle]
pub unsafe extern "C" fn pl011_reset(dev: *mut DeviceState) {
unsafe {
assert!(!dev.is_null());
diff --git a/rust/hw/char/pl011/src/memory_ops.rs b/rust/hw/char/pl011/src/memory_ops.rs
index 8d066ebf6d0..5a5320e66c3 100644
--- a/rust/hw/char/pl011/src/memory_ops.rs
+++ b/rust/hw/char/pl011/src/memory_ops.rs
@@ -22,7 +22,6 @@
},
};
-#[no_mangle]
unsafe extern "C" fn pl011_read(
opaque: *mut core::ffi::c_void,
addr: hwaddr,
@@ -44,7 +43,6 @@
}
}
-#[no_mangle]
unsafe extern "C" fn pl011_write(
opaque: *mut core::ffi::c_void,
addr: hwaddr,
diff --git a/rust/qemu-api/src/definitions.rs b/rust/qemu-api/src/definitions.rs
index 0b681c593f2..49ac59af123 100644
--- a/rust/qemu-api/src/definitions.rs
+++ b/rust/qemu-api/src/definitions.rs
@@ -53,7 +53,6 @@ extern "C" fn __load() {
#[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
pub static LOAD_MODULE: extern "C" fn() = {
extern "C" fn __load() {
- #[no_mangle]
unsafe extern "C" fn $func() {
$body
}
diff --git a/rust/qemu-api/src/device_class.rs b/rust/qemu-api/src/device_class.rs
index b6b68cf9ce2..2219b9f73d0 100644
--- a/rust/qemu-api/src/device_class.rs
+++ b/rust/qemu-api/src/device_class.rs
@@ -9,7 +9,6 @@
#[macro_export]
macro_rules! device_class_init {
($func:ident, props => $props:ident, realize_fn => $realize_fn:expr, legacy_reset_fn => $legacy_reset_fn:expr, vmsd => $vmsd:ident$(,)*) => {
- #[no_mangle]
pub unsafe extern "C" fn $func(
klass: *mut $crate::bindings::ObjectClass,
_: *mut ::core::ffi::c_void,
@@ -103,7 +102,6 @@ const fn _calc_prop_len() -> usize {
]
}
- #[no_mangle]
pub static mut $ident: $crate::device_class::Properties<PROP_LEN> = $crate::device_class::Properties(::std::sync::OnceLock::new(), _make_properties);
};
}
--
2.46.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 06/13] rust: remove unused macro module_init!
2024-10-18 14:42 [PATCH 00/13] rust: miscellaneous cleanups + QOM integration tests Paolo Bonzini
` (4 preceding siblings ...)
2024-10-18 14:42 ` [PATCH 05/13] rust: remove uses of #[no_mangle] Paolo Bonzini
@ 2024-10-18 14:42 ` Paolo Bonzini
2024-10-21 10:16 ` Junjie Mao
2024-10-18 14:42 ` [PATCH 07/13] rust: modernize #[derive(Object)] for ELF platforms Paolo Bonzini
` (6 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-18 14:42 UTC (permalink / raw)
To: qemu-devel; +Cc: Manos Pitsidianakis, Junjie Mao
Registering the object is now done by the #[derive(Object)] macro.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
rust/qemu-api/src/definitions.rs | 43 --------------------------------
1 file changed, 43 deletions(-)
diff --git a/rust/qemu-api/src/definitions.rs b/rust/qemu-api/src/definitions.rs
index 49ac59af123..73ef9a52c1b 100644
--- a/rust/qemu-api/src/definitions.rs
+++ b/rust/qemu-api/src/definitions.rs
@@ -27,49 +27,6 @@ pub trait Class {
>;
}
-#[macro_export]
-macro_rules! module_init {
- ($func:expr, $type:expr) => {
- #[used]
- #[cfg_attr(target_os = "linux", link_section = ".ctors")]
- #[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
- #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
- pub static LOAD_MODULE: extern "C" fn() = {
- extern "C" fn __load() {
- unsafe {
- $crate::bindings::register_module_init(Some($func), $type);
- }
- }
-
- __load
- };
- };
- (qom: $func:ident => $body:block) => {
- // NOTE: To have custom identifiers for the ctor func we need to either supply
- // them directly as a macro argument or create them with a proc macro.
- #[used]
- #[cfg_attr(target_os = "linux", link_section = ".ctors")]
- #[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
- #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
- pub static LOAD_MODULE: extern "C" fn() = {
- extern "C" fn __load() {
- unsafe extern "C" fn $func() {
- $body
- }
-
- unsafe {
- $crate::bindings::register_module_init(
- Some($func),
- $crate::bindings::module_init_type::MODULE_INIT_QOM,
- );
- }
- }
-
- __load
- };
- };
-}
-
#[macro_export]
macro_rules! type_info {
($t:ty) => {
--
2.46.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 07/13] rust: modernize #[derive(Object)] for ELF platforms
2024-10-18 14:42 [PATCH 00/13] rust: miscellaneous cleanups + QOM integration tests Paolo Bonzini
` (5 preceding siblings ...)
2024-10-18 14:42 ` [PATCH 06/13] rust: remove unused macro module_init! Paolo Bonzini
@ 2024-10-18 14:42 ` Paolo Bonzini
2024-10-21 10:23 ` Junjie Mao
2024-10-18 14:43 ` [PATCH 08/13] rust: build integration test for the qemu_api crate Paolo Bonzini
` (5 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-18 14:42 UTC (permalink / raw)
To: qemu-devel; +Cc: Manos Pitsidianakis, Junjie Mao
Some newer ABI implementations do not provide .ctors; and while
some linkers rewrite .ctors into .init_array, not all of them do.
Use the newer .init_array ABI, which works more reliably, and
apply it to all non-Apple, non-Windows platforms.
This is similar to how the ctor crate operates; without this change,
"#[derive(Object)]" does not work on Fedora 41.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
rust/qemu-api-macros/src/lib.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/rust/qemu-api-macros/src/lib.rs b/rust/qemu-api-macros/src/lib.rs
index 59aba592d9a..be8874caea1 100644
--- a/rust/qemu-api-macros/src/lib.rs
+++ b/rust/qemu-api-macros/src/lib.rs
@@ -16,8 +16,8 @@ pub fn derive_object(input: TokenStream) -> TokenStream {
let expanded = quote! {
#[allow(non_upper_case_globals)]
#[used]
- #[cfg_attr(target_os = "linux", link_section = ".ctors")]
- #[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
+ #[cfg_attr(not(any(target_vendor = "apple", target_os = "windows")), link_section = ".init_array")]
+ #[cfg_attr(target_vendor = "apple", link_section = "__DATA,__mod_init_func")]
#[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
pub static #module_static: extern "C" fn() = {
extern "C" fn __register() {
--
2.46.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 08/13] rust: build integration test for the qemu_api crate
2024-10-18 14:42 [PATCH 00/13] rust: miscellaneous cleanups + QOM integration tests Paolo Bonzini
` (6 preceding siblings ...)
2024-10-18 14:42 ` [PATCH 07/13] rust: modernize #[derive(Object)] for ELF platforms Paolo Bonzini
@ 2024-10-18 14:43 ` Paolo Bonzini
2024-10-21 10:28 ` Junjie Mao
2024-10-21 11:28 ` Junjie Mao
2024-10-18 14:43 ` [PATCH 09/13] rust: clean up define_property macro Paolo Bonzini
` (4 subsequent siblings)
12 siblings, 2 replies; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-18 14:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Manos Pitsidianakis, Junjie Mao
Adjust the integration test to compile with a subset of QEMU object
files, and make it actually create an object of the class it defines.
Follow the Rust filesystem conventions, where tests go in tests/ if
they use the library in the same way any other code would.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
meson.build | 10 ++++-
rust/qemu-api/meson.build | 20 +++++++--
rust/qemu-api/src/tests.rs | 49 ----------------------
rust/qemu-api/tests/tests.rs | 78 ++++++++++++++++++++++++++++++++++++
4 files changed, 104 insertions(+), 53 deletions(-)
delete mode 100644 rust/qemu-api/src/tests.rs
create mode 100644 rust/qemu-api/tests/tests.rs
diff --git a/meson.build b/meson.build
index 48f82fd4ba6..e50a7edf6ea 100644
--- a/meson.build
+++ b/meson.build
@@ -3324,7 +3324,15 @@ if have_rust and have_system
capture : true,
check: true).stdout().strip().split()
rustc_args += ['-D', 'unsafe_op_in_unsafe_fn']
- add_project_arguments(rustc_args, native: false, language: 'rust')
+
+ # Apart from procedural macros, our Rust executables will often link
+ # with C code, so include all the libraries that C code needs. This
+ # is safe; https://github.com/rust-lang/rust/pull/54675 says that
+ # passing -nodefaultlibs to the linker "was more ideological to
+ # start with than anything".
+ add_project_arguments(rustc_args + ['-C', 'default-linker-libraries'],
+ native: false, language: 'rust')
+
add_project_arguments(rustc_args, native: true, language: 'rust')
endif
diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build
index 42ea815fa5a..d24e0c0725e 100644
--- a/rust/qemu-api/meson.build
+++ b/rust/qemu-api/meson.build
@@ -14,11 +14,25 @@ _qemu_api_rs = static_library(
'--cfg', 'MESON',
# '--cfg', 'feature="allocator"',
],
- dependencies: [
- qemu_api_macros,
- ],
)
qemu_api = declare_dependency(
link_with: _qemu_api_rs,
+ dependencies: qemu_api_macros,
)
+
+# Rust executable do not support objects, so add an intermediate step.
+rust_qemu_api_objs = static_library(
+ 'rust_qemu_api_objs',
+ objects: [libqom.extract_all_objects(recursive: false),
+ libhwcore.extract_all_objects(recursive: false)])
+
+rust.test('rust-qemu-api-integration',
+ static_library(
+ 'rust_qemu_api_integration',
+ 'tests/tests.rs',
+ override_options: ['rust_std=2021', 'build.rust_std=2021'],
+ link_whole: [rust_qemu_api_objs, libqemuutil]),
+
+ dependencies: [qemu_api, qemu_api_macros],
+ suite: ['unit', 'rust'])
diff --git a/rust/qemu-api/src/tests.rs b/rust/qemu-api/src/tests.rs
deleted file mode 100644
index df54edbd4e2..00000000000
--- a/rust/qemu-api/src/tests.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2024, Linaro Limited
-// Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-use crate::{
- bindings::*, declare_properties, define_property, device_class_init, vm_state_description,
-};
-
-#[test]
-fn test_device_decl_macros() {
- // Test that macros can compile.
- vm_state_description! {
- VMSTATE,
- name: c"name",
- unmigratable: true,
- }
-
- #[repr(C)]
- pub struct DummyState {
- pub char_backend: CharBackend,
- pub migrate_clock: bool,
- }
-
- declare_properties! {
- DUMMY_PROPERTIES,
- define_property!(
- c"chardev",
- DummyState,
- char_backend,
- unsafe { &qdev_prop_chr },
- CharBackend
- ),
- define_property!(
- c"migrate-clk",
- DummyState,
- migrate_clock,
- unsafe { &qdev_prop_bool },
- bool
- ),
- }
-
- device_class_init! {
- dummy_class_init,
- props => DUMMY_PROPERTIES,
- realize_fn => None,
- reset_fn => None,
- vmsd => VMSTATE,
- }
-}
diff --git a/rust/qemu-api/tests/tests.rs b/rust/qemu-api/tests/tests.rs
new file mode 100644
index 00000000000..57bab62772d
--- /dev/null
+++ b/rust/qemu-api/tests/tests.rs
@@ -0,0 +1,78 @@
+// Copyright 2024, Linaro Limited
+// Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+use core::ffi::CStr;
+
+use qemu_api::{
+ bindings::*, declare_properties, define_property,
+ definitions::Class,
+ definitions::ObjectImpl,
+ device_class_init, vm_state_description,
+};
+
+#[test]
+fn test_device_decl_macros() {
+ // Test that macros can compile.
+ vm_state_description! {
+ VMSTATE,
+ name: c"name",
+ unmigratable: true,
+ }
+
+ #[repr(C)]
+ #[derive(qemu_api_macros::Object)]
+ pub struct DummyState {
+ pub _parent: DeviceState,
+ pub migrate_clock: bool,
+ }
+
+ #[repr(C)]
+ pub struct DummyClass {
+ pub _parent: DeviceClass,
+ }
+
+ declare_properties! {
+ DUMMY_PROPERTIES,
+ define_property!(
+ c"migrate-clk",
+ DummyState,
+ migrate_clock,
+ unsafe { &qdev_prop_bool },
+ bool
+ ),
+ }
+
+ device_class_init! {
+ dummy_class_init,
+ props => DUMMY_PROPERTIES,
+ realize_fn => None,
+ legacy_reset_fn => None,
+ vmsd => VMSTATE,
+ }
+
+ impl ObjectImpl for DummyState {
+ type Class = DummyClass;
+ const TYPE_INFO: qemu_api::bindings::TypeInfo = qemu_api::type_info! { Self };
+ const TYPE_NAME: &'static CStr = c"dummy";
+ const PARENT_TYPE_NAME: Option<&'static CStr> = Some(TYPE_DEVICE);
+ const ABSTRACT: bool = false;
+ const INSTANCE_INIT: Option<unsafe extern "C" fn(obj: *mut Object)> = None;
+ const INSTANCE_POST_INIT: Option<unsafe extern "C" fn(obj: *mut Object)> = None;
+ const INSTANCE_FINALIZE: Option<unsafe extern "C" fn(obj: *mut Object)> = None;
+ }
+
+ impl Class for DummyClass {
+ const CLASS_INIT: Option<
+ unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut core::ffi::c_void),
+ > = Some(dummy_class_init);
+ const CLASS_BASE_INIT: Option<
+ unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut core::ffi::c_void),
+ > = None;
+ }
+
+ unsafe {
+ module_call_init(module_init_type::MODULE_INIT_QOM);
+ object_unref(object_new(DummyState::TYPE_NAME.as_ptr()) as *mut _);
+ }
+}
--
2.46.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 09/13] rust: clean up define_property macro
2024-10-18 14:42 [PATCH 00/13] rust: miscellaneous cleanups + QOM integration tests Paolo Bonzini
` (7 preceding siblings ...)
2024-10-18 14:43 ` [PATCH 08/13] rust: build integration test for the qemu_api crate Paolo Bonzini
@ 2024-10-18 14:43 ` Paolo Bonzini
2024-10-21 10:35 ` Junjie Mao
2024-10-18 14:43 ` [PATCH 10/13] qdev: make properties array "const" Paolo Bonzini
` (3 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-18 14:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Manos Pitsidianakis, Junjie Mao
Use the "struct update" syntax to initialize most of the fields to zero,
and simplify the handmade type-checking of $name.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
rust/qemu-api/src/device_class.rs | 29 ++++++-----------------------
1 file changed, 6 insertions(+), 23 deletions(-)
diff --git a/rust/qemu-api/src/device_class.rs b/rust/qemu-api/src/device_class.rs
index 2219b9f73d0..5aba426d243 100644
--- a/rust/qemu-api/src/device_class.rs
+++ b/rust/qemu-api/src/device_class.rs
@@ -29,44 +29,27 @@ macro_rules! device_class_init {
macro_rules! define_property {
($name:expr, $state:ty, $field:expr, $prop:expr, $type:expr, default = $defval:expr$(,)*) => {
$crate::bindings::Property {
- name: {
- #[used]
- static _TEMP: &::core::ffi::CStr = $name;
- _TEMP.as_ptr()
- },
+ // use associated function syntax for type checking
+ name: ::core::ffi::CStr::as_ptr($name),
info: $prop,
offset: ::core::mem::offset_of!($state, $field)
.try_into()
.expect("Could not fit offset value to type"),
- bitnr: 0,
- bitmask: 0,
set_default: true,
defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval.into() },
- arrayoffset: 0,
- arrayinfo: ::core::ptr::null(),
- arrayfieldsize: 0,
- link_type: ::core::ptr::null(),
+ ..unsafe { ::core::mem::MaybeUninit::<$crate::bindings::Property>::zeroed().assume_init() }
}
};
($name:expr, $state:ty, $field:expr, $prop:expr, $type:expr$(,)*) => {
$crate::bindings::Property {
- name: {
- #[used]
- static _TEMP: &::core::ffi::CStr = $name;
- _TEMP.as_ptr()
- },
+ // use associated function syntax for type checking
+ name: ::core::ffi::CStr::as_ptr($name),
info: $prop,
offset: ::core::mem::offset_of!($state, $field)
.try_into()
.expect("Could not fit offset value to type"),
- bitnr: 0,
- bitmask: 0,
set_default: false,
- defval: $crate::bindings::Property__bindgen_ty_1 { i: 0 },
- arrayoffset: 0,
- arrayinfo: ::core::ptr::null(),
- arrayfieldsize: 0,
- link_type: ::core::ptr::null(),
+ ..unsafe { ::core::mem::MaybeUninit::<$crate::bindings::Property>::zeroed().assume_init() }
}
};
}
--
2.46.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 10/13] qdev: make properties array "const"
2024-10-18 14:42 [PATCH 00/13] rust: miscellaneous cleanups + QOM integration tests Paolo Bonzini
` (8 preceding siblings ...)
2024-10-18 14:43 ` [PATCH 09/13] rust: clean up define_property macro Paolo Bonzini
@ 2024-10-18 14:43 ` Paolo Bonzini
2024-10-18 14:43 ` [PATCH 11/13] rust: make properties array immutable Paolo Bonzini
` (2 subsequent siblings)
12 siblings, 0 replies; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-18 14:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Manos Pitsidianakis, Junjie Mao
Constify all accesses to qdev properties, except for the
ObjectPropertyAccessor itself. This makes it possible to place them in
read-only memory, and also lets Rust bindings switch from "static mut"
arrays to "static"; which is advantageous, because mutable statics are
highly discouraged.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/hw/qdev-core.h | 4 ++--
include/hw/qdev-properties.h | 4 ++--
hw/core/qdev-properties.c | 26 +++++++++++++-------------
system/qdev-monitor.c | 2 +-
4 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index aa97c34a4be..f9fa291cc63 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -132,7 +132,7 @@ struct DeviceClass {
* ensures a compile-time error if someone attempts to assign
* dc->props directly.
*/
- Property *props_;
+ const Property *props_;
/**
* @user_creatable: Can user instantiate with -device / device_add?
@@ -935,7 +935,7 @@ char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev);
* you attempt to add an existing property defined by a parent class.
* To modify an inherited property you need to use????
*/
-void device_class_set_props(DeviceClass *dc, Property *props);
+void device_class_set_props(DeviceClass *dc, const Property *props);
/**
* device_class_set_parent_realize() - set up for chaining realize fns
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 09aa04ca1e2..26ebd230685 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -37,7 +37,7 @@ struct PropertyInfo {
int (*print)(Object *obj, Property *prop, char *dest, size_t len);
void (*set_default_value)(ObjectProperty *op, const Property *prop);
ObjectProperty *(*create)(ObjectClass *oc, const char *name,
- Property *prop);
+ const Property *prop);
ObjectPropertyAccessor *get;
ObjectPropertyAccessor *set;
ObjectPropertyRelease *release;
@@ -223,7 +223,7 @@ void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj,
* On error, store error in @errp. Static properties access data in a struct.
* The type of the QOM property is derived from prop->info.
*/
-void qdev_property_add_static(DeviceState *dev, Property *prop);
+void qdev_property_add_static(DeviceState *dev, const Property *prop);
/**
* qdev_alias_all_properties: Create aliases on source for all target properties
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 86a583574dd..315196bd85a 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -749,7 +749,7 @@ const PropertyInfo qdev_prop_array = {
/* --- public helpers --- */
-static Property *qdev_prop_walk(Property *props, const char *name)
+static const Property *qdev_prop_walk(const Property *props, const char *name)
{
if (!props) {
return NULL;
@@ -763,10 +763,10 @@ static Property *qdev_prop_walk(Property *props, const char *name)
return NULL;
}
-static Property *qdev_prop_find(DeviceState *dev, const char *name)
+static const Property *qdev_prop_find(DeviceState *dev, const char *name)
{
ObjectClass *class;
- Property *prop;
+ const Property *prop;
/* device properties */
class = object_get_class(OBJECT(dev));
@@ -840,7 +840,7 @@ void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
{
- Property *prop;
+ const Property *prop;
prop = qdev_prop_find(dev, name);
object_property_set_str(OBJECT(dev), name,
@@ -956,7 +956,7 @@ const PropertyInfo qdev_prop_size = {
/* --- object link property --- */
static ObjectProperty *create_link_property(ObjectClass *oc, const char *name,
- Property *prop)
+ const Property *prop)
{
return object_class_property_add_link(oc, name, prop->link_type,
prop->offset,
@@ -969,7 +969,7 @@ const PropertyInfo qdev_prop_link = {
.create = create_link_property,
};
-void qdev_property_add_static(DeviceState *dev, Property *prop)
+void qdev_property_add_static(DeviceState *dev, const Property *prop)
{
Object *obj = OBJECT(dev);
ObjectProperty *op;
@@ -980,7 +980,7 @@ void qdev_property_add_static(DeviceState *dev, Property *prop)
field_prop_getter(prop->info),
field_prop_setter(prop->info),
prop->info->release,
- prop);
+ (Property *)prop);
object_property_set_description(obj, prop->name,
prop->info->description);
@@ -994,7 +994,7 @@ void qdev_property_add_static(DeviceState *dev, Property *prop)
}
static void qdev_class_add_property(DeviceClass *klass, const char *name,
- Property *prop)
+ const Property *prop)
{
ObjectClass *oc = OBJECT_CLASS(klass);
ObjectProperty *op;
@@ -1007,7 +1007,7 @@ static void qdev_class_add_property(DeviceClass *klass, const char *name,
field_prop_getter(prop->info),
field_prop_setter(prop->info),
prop->info->release,
- prop);
+ (Property *)prop);
}
if (prop->set_default) {
prop->info->set_default_value(op, prop);
@@ -1046,7 +1046,7 @@ static void qdev_get_legacy_property(Object *obj, Visitor *v,
* Do not use this in new code! QOM Properties added through this interface
* will be given names in the "legacy" namespace.
*/
-static void qdev_class_add_legacy_property(DeviceClass *dc, Property *prop)
+static void qdev_class_add_legacy_property(DeviceClass *dc, const Property *prop)
{
g_autofree char *name = NULL;
@@ -1058,12 +1058,12 @@ static void qdev_class_add_legacy_property(DeviceClass *dc, Property *prop)
name = g_strdup_printf("legacy-%s", prop->name);
object_class_property_add(OBJECT_CLASS(dc), name, "str",
prop->info->print ? qdev_get_legacy_property : prop->info->get,
- NULL, NULL, prop);
+ NULL, NULL, (Property *)prop);
}
-void device_class_set_props(DeviceClass *dc, Property *props)
+void device_class_set_props(DeviceClass *dc, const Property *props)
{
- Property *prop;
+ const Property *prop;
dc->props_ = props;
for (prop = props; prop && prop->name; prop++) {
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index 44994ea0e16..c346ea6ae4b 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -751,7 +751,7 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
-static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
+static void qdev_print_props(Monitor *mon, DeviceState *dev, const Property *props,
int indent)
{
if (!props)
--
2.46.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 11/13] rust: make properties array immutable
2024-10-18 14:42 [PATCH 00/13] rust: miscellaneous cleanups + QOM integration tests Paolo Bonzini
` (9 preceding siblings ...)
2024-10-18 14:43 ` [PATCH 10/13] qdev: make properties array "const" Paolo Bonzini
@ 2024-10-18 14:43 ` Paolo Bonzini
2024-10-21 11:42 ` Junjie Mao
2024-10-18 14:43 ` [PATCH 12/13] rust: provide safe wrapper for MaybeUninit::zeroed() Paolo Bonzini
2024-10-18 14:43 ` [PATCH 13/13] rust: do not use TYPE_CHARDEV unnecessarily Paolo Bonzini
12 siblings, 1 reply; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-18 14:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Manos Pitsidianakis, Junjie Mao
Now that device_class_set_props() takes a const pointer, the only part of
"define_property!" that needs to be non-const is the call to try_into().
This in turn will only break if offset_of returns a value with the most
significant bit set (i.e. a struct size that is >=2^31 or >= 2^63,
respectively on 32- and 64-bit system), which is impossible.
Just use a cast and clean everything up to remove the run-time
initialization. This also removes a use of OnceLock, which was only
stabilized in 1.70.0.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
rust/qemu-api/src/device_class.rs | 42 ++++++-------------------------
1 file changed, 8 insertions(+), 34 deletions(-)
diff --git a/rust/qemu-api/src/device_class.rs b/rust/qemu-api/src/device_class.rs
index 5aba426d243..d885f2fcf19 100644
--- a/rust/qemu-api/src/device_class.rs
+++ b/rust/qemu-api/src/device_class.rs
@@ -2,10 +2,6 @@
// Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
// SPDX-License-Identifier: GPL-2.0-or-later
-use std::sync::OnceLock;
-
-use crate::bindings::Property;
-
#[macro_export]
macro_rules! device_class_init {
($func:ident, props => $props:ident, realize_fn => $realize_fn:expr, legacy_reset_fn => $legacy_reset_fn:expr, vmsd => $vmsd:ident$(,)*) => {
@@ -19,7 +15,7 @@ macro_rules! device_class_init {
dc.as_mut().realize = $realize_fn;
dc.as_mut().vmsd = &$vmsd;
$crate::bindings::device_class_set_legacy_reset(dc.as_mut(), $legacy_reset_fn);
- $crate::bindings::device_class_set_props(dc.as_mut(), $props.as_mut_ptr());
+ $crate::bindings::device_class_set_props(dc.as_mut(), $props.as_ptr());
}
}
};
@@ -32,9 +28,7 @@ macro_rules! define_property {
// use associated function syntax for type checking
name: ::core::ffi::CStr::as_ptr($name),
info: $prop,
- offset: ::core::mem::offset_of!($state, $field)
- .try_into()
- .expect("Could not fit offset value to type"),
+ offset: ::core::mem::offset_of!($state, $field) as isize,
set_default: true,
defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval.into() },
..unsafe { ::core::mem::MaybeUninit::<$crate::bindings::Property>::zeroed().assume_init() }
@@ -45,47 +39,27 @@ macro_rules! define_property {
// use associated function syntax for type checking
name: ::core::ffi::CStr::as_ptr($name),
info: $prop,
- offset: ::core::mem::offset_of!($state, $field)
- .try_into()
- .expect("Could not fit offset value to type"),
+ offset: ::core::mem::offset_of!($state, $field) as isize,
set_default: false,
..unsafe { ::core::mem::MaybeUninit::<$crate::bindings::Property>::zeroed().assume_init() }
}
};
}
-#[repr(C)]
-pub struct Properties<const N: usize>(pub OnceLock<[Property; N]>, pub fn() -> [Property; N]);
-
-impl<const N: usize> Properties<N> {
- pub fn as_mut_ptr(&mut self) -> *mut Property {
- _ = self.0.get_or_init(self.1);
- self.0.get_mut().unwrap().as_mut_ptr()
- }
-}
-
#[macro_export]
macro_rules! declare_properties {
($ident:ident, $($prop:expr),*$(,)*) => {
-
- const fn _calc_prop_len() -> usize {
+ pub static $ident: [$crate::bindings::Property; {
let mut len = 1;
$({
_ = stringify!($prop);
len += 1;
})*
len
- }
- const PROP_LEN: usize = _calc_prop_len();
-
- fn _make_properties() -> [$crate::bindings::Property; PROP_LEN] {
- [
- $($prop),*,
- unsafe { ::core::mem::MaybeUninit::<$crate::bindings::Property>::zeroed().assume_init() },
- ]
- }
-
- pub static mut $ident: $crate::device_class::Properties<PROP_LEN> = $crate::device_class::Properties(::std::sync::OnceLock::new(), _make_properties);
+ }] = [
+ $($prop),*,
+ unsafe { ::core::mem::MaybeUninit::<$crate::bindings::Property>::zeroed().assume_init() },
+ ];
};
}
--
2.46.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 12/13] rust: provide safe wrapper for MaybeUninit::zeroed()
2024-10-18 14:42 [PATCH 00/13] rust: miscellaneous cleanups + QOM integration tests Paolo Bonzini
` (10 preceding siblings ...)
2024-10-18 14:43 ` [PATCH 11/13] rust: make properties array immutable Paolo Bonzini
@ 2024-10-18 14:43 ` Paolo Bonzini
2024-10-21 11:46 ` Junjie Mao
2024-10-18 14:43 ` [PATCH 13/13] rust: do not use TYPE_CHARDEV unnecessarily Paolo Bonzini
12 siblings, 1 reply; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-18 14:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Manos Pitsidianakis, Junjie Mao
MaybeUninit::zeroed() is handy, but it introduces unsafe (and has a
pretty heavy syntax in general). Introduce a trait that provides the
same functionality while staying within safe Rust.
In addition, MaybeUninit::zeroed() is not available as a "const"
function until Rust 1.75.0, so this also prepares for having handwritten
implementations of the trait until we can assume that version.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
rust/hw/char/pl011/src/device_class.rs | 8 ++++++--
rust/hw/char/pl011/src/memory_ops.rs | 11 +++++++----
rust/qemu-api/meson.build | 1 +
rust/qemu-api/src/device_class.rs | 8 ++++----
rust/qemu-api/src/lib.rs | 1 +
rust/qemu-api/src/zeroable.rs | 23 +++++++++++++++++++++++
6 files changed, 42 insertions(+), 10 deletions(-)
create mode 100644 rust/qemu-api/src/zeroable.rs
diff --git a/rust/hw/char/pl011/src/device_class.rs b/rust/hw/char/pl011/src/device_class.rs
index 2ad80451e87..78fa1cdd5b6 100644
--- a/rust/hw/char/pl011/src/device_class.rs
+++ b/rust/hw/char/pl011/src/device_class.rs
@@ -4,7 +4,11 @@
use core::ptr::NonNull;
-use qemu_api::{bindings::*, definitions::ObjectImpl};
+use qemu_api::{
+ bindings::*,
+ definitions::ObjectImpl,
+ zeroable::Zeroable,
+};
use crate::device::PL011State;
@@ -12,7 +16,7 @@
pub static VMSTATE_PL011: VMStateDescription = VMStateDescription {
name: PL011State::TYPE_INFO.name,
unmigratable: true,
- ..unsafe { ::core::mem::MaybeUninit::<VMStateDescription>::zeroed().assume_init() }
+ ..Zeroable::ZERO
};
qemu_api::declare_properties! {
diff --git a/rust/hw/char/pl011/src/memory_ops.rs b/rust/hw/char/pl011/src/memory_ops.rs
index 5a5320e66c3..24ac9c870c1 100644
--- a/rust/hw/char/pl011/src/memory_ops.rs
+++ b/rust/hw/char/pl011/src/memory_ops.rs
@@ -2,9 +2,12 @@
// Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
// SPDX-License-Identifier: GPL-2.0-or-later
-use core::{mem::MaybeUninit, ptr::NonNull};
+use core::ptr::NonNull;
-use qemu_api::bindings::*;
+use qemu_api::{
+ bindings::*,
+ zeroable::Zeroable
+};
use crate::device::PL011State;
@@ -14,11 +17,11 @@
read_with_attrs: None,
write_with_attrs: None,
endianness: device_endian::DEVICE_NATIVE_ENDIAN,
- valid: unsafe { MaybeUninit::<MemoryRegionOps__bindgen_ty_1>::zeroed().assume_init() },
+ valid: Zeroable::ZERO,
impl_: MemoryRegionOps__bindgen_ty_2 {
min_access_size: 4,
max_access_size: 4,
- ..unsafe { MaybeUninit::<MemoryRegionOps__bindgen_ty_2>::zeroed().assume_init() }
+ ..Zeroable::ZERO
},
};
diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build
index d24e0c0725e..5fa4a08e76b 100644
--- a/rust/qemu-api/meson.build
+++ b/rust/qemu-api/meson.build
@@ -5,6 +5,7 @@ _qemu_api_rs = static_library(
'src/lib.rs',
'src/definitions.rs',
'src/device_class.rs',
+ 'src/zeroable.rs',
],
{'.' : bindings_rs},
),
diff --git a/rust/qemu-api/src/device_class.rs b/rust/qemu-api/src/device_class.rs
index d885f2fcf19..ed2d7ce1a54 100644
--- a/rust/qemu-api/src/device_class.rs
+++ b/rust/qemu-api/src/device_class.rs
@@ -31,7 +31,7 @@ macro_rules! define_property {
offset: ::core::mem::offset_of!($state, $field) as isize,
set_default: true,
defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval.into() },
- ..unsafe { ::core::mem::MaybeUninit::<$crate::bindings::Property>::zeroed().assume_init() }
+ ..$crate::zeroable::Zeroable::ZERO
}
};
($name:expr, $state:ty, $field:expr, $prop:expr, $type:expr$(,)*) => {
@@ -41,7 +41,7 @@ macro_rules! define_property {
info: $prop,
offset: ::core::mem::offset_of!($state, $field) as isize,
set_default: false,
- ..unsafe { ::core::mem::MaybeUninit::<$crate::bindings::Property>::zeroed().assume_init() }
+ ..$crate::zeroable::Zeroable::ZERO
}
};
}
@@ -58,7 +58,7 @@ macro_rules! declare_properties {
len
}] = [
$($prop),*,
- unsafe { ::core::mem::MaybeUninit::<$crate::bindings::Property>::zeroed().assume_init() },
+ $crate::zeroable::Zeroable::ZERO,
];
};
}
@@ -79,7 +79,7 @@ macro_rules! vm_state_description {
$vname.as_ptr()
},)*
unmigratable: true,
- ..unsafe { ::core::mem::MaybeUninit::<$crate::bindings::VMStateDescription>::zeroed().assume_init() }
+ ..$crate::zeroable::Zeroable::ZERO
};
}
}
diff --git a/rust/qemu-api/src/lib.rs b/rust/qemu-api/src/lib.rs
index e72fb4b4bb1..91b9459235b 100644
--- a/rust/qemu-api/src/lib.rs
+++ b/rust/qemu-api/src/lib.rs
@@ -29,6 +29,7 @@ unsafe impl Sync for bindings::VMStateDescription {}
pub mod definitions;
pub mod device_class;
+pub mod zeroable;
#[cfg(test)]
mod tests;
diff --git a/rust/qemu-api/src/zeroable.rs b/rust/qemu-api/src/zeroable.rs
new file mode 100644
index 00000000000..927c634b48f
--- /dev/null
+++ b/rust/qemu-api/src/zeroable.rs
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/// Encapsulates the requirement that
+/// `MaybeUninit::<Self>::zeroed().assume_init()` does not cause
+/// undefined behavior.
+///
+/// SAFETY: do not add this trait to a type unless all-zeroes is
+/// a valid value for the type. In particular, remember that raw
+/// pointers can be zero, but references and `NonNull<T>` cannot
+/// unless wrapped with `Option<>`.
+pub unsafe trait Zeroable: Default {
+ /// SAFETY: If the trait was added to a type, then by definition
+ /// this is safe.
+ const ZERO: Self = unsafe {
+ ::core::mem::MaybeUninit::<Self>::zeroed().assume_init()
+ };
+}
+
+unsafe impl Zeroable for crate::bindings::Property__bindgen_ty_1 {}
+unsafe impl Zeroable for crate::bindings::Property {}
+unsafe impl Zeroable for crate::bindings::VMStateDescription {}
+unsafe impl Zeroable for crate::bindings::MemoryRegionOps__bindgen_ty_1 {}
+unsafe impl Zeroable for crate::bindings::MemoryRegionOps__bindgen_ty_2 {}
--
2.46.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 13/13] rust: do not use TYPE_CHARDEV unnecessarily
2024-10-18 14:42 [PATCH 00/13] rust: miscellaneous cleanups + QOM integration tests Paolo Bonzini
` (11 preceding siblings ...)
2024-10-18 14:43 ` [PATCH 12/13] rust: provide safe wrapper for MaybeUninit::zeroed() Paolo Bonzini
@ 2024-10-18 14:43 ` Paolo Bonzini
2024-10-21 11:48 ` Junjie Mao
12 siblings, 1 reply; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-18 14:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Manos Pitsidianakis, Junjie Mao
In the invocation of qdev_prop_set_chr(), "chardev" is the name of a
property rather than a type and has to match the name of the property
in device_class.rs. Do not use TYPE_CHARDEV here, just like in the C
version of pl011_create.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
rust/hw/char/pl011/src/device.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs
index 2b43f5e0939..0f6918dd224 100644
--- a/rust/hw/char/pl011/src/device.rs
+++ b/rust/hw/char/pl011/src/device.rs
@@ -572,7 +572,7 @@ pub fn update(&self) {
let dev: *mut DeviceState = qdev_new(PL011State::TYPE_INFO.name);
let sysbus: *mut SysBusDevice = dev.cast::<SysBusDevice>();
- qdev_prop_set_chr(dev, bindings::TYPE_CHARDEV.as_ptr(), chr);
+ qdev_prop_set_chr(dev, c"chardev".as_ptr(), chr);
sysbus_realize_and_unref(sysbus, addr_of!(error_fatal) as *mut *mut Error);
sysbus_mmio_map(sysbus, 0, addr);
sysbus_connect_irq(sysbus, 0, irq);
--
2.46.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [PATCH 05/13] rust: remove uses of #[no_mangle]
2024-10-18 14:42 ` [PATCH 05/13] rust: remove uses of #[no_mangle] Paolo Bonzini
@ 2024-10-21 10:07 ` Junjie Mao
0 siblings, 0 replies; 30+ messages in thread
From: Junjie Mao @ 2024-10-21 10:07 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, Manos Pitsidianakis
Paolo Bonzini <pbonzini@redhat.com> writes:
> Mangled symbols do not cause any issue; disabling mangling is only useful if
> C headers reference the Rust function, which is not the case here.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
--
Best Regards
Junjie Mao
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 06/13] rust: remove unused macro module_init!
2024-10-18 14:42 ` [PATCH 06/13] rust: remove unused macro module_init! Paolo Bonzini
@ 2024-10-21 10:16 ` Junjie Mao
2024-10-21 10:46 ` Paolo Bonzini
0 siblings, 1 reply; 30+ messages in thread
From: Junjie Mao @ 2024-10-21 10:16 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, Manos Pitsidianakis
Paolo Bonzini <pbonzini@redhat.com> writes:
> Registering the object is now done by the #[derive(Object)] macro.
The module_init! macro is still necessary when a device needs more logic
(in addition to a single type registration) in module init. That is not
rare among the devices in C we have today.
Manos and I had a conversation on this. He mentioned that he had a
second Rust device that needs this macro [1].
[1] https://lore.kernel.org/qemu-devel/itblf.by425lac4ow@linaro.org/
--
Best Regards
Junjie Mao
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> rust/qemu-api/src/definitions.rs | 43 --------------------------------
> 1 file changed, 43 deletions(-)
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 07/13] rust: modernize #[derive(Object)] for ELF platforms
2024-10-18 14:42 ` [PATCH 07/13] rust: modernize #[derive(Object)] for ELF platforms Paolo Bonzini
@ 2024-10-21 10:23 ` Junjie Mao
0 siblings, 0 replies; 30+ messages in thread
From: Junjie Mao @ 2024-10-21 10:23 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, Manos Pitsidianakis
Paolo Bonzini <pbonzini@redhat.com> writes:
> Some newer ABI implementations do not provide .ctors; and while
> some linkers rewrite .ctors into .init_array, not all of them do.
> Use the newer .init_array ABI, which works more reliably, and
> apply it to all non-Apple, non-Windows platforms.
>
> This is similar to how the ctor crate operates; without this change,
> "#[derive(Object)]" does not work on Fedora 41.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
--
Best Regards
Junjie Mao
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 08/13] rust: build integration test for the qemu_api crate
2024-10-18 14:43 ` [PATCH 08/13] rust: build integration test for the qemu_api crate Paolo Bonzini
@ 2024-10-21 10:28 ` Junjie Mao
2024-10-21 10:47 ` Paolo Bonzini
2024-10-21 11:28 ` Junjie Mao
1 sibling, 1 reply; 30+ messages in thread
From: Junjie Mao @ 2024-10-21 10:28 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, Manos Pitsidianakis
Paolo Bonzini <pbonzini@redhat.com> writes:
> Adjust the integration test to compile with a subset of QEMU object
> files, and make it actually create an object of the class it defines.
>
> Follow the Rust filesystem conventions, where tests go in tests/ if
> they use the library in the same way any other code would.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
A few minor comments on cosmetic below.
> ---
> meson.build | 10 ++++-
> rust/qemu-api/meson.build | 20 +++++++--
> rust/qemu-api/src/tests.rs | 49 ----------------------
> rust/qemu-api/tests/tests.rs | 78 ++++++++++++++++++++++++++++++++++++
> 4 files changed, 104 insertions(+), 53 deletions(-)
> delete mode 100644 rust/qemu-api/src/tests.rs
> create mode 100644 rust/qemu-api/tests/tests.rs
>
<snip>
> diff --git a/rust/qemu-api/tests/tests.rs b/rust/qemu-api/tests/tests.rs
> new file mode 100644
> index 00000000000..57bab62772d
> --- /dev/null
> +++ b/rust/qemu-api/tests/tests.rs
> @@ -0,0 +1,78 @@
> +// Copyright 2024, Linaro Limited
> +// Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +
> +use core::ffi::CStr;
> +
> +use qemu_api::{
> + bindings::*, declare_properties, define_property,
> + definitions::Class,
> + definitions::ObjectImpl,
> + device_class_init, vm_state_description,
Cargo fmt (with the current rust/rustfmt.toml) formats those lines in a
different way, and ...
> +};
> +
<snip>
> + impl ObjectImpl for DummyState {
> + type Class = DummyClass;
> + const TYPE_INFO: qemu_api::bindings::TypeInfo = qemu_api::type_info! { Self };
> + const TYPE_NAME: &'static CStr = c"dummy";
> + const PARENT_TYPE_NAME: Option<&'static CStr> = Some(TYPE_DEVICE);
> + const ABSTRACT: bool = false;
> + const INSTANCE_INIT: Option<unsafe extern "C" fn(obj: *mut Object)> = None;
> + const INSTANCE_POST_INIT: Option<unsafe extern "C" fn(obj: *mut Object)> = None;
> + const INSTANCE_FINALIZE: Option<unsafe extern "C" fn(obj: *mut Object)> = None;
> + }
> +
> + impl Class for DummyClass {
> + const CLASS_INIT: Option<
> + unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut core::ffi::c_void),
> + > = Some(dummy_class_init);
... ditto. Shall we tweak the formats here or adjust the rustfmt
settings later?
--
Best Regards
Junjie Mao
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 09/13] rust: clean up define_property macro
2024-10-18 14:43 ` [PATCH 09/13] rust: clean up define_property macro Paolo Bonzini
@ 2024-10-21 10:35 ` Junjie Mao
2024-10-21 10:44 ` Paolo Bonzini
0 siblings, 1 reply; 30+ messages in thread
From: Junjie Mao @ 2024-10-21 10:35 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, Manos Pitsidianakis
Paolo Bonzini <pbonzini@redhat.com> writes:
> Use the "struct update" syntax to initialize most of the fields to zero,
> and simplify the handmade type-checking of $name.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> rust/qemu-api/src/device_class.rs | 29 ++++++-----------------------
> 1 file changed, 6 insertions(+), 23 deletions(-)
>
> diff --git a/rust/qemu-api/src/device_class.rs b/rust/qemu-api/src/device_class.rs
> index 2219b9f73d0..5aba426d243 100644
> --- a/rust/qemu-api/src/device_class.rs
> +++ b/rust/qemu-api/src/device_class.rs
> @@ -29,44 +29,27 @@ macro_rules! device_class_init {
> macro_rules! define_property {
> ($name:expr, $state:ty, $field:expr, $prop:expr, $type:expr, default = $defval:expr$(,)*) => {
> $crate::bindings::Property {
> - name: {
> - #[used]
> - static _TEMP: &::core::ffi::CStr = $name;
> - _TEMP.as_ptr()
> - },
> + // use associated function syntax for type checking
> + name: ::core::ffi::CStr::as_ptr($name),
> info: $prop,
> offset: ::core::mem::offset_of!($state, $field)
> .try_into()
> .expect("Could not fit offset value to type"),
> - bitnr: 0,
> - bitmask: 0,
> set_default: true,
> defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval.into() },
> - arrayoffset: 0,
> - arrayinfo: ::core::ptr::null(),
> - arrayfieldsize: 0,
> - link_type: ::core::ptr::null(),
> + ..unsafe { ::core::mem::MaybeUninit::<$crate::bindings::Property>::zeroed().assume_init() }
zeroed() is const only since 1.75.0 [1]. Is there any alternative for
older Rust versions?
[1] https://doc.rust-lang.org/std/mem/union.MaybeUninit.html#method.zeroed
--
Best Regards
Junjie Mao
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 09/13] rust: clean up define_property macro
2024-10-21 10:35 ` Junjie Mao
@ 2024-10-21 10:44 ` Paolo Bonzini
2024-10-21 11:37 ` Junjie Mao
0 siblings, 1 reply; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-21 10:44 UTC (permalink / raw)
To: Junjie Mao; +Cc: qemu-devel, Manos Pitsidianakis
[-- Attachment #1: Type: text/plain, Size: 2298 bytes --]
Il lun 21 ott 2024, 12:39 Junjie Mao <junjie.mao@hotmail.com> ha scritto:
>
> Paolo Bonzini <pbonzini@redhat.com> writes:
>
> > Use the "struct update" syntax to initialize most of the fields to zero,
> > and simplify the handmade type-checking of $name.
> >
> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> > ---
> > rust/qemu-api/src/device_class.rs | 29 ++++++-----------------------
> > 1 file changed, 6 insertions(+), 23 deletions(-)
> >
> > diff --git a/rust/qemu-api/src/device_class.rs b/rust/qemu-api/src/
> device_class.rs
> > index 2219b9f73d0..5aba426d243 100644
> > --- a/rust/qemu-api/src/device_class.rs
> > +++ b/rust/qemu-api/src/device_class.rs
> > @@ -29,44 +29,27 @@ macro_rules! device_class_init {
> > macro_rules! define_property {
> > ($name:expr, $state:ty, $field:expr, $prop:expr, $type:expr,
> default = $defval:expr$(,)*) => {
> > $crate::bindings::Property {
> > - name: {
> > - #[used]
> > - static _TEMP: &::core::ffi::CStr = $name;
> > - _TEMP.as_ptr()
> > - },
> > + // use associated function syntax for type checking
> > + name: ::core::ffi::CStr::as_ptr($name),
> > info: $prop,
> > offset: ::core::mem::offset_of!($state, $field)
> > .try_into()
> > .expect("Could not fit offset value to type"),
> > - bitnr: 0,
> > - bitmask: 0,
> > set_default: true,
> > defval: $crate::bindings::Property__bindgen_ty_1 { u:
> $defval.into() },
> > - arrayoffset: 0,
> > - arrayinfo: ::core::ptr::null(),
> > - arrayfieldsize: 0,
> > - link_type: ::core::ptr::null(),
> > + ..unsafe {
> ::core::mem::MaybeUninit::<$crate::bindings::Property>::zeroed().assume_init()
> }
>
> zeroed() is const only since 1.75.0 [1]. Is there any alternative for
> older Rust versions?
>
Yes: manual implementation of a Zeroable trait, as in the series I sent
before one. For now I am not worrying about the MSRV, since the
hacks/workarounds from those patches do not become any worse.
Paolo
>
> [1] https://doc.rust-lang.org/std/mem/union.MaybeUninit.html#method.zeroed
>
> --
> Best Regards
> Junjie Mao
>
>
[-- Attachment #2: Type: text/html, Size: 3996 bytes --]
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 06/13] rust: remove unused macro module_init!
2024-10-21 10:16 ` Junjie Mao
@ 2024-10-21 10:46 ` Paolo Bonzini
0 siblings, 0 replies; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-21 10:46 UTC (permalink / raw)
To: Junjie Mao; +Cc: qemu-devel, Manos Pitsidianakis
[-- Attachment #1: Type: text/plain, Size: 956 bytes --]
Il lun 21 ott 2024, 12:19 Junjie Mao <junjie.mao@hotmail.com> ha scritto:
>
> Paolo Bonzini <pbonzini@redhat.com> writes:
>
> > Registering the object is now done by the #[derive(Object)] macro.
>
> The module_init! macro is still necessary when a device needs more logic
> (in addition to a single type registration) in module init. That is not
> rare among the devices in C we have today.
>
> Manos and I had a conversation on this. He mentioned that he had a
> second Rust device that needs this macro [1].
>
Ok, I will change derive(Object) to use module_init! instead. What matters
is that module_init! is also fixed to not use the .ctors section.
Paolo
> [1] https://lore.kernel.org/qemu-devel/itblf.by425lac4ow@linaro.org/
>
> --
> Best Regards
> Junjie Mao
>
> >
> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> > ---
> > rust/qemu-api/src/definitions.rs | 43 --------------------------------
> > 1 file changed, 43 deletions(-)
>
>
[-- Attachment #2: Type: text/html, Size: 2020 bytes --]
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 08/13] rust: build integration test for the qemu_api crate
2024-10-21 10:28 ` Junjie Mao
@ 2024-10-21 10:47 ` Paolo Bonzini
0 siblings, 0 replies; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-21 10:47 UTC (permalink / raw)
To: Junjie Mao; +Cc: qemu-devel, Manos Pitsidianakis
[-- Attachment #1: Type: text/plain, Size: 2738 bytes --]
Il lun 21 ott 2024, 12:34 Junjie Mao <junjie.mao@hotmail.com> ha scritto:
>
> Paolo Bonzini <pbonzini@redhat.com> writes:
>
> > Adjust the integration test to compile with a subset of QEMU object
> > files, and make it actually create an object of the class it defines.
> >
> > Follow the Rust filesystem conventions, where tests go in tests/ if
> > they use the library in the same way any other code would.
> >
> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>
> Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
>
> A few minor comments on cosmetic below.
>
> > ---
> > meson.build | 10 ++++-
> > rust/qemu-api/meson.build | 20 +++++++--
> > rust/qemu-api/src/tests.rs | 49 ----------------------
> > rust/qemu-api/tests/tests.rs | 78 ++++++++++++++++++++++++++++++++++++
> > 4 files changed, 104 insertions(+), 53 deletions(-)
> > delete mode 100644 rust/qemu-api/src/tests.rs
> > create mode 100644 rust/qemu-api/tests/tests.rs
> >
> <snip>
> > diff --git a/rust/qemu-api/tests/tests.rs b/rust/qemu-api/tests/tests.rs
> > new file mode 100644
> > index 00000000000..57bab62772d
> > --- /dev/null
> > +++ b/rust/qemu-api/tests/tests.rs
> > @@ -0,0 +1,78 @@
> > +// Copyright 2024, Linaro Limited
> > +// Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +
> > +use core::ffi::CStr;
> > +
> > +use qemu_api::{
> > + bindings::*, declare_properties, define_property,
> > + definitions::Class,
> > + definitions::ObjectImpl,
> > + device_class_init, vm_state_description,
>
> Cargo fmt (with the current rust/rustfmt.toml) formats those lines in a
> different way, and ...
>
I will tweak this.
Paolo
> +};
> > +
> <snip>
> > + impl ObjectImpl for DummyState {
> > + type Class = DummyClass;
> > + const TYPE_INFO: qemu_api::bindings::TypeInfo =
> qemu_api::type_info! { Self };
> > + const TYPE_NAME: &'static CStr = c"dummy";
> > + const PARENT_TYPE_NAME: Option<&'static CStr> =
> Some(TYPE_DEVICE);
> > + const ABSTRACT: bool = false;
> > + const INSTANCE_INIT: Option<unsafe extern "C" fn(obj: *mut
> Object)> = None;
> > + const INSTANCE_POST_INIT: Option<unsafe extern "C" fn(obj: *mut
> Object)> = None;
> > + const INSTANCE_FINALIZE: Option<unsafe extern "C" fn(obj: *mut
> Object)> = None;
> > + }
> > +
> > + impl Class for DummyClass {
> > + const CLASS_INIT: Option<
> > + unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut
> core::ffi::c_void),
> > + > = Some(dummy_class_init);
>
> ... ditto. Shall we tweak the formats here or adjust the rustfmt
> settings later?
>
> --
> Best Regards
> Junjie Mao
>
>
[-- Attachment #2: Type: text/html, Size: 4742 bytes --]
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 08/13] rust: build integration test for the qemu_api crate
2024-10-18 14:43 ` [PATCH 08/13] rust: build integration test for the qemu_api crate Paolo Bonzini
2024-10-21 10:28 ` Junjie Mao
@ 2024-10-21 11:28 ` Junjie Mao
2024-10-21 11:43 ` Paolo Bonzini
1 sibling, 1 reply; 30+ messages in thread
From: Junjie Mao @ 2024-10-21 11:28 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, Manos Pitsidianakis
Paolo Bonzini <pbonzini@redhat.com> writes:
> Adjust the integration test to compile with a subset of QEMU object
> files, and make it actually create an object of the class it defines.
>
> Follow the Rust filesystem conventions, where tests go in tests/ if
> they use the library in the same way any other code would.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> meson.build | 10 ++++-
> rust/qemu-api/meson.build | 20 +++++++--
> rust/qemu-api/src/tests.rs | 49 ----------------------
> rust/qemu-api/tests/tests.rs | 78 ++++++++++++++++++++++++++++++++++++
> 4 files changed, 104 insertions(+), 53 deletions(-)
> delete mode 100644 rust/qemu-api/src/tests.rs
> create mode 100644 rust/qemu-api/tests/tests.rs
<snip>
> diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build
> index 42ea815fa5a..d24e0c0725e 100644
> --- a/rust/qemu-api/meson.build
> +++ b/rust/qemu-api/meson.build
> @@ -14,11 +14,25 @@ _qemu_api_rs = static_library(
> '--cfg', 'MESON',
> # '--cfg', 'feature="allocator"',
> ],
> - dependencies: [
> - qemu_api_macros,
> - ],
> )
>
> qemu_api = declare_dependency(
> link_with: _qemu_api_rs,
> + dependencies: qemu_api_macros,
> )
> +
> +# Rust executable do not support objects, so add an intermediate step.
> +rust_qemu_api_objs = static_library(
> + 'rust_qemu_api_objs',
> + objects: [libqom.extract_all_objects(recursive: false),
> + libhwcore.extract_all_objects(recursive: false)])
> +
> +rust.test('rust-qemu-api-integration',
> + static_library(
> + 'rust_qemu_api_integration',
> + 'tests/tests.rs',
> + override_options: ['rust_std=2021', 'build.rust_std=2021'],
> + link_whole: [rust_qemu_api_objs, libqemuutil]),
> +
> + dependencies: [qemu_api, qemu_api_macros],
> + suite: ['unit', 'rust'])
I met the following error when trying to build the test:
[4/8] Compiling Rust source ../rust/qemu-api/tests/tests.rs
FAILED: rust/qemu-api/librust_qemu_api_integration.rlib
rustc -C linker=cc -C link-arg=-m64 --color=auto -C debug-assertions=yes -C overflow-checks=no --crate-type rlib -D warnings --edition=2021 -C opt-level=2 -g --cfg CONFIG_ACCEPT4 --cfg CONFIG_AF_VSOCK --cfg CONFIG_ASAN_IFACE_FIBER --cfg CONFIG_ATOMIC64 --cfg CONFIG_ATTR --cfg CONFIG_AUDIO_OSS --cfg CONFIG_AUDIO_PA --cfg CONFIG_AUDIO_SDL --cfg CONFIG_AVX2_OPT --cfg CONFIG_AVX512BW_OPT --cfg CONFIG_BDRV_RO_WHITELIST --cfg CONFIG_BDRV_RW_WHITELIST --cfg CONFIG_BLKZONED --cfg CONFIG_CLOCK_ADJTIME --cfg CONFIG_CLOSE_RANGE --cfg CONFIG_CMPXCHG128 --cfg CONFIG_COROUTINE_POOL --cfg CONFIG_CPUID_H --cfg CONFIG_CURSES --cfg CONFIG_DBUS_DISPLAY --cfg CONFIG_DUP3 --cfg CONFIG_EPOLL --cfg CONFIG_EPOLL_CREATE1 --cfg CONFIG_EVENTFD --cfg CONFIG_FALLOCATE --cfg CONFIG_FALLOCATE_PUNCH_HOLE --cfg CONFIG_FALLOCATE_ZERO_RANGE --cfg CONFIG_FDATASYNC --cfg CONFIG_FDT --cfg CONFIG_FIEMAP --cfg CONFIG_FSFREEZE --cfg CONFIG_FSTRIM --cfg CONFIG_GBM --cfg CONFIG_GETAUXVAL --cfg CONFIG_GETCPU --cfg CONFIG_GETRANDOM --cfg CONFIG_GETTID --cfg CONFIG_GIO --cfg CONFIG_GNUTLS --cfg CONFIG_GNUTLS_CRYPTO --cfg CONFIG_HAVE_RUST --cfg CONFIG_HEXAGON_IDEF_PARSER --cfg CONFIG_INOTIFY --cfg CONFIG_INOTIFY1 --cfg CONFIG_INT128 --cfg CONFIG_INT128_TYPE --cfg CONFIG_IOVEC --cfg CONFIG_L2TPV3 --cfg CONFIG_LIBDW --cfg CONFIG_LIBUDEV --cfg CONFIG_LINUX --cfg CONFIG_LINUX_MAGIC_H --cfg CONFIG_MADVISE --cfg CONFIG_MALLOC_TRIM --cfg CONFIG_MEMALIGN --cfg CONFIG_MEMFD --cfg CONFIG_OPENGL --cfg CONFIG_OPEN_BY_HANDLE --cfg CONFIG_PIXMAN --cfg CONFIG_PLUGIN --cfg CONFIG_PNG --cfg CONFIG_POSIX --cfg CONFIG_POSIX_FALLOCATE --cfg CONFIG_POSIX_MADVISE --cfg CONFIG_POSIX_MEMALIGN --cfg CONFIG_PPOLL --cfg CONFIG_PRCTL_PR_SET_TIMERSLACK --cfg CONFIG_PREADV --cfg CONFIG_PTHREAD_AFFINITY_NP --cfg CONFIG_PTHREAD_SETNAME_NP_W_TID --cfg CONFIG_QOM_CAST_DEBUG --cfg CONFIG_RELOCATABLE --cfg CONFIG_REPLICATION --cfg CONFIG_RTNETLINK --cfg CONFIG_SDL --cfg CONFIG_SECRET_KEYRING --cfg CONFIG_SELINUX --cfg CONFIG_SENDFILE --cfg CONFIG_SETNS --cfg CONFIG_SIGNALFD --cfg CONFIG_SLIRP --cfg CONFIG_SPLICE --cfg CONFIG_STATX --cfg CONFIG_STATX_MNT_ID --cfg CONFIG_SYNCFS --cfg CONFIG_SYNC_FILE_RANGE --cfg CONFIG_SYSMACROS --cfg CONFIG_TASN1 --cfg CONFIG_TCG --cfg CONFIG_TIMERFD --cfg CONFIG_TPM --cfg CONFIG_TRACE_LOG --cfg CONFIG_VALGRIND_H --cfg CONFIG_VALLOC --cfg CONFIG_VDUSE_BLK_EXPORT --cfg CONFIG_VHOST --cfg CONFIG_VHOST_CRYPTO --cfg CONFIG_VHOST_KERNEL --cfg CONFIG_VHOST_NET --cfg CONFIG_VHOST_NET_USER --cfg CONFIG_VHOST_NET_VDPA --cfg CONFIG_VHOST_USER --cfg CONFIG_VHOST_USER_BLK_SERVER --cfg CONFIG_VHOST_VDPA --cfg CONFIG_VIRTFS --cfg CONFIG_VNC --cfg CONFIG_VNC_JPEG --cfg CONFIG_XKBCOMMON --cfg HAVE_BLK_ZONE_REP_CAPACITY --cfg HAVE_BTRFS_H --cfg HAVE_COPY_FILE_RANGE --cfg HAVE_DRM_H --cfg HAVE_FSXATTR --cfg HAVE_GETIFADDRS --cfg HAVE_GLIB_WITH_ALIGNED_ALLOC --cfg HAVE_GLIB_WITH_SLICE_ALLOCATOR --cfg HAVE_HOST_BLOCK_DEVICE --cfg HAVE_IPPROTO_MPTCP --cfg HAVE_MLOCKALL --cfg HAVE_OPENAT2_H --cfg HAVE_OPENPTY --cfg HAVE_PTY_H --cfg HAVE_STRCHRNUL --cfg HAVE_STRUCT_STAT_ST_ATIM --cfg HAVE_SYSTEM_FUNCTION --cfg HAVE_UTMPX -D unsafe_op_in_unsafe_fn -C default-linker-libraries --crate-name rust_qemu_api_integration --emit dep-info=rust/qemu-api/rust_qemu_api_integration.d --emit link=rust/qemu-api/librust_qemu_api_integration.rlib --out-dir rust/qemu-api/librust_qemu_api_integration.rlib.p -C metadata=81e2432@@rust_qemu_api_integration@sta -lstatic:+verbatim=librust_qemu_api_objs.a -lstatic:+verbatim=libqemuutil.a -lstatic:-bundle,+verbatim=libvhost-user-glib.a -lstatic:-bundle,+verbatim=libvhost-user.a -ldylib:+verbatim=libgio-2.0.so -ldylib:+verbatim=libgobject-2.0.so -ldylib:+verbatim=libglib-2.0.so -ldylib:+verbatim=libgmodule-2.0.so -Clink-arg=-pthread -ldylib:+verbatim=libgnutls.so -Clink-arg=-pthread -Clink-arg=-pthread -Clink-arg=-pthread -Lrust/qemu-api -L. -Lsubprojects/libvhost-user -L/usr/lib/x86_64-linux-gnu ../rust/qemu-api/tests/tests.rs
error[E0433]: failed to resolve: use of undeclared crate or module `qemu_api`
--> ../rust/qemu-api/tests/tests.rs:7:5
|
7 | use qemu_api::{
| ^^^^^^^^ use of undeclared crate or module `qemu_api`
error[E0432]: unresolved import `qemu_api`
--> ../rust/qemu-api/tests/tests.rs:7:5
|
7 | use qemu_api::{
| ^^^^^^^^ use of undeclared crate or module `qemu_api`
error: unused import: `core::ffi::CStr`
--> ../rust/qemu-api/tests/tests.rs:5:5
|
5 | use core::ffi::CStr;
| ^^^^^^^^^^^^^^^
|
= note: `-D unused-imports` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(unused_imports)]`
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0432, E0433.
For more information about an error, try `rustc --explain E0432`.
This is probably because rust.test() is designed to build unit tests
(i.e., tests within the same crate under test), but tests/*.rs are
integration tests which are standalone crates to be linked with the
crate under test.
Rust.test() builds unit tests by "copying the sources and arguments
passed to the original target and adding the --test argument to the
compilation" [1], but that doesn't seem to apply to integration tests.
[1] https://mesonbuild.com/Rust-module.html
I can build and run the test with the following instead:
test('rust-qemu-api-integration',
executable(
'rust_qemu_api_integration',
'tests/tests.rs',
override_options: ['rust_std=2021', 'build.rust_std=2021'],
rust_args: [
'--test',
],
install: false,
dependencies: [qemu_api, qemu_api_macros],
link_whole: [rust_qemu_api_objs, libqemuutil]),
args: [
'--test',
'--format', 'pretty',
],
protocol: 'rust',
suite: ['unit', 'rust'])
--
Best Regards
Junjie Mao
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 09/13] rust: clean up define_property macro
2024-10-21 10:44 ` Paolo Bonzini
@ 2024-10-21 11:37 ` Junjie Mao
0 siblings, 0 replies; 30+ messages in thread
From: Junjie Mao @ 2024-10-21 11:37 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, Manos Pitsidianakis
Paolo Bonzini <pbonzini@redhat.com> writes:
> Il lun 21 ott 2024, 12:39 Junjie Mao <junjie.mao@hotmail.com> ha scritto:
>
> Paolo Bonzini <pbonzini@redhat.com> writes:
>
> > Use the "struct update" syntax to initialize most of the fields to zero,
> > and simplify the handmade type-checking of $name.
> >
> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> > ---
> > rust/qemu-api/src/device_class.rs | 29 ++++++-----------------------
> > 1 file changed, 6 insertions(+), 23 deletions(-)
> >
> > diff --git a/rust/qemu-api/src/device_class.rs b/rust/qemu-api/src/device_class.rs
> > index 2219b9f73d0..5aba426d243 100644
> > --- a/rust/qemu-api/src/device_class.rs
> > +++ b/rust/qemu-api/src/device_class.rs
> > @@ -29,44 +29,27 @@ macro_rules! device_class_init {
> > macro_rules! define_property {
> > ($name:expr, $state:ty, $field:expr, $prop:expr, $type:expr, default = $defval:expr$(,)*) => {
> > $crate::bindings::Property {
> > - name: {
> > - #[used]
> > - static _TEMP: &::core::ffi::CStr = $name;
> > - _TEMP.as_ptr()
> > - },
> > + // use associated function syntax for type checking
> > + name: ::core::ffi::CStr::as_ptr($name),
> > info: $prop,
> > offset: ::core::mem::offset_of!($state, $field)
> > .try_into()
> > .expect("Could not fit offset value to type"),
> > - bitnr: 0,
> > - bitmask: 0,
> > set_default: true,
> > defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval.into() },
> > - arrayoffset: 0,
> > - arrayinfo: ::core::ptr::null(),
> > - arrayfieldsize: 0,
> > - link_type: ::core::ptr::null(),
> > + ..unsafe { ::core::mem::MaybeUninit::<$crate::bindings::Property>::zeroed().assume_init() }
>
> zeroed() is const only since 1.75.0 [1]. Is there any alternative for
> older Rust versions?
>
> Yes: manual implementation of a Zeroable trait, as in the series I sent before one. For now I am not worrying about the MSRV, since the hacks/workarounds from those patches do not become any worse.
Ah, yes, I should have recalled seeing that earlier.
Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
--
Best Regards
Junjie Mao
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 11/13] rust: make properties array immutable
2024-10-18 14:43 ` [PATCH 11/13] rust: make properties array immutable Paolo Bonzini
@ 2024-10-21 11:42 ` Junjie Mao
0 siblings, 0 replies; 30+ messages in thread
From: Junjie Mao @ 2024-10-21 11:42 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, Manos Pitsidianakis
Paolo Bonzini <pbonzini@redhat.com> writes:
> Now that device_class_set_props() takes a const pointer, the only part of
> "define_property!" that needs to be non-const is the call to try_into().
> This in turn will only break if offset_of returns a value with the most
> significant bit set (i.e. a struct size that is >=2^31 or >= 2^63,
> respectively on 32- and 64-bit system), which is impossible.
>
> Just use a cast and clean everything up to remove the run-time
> initialization. This also removes a use of OnceLock, which was only
> stabilized in 1.70.0.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
--
Best Regards
Junjie Mao
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 08/13] rust: build integration test for the qemu_api crate
2024-10-21 11:28 ` Junjie Mao
@ 2024-10-21 11:43 ` Paolo Bonzini
2024-10-21 11:51 ` Junjie Mao
0 siblings, 1 reply; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-21 11:43 UTC (permalink / raw)
To: Junjie Mao; +Cc: qemu-devel, Manos Pitsidianakis
On Mon, Oct 21, 2024 at 1:35 PM Junjie Mao <junjie.mao@hotmail.com> wrote:
>
>
> Paolo Bonzini <pbonzini@redhat.com> writes:
>
> > Adjust the integration test to compile with a subset of QEMU object
> > files, and make it actually create an object of the class it defines.
> >
> > Follow the Rust filesystem conventions, where tests go in tests/ if
> > they use the library in the same way any other code would.
> >
> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> > ---
> > meson.build | 10 ++++-
> > rust/qemu-api/meson.build | 20 +++++++--
> > rust/qemu-api/src/tests.rs | 49 ----------------------
> > rust/qemu-api/tests/tests.rs | 78 ++++++++++++++++++++++++++++++++++++
> > 4 files changed, 104 insertions(+), 53 deletions(-)
> > delete mode 100644 rust/qemu-api/src/tests.rs
> > create mode 100644 rust/qemu-api/tests/tests.rs
> <snip>
> > diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build
> > index 42ea815fa5a..d24e0c0725e 100644
> > --- a/rust/qemu-api/meson.build
> > +++ b/rust/qemu-api/meson.build
> > @@ -14,11 +14,25 @@ _qemu_api_rs = static_library(
> > '--cfg', 'MESON',
> > # '--cfg', 'feature="allocator"',
> > ],
> > - dependencies: [
> > - qemu_api_macros,
> > - ],
> > )
> >
> > qemu_api = declare_dependency(
> > link_with: _qemu_api_rs,
> > + dependencies: qemu_api_macros,
> > )
> > +
> > +# Rust executable do not support objects, so add an intermediate step.
> > +rust_qemu_api_objs = static_library(
> > + 'rust_qemu_api_objs',
> > + objects: [libqom.extract_all_objects(recursive: false),
> > + libhwcore.extract_all_objects(recursive: false)])
> > +
> > +rust.test('rust-qemu-api-integration',
> > + static_library(
> > + 'rust_qemu_api_integration',
> > + 'tests/tests.rs',
> > + override_options: ['rust_std=2021', 'build.rust_std=2021'],
> > + link_whole: [rust_qemu_api_objs, libqemuutil]),
> > +
> > + dependencies: [qemu_api, qemu_api_macros],
> > + suite: ['unit', 'rust'])
>
> I met the following error when trying to build the test:
It works for me, but I'll switch to your meson.build code just to be safe.
Paolo
> test('rust-qemu-api-integration',
> executable(
> 'rust_qemu_api_integration',
> 'tests/tests.rs',
> override_options: ['rust_std=2021', 'build.rust_std=2021'],
> rust_args: [
> '--test',
> ],
> install: false,
> dependencies: [qemu_api, qemu_api_macros],
> link_whole: [rust_qemu_api_objs, libqemuutil]),
> args: [
> '--test',
> '--format', 'pretty',
> ],
> protocol: 'rust',
> suite: ['unit', 'rust'])
>
> --
> Best Regards
> Junjie Mao
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 12/13] rust: provide safe wrapper for MaybeUninit::zeroed()
2024-10-18 14:43 ` [PATCH 12/13] rust: provide safe wrapper for MaybeUninit::zeroed() Paolo Bonzini
@ 2024-10-21 11:46 ` Junjie Mao
0 siblings, 0 replies; 30+ messages in thread
From: Junjie Mao @ 2024-10-21 11:46 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, Manos Pitsidianakis
Paolo Bonzini <pbonzini@redhat.com> writes:
> MaybeUninit::zeroed() is handy, but it introduces unsafe (and has a
> pretty heavy syntax in general). Introduce a trait that provides the
> same functionality while staying within safe Rust.
>
> In addition, MaybeUninit::zeroed() is not available as a "const"
> function until Rust 1.75.0, so this also prepares for having handwritten
> implementations of the trait until we can assume that version.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
--
Best Regards
Junjie Mao
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 13/13] rust: do not use TYPE_CHARDEV unnecessarily
2024-10-18 14:43 ` [PATCH 13/13] rust: do not use TYPE_CHARDEV unnecessarily Paolo Bonzini
@ 2024-10-21 11:48 ` Junjie Mao
0 siblings, 0 replies; 30+ messages in thread
From: Junjie Mao @ 2024-10-21 11:48 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, Manos Pitsidianakis
Paolo Bonzini <pbonzini@redhat.com> writes:
> In the invocation of qdev_prop_set_chr(), "chardev" is the name of a
> property rather than a type and has to match the name of the property
> in device_class.rs. Do not use TYPE_CHARDEV here, just like in the C
> version of pl011_create.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
--
Best Regards
Junjie Mao
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 08/13] rust: build integration test for the qemu_api crate
2024-10-21 11:43 ` Paolo Bonzini
@ 2024-10-21 11:51 ` Junjie Mao
2024-10-21 13:02 ` Paolo Bonzini
0 siblings, 1 reply; 30+ messages in thread
From: Junjie Mao @ 2024-10-21 11:51 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, Manos Pitsidianakis
Paolo Bonzini <pbonzini@redhat.com> writes:
> On Mon, Oct 21, 2024 at 1:35 PM Junjie Mao <junjie.mao@hotmail.com> wrote:
>>
>>
>> Paolo Bonzini <pbonzini@redhat.com> writes:
>>
>> > Adjust the integration test to compile with a subset of QEMU object
>> > files, and make it actually create an object of the class it defines.
>> >
>> > Follow the Rust filesystem conventions, where tests go in tests/ if
>> > they use the library in the same way any other code would.
>> >
>> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> > ---
>> > meson.build | 10 ++++-
>> > rust/qemu-api/meson.build | 20 +++++++--
>> > rust/qemu-api/src/tests.rs | 49 ----------------------
>> > rust/qemu-api/tests/tests.rs | 78 ++++++++++++++++++++++++++++++++++++
>> > 4 files changed, 104 insertions(+), 53 deletions(-)
>> > delete mode 100644 rust/qemu-api/src/tests.rs
>> > create mode 100644 rust/qemu-api/tests/tests.rs
>> <snip>
>> > diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build
>> > index 42ea815fa5a..d24e0c0725e 100644
>> > --- a/rust/qemu-api/meson.build
>> > +++ b/rust/qemu-api/meson.build
>> > @@ -14,11 +14,25 @@ _qemu_api_rs = static_library(
>> > '--cfg', 'MESON',
>> > # '--cfg', 'feature="allocator"',
>> > ],
>> > - dependencies: [
>> > - qemu_api_macros,
>> > - ],
>> > )
>> >
>> > qemu_api = declare_dependency(
>> > link_with: _qemu_api_rs,
>> > + dependencies: qemu_api_macros,
>> > )
>> > +
>> > +# Rust executable do not support objects, so add an intermediate step.
>> > +rust_qemu_api_objs = static_library(
>> > + 'rust_qemu_api_objs',
>> > + objects: [libqom.extract_all_objects(recursive: false),
>> > + libhwcore.extract_all_objects(recursive: false)])
>> > +
>> > +rust.test('rust-qemu-api-integration',
>> > + static_library(
>> > + 'rust_qemu_api_integration',
>> > + 'tests/tests.rs',
>> > + override_options: ['rust_std=2021', 'build.rust_std=2021'],
>> > + link_whole: [rust_qemu_api_objs, libqemuutil]),
>> > +
>> > + dependencies: [qemu_api, qemu_api_macros],
>> > + suite: ['unit', 'rust'])
>>
>> I met the following error when trying to build the test:
>
> It works for me, but I'll switch to your meson.build code just to be safe.
That's odd. What's the version of Rust and meson you have used in your
test? On my side they're 1.82.0 and 1.5.1.
Rust.test() is still preferrable to me for its brevity, as long as it
works.
--
Best Regards
Junjie Mao
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 08/13] rust: build integration test for the qemu_api crate
2024-10-21 11:51 ` Junjie Mao
@ 2024-10-21 13:02 ` Paolo Bonzini
0 siblings, 0 replies; 30+ messages in thread
From: Paolo Bonzini @ 2024-10-21 13:02 UTC (permalink / raw)
To: Junjie Mao; +Cc: qemu-devel, Manos Pitsidianakis
[-- Attachment #1: Type: text/plain, Size: 2995 bytes --]
Il lun 21 ott 2024, 13:55 Junjie Mao <junjie.mao@hotmail.com> ha scritto:
>
> Paolo Bonzini <pbonzini@redhat.com> writes:
>
> > On Mon, Oct 21, 2024 at 1:35 PM Junjie Mao <junjie.mao@hotmail.com>
> wrote:
> >>
> >>
> >> Paolo Bonzini <pbonzini@redhat.com> writes:
> >>
> >> > Adjust the integration test to compile with a subset of QEMU object
> >> > files, and make it actually create an object of the class it defines.
> >> >
> >> > Follow the Rust filesystem conventions, where tests go in tests/ if
> >> > they use the library in the same way any other code would.
> >> >
> >> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> >> > ---
> >> > meson.build | 10 ++++-
> >> > rust/qemu-api/meson.build | 20 +++++++--
> >> > rust/qemu-api/src/tests.rs | 49 ----------------------
> >> > rust/qemu-api/tests/tests.rs | 78
> ++++++++++++++++++++++++++++++++++++
> >> > 4 files changed, 104 insertions(+), 53 deletions(-)
> >> > delete mode 100644 rust/qemu-api/src/tests.rs
> >> > create mode 100644 rust/qemu-api/tests/tests.rs
> >> <snip>
> >> > diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build
> >> > index 42ea815fa5a..d24e0c0725e 100644
> >> > --- a/rust/qemu-api/meson.build
> >> > +++ b/rust/qemu-api/meson.build
> >> > @@ -14,11 +14,25 @@ _qemu_api_rs = static_library(
> >> > '--cfg', 'MESON',
> >> > # '--cfg', 'feature="allocator"',
> >> > ],
> >> > - dependencies: [
> >> > - qemu_api_macros,
> >> > - ],
> >> > )
> >> >
> >> > qemu_api = declare_dependency(
> >> > link_with: _qemu_api_rs,
> >> > + dependencies: qemu_api_macros,
> >> > )
> >> > +
> >> > +# Rust executable do not support objects, so add an intermediate
> step.
> >> > +rust_qemu_api_objs = static_library(
> >> > + 'rust_qemu_api_objs',
> >> > + objects: [libqom.extract_all_objects(recursive: false),
> >> > + libhwcore.extract_all_objects(recursive: false)])
> >> > +
> >> > +rust.test('rust-qemu-api-integration',
> >> > + static_library(
> >> > + 'rust_qemu_api_integration',
> >> > + 'tests/tests.rs',
> >> > + override_options: ['rust_std=2021', 'build.rust_std=2021'],
> >> > + link_whole: [rust_qemu_api_objs, libqemuutil]),
> >> > +
> >> > + dependencies: [qemu_api, qemu_api_macros],
> >> > + suite: ['unit', 'rust'])
> >>
> >> I met the following error when trying to build the test:
> >
> > It works for me, but I'll switch to your meson.build code just to be
> safe.
>
> That's odd. What's the version of Rust and meson you have used in your
> test? On my side they're 1.82.0 and 1.5.1.
>
Nightly and 1.5.1, but I also tested with 1.63.0.
Anyhow the extra static_library() is not too nice either; so using test()
and executable() is fine by me.
Paolo
Rust.test() is still preferrable to me for its brevity, as long as it
> works.
>
> --
> Best Regards
> Junjie Mao
>
>
[-- Attachment #2: Type: text/html, Size: 5148 bytes --]
^ permalink raw reply [flat|nested] 30+ messages in thread
end of thread, other threads:[~2024-10-21 13:03 UTC | newest]
Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-18 14:42 [PATCH 00/13] rust: miscellaneous cleanups + QOM integration tests Paolo Bonzini
2024-10-18 14:42 ` [PATCH 01/13] meson: import rust module into a global variable Paolo Bonzini
2024-10-18 14:42 ` [PATCH 02/13] meson: remove repeated search for rust_root_crate.sh Paolo Bonzini
2024-10-18 14:42 ` [PATCH 03/13] meson: pass rustc_args when building all crates Paolo Bonzini
2024-10-18 14:42 ` [PATCH 04/13] rust: do not use --no-size_t-is-usize Paolo Bonzini
2024-10-18 14:42 ` [PATCH 05/13] rust: remove uses of #[no_mangle] Paolo Bonzini
2024-10-21 10:07 ` Junjie Mao
2024-10-18 14:42 ` [PATCH 06/13] rust: remove unused macro module_init! Paolo Bonzini
2024-10-21 10:16 ` Junjie Mao
2024-10-21 10:46 ` Paolo Bonzini
2024-10-18 14:42 ` [PATCH 07/13] rust: modernize #[derive(Object)] for ELF platforms Paolo Bonzini
2024-10-21 10:23 ` Junjie Mao
2024-10-18 14:43 ` [PATCH 08/13] rust: build integration test for the qemu_api crate Paolo Bonzini
2024-10-21 10:28 ` Junjie Mao
2024-10-21 10:47 ` Paolo Bonzini
2024-10-21 11:28 ` Junjie Mao
2024-10-21 11:43 ` Paolo Bonzini
2024-10-21 11:51 ` Junjie Mao
2024-10-21 13:02 ` Paolo Bonzini
2024-10-18 14:43 ` [PATCH 09/13] rust: clean up define_property macro Paolo Bonzini
2024-10-21 10:35 ` Junjie Mao
2024-10-21 10:44 ` Paolo Bonzini
2024-10-21 11:37 ` Junjie Mao
2024-10-18 14:43 ` [PATCH 10/13] qdev: make properties array "const" Paolo Bonzini
2024-10-18 14:43 ` [PATCH 11/13] rust: make properties array immutable Paolo Bonzini
2024-10-21 11:42 ` Junjie Mao
2024-10-18 14:43 ` [PATCH 12/13] rust: provide safe wrapper for MaybeUninit::zeroed() Paolo Bonzini
2024-10-21 11:46 ` Junjie Mao
2024-10-18 14:43 ` [PATCH 13/13] rust: do not use TYPE_CHARDEV unnecessarily Paolo Bonzini
2024-10-21 11:48 ` Junjie Mao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).