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