aboutsummaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2025-03-21 11:25:23 +0000
committerPaolo Bonzini <pbonzini@redhat.com>2025-03-21 12:51:16 +0100
commitcc3d262aa93a42e19c38f6acb6d0f6012a71eb4b (patch)
tree84e1990458c769671d9930ddb42f1cae4db5b099 /rust
parent5b87a07e76816ed61e5968eb370859a5901b8516 (diff)
downloadqemu-cc3d262aa93a42e19c38f6acb6d0f6012a71eb4b.zip
qemu-cc3d262aa93a42e19c38f6acb6d0f6012a71eb4b.tar.gz
qemu-cc3d262aa93a42e19c38f6acb6d0f6012a71eb4b.tar.bz2
rust: pl011: Check size of state struct at compile time
The PL011 device's C implementation exposes its PL011State struct to users of the device, and one common usage pattern is to embed that struct into the user's own state struct. (The internals of the struct are technically visible to the C user of the device, but in practice are treated as implementation details.) This means that the Rust version of the state struct must not be larger than the C version's struct; otherwise it will trip a runtime assertion in object_initialize_type() when the C user attempts to in-place initialize the type. Add a compile-time assertion on the Rust side, so that if we accidentally make the Rust device state larger we know immediately that we need to expand the padding in the C version of the struct. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Link: https://lore.kernel.org/r/20250321112523.1774131-4-peter.maydell@linaro.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'rust')
-rw-r--r--rust/hw/char/pl011/src/device.rs9
-rw-r--r--rust/wrapper.h1
2 files changed, 9 insertions, 1 deletions
diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs
index f137b49..bf88e0b 100644
--- a/rust/hw/char/pl011/src/device.rs
+++ b/rust/hw/char/pl011/src/device.rs
@@ -2,7 +2,7 @@
// Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
// SPDX-License-Identifier: GPL-2.0-or-later
-use std::{ffi::CStr, ptr::addr_of_mut};
+use std::{ffi::CStr, mem::size_of, ptr::addr_of_mut};
use qemu_api::{
chardev::{CharBackend, Chardev, Event},
@@ -12,6 +12,7 @@ use qemu_api::{
prelude::*,
qdev::{Clock, ClockEvent, DeviceImpl, DeviceState, Property, ResetType, ResettablePhasesImpl},
qom::{ObjectImpl, Owned, ParentField},
+ static_assert,
sysbus::{SysBusDevice, SysBusDeviceImpl},
vmstate::VMStateDescription,
};
@@ -124,6 +125,12 @@ pub struct PL011State {
pub migrate_clock: bool,
}
+// Some C users of this device embed its state struct into their own
+// structs, so the size of the Rust version must not be any larger
+// than the size of the C one. If this assert triggers you need to
+// expand the padding_for_rust[] array in the C PL011State struct.
+static_assert!(size_of::<PL011State>() <= size_of::<qemu_api::bindings::PL011State>());
+
qom_isa!(PL011State : SysBusDevice, DeviceState, Object);
#[repr(C)]
diff --git a/rust/wrapper.h b/rust/wrapper.h
index d927ad6..d4fec54 100644
--- a/rust/wrapper.h
+++ b/rust/wrapper.h
@@ -65,3 +65,4 @@ typedef enum memory_order {
#include "exec/memattrs.h"
#include "qemu/timer.h"
#include "exec/address-spaces.h"
+#include "hw/char/pl011.h"