diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 387720933973..cfec5c333385 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -92,6 +92,8 @@ void warn_slowpath_fmt(const char *file, const int line, unsigned taint, const char *fmt, ...); extern __printf(1, 2) void __warn_printk(const char *fmt, ...); +void rust_panic(const char *file, int file_len, int line, void *message); + #ifndef __WARN_FLAGS #define __WARN() __WARN_printf(TAINT_WARN, NULL) #define __WARN_printf(taint, arg...) do { \ diff --git a/kernel/panic.c b/kernel/panic.c index fbc59b3b64d0..49eff489ead9 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -801,6 +801,24 @@ void __warn_printk(const char *fmt, ...) EXPORT_SYMBOL(__warn_printk); #endif +#ifdef CONFIG_RUST +void rust_panic(const char *file, int file_len, int line, void *message) +{ + pr_emerg(CUT_HERE); + nbcon_cpu_emergency_enter(); + disable_trace_on_warning(); + if (file) + pr_emerg("RUST PANIC: CPU: %d PID: %d at %.*s:%d\n", + raw_smp_processor_id(), current->pid, + file_len, file, line); + else + pr_emerg("RUST PANIC: CPU: %d PID: %d\n", + raw_smp_processor_id(), current->pid); + panic("%pA\n", message); +} +EXPORT_SYMBOL(rust_panic); +#endif + /* Support resetting WARN*_ONCE state */ static int clear_warn_once_set(void *data, u64 val) diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 1eafd696d232..51163c8749e7 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -123,9 +123,25 @@ pub const fn as_ptr(&self) -> *mut bindings::module { #[cfg(not(any(testlib, test)))] #[panic_handler] fn panic(info: &core::panic::PanicInfo<'_>) -> ! { - pr_emerg!("{}\n", info); - // SAFETY: FFI call. - unsafe { bindings::BUG() }; + use ffi::*; + + let (file, file_len, line) = match info.location() { + Some(location) => { + let file = location.file(); + (file.as_ptr(), file.len() as c_int, location.line() as c_int) + } + None => (core::ptr::null(), 0, 0), + }; + + match core::format_args!("{}", info.message()) { + args => { + let args = (&args) as *const core::fmt::Arguments<'_> as *mut c_void; + // SAFETY: FFI call. + unsafe { bindings::rust_panic(file, file_len, line, args) }; + } + } + + loop {} } /// Produces a pointer to an object from a pointer to one of its fields.