From 0b5476eddefd21da725313fa22f24fc1a002a47a Mon Sep 17 00:00:00 2001 From: Tom Dohrmann Date: Mon, 21 Oct 2024 19:28:23 +0200 Subject: [PATCH] gate HandlerFunc behind target_arch = "x86{_64}" rustc is phasing out allowing the "x86-interrupt" ABI on non-x86 targets. Using "x86-interrupt" on a non-x86 target currently causes a warning, but this will become a hard error in a future version. Previously, if `abi_x86_interrupt` was enabled (it's enabled by default ), we used it in a pointer type for the declaration of the `HandlerFunc`- family of types and used a private empty tuple if `abi_x86_interrupt` wasn't enabled. This patch changes the cfg gate to only use the "x86-interrupt" abi on x86 targets. This is technically a breaking change, but I'd like to argue that we shouldn't treat it as such: The danger with treating this as a breaking change is that we can't release this fix as a patch update and so once rustc eventually treats this as an error, we might not yet have released the next breaking version leaving our users with not published fix. My hope is that there is no one using `HandlerFunc` on a non-x86 target. Even today, declaring a function (not just a function pointer) with the "x86-interrupt" abi on a non-x86 target causes an error, so it's unlikely that this will affect real code. It's technically possible to create a `HandlerFunc` on a non-x86 target by using transmute, but, again my hope is that no one is actually doing that. I'd also like to point out that the only use of a `HandlerFunc` on a non-x86 target would be to call set_handler_fn and any such calls could simply be replaced by calls to set_handler_addr. --- src/structures/idt.rs | 55 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/src/structures/idt.rs b/src/structures/idt.rs index 4a92bacf..1da184e7 100644 --- a/src/structures/idt.rs +++ b/src/structures/idt.rs @@ -712,52 +712,82 @@ impl PartialEq for Entry { /// A handler function for an interrupt or an exception without error code. /// /// This type alias is only usable with the `abi_x86_interrupt` feature enabled. -#[cfg(feature = "abi_x86_interrupt")] +#[cfg(all( + any(target_arch = "x86", target_arch = "x86_64"), + feature = "abi_x86_interrupt" +))] pub type HandlerFunc = extern "x86-interrupt" fn(InterruptStackFrame); /// This type is not usable without the `abi_x86_interrupt` feature. -#[cfg(not(feature = "abi_x86_interrupt"))] +#[cfg(not(all( + any(target_arch = "x86", target_arch = "x86_64"), + feature = "abi_x86_interrupt" +)))] #[derive(Copy, Clone, Debug)] pub struct HandlerFunc(()); /// A handler function for an exception that pushes an error code. /// /// This type alias is only usable with the `abi_x86_interrupt` feature enabled. -#[cfg(feature = "abi_x86_interrupt")] +#[cfg(all( + any(target_arch = "x86", target_arch = "x86_64"), + feature = "abi_x86_interrupt" +))] pub type HandlerFuncWithErrCode = extern "x86-interrupt" fn(InterruptStackFrame, error_code: u64); /// This type is not usable without the `abi_x86_interrupt` feature. -#[cfg(not(feature = "abi_x86_interrupt"))] +#[cfg(not(all( + any(target_arch = "x86", target_arch = "x86_64"), + feature = "abi_x86_interrupt" +)))] #[derive(Copy, Clone, Debug)] pub struct HandlerFuncWithErrCode(()); /// A page fault handler function that pushes a page fault error code. /// /// This type alias is only usable with the `abi_x86_interrupt` feature enabled. -#[cfg(feature = "abi_x86_interrupt")] +#[cfg(all( + any(target_arch = "x86", target_arch = "x86_64"), + feature = "abi_x86_interrupt" +))] pub type PageFaultHandlerFunc = extern "x86-interrupt" fn(InterruptStackFrame, error_code: PageFaultErrorCode); /// This type is not usable without the `abi_x86_interrupt` feature. -#[cfg(not(feature = "abi_x86_interrupt"))] +#[cfg(not(all( + any(target_arch = "x86", target_arch = "x86_64"), + feature = "abi_x86_interrupt" +)))] #[derive(Copy, Clone, Debug)] pub struct PageFaultHandlerFunc(()); /// A handler function that must not return, e.g. for a machine check exception. /// /// This type alias is only usable with the `abi_x86_interrupt` feature enabled. -#[cfg(feature = "abi_x86_interrupt")] +#[cfg(all( + any(target_arch = "x86", target_arch = "x86_64"), + feature = "abi_x86_interrupt" +))] pub type DivergingHandlerFunc = extern "x86-interrupt" fn(InterruptStackFrame) -> !; /// This type is not usable without the `abi_x86_interrupt` feature. -#[cfg(not(feature = "abi_x86_interrupt"))] +#[cfg(not(all( + any(target_arch = "x86", target_arch = "x86_64"), + feature = "abi_x86_interrupt" +)))] #[derive(Copy, Clone, Debug)] pub struct DivergingHandlerFunc(()); /// A handler function with an error code that must not return, e.g. for a double fault exception. /// /// This type alias is only usable with the `abi_x86_interrupt` feature enabled. -#[cfg(feature = "abi_x86_interrupt")] +#[cfg(all( + any(target_arch = "x86", target_arch = "x86_64"), + feature = "abi_x86_interrupt" +))] pub type DivergingHandlerFuncWithErrCode = extern "x86-interrupt" fn(InterruptStackFrame, error_code: u64) -> !; /// This type is not usable without the `abi_x86_interrupt` feature. -#[cfg(not(feature = "abi_x86_interrupt"))] +#[cfg(not(all( + any(target_arch = "x86", target_arch = "x86_64"), + feature = "abi_x86_interrupt" +)))] #[derive(Copy, Clone, Debug)] pub struct DivergingHandlerFuncWithErrCode(()); @@ -853,7 +883,10 @@ pub unsafe trait HandlerFuncType { macro_rules! impl_handler_func_type { ($f:ty) => { - #[cfg(feature = "abi_x86_interrupt")] + #[cfg(all( + any(target_arch = "x86", target_arch = "x86_64"), + feature = "abi_x86_interrupt" + ))] unsafe impl HandlerFuncType for $f { #[inline] fn to_virt_addr(self) -> VirtAddr {