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 {
942942 pub stack_segment : u64 ,
943943}
944944
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+
945978impl fmt:: Debug for InterruptStackFrameValue {
946979 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
947980 struct Hex ( u64 ) ;
You can’t perform that action at this time.
0 commit comments