Disable local interrupts before testing the PCB_FULL_IRET flag.

Thread might be preempted after testing, which causes the flag to be
cleared. If ast was not delivered, we will do sysret with potentially
wrong fs/gs bases.

Reviewed by:	jhb, jkim
MFC after:	1 week (together with r220430, r220452)
This commit is contained in:
kib 2011-04-08 21:26:50 +00:00
parent 096c7a804f
commit dae91cc140

View File

@ -383,10 +383,11 @@ IDTVEC(fast_syscall)
movq %rsp,%rdi movq %rsp,%rdi
call syscall call syscall
1: movq PCPU(CURPCB),%rax 1: movq PCPU(CURPCB),%rax
/* Disable interrupts before testing PCB_FULL_IRET. */
cli
testl $PCB_FULL_IRET,PCB_FLAGS(%rax) testl $PCB_FULL_IRET,PCB_FLAGS(%rax)
jnz 3f jnz 3f
/* Check for and handle AST's on return to userland. */ /* Check for and handle AST's on return to userland. */
cli
movq PCPU(CURTHREAD),%rax movq PCPU(CURTHREAD),%rax
testl $TDF_ASTPENDING | TDF_NEEDRESCHED,TD_FLAGS(%rax) testl $TDF_ASTPENDING | TDF_NEEDRESCHED,TD_FLAGS(%rax)
je 2f je 2f