@@ -16,6 +16,7 @@ use core::fmt;
1616use core:: marker:: PhantomData ;
1717use core:: ops:: Bound :: { Excluded , Included , Unbounded } ;
1818use core:: ops:: { Deref , Index , IndexMut , RangeBounds } ;
19+ use volatile:: Volatile ;
1920
2021/// An Interrupt Descriptor Table with 256 entries.
2122///
@@ -572,18 +573,17 @@ pub struct Entry<F> {
572573}
573574
574575/// 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 ) ;
576577/// 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 ) ;
579579/// A page fault handler function that pushes a page fault error code.
580580pub type PageFaultHandlerFunc =
581- extern "x86-interrupt" fn ( & mut InterruptStackFrame , error_code : PageFaultErrorCode ) ;
581+ extern "x86-interrupt" fn ( InterruptStackFrame , error_code : PageFaultErrorCode ) ;
582582/// 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 ) -> !;
584584/// A handler function with an error code that must not return, e.g. for a double fault exception.
585585pub type DivergingHandlerFuncWithErrCode =
586- extern "x86-interrupt" fn ( & mut InterruptStackFrame , error_code : u64 ) -> !;
586+ extern "x86-interrupt" fn ( InterruptStackFrame , error_code : u64 ) -> !;
587587
588588impl < F > Entry < F > {
589589 /// Creates a non-present IDT entry (but sets the must-be-one bits).
@@ -721,16 +721,22 @@ pub struct InterruptStackFrame {
721721impl InterruptStackFrame {
722722 /// Gives mutable access to the contents of the interrupt stack frame.
723723 ///
724+ /// The `Volatile` wrapper is used because LLVM optimizations remove non-volatile
725+ /// modifications of the interrupt stack frame.
726+ ///
724727 /// ## Safety
725728 ///
726729 /// This function is unsafe since modifying the content of the interrupt stack frame
727730 /// can easily lead to undefined behavior. For example, by writing an invalid value to
728731 /// the instruction pointer field, the CPU can jump to arbitrary code at the end of the
729732 /// 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.
730736 #[ allow( clippy:: should_implement_trait) ]
731737 #[ 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 )
734740 }
735741}
736742
0 commit comments