summary refs log tree commit diff stats
path: root/rust/qemu-api/src (follow)
Commit message (Collapse)AuthorAgeFilesLines
* rust/vmstate: Fix unnecessary VMState bound of with_varray_flag()Zhao Liu2025-03-211-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>
* rust/vmstate: Fix "cannot infer type" error in vmstate_structZhao Liu2025-03-211-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>
* rust/vmstate: Fix type check for varray in vmstate_structZhao Liu2025-03-212-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>
* rust/vmstate: Fix size field of VMStateField with VMS_ARRAY_OF_POINTER flagZhao Liu2025-03-211-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>
* rust/vmstate: Fix num field when varray flags are setZhao Liu2025-03-211-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>
* rust/vmstate: Fix num_offset in vmstate macrosZhao Liu2025-03-211-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>
* rust/vmstate: Remove unnecessary unsafeZhao Liu2025-03-211-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>
* rust: assertions: add static_assertPaolo Bonzini2025-03-211-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>
* rust: qom: remove operations on &mutPaolo Bonzini2025-03-063-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>
* rust: cell: add full example of declaring a SysBusDevicePaolo Bonzini2025-03-061-0/+28
| | | | | Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* rust: chardev: provide basic bindings to character devicesPaolo Bonzini2025-03-062-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>
* rust: bindings: remove more unnecessary Send/Sync implsPaolo Bonzini2025-03-061-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>
* rust: chardev: wrap Chardev with Opaque<>Paolo Bonzini2025-03-063-5/+7
| | | | | Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* rust: memory: wrap MemoryRegion with Opaque<>Paolo Bonzini2025-03-062-17/+21
| | | | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* rust: sysbus: wrap SysBusDevice with Opaque<>Paolo Bonzini2025-03-062-11/+21
| | | | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* rust: hpet: do not access fields of SysBusDevicePaolo Bonzini2025-03-061-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>
* rust: qdev: wrap Clock and DeviceState with Opaque<>Paolo Bonzini2025-03-063-27/+49
| | | | | Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* rust: qom: wrap Object with Opaque<>Paolo Bonzini2025-03-064-20/+26
| | | | | Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* rust: irq: wrap IRQState with Opaque<>Paolo Bonzini2025-03-062-5/+11
| | | | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* rust: timer: wrap QEMUTimer with Opaque<> and express pinning requirementsPaolo Bonzini2025-03-061-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>
* rust: vmstate: add std::pin::Pin as transparent wrapperPaolo Bonzini2025-03-061-0/+1
| | | | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* rust: qemu_api_macros: add Wrapper derive macroPaolo Bonzini2025-03-061-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>
* rust: cell: add wrapper for FFI typesPaolo Bonzini2025-03-061-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>
* rust: qom: get rid of ClassInitImplPaolo Bonzini2025-02-253-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>
* rust: qom: add ObjectImpl::CLASS_INITPaolo Bonzini2025-02-251-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>
* rust: add SysBusDeviceImplPaolo Bonzini2025-02-251-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>
* rust: add IsA bounds to QOM implementation traitsPaolo Bonzini2025-02-252-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>
* rust: prefer importing std::ptr over core::ptrZhao Liu2025-02-251-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>
* rust: add module to convert between success/-errno and io::ResultPaolo Bonzini2025-02-254-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>
* rust: fix doctestsPaolo Bonzini2025-02-132-2/+2
| | | | | | Doctests were not being run by CI, and have broken. Fix them. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* rust: vmstate: remove redundant link targetsPaolo Bonzini2025-02-131-3/+2
| | | | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* rust: qemu_api: add a documentation header for all modulesPaolo Bonzini2025-02-137-0/+27
| | | | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* rust/timer/hpet: define hpet_fw_cfgZhao Liu2025-02-131-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>
* rust: add bindings for timerZhao Liu2025-02-132-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>
* rust: add bindings for memattrsZhao Liu2025-02-132-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>
* rust: add bindings for gpio_{in|out} initializationZhao Liu2025-02-132-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>
* rust/irq: Add a helper to convert [InterruptSource] to pointerZhao Liu2025-02-131-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>
* rust/qdev: add the macro to define bit propertyZhao Liu2025-02-131-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>
* rust: pl011: convert pl011_create to safe RustPaolo Bonzini2025-02-131-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>
* rust: chardev, qdev: add bindings to qdev_prop_set_chrPaolo Bonzini2025-02-133-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>
* rust: irq: define ObjectType for IRQStatePaolo Bonzini2025-02-131-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>
* rust: bindings for MemoryRegionOpsPaolo Bonzini2025-02-134-3/+197
| | | | | Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* rust: bindings: add Send and Sync markers for types that have bindingsPaolo Bonzini2025-02-132-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>
* rust: qdev: switch from legacy reset to ResettablePaolo Bonzini2025-02-131-24/+87
| | | | | Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* rust: qdev: make ObjectImpl a supertrait of DeviceImplPaolo Bonzini2025-02-131-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>
* rust: qom: allow initializing interface vtablesPaolo Bonzini2025-02-132-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>
* rust: qdev: add clock creationPaolo Bonzini2025-02-133-5/+108
| | | | | | | | | | | | | | | | | | | | | | Add a Rust version of qdev_init_clock_in, which can be used in instance_init. There are a couple differences with the C version: - in Rust the object keeps its own reference to the clock (in addition to the one embedded in the NamedClockList), and the reference is dropped automatically by instance_finalize(); this is encoded in the signature of DeviceClassMethods::init_clock_in, which makes the lifetime of the clock independent of that of the object it holds. This goes unnoticed in the C version and is due to the existence of aliases. - also, anything that happens during instance_init uses the pinned_init framework to operate on a partially initialized object, and is done through class methods (i.e. through DeviceClassMethods rather than DeviceMethods) because the device does not exist yet. Therefore, Rust code *must* create clocks from instance_init, which is stricter than C. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* rust: callbacks: allow passing optional callbacks as ()Paolo Bonzini2025-02-131-0/+97
| | | | | | | | | | | | | In some cases, callbacks are optional. Using "Some(function)" and "None" does not work well, because when someone writes "None" the compiler does not know what to use for "F" in "Option<F>". Therefore, adopt () to mean a "null" callback. It is possible to enforce that a callback is valid by adding a "let _: () = F::ASSERT_IS_SOME" before the invocation of F::call. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* rust: qom: add object creation functionalityPaolo Bonzini2025-02-132-2/+22
| | | | | | | The basic object lifecycle test can now be implemented using safe code! Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* rust: qom: add reference counting functionalityPaolo Bonzini2025-02-132-6/+166
| | | | | | | | | | | | | | Add a smart pointer that allows to add and remove references from QOM objects. It's important to note that while all QOM objects have a reference count, in practice not all of them have their lifetime guarded by it. Embedded objects, specifically, are confined to the lifetime of the owner. When writing Rust bindings this is important, because embedded objects are *never* used through the "Owned<>" smart pointer that is introduced here. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>