When ast_from_interrupt fires on a user-mode interrupt,
POP_AREGS_ISR restores the user's r12, clobbering the SWAPGS state
that was set by SWAPGS_ENTRY_IF_NEEDED_R12 on interrupt entry.
Since the user's r12 value is preserved on the stack by pusha,
we set the state back to RETURN_TO_USER before calling _return_from_trap.

Reported by Brent Baccala
---
 x86_64/locore.S | 1 +
 1 file changed, 1 insertion(+)

diff --git a/x86_64/locore.S b/x86_64/locore.S
index 28e7d21c..b1ec6197 100644
--- a/x86_64/locore.S
+++ b/x86_64/locore.S
@@ -1021,6 +1021,7 @@ ast_from_interrupt:
                                        /* switch to kernel stack */
        call    EXT(i386_astintr)       /* take the AST */
        popq    %rsp                    /* back to PCB stack */
+       movq    $RETURN_TO_USER, %r12   /* definitely returning to user mode */
        jmp     _return_from_trap       /* return */
 
 #if    MACH_KDB
-- 
2.51.0



Reply via email to