aboutsummaryrefslogtreecommitdiff
path: root/rust/qemu-api/src
AgeCommit message (Collapse)AuthorFilesLines
4 daysrust/vmstate: Include complete crate path of VMStateFlags in vmstate_clockZhao Liu1-1/+4
The use of "bindings::*" masks incomplete path of VMStateFlags. Include complete crate path of VMStateFlags in vmstate_clock, and clean up "bindings::*" in device_class.rs of pl011. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-16-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
4 daysrust/vmstate: Support vmstate_validateZhao Liu1-1/+51
In C version, VMSTATE_VALIDATE accepts the function pointer, which is used to check if some conditions of structure could meet, although the C version macro doesn't accept any structure as the opaque type. But it's hard to integrate VMSTATE_VALIDAE into vmstate_struct, a new macro has to be introduced to specifically handle the case corresponding to VMSTATE_VALIDATE. One of the difficulties is inferring the type of a callback by its name `test_fn`. We can't directly use `test_fn` as a parameter of test_cb_builder__() to get its type "F", because in this way, Rust compiler will be too conservative on drop check and complain "the destructor for this type cannot be evaluated in constant functions". Fortunately, PhantomData<T> could help in this case, because it is considered to never have a destructor, no matter its field type [*]. The `phantom__()` in the `call_func_with_field` macro provides a good example of using PhantomData to infer type. So copy this idea and apply it to the `vmstate_validate` macro. [*]: https://doc.rust-lang.org/std/ops/trait.Drop.html#drop-check Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-11-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
4 daysrust/vmstate: Re-implement VMState trait for timer bindingZhao Liu1-7/+3
At present, Rust side has a timer binding "timer::Timer", so the vmstate for timer should base on that binding instead of the raw "binding::QEMUTimer". It's possible to apply impl_vmstate_transparent for cell::Opaque and then impl_vmstate_forward for timer::Timer. But binding::QEMUTimer shouldn't be used directly, so that vmstate for such raw timer type is useless. Thus, apply impl_vmstate_scalar for timer::Timer. And since Opaque<> is useful, apply impl_vmstate_transparent for cell::Opaque as well. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-10-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
4 daysrust/vmstate: Relax array check when build varray in vmstate_structZhao Liu1-3/+9
The varry of structure created by vmstate_struct is different with vmstate_of. This is because vmstate_struct uses the `vmsd` to traverse the vmstates of structure's fields, rather than treating the structure directly as a well-defined vmstate. Therefore, there's no need to check array flag when building varray by vmstate_struct. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-9-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
4 daysrust/vmstate: Fix unnecessary VMState bound of with_varray_flag()Zhao Liu1-1/+1
The VMState type bound is not used in with_varray_flag(). And for vmstate_struct, Rust cannot infer the type of `num` from the call_func_with_field(), so this causes the compiling error because it complains "cannot satisfy `_: VMState`" in with_varray_flag(). Note Rust can infer the type in vmstate_of macro so that with_varray_flag() can work at there. It is possible that the different initialization ways in the two macros cause differences in Rust's type inference. But in fact, the VMState type bound is not used in with_varray_flag() and vmstate_varray_flag() has already checked the VMState type, it's safe to drop VMState bound of with_varray_flag(), which can fix the above compiling error. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-8-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
4 daysrust/vmstate: Fix "cannot infer type" error in vmstate_structZhao Liu1-7/+9
Rust cannot infer the type (it should be VMStateField) after Zeroable::ZERO, which cause the compiling error. To fix this error, call with_varray_flag() after VMStateField's initialization. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-7-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
4 daysrust/vmstate: Fix type check for varray in vmstate_structZhao Liu2-1/+16
When pass a varray to vmstate_struct, the `type` parameter should be the type of the element in the varray, for example: vmstate_struct!(HPETState, timers, [0 .. num_timers], VMSTATE_HPET_TIMER, BqlRefCell<HPETTimer>).with_version_id(0) But this breaks current type check, because it checks the type of `field`, which is an array type (for the above example, type of timers is [BqlRefCell<HPETTimer>; 32], not BqlRefCell<HPETTimer>). But the current assert_field_type() can no longer be extended to include new arguments, so a variant of it (a second macro containing the `num = $num:ident` parameter) had to be added to handle array cases. In this new macro, it not only checks the type of element, but also checks whether the `num` (number of elements in varray) is out of range. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-6-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
4 daysrust/vmstate: Fix size field of VMStateField with VMS_ARRAY_OF_POINTER flagZhao Liu1-0/+4
The `size` field of the VMStateField with VMS_ARRAY_OF_POINTER flag should stores the size of pointer, which depends on platform. Currently, `*const`, `*mut`, `NonNull`, `Box<>` and their wrapper are supported, and they have the same size as `usize`. Store the size (of `usize`) when VMS_ARRAY_OF_POINTER flag is set. The size may be changed when more smart pointers are supported, but now the size of "usize" is enough. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-5-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
4 daysrust/vmstate: Fix num field when varray flags are setZhao Liu1-0/+1
Array type vmstate has the VMStateField with `num` equals its length. When the varray vmstate is built based a array type, the `num` field should be cleaned to 0, because varray uses `num_offset` instead of `num` to store elements number information. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-4-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
4 daysrust/vmstate: Fix num_offset in vmstate macrosZhao Liu1-2/+2
`num_offset` is a member of `VMStateField`, and there's no need to use "." to access this field in a `VMStateField` instance. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-3-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
4 daysrust/vmstate: Remove unnecessary unsafeZhao Liu1-1/+1
Remove the `unsafe` block of vmsd, because vmsd (passed to vmstate_struct) is defined in Rust side now, and it doesn't need `unsafe`. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-2-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
4 daysrust: assertions: add static_assertPaolo Bonzini1-0/+22
Add a new assertion that is similar to "const { assert!(...) }" but can be used outside functions and with older versions of Rust. A similar macro is found in Linux, whereas the "static_assertions" crate has a const_assert macro that produces worse error messages. Suggested-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Link: https://lore.kernel.org/r/20250321112523.1774131-2-peter.maydell@linaro.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: qom: remove operations on &mutPaolo Bonzini3-89/+0
The dubious casts of mutable references to objects are not used anymore: the wrappers for qdev_init_clock_in and for IRQ and MMIO initialization can be called directly on the subclasses, without casts, plus they take a shared reference so they can just use "upcast()" instead of "upcast_mut()". Remove them. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: cell: add full example of declaring a SysBusDevicePaolo Bonzini1-0/+28
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: chardev: provide basic bindings to character devicesPaolo Bonzini2-2/+241
Most of the character device API is pretty simple, with "0 or -errno" or "number of bytes or -errno" as the convention for return codes. Add safe wrappers for the API to the CharBackend bindgen-generated struct. The API is not complete, but it covers the parts that are used by the PL011 device, plus qemu_chr_fe_write which is needed to implement the standard library Write trait. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: bindings: remove more unnecessary Send/Sync implsPaolo Bonzini1-6/+2
Send and Sync are now implemented on the opaque wrappers. Remove them from the bindings module, unless the structs are pure data containers and/or have no C functions defined on them. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: chardev: wrap Chardev with Opaque<>Paolo Bonzini3-5/+7
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: memory: wrap MemoryRegion with Opaque<>Paolo Bonzini2-17/+21
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: sysbus: wrap SysBusDevice with Opaque<>Paolo Bonzini2-11/+21
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: hpet: do not access fields of SysBusDevicePaolo Bonzini1-0/+12
Fields of SysBusDevice must only be accessed with the BQL taken. Add a wrapper that verifies that. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: qdev: wrap Clock and DeviceState with Opaque<>Paolo Bonzini3-27/+49
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: qom: wrap Object with Opaque<>Paolo Bonzini4-20/+26
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: irq: wrap IRQState with Opaque<>Paolo Bonzini2-5/+11
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: timer: wrap QEMUTimer with Opaque<> and express pinning requirementsPaolo Bonzini1-11/+36
Timers must be pinned in memory, because modify() stores a pointer to them in the TimerList. To express this requirement, change init_full() to take a pinned reference. Because the only way to obtain a Timer is through Timer::new(), which is unsafe, modify() can assume that the timer it got was later initialized; and because the initialization takes a Pin<&mut Timer> modify() can assume that the timer is pinned. In the future the pinning requirement will be expressed through the pin_init crate instead. Note that Timer is a bit different from other users of Opaque, in that it is created in Rust code rather than C code. This is why it has to use the unsafe constructors provided by Opaque; and in fact Timer::new() is also unsafe, because it leaves it to the caller to invoke init_full() before modify(). Without a call to init_full(), modify() will cause a NULL pointer dereference. An alternative could be to combine new() + init_full() by returning a pinned box; however, using a reference makes it easier to express the requirement that the opaque outlives the timer. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: vmstate: add std::pin::Pin as transparent wrapperPaolo Bonzini1-0/+1
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: qemu_api_macros: add Wrapper derive macroPaolo Bonzini1-0/+45
Add a derive macro that makes it easy to peel off all the layers of specialness (UnsafeCell, MaybeUninit, etc.) and just get a pointer to the wrapped type; and likewise add them back starting from a *mut. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: cell: add wrapper for FFI typesPaolo Bonzini1-7/+197
Inspired by the same-named type in Linux. This type provides the compiler with a correct view of what goes on with FFI types. In addition, it separates the glue code from the bindgen-generated code, allowing traits such as Send, Sync or Zeroable to be specified independently for C and Rust structs. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-25rust: qom: get rid of ClassInitImplPaolo Bonzini3-123/+94
Complete the conversion from the ClassInitImpl trait to class_init() methods. This will provide more freedom to split the qemu_api crate in separate parts. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-25rust: qom: add ObjectImpl::CLASS_INITPaolo Bonzini1-3/+11
As shown in the PL011 device, the orphan rules required a manual implementation of ClassInitImpl for anything not in the qemu_api crate; this gets in the way of moving system emulation-specific code (including DeviceClass, which as a blanket ClassInitImpl<DeviceClass> implementation) into its own crate. Make ClassInitImpl optional, at the cost of having to specify the CLASS_INIT member by hand in every implementation of ObjectImpl. The next commits will get rid of it, replacing all the "impl<T> ClassInitImpl<Class> for T" blocks with a generic class_init<T> method on Class. Right now the definition is always the same, but do not provide a default as that will not be true once ClassInitImpl goes away. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-25rust: add SysBusDeviceImplPaolo Bonzini1-3/+5
The only function, right now, is to ensure that anything with a SysBusDeviceClass class is a SysBusDevice. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-25rust: add IsA bounds to QOM implementation traitsPaolo Bonzini2-2/+4
Check that the right bounds are provided to the qom_isa! macro whenever the class is defined to implement a certain class. This removes the need to add IsA<> bounds together with the *Impl trait bounds. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-25rust: prefer importing std::ptr over core::ptrZhao Liu1-2/+1
The std::ptr is same as core::ptr, but std has already been used in many cases and there's no need to choose non-std library. So, use std::ptr directly to make the used ptr library as consistent as possible. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250218080835.3341082-1-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-25rust: add module to convert between success/-errno and io::ResultPaolo Bonzini4-0/+376
It is a common convention in QEMU to return a positive value in case of success, and a negated errno value in case of error. Unfortunately, using errno portably in Rust is a bit complicated; on Unix the errno values are supported natively by io::Error, but on Windows they are not; so, use the libc crate. This is a set of utility functions that are used by both chardev and block layer bindings. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: fix doctestsPaolo Bonzini2-2/+2
Doctests were not being run by CI, and have broken. Fix them. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: vmstate: remove redundant link targetsPaolo Bonzini1-3/+2
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: qemu_api: add a documentation header for all modulesPaolo Bonzini7-0/+27
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust/timer/hpet: define hpet_fw_cfgZhao Liu1-2/+4
Define HPETFwEntry structure with the same memory layout as hpet_fw_entry in C. Further, define the global hpet_cfg variable in Rust which is the same as the C version. This hpet_cfg variable in Rust will replace the C version one and allows both Rust code and C code to access it. The Rust version of hpet_cfg is self-contained, avoiding unsafe access to C code. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250210030051.2562726-8-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: add bindings for timerZhao Liu2-0/+99
Add timer bindings to help handle idiomatic Rust callbacks. Additionally, wrap QEMUClockType in ClockType binding to avoid unsafe calls in device code. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250210030051.2562726-7-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: add bindings for memattrsZhao Liu2-2/+15
The MemTxAttrs structure contains bitfield members, and bindgen is unable to generate an equivalent macro definition for MEMTXATTRS_UNSPECIFIED. Therefore, manually define a global constant variable MEMTXATTRS_UNSPECIFIED to support calls from Rust code. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250125125137.1223277-6-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: add bindings for gpio_{in|out} initializationZhao Liu2-5/+43
Wrap qdev_init_gpio_{in|out} as methods in DeviceMethods. And for qdev_init_gpio_in, based on FnCall, it can support idiomatic Rust callback without the need for C style wrapper. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250210030051.2562726-5-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust/irq: Add a helper to convert [InterruptSource] to pointerZhao Liu1-0/+6
This is useful when taking an InterruptSource slice and passing it to C function. Suggested-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250210030051.2562726-4-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust/qdev: add the macro to define bit propertyZhao Liu1-0/+12
HPET device (Rust device) needs to define the bit type property. Add a variant of define_property macro to define bit type property. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250210030051.2562726-3-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: pl011: convert pl011_create to safe RustPaolo Bonzini1-3/+31
Not a major change but, as a small but significant step in creating qdev bindings, show how pl011_create can be written without "unsafe" calls (apart from converting pointers to references). This also provides a starting point for creating Error** bindings. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: chardev, qdev: add bindings to qdev_prop_set_chrPaolo Bonzini3-0/+29
Because the argument to the function is an Owned<Chardev>, this also adds an ObjectType implementation to Chardev. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: irq: define ObjectType for IRQStatePaolo Bonzini1-3/+12
This is a small preparation in order to use an Owned<IRQState> for the argument to sysbus_connect_irq. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: bindings for MemoryRegionOpsPaolo Bonzini4-3/+197
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: bindings: add Send and Sync markers for types that have bindingsPaolo Bonzini2-0/+49
This is needed for the MemoryRegionOps<T> to be declared as static; Rust requires static elements to be Sync. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: qdev: switch from legacy reset to ResettablePaolo Bonzini1-24/+87
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: qdev: make ObjectImpl a supertrait of DeviceImplPaolo Bonzini1-2/+2
In practice it has to be implemented always in order to access an implementation of ClassInitImpl<ObjectClass>. Make the relationship explicit in the code. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: qom: allow initializing interface vtablesPaolo Bonzini2-2/+44
Unlike regular classes, interface vtables can only be obtained via object_class_dynamic_cast. Provide a wrapper that allows accessing the vtable and pass it to a ClassInitImpl implementation, for example ClassInitImpl<ResettableClass>. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>