summaryrefslogtreecommitdiffstats
path: root/sys/amd64/amd64/exception.S
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2011-04-08 13:33:57 +0000
committerjhb <jhb@FreeBSD.org>2011-04-08 13:33:57 +0000
commit9a34a392bbbc68650b156b25b25b735828288990 (patch)
tree9c80e082a744c65229a87ea8b6eca5ad32273f99 /sys/amd64/amd64/exception.S
parent6ff99aec8cfc17b8f4ab83a77376502b62de51ce (diff)
downloadFreeBSD-src-9a34a392bbbc68650b156b25b25b735828288990.zip
FreeBSD-src-9a34a392bbbc68650b156b25b25b735828288990.tar.gz
Fix a bug in the previous change to restore the fast path for syscall
return. The ast() function may cause a context switch in which case PCB_FULL_IRET would be set in the pcb. However, the code was not rechecking the flag after ast() returned and would not properly restore the FSBASE and GSBASE MSRs. To fix, recheck the PCB_FULL_IRET flag after ast() returns. While here, trim an instruction (and memory access) from the doreti path and fix a typo in a comment. MFC after: 1 week
Diffstat (limited to 'sys/amd64/amd64/exception.S')
-rw-r--r--sys/amd64/amd64/exception.S11
1 files changed, 5 insertions, 6 deletions
diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
index 2053a70..65515aa 100644
--- a/sys/amd64/amd64/exception.S
+++ b/sys/amd64/amd64/exception.S
@@ -382,10 +382,10 @@ IDTVEC(fast_syscall)
FAKE_MCOUNT(TF_RIP(%rsp))
movq %rsp,%rdi
call syscall
- movq PCPU(CURPCB),%rax
+1: movq PCPU(CURPCB),%rax
testl $PCB_FULL_IRET,PCB_FLAGS(%rax)
- jne 3f
-1: /* Check for and handle AST's on return to userland. */
+ jnz 3f
+ /* Check for and handle AST's on return to userland. */
cli
movq PCPU(CURTHREAD),%rax
testl $TDF_ASTPENDING | TDF_NEEDRESCHED,TD_FLAGS(%rax)
@@ -661,7 +661,7 @@ doreti:
doreti_ast:
/*
* Check for ASTs atomically with returning. Disabling CPU
- * interrupts provides sufficient locking eve in the SMP case,
+ * interrupts provides sufficient locking even in the SMP case,
* since we will be informed of any new ASTs by an IPI.
*/
cli
@@ -682,8 +682,7 @@ doreti_ast:
*/
doreti_exit:
MEXITCOUNT
- movq PCPU(CURTHREAD),%r8
- movq TD_PCB(%r8),%r8
+ movq PCPU(CURPCB),%r8
/*
* Do not reload segment registers for kernel.
OpenPOWER on IntegriCloud