Skip to content

Commit cc3d262

Browse files
pm215bonzini
authored andcommitted
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 <[email protected]> Signed-off-by: Peter Maydell <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 5b87a07 commit cc3d262

File tree

2 files changed

+9
-1
lines changed

2 files changed

+9
-1
lines changed

rust/hw/char/pl011/src/device.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Author(s): Manos Pitsidianakis <[email protected]>
33
// SPDX-License-Identifier: GPL-2.0-or-later
44

5-
use std::{ffi::CStr, ptr::addr_of_mut};
5+
use std::{ffi::CStr, mem::size_of, ptr::addr_of_mut};
66

77
use qemu_api::{
88
chardev::{CharBackend, Chardev, Event},
@@ -12,6 +12,7 @@ use qemu_api::{
1212
prelude::*,
1313
qdev::{Clock, ClockEvent, DeviceImpl, DeviceState, Property, ResetType, ResettablePhasesImpl},
1414
qom::{ObjectImpl, Owned, ParentField},
15+
static_assert,
1516
sysbus::{SysBusDevice, SysBusDeviceImpl},
1617
vmstate::VMStateDescription,
1718
};
@@ -124,6 +125,12 @@ pub struct PL011State {
124125
pub migrate_clock: bool,
125126
}
126127

128+
// Some C users of this device embed its state struct into their own
129+
// structs, so the size of the Rust version must not be any larger
130+
// than the size of the C one. If this assert triggers you need to
131+
// expand the padding_for_rust[] array in the C PL011State struct.
132+
static_assert!(size_of::<PL011State>() <= size_of::<qemu_api::bindings::PL011State>());
133+
127134
qom_isa!(PL011State : SysBusDevice, DeviceState, Object);
128135

129136
#[repr(C)]

rust/wrapper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,4 @@ typedef enum memory_order {
6565
#include "exec/memattrs.h"
6666
#include "qemu/timer.h"
6767
#include "exec/address-spaces.h"
68+
#include "hw/char/pl011.h"

0 commit comments

Comments
 (0)