This is useful to hanlde InterruptSource slice and pass it to C bindings. Suggested-by: Paolo Bonzini <pbonz...@redhat.com> Signed-off-by: Zhao Liu <zhao1....@intel.com> --- Changes since RFC: * New commit. --- rust/qemu-api/src/irq.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/rust/qemu-api/src/irq.rs b/rust/qemu-api/src/irq.rs index 638545c3a649..7dca3b9ee5a8 100644 --- a/rust/qemu-api/src/irq.rs +++ b/rust/qemu-api/src/irq.rs @@ -5,12 +5,10 @@ //! Bindings for interrupt sources use core::ptr; -use std::{marker::PhantomData, os::raw::c_int}; +use std::{marker::PhantomData, os::raw::c_int, slice}; -use crate::{ - bindings::{qemu_set_irq, IRQState}, - prelude::*, -}; +pub(crate) use crate::bindings::IRQState; +use crate::{bindings::qemu_set_irq, prelude::*}; /// Interrupt sources are used by devices to pass changes to a value (typically /// a boolean). The interrupt sink is usually an interrupt controller or @@ -81,6 +79,16 @@ pub fn set(&self, level: T) { pub(crate) const fn as_ptr(&self) -> *mut *mut IRQState { self.cell.as_ptr() } + + #[allow(dead_code)] + pub(crate) fn as_slice_of_qemu_irq(slice: &[Self]) -> &[*mut IRQState] { + unsafe { + // SAFETY: InterruptSource has the same memory layout as *mut IRQState. + // Additionally, the slice parameter itself, as a reference to a slice type, + // can be converted into a valid pointer and has a valid length. + slice::from_raw_parts(slice.as_ptr().cast::<*mut IRQState>(), slice.len()) + } + } } impl Default for InterruptSource { -- 2.34.1