File tree Expand file tree Collapse file tree 1 file changed +33
-0
lines changed Expand file tree Collapse file tree 1 file changed +33
-0
lines changed Original file line number Diff line number Diff line change @@ -942,6 +942,39 @@ pub struct InterruptStackFrameValue {
942
942
pub stack_segment : u64 ,
943
943
}
944
944
945
+ impl InterruptStackFrameValue {
946
+ /// Call the `iretq` (interrupt return) instruction.
947
+ ///
948
+ /// It is not required to be in a interrupt handler to be able to call this instruction.
949
+ /// By manually construction a new [`InterruptStackFrameValue`] it's possible to transition
950
+ /// from a higher privilege level to a lower one.
951
+ ///
952
+ /// ## Safety
953
+ ///
954
+ /// Calling `iretq` is unsafe because setting the instruction pointer, stack pointer, RFlags,
955
+ /// CS and SS register can all cause undefined behaviour when done incorrectly.
956
+ ///
957
+ #[ inline( always) ]
958
+ pub unsafe fn iretq ( & self ) -> ! {
959
+ unsafe {
960
+ core:: arch:: asm!(
961
+ "push {data_segment}" ,
962
+ "push {new_stack_pointer}" ,
963
+ "push {rflags}" ,
964
+ "push {code_segment}" ,
965
+ "push {new_instruction_pointer}" ,
966
+ "iretq" ,
967
+ rflags = in( reg) self . cpu_flags,
968
+ new_instruction_pointer = in( reg) self . instruction_pointer. as_u64( ) ,
969
+ new_stack_pointer = in( reg) self . stack_pointer. as_u64( ) ,
970
+ code_segment = in( reg) self . code_segment,
971
+ data_segment = in( reg) self . stack_segment,
972
+ options( noreturn)
973
+ )
974
+ }
975
+ }
976
+ }
977
+
945
978
impl fmt:: Debug for InterruptStackFrameValue {
946
979
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
947
980
struct Hex ( u64 ) ;
You can’t perform that action at this time.
0 commit comments