@@ -16,6 +16,7 @@ use core::fmt;
16
16
use core:: marker:: PhantomData ;
17
17
use core:: ops:: Bound :: { Excluded , Included , Unbounded } ;
18
18
use core:: ops:: { Deref , Index , IndexMut , RangeBounds } ;
19
+ use volatile:: Volatile ;
19
20
20
21
/// An Interrupt Descriptor Table with 256 entries.
21
22
///
@@ -572,18 +573,17 @@ pub struct Entry<F> {
572
573
}
573
574
574
575
/// A handler function for an interrupt or an exception without error code.
575
- pub type HandlerFunc = extern "x86-interrupt" fn ( & mut InterruptStackFrame ) ;
576
+ pub type HandlerFunc = extern "x86-interrupt" fn ( InterruptStackFrame ) ;
576
577
/// A handler function for an exception that pushes an error code.
577
- pub type HandlerFuncWithErrCode =
578
- extern "x86-interrupt" fn ( & mut InterruptStackFrame , error_code : u64 ) ;
578
+ pub type HandlerFuncWithErrCode = extern "x86-interrupt" fn ( InterruptStackFrame , error_code : u64 ) ;
579
579
/// A page fault handler function that pushes a page fault error code.
580
580
pub type PageFaultHandlerFunc =
581
- extern "x86-interrupt" fn ( & mut InterruptStackFrame , error_code : PageFaultErrorCode ) ;
581
+ extern "x86-interrupt" fn ( InterruptStackFrame , error_code : PageFaultErrorCode ) ;
582
582
/// A handler function that must not return, e.g. for a machine check exception.
583
- pub type DivergingHandlerFunc = extern "x86-interrupt" fn ( & mut InterruptStackFrame ) -> !;
583
+ pub type DivergingHandlerFunc = extern "x86-interrupt" fn ( InterruptStackFrame ) -> !;
584
584
/// A handler function with an error code that must not return, e.g. for a double fault exception.
585
585
pub type DivergingHandlerFuncWithErrCode =
586
- extern "x86-interrupt" fn ( & mut InterruptStackFrame , error_code : u64 ) -> !;
586
+ extern "x86-interrupt" fn ( InterruptStackFrame , error_code : u64 ) -> !;
587
587
588
588
impl < F > Entry < F > {
589
589
/// Creates a non-present IDT entry (but sets the must-be-one bits).
@@ -721,16 +721,22 @@ pub struct InterruptStackFrame {
721
721
impl InterruptStackFrame {
722
722
/// Gives mutable access to the contents of the interrupt stack frame.
723
723
///
724
+ /// The `Volatile` wrapper is used because LLVM optimizations remove non-volatile
725
+ /// modifications of the interrupt stack frame.
726
+ ///
724
727
/// ## Safety
725
728
///
726
729
/// This function is unsafe since modifying the content of the interrupt stack frame
727
730
/// can easily lead to undefined behavior. For example, by writing an invalid value to
728
731
/// the instruction pointer field, the CPU can jump to arbitrary code at the end of the
729
732
/// interrupt.
733
+ ///
734
+ /// Also, it is not fully clear yet whether modifications of the interrupt stack frame are
735
+ /// officially supported by LLVM's x86 interrupt calling convention.
730
736
#[ allow( clippy:: should_implement_trait) ]
731
737
#[ inline]
732
- pub unsafe fn as_mut ( & mut self ) -> & mut InterruptStackFrameValue {
733
- & mut self . value
738
+ pub unsafe fn as_mut ( & mut self ) -> Volatile < & mut InterruptStackFrameValue > {
739
+ Volatile :: new ( & mut self . value )
734
740
}
735
741
}
736
742
0 commit comments