From: Paolo Bonzini Date: Tue, 7 Oct 2025 15:13:43 +0000 (+0200) Subject: rust: pull error_fatal out of SysbusDeviceMethods::sysbus_realize X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8abea41ecd9fe5614f39226c04600b177eb94b52;p=thirdparty%2Fqemu.git rust: pull error_fatal out of SysbusDeviceMethods::sysbus_realize Return a Result<()> from the method, and "unwrap" it into error_fatal in the caller. Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index 5e9b13fdf9..04155dabe1 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -17,7 +17,7 @@ use migration::{ }; use qom::{prelude::*, ObjectImpl, Owned, ParentField, ParentInit}; use system::{hwaddr, MemoryRegion, MemoryRegionOps, MemoryRegionOpsBuilder}; -use util::{log::Log, log_mask_ln}; +use util::{log::Log, log_mask_ln, ResultExt}; use crate::registers::{self, Interrupt, RegisterOffset}; @@ -697,7 +697,7 @@ pub unsafe extern "C" fn pl011_create( let chr = unsafe { Owned::::from(&*chr) }; dev.prop_set_chr("chardev", &chr); } - dev.sysbus_realize(); + dev.sysbus_realize().unwrap_fatal(); dev.mmio_map(0, addr); dev.connect_irq(0, &irq); diff --git a/rust/hw/core/src/sysbus.rs b/rust/hw/core/src/sysbus.rs index 282315fce9..68165e8929 100644 --- a/rust/hw/core/src/sysbus.rs +++ b/rust/hw/core/src/sysbus.rs @@ -4,12 +4,13 @@ //! Bindings to access `sysbus` functionality from Rust. -use std::{ffi::CStr, ptr::addr_of_mut}; +use std::ffi::CStr; pub use bindings::SysBusDeviceClass; use common::Opaque; use qom::{prelude::*, Owned}; use system::MemoryRegion; +use util::{Error, Result}; use crate::{ bindings, @@ -107,14 +108,12 @@ where } } - fn sysbus_realize(&self) { - // TODO: return an Error + fn sysbus_realize(&self) -> Result<()> { assert!(bql::is_locked()); unsafe { - bindings::sysbus_realize( - self.upcast().as_mut_ptr(), - addr_of_mut!(util::bindings::error_fatal), - ); + Error::with_errp(|errp| { + bindings::sysbus_realize(self.upcast().as_mut_ptr(), errp); + }) } } } diff --git a/rust/util/src/error.rs b/rust/util/src/error.rs index 346577e2e5..4edceff42f 100644 --- a/rust/util/src/error.rs +++ b/rust/util/src/error.rs @@ -38,7 +38,8 @@ use std::{ ffi::{c_char, c_int, c_void, CStr}, fmt::{self, Display}, ops::Deref, - panic, ptr, + panic, + ptr::{self, addr_of_mut}, }; use foreign::{prelude::*, OwnedPointer}; @@ -231,6 +232,34 @@ impl Error { } } +/// Extension trait for `std::result::Result`, providing extra +/// methods when the error type can be converted into a QEMU +/// Error. +pub trait ResultExt { + /// The success type `T` in `Result`. + type OkType; + + /// Report a fatal error and exit QEMU, or return the success value. + /// Note that, unlike [`unwrap()`](std::result::Result::unwrap), this + /// is not an abort and can be used for user errors. + fn unwrap_fatal(self) -> Self::OkType; +} + +impl ResultExt for std::result::Result +where + Error: From, +{ + type OkType = T; + + fn unwrap_fatal(self) -> T { + // SAFETY: errp is valid + self.map_err(|err| unsafe { + Error::from(err).propagate(addr_of_mut!(bindings::error_fatal)) + }) + .unwrap() + } +} + impl FreeForeign for Error { type Foreign = bindings::Error; diff --git a/rust/util/src/lib.rs b/rust/util/src/lib.rs index 16c89b9517..d14aa14ca7 100644 --- a/rust/util/src/lib.rs +++ b/rust/util/src/lib.rs @@ -6,4 +6,4 @@ pub mod log; pub mod module; pub mod timer; -pub use error::{Error, Result}; +pub use error::{Error, Result, ResultExt};