476d6e4c | 07-Feb-2025 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: restrict missing_const_for_fn to qemu_api crate
missing_const_for_fn is not necessarily useful or good. For example in a private API you can always add const later, and in a public API it can
rust: restrict missing_const_for_fn to qemu_api crate
missing_const_for_fn is not necessarily useful or good. For example in a private API you can always add const later, and in a public API it can be unnecessarily restrictive to annotate everything with const (blocking further improvements to the API).
Nevertheless, QEMU turns it on because qemu_api uses const quite aggressively and therefore it can be handy to have as much as possible annotated with const. Outside qemu_api though, not so much: devices are self contained consumers and if there is nothing that could use their functions in const contexts that were not anticipated.
Since missing_const_for_fn can be a bit noisy and trigger on trivial functions that no one would ever call in const context, do not turn it on everywhere and only keep it in qemu_api as a special case.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
aaf3778b | 23-Jan-2025 |
Zhao Liu <zhao1.liu@intel.com> |
rust/zeroable: Implement Zeroable with const_zero macro
The `const_zero` crate provides a nice macro to zero type-specific constants, which doesn't need to enumerates the fields one by one.
Introdu
rust/zeroable: Implement Zeroable with const_zero macro
The `const_zero` crate provides a nice macro to zero type-specific constants, which doesn't need to enumerates the fields one by one.
Introduce the `const_zero` macro to QEMU (along with its documentation), and use it to simplify the implementation of `Zeroable` trait.
Suggested-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250123163143.679841-1-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
af7edb1d | 02-Dec-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qdev: make reset take a shared reference
Because register reset is within a borrow_mut() call, reset does not need anymore a mut reference to the PL011State.
Reviewed-by: Zhao Liu <zhao1.liu@
rust: qdev: make reset take a shared reference
Because register reset is within a borrow_mut() call, reset does not need anymore a mut reference to the PL011State.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
7d052039 | 23-Jan-2025 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: prefer NonNull::new to assertions
Do not use new_unchecked; the effect is the same, but the code is easier to read and unsafe regions become smaller. Likewise, NonNull::new can be used instead
rust: prefer NonNull::new to assertions
Do not use new_unchecked; the effect is the same, but the code is easier to read and unsafe regions become smaller. Likewise, NonNull::new can be used instead of assertion and followed by as_ref() or as_mut() instead of dereferencing the pointer.
Suggested-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
24f0e8d8 | 07-Jan-2025 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: vmstate: make order of parameters consistent in vmstate_clock
Place struct_name before field_name, similar to offset_of.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
9d489949 | 07-Jan-2025 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: vmstate: remove translation of C vmstate macros
Keep vmstate_clock!; because it uses a field of type VMStateDescription, it cannot be converted to the VMState trait without access to the const
rust: vmstate: remove translation of C vmstate macros
Keep vmstate_clock!; because it uses a field of type VMStateDescription, it cannot be converted to the VMState trait without access to the const_refs_static feature.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
9a2ba488 | 21-Dec-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qemu_api: add vmstate_struct
It is not type safe, but it's the best that can be done without const_refs_static. It can also be used with BqlCell and BqlRefCell.
Signed-off-by: Paolo Bonzini
rust: qemu_api: add vmstate_struct
It is not type safe, but it's the best that can be done without const_refs_static. It can also be used with BqlCell and BqlRefCell.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
00f89716 | 21-Dec-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: vmstate: add public utility macros to implement VMState
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
f2cb78bd | 29-Dec-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: vmstate: implement VMState for scalar types
Scalar types are those that have their own VMStateInfo. This poses a problem in that references to VMStateInfo can only be included in associated c
rust: vmstate: implement VMState for scalar types
Scalar types are those that have their own VMStateInfo. This poses a problem in that references to VMStateInfo can only be included in associated consts starting with Rust 1.83.0, when the const_refs_static was stabilized. Removing the requirement is done by placing a limited list of VMStateInfos in an enum, and going from enum to &VMStateInfo only when building the VMStateField.
The same thing cannot be done with VMS_STRUCT because the set of VMStateDescriptions extends to structs defined by the devices. Therefore, structs and cells cannot yet use vmstate_of!.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
2537f830 | 29-Dec-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: vmstate: implement Zeroable for VMStateField
This shortens a bit the constants. Do not bother using it in the vmstate macros since most of them will go away soon.
Reviewed-by: Zhao Liu <zhao
rust: vmstate: implement Zeroable for VMStateField
This shortens a bit the constants. Do not bother using it in the vmstate macros since most of them will go away soon.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
5b024b4e | 19-Dec-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: vmstate: add varray support to vmstate_of!
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
80aa3045 | 29-Dec-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: vmstate: implement VMState for non-leaf types
Arrays, pointers and cells use a VMStateField that is based on that for the inner type. The implementation therefore delegates to the VMState imp
rust: vmstate: implement VMState for non-leaf types
Arrays, pointers and cells use a VMStateField that is based on that for the inner type. The implementation therefore delegates to the VMState implementation of the inner type.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
0d43ddae | 08-Dec-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: vmstate: add new type safe implementation
The existing translation of the C macros for vmstate does not make any attempt to type-check vmstate declarations against the struct, so introduce a n
rust: vmstate: add new type safe implementation
The existing translation of the C macros for vmstate does not make any attempt to type-check vmstate declarations against the struct, so introduce a new system that computes VMStateField based on the actual struct declaration.
Macros do not have full access to the type system, therefore a full implementation of this scheme requires a helper trait to analyze the type and produce a VMStateField from it; a macro "vmstate_of!" accepts arguments similar to "offset_of!" and tricks the compiler into looking up the trait for the right type.
The patch introduces not just vmstate_of!, but also the slightly too clever enabling macro call_func_with_field!. The particular trick used here was proposed on the users.rust-lang.org forum, so I take no merit and all the blame.
Introduce the trait and some functions to access it; the actual implementation comes later.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
0f9eb0ff | 21-Jan-2025 |
Zhao Liu <zhao1.liu@intel.com> |
rust/qdev: Make REALIZE safe
A safe REALIZE accepts immutable reference.
Since current PL011's realize() only calls a char binding function ( qemu_chr_fe_set_handlers), it is possible to convert mu
rust/qdev: Make REALIZE safe
A safe REALIZE accepts immutable reference.
Since current PL011's realize() only calls a char binding function ( qemu_chr_fe_set_handlers), it is possible to convert mutable reference (&mut self) to immutable reference (&self), which only needs to convert the pointers passed to C to mutable pointers.
Thus, make REALIZE accept immutable reference.
Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250121140457.84631-2-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
559a779c | 29-Nov-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qdev: expose inherited methods to subclasses of SysBusDevice
The ObjectDeref trait now provides all the magic that is required to fake inheritance. Replace the "impl SysBusDevice" block of qe
rust: qdev: expose inherited methods to subclasses of SysBusDevice
The ObjectDeref trait now provides all the magic that is required to fake inheritance. Replace the "impl SysBusDevice" block of qemu_api::sysbus with a trait, so that sysbus_init_irq() can be invoked as "self.init_irq()" without any intermediate upcast.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
22a18f0a | 29-Nov-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: qom: make INSTANCE_POST_INIT take a shared reference
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
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 ...
|