af68b41d | 02-Dec-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: pl011: only leave embedded object initialization in instance_init
Leave IRQ and MMIO initialization to instance_post_init. In Rust the two callbacks are more distinct, because only instance_p
rust: pl011: only leave embedded object initialization in instance_init
Leave IRQ and MMIO initialization to instance_post_init. In Rust the two callbacks are more distinct, because only instance_post_init has a fully initialized object available.
While at it, add a wrapper for sysbus_init_mmio so that accesses to the SysBusDevice correctly use shared references.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
33aa6605 | 11-Dec-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qom: automatically use Drop trait to implement instance_finalize
Replace the customizable INSTANCE_FINALIZE with a generic function that drops the Rust object.
Reviewed-by: Zhao Liu <zhao1.li
rust: qom: automatically use Drop trait to implement instance_finalize
Replace the customizable INSTANCE_FINALIZE with a generic function that drops the Rust object.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
7f65d4e5 | 11-Dec-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: add a utility module for compile-time type checks
It is relatively common in the low-level qemu_api code to assert that a field of a struct has a specific type; for example, it can be used to
rust: add a utility module for compile-time type checks
It is relatively common in the low-level qemu_api code to assert that a field of a struct has a specific type; for example, it can be used to ensure that the fields match what the qemu_api and C code expects for safety.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
ca0d60a6 | 11-Dec-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qom: add ParentField
Add a type that, together with the C function object_deinit, ensures the correct drop order for QOM objects relative to their superclasses.
Right now it is not possible t
rust: qom: add ParentField
Add a type that, together with the C function object_deinit, ensures the correct drop order for QOM objects relative to their superclasses.
Right now it is not possible to implement the Drop trait for QOM classes that are defined in Rust, as the drop() function would not be called when the object goes away; instead what is called is ObjectImpl::INSTANCE_FINALIZE. It would be nice for INSTANCE_FINALIZE to just drop the object, but this has a problem: suppose you have
pub struct MySuperclass { parent: DeviceState, field: Box<MyData>, ... }
impl Drop for MySuperclass { ... }
pub struct MySubclass { parent: MySuperclass, ... }
and an instance_finalize implementation that is like
unsafe extern "C" fn drop_object<T: ObjectImpl>(obj: *mut Object) { unsafe { std::ptr::drop_in_place(obj.cast::<T>()) } }
When instance_finalize is called for MySubclass, it will walk the struct's list of fields and call the drop method for MySuperclass. Then, object_deinit recurses to the superclass and calls the same drop method again. This will cause double-freeing of the Box<Data>.
What's happening here is that QOM wants to control the drop order of MySuperclass and MySubclass's fields. To do so, the parent field must be marked ManuallyDrop<>, which is quite ugly. Instead, add a wrapper type ParentField<> that is specific to QOM. This hides the implementation detail of *what* is special about the ParentField, and will also be easy to check in the #[derive(Object)] macro.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
6b4f7b07 | 10-Dec-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: pl011: fix migration stream
The Rust vmstate macros lack the type-safety of their C equivalents (so safe, much abstraction), and therefore they were predictably wrong.
The registers have alre
rust: pl011: fix migration stream
The Rust vmstate macros lack the type-safety of their C equivalents (so safe, much abstraction), and therefore they were predictably wrong.
The registers have already been changed to 32-bits in the previous patch, but read_pos/read_count/read_trigger also have to be u32 instead of usize. The easiest way to do so is to let the FIFO use u32 indices instead of usize.
My plan for making VMStateField typesafe is to have a trait to retrieve a basic VMStateField; for example something like vmstate_uint32 would become an implementation of the VMState trait on u32. Then you'd write something like "vmstate_of!(Type, field).with_version_id(2)". That is, vmstate_of retrieves the basic VMStateField and fills in the offset, and then more changes can be applied on top.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
e05fbacd | 30-Nov-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qemu-api: add a module to wrap functions and zero-sized closures
One recurring issue when writing Rust bindings is how to convert a Rust function ("fn" or "impl Fn") to a C function, and how t
rust: qemu-api: add a module to wrap functions and zero-sized closures
One recurring issue when writing Rust bindings is how to convert a Rust function ("fn" or "impl Fn") to a C function, and how to pass around "self" to a C function that only takes a void*.
An easy solution would be to store on the heap a pair consisting of a pointer to the Rust function and the pointer to "self", but it is possible to do better. If an "Fn" has zero size (that is, if it is a zero-capture closures or a function pointer---which in turn includes all methods), it is possible to build a generic Rust function that calls it even if you only have the type; you don't need either the pointer to the function itself (because the address of the code is part of the type) or any closure data (because it has size zero).
Introduce a wrapper that provides the functionality of calling the function given only its type.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
ba3b81f3 | 05-Nov-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qom: add initial subset of methods on Object
Add an example of implementing instance methods and converting the result back to a Rust type. In this case the returned types are a string (actua
rust: qom: add initial subset of methods on Object
Add an example of implementing instance methods and converting the result back to a Rust type. In this case the returned types are a string (actually a Cow<str>; but that's transparent as long as it derefs to &str) and a QOM class.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
f50cd85c | 19-Dec-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qom: add casting functionality
Add traits that let client cast typecast safely between object types. In particular, an upcast is compile-time guaranteed to succeed, and a YOLO C-style downcast
rust: qom: add casting functionality
Add traits that let client cast typecast safely between object types. In particular, an upcast is compile-time guaranteed to succeed, and a YOLO C-style downcast must be marked as unsafe.
The traits are based on an IsA<> trait that declares what is a subclass of what, which is an idea taken from glib-rs (https://docs.rs/glib/latest/glib/object/trait.IsA.html). The four primitives are also taken from there (https://docs.rs/glib/latest/glib/object/trait.Cast.html). However, the implementation of casting itself is a bit different and uses the Deref trait.
This removes some pointer arithmetic from the pl011 device; it is also a prerequisite for the definition of methods, so that they can be invoked on all subclass structs. This will use the IsA<> trait to detect the structs that support the methods.
glib also has a "monadic" casting trait which could be implemented on Option (as in https://docs.rs/glib/latest/glib/object/trait.CastNone.html) and perhaps even Result. For now I'm leaving it out, as the patch is already big enough and the benefit seems debatable.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
d4873c5d | 15-Nov-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
bql: add a "mock" BQL for Rust unit tests
Right now, the stub BQL in stubs/iothread-lock.c always reports itself as unlocked. However, Rust would like to run its tests in an environment where the B
bql: add a "mock" BQL for Rust unit tests
Right now, the stub BQL in stubs/iothread-lock.c always reports itself as unlocked. However, Rust would like to run its tests in an environment where the BQL *is* locked. Provide an extremely dirty function that flips the return value of bql_is_locked() to true.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
716d89f9 | 31-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: re-export C types from qemu-api submodules
Long term we do not want device code to use "bindings" at all, so make it possible to get the relevant types from the other modules of qemu-api.
Rev
rust: re-export C types from qemu-api submodules
Long term we do not want device code to use "bindings" at all, so make it possible to get the relevant types from the other modules of qemu-api.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
4aed0296 | 29-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: rename qemu-api modules to follow C code a bit more
A full match would mean calling them qom::object and hw::core::qdev. For now, keep the names shorter but still a bit easier to find.
Revie
rust: rename qemu-api modules to follow C code a bit more
A full match would mean calling them qom::object and hw::core::qdev. For now, keep the names shorter but still a bit easier to find.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
cb36da9b | 29-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qom: add possibility of overriding unparent
Add a blanket definition of ClassInitImpl<ObjectClass> that thunks ObjectImpl::UNPARENT and overrides it in ObjectClass if it is not None.
ClassIni
rust: qom: add possibility of overriding unparent
Add a blanket definition of ClassInitImpl<ObjectClass> that thunks ObjectImpl::UNPARENT and overrides it in ObjectClass if it is not None.
ClassInitImpl<DeviceClass> can now call its superclass's ClassInitImpl, so that the C and Rust hierarchies match more closely.
This is mostly done as an example of implementing the metaclass hierarchy under ClassInitImpl.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
6dd818fb | 29-Nov-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qom: put class_init together from multiple ClassInitImpl<>
Parameterize the implementation of ClassInitImpl so that it is possible to call up the chain of implementations, one superclass at a
rust: qom: put class_init together from multiple ClassInitImpl<>
Parameterize the implementation of ClassInitImpl so that it is possible to call up the chain of implementations, one superclass at a time starting at ClassInitImpl<Self::Class>.
In order to avoid having to implement (for example) ClassInitImpl<PL011Class>, also remove the dummy PL011Class and PL011LuminaryClass structs and specify the same ObjectType::Class as the superclass. In the future this default behavior can be handled by a procedural macro, by looking at the first field in the struct.
Note that the new trait is safe: the calls are started by rust_class_init<>(), which is not public and can convert the class pointer to a Rust reference.
Since CLASS_BASE_INIT applies to the type that is being defined, and only to it, move it to ObjectImpl.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
5f997648 | 18-Dec-2024 |
Richard Henderson <richard.henderson@linaro.org> |
rust/qemu-api: Use device_class_set_props_n
This means we can update declare_properties to drop the zero terminator at the end of the array as well.
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
rust/qemu-api: Use device_class_set_props_n
This means we can update declare_properties to drop the zero terminator at the end of the array as well.
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Tested-by: Lei Yang <leiyang@redhat.com> Link: https://lore.kernel.org/r/20241218134251.4724-18-richard.henderson@linaro.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
166e8a1f | 24-Nov-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qom: change the parent type to an associated type
Avoid duplicated code to retrieve the QOM type strings from the Rust type.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo B
rust: qom: change the parent type to an associated type
Avoid duplicated code to retrieve the QOM type strings from the Rust type.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
7bd8e3ef | 31-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qom: split ObjectType from ObjectImpl trait
Define a separate trait for fields that also applies to classes that are defined by C code. This makes it possible to add metadata to core classes,
rust: qom: split ObjectType from ObjectImpl trait
Define a separate trait for fields that also applies to classes that are defined by C code. This makes it possible to add metadata to core classes, which has multiple uses:
- it makes it possible to access the parent struct's TYPE_* for types that are defined in Rust code, and to avoid repeating it in every subclass
- implementors of ObjectType will be allowed to implement the IsA<> trait and therefore to perform typesafe casts from one class to another.
- in the future, an ObjectType could be created with Foo::new() in a type-safe manner, without having to pass a TYPE_* constant.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
1f9d52c9 | 28-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qom: move bridge for TypeInfo functions out of pl011
Allow the ObjectImpl trait to expose Rust functions that avoid raw pointers (though INSTANCE_INIT for example is still unsafe). ObjectImpl:
rust: qom: move bridge for TypeInfo functions out of pl011
Allow the ObjectImpl trait to expose Rust functions that avoid raw pointers (though INSTANCE_INIT for example is still unsafe). ObjectImpl::TYPE_INFO adds thunks around the functions in ObjectImpl.
While at it, document `TypeInfo`.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
f75fb90f | 12-Nov-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qdev: move bridge for realize and reset functions out of pl011
Allow the DeviceImpl trait to expose safe Rust functions. rust_device_class_init<> adds thunks around the functions in DeviceImpl
rust: qdev: move bridge for realize and reset functions out of pl011
Allow the DeviceImpl trait to expose safe Rust functions. rust_device_class_init<> adds thunks around the functions in DeviceImpl.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
8c80c472 | 28-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qdev: move device_class_init! body to generic function, ClassInitImpl implementation to macro
Use a trait to access the former parameters to device_class_init!. This allows hiding the details
rust: qdev: move device_class_init! body to generic function, ClassInitImpl implementation to macro
Use a trait to access the former parameters to device_class_init!. This allows hiding the details of the class_init implementation behind a generic function and makes higher-level functionality available from qemu_api.
The implementation of ClassInitImpl is then the same for all devices and is easily macroized. Later on, we can remove the need to implement ClassInitImpl by hand for all device types, and stop making rust_device_class_init<>() public.
While at it, document the members of DeviceImpl.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
c6c4f3e0 | 28-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qom: move ClassInitImpl to the instance side
Put all traits on the instance struct, which makes it possible to reuse class structs if no new virtual methods or class fields are added. This is
rust: qom: move ClassInitImpl to the instance side
Put all traits on the instance struct, which makes it possible to reuse class structs if no new virtual methods or class fields are added. This is almost always the case for devices (because they are leaf classes), which is the primary use case for Rust.
This is also simpler: soon we will find the implemented methods without macros, and this removes the need to go from the class struct to the instance struct to find the implementation of the *Impl traits.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
3701fb22 | 28-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qom: convert type_info! macro to an associated const
type_info! is only used in the definition of ObjectImpl::TYPE_INFO, and in fact in all of them. Pull type_info!'s definition into the Obje
rust: qom: convert type_info! macro to an associated const
type_info! is only used in the definition of ObjectImpl::TYPE_INFO, and in fact in all of them. Pull type_info!'s definition into the ObjectImpl trait, thus simplifying the external interface of qemu_api::definitions.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
93ea0896 | 28-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qom: rename Class trait to ClassInitImpl
While at it, document it.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
b2a48545 | 28-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qom: add default definitions for ObjectImpl
Remove a bunch of duplicate const definitions.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
ab870fa1 | 05-Dec-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: add a bit operation module
The bindgen supports `static inline` function binding since v0.64.0 as an experimental feature (`--wrap-static-fns`), and stabilizes it after v0.70.0.
But the oldes
rust: add a bit operation module
The bindgen supports `static inline` function binding since v0.64.0 as an experimental feature (`--wrap-static-fns`), and stabilizes it after v0.70.0.
But the oldest version of bindgen supported by QEMU is v0.60.1, so there's no way to generate the binding for deposit64() which is `static inline` (in include/qemu/bitops.h).
Instead, implement it by hand in Rust and make it available for all unsigned types through an IntegerExt trait. Since it only involves bit operations, the Rust version of the code is almost identical to the original C version, but it applies to more types than just u64.
Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Co-authored-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
4ed4da16 | 31-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: add bindings for interrupt sources
The InterruptSource bindings let us call qemu_set_irq() and sysbus_init_irq() as safe code.
Interrupt sources, qemu_irq in C code, are pointers to IRQState
rust: add bindings for interrupt sources
The InterruptSource bindings let us call qemu_set_irq() and sysbus_init_irq() as safe code.
Interrupt sources, qemu_irq in C code, are pointers to IRQState objects. They are QOM link properties and can be written to outside the control of the device (i.e. from a shared reference); therefore they must be interior-mutable in Rust. Since thread-safety is provided by the BQL, what we want here is the newly-introduced BqlCell. A pointer to the contents of the BqlCell (an IRQState**, or equivalently qemu_irq*) is then passed to the C sysbus_init_irq function.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|