]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
rust: pull error_fatal out of SysbusDeviceMethods::sysbus_realize
authorPaolo Bonzini <pbonzini@redhat.com>
Tue, 7 Oct 2025 15:13:43 +0000 (17:13 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 4 Nov 2025 16:13:22 +0000 (17:13 +0100)
Return a Result<()> from the method, and "unwrap" it into error_fatal
in the caller.

Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
rust/hw/char/pl011/src/device.rs
rust/hw/core/src/sysbus.rs
rust/util/src/error.rs
rust/util/src/lib.rs

index 5e9b13fdf9258b995eea317795b4184e4e26617c..04155dabe1a28fcb274d5ce572fb754c8b761ba4 100644 (file)
@@ -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::<Chardev>::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);
 
index 282315fce99ffc2738ec22b45b6f857ed28704be..68165e8929557c3caaa4ccb87895b183d9af0ce7 100644 (file)
@@ -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);
+            })
         }
     }
 }
index 346577e2e53c7c413dc1e28921fc9bc558ef8ba6..4edceff42f3bcb6e19eceb184d7db77723b0511a 100644 (file)
@@ -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<T, E>`.
+    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<T, E> ResultExt for std::result::Result<T, E>
+where
+    Error: From<E>,
+{
+    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;
 
index 16c89b95174d0d4e81d14286260816807384d210..d14aa14ca7703f9efffcb3335c071df22a5bda81 100644 (file)
@@ -6,4 +6,4 @@ pub mod log;
 pub mod module;
 pub mod timer;
 
-pub use error::{Error, Result};
+pub use error::{Error, Result, ResultExt};