summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2013-05-27 18:26:08 +0000
committerkib <kib@FreeBSD.org>2013-05-27 18:26:08 +0000
commitda32b7c3140b4a6f5caaf4183cd6f8520d99c7d2 (patch)
tree1fc7ffbce7fb0f831544b4ffa6752510f35c860f
parente7b0a63c190c7ecb475b09f41387a75952540f49 (diff)
downloadFreeBSD-src-da32b7c3140b4a6f5caaf4183cd6f8520d99c7d2.zip
FreeBSD-src-da32b7c3140b4a6f5caaf4183cd6f8520d99c7d2.tar.gz
When handling an exception from the attempt from loading the faulting
context on return from the trap handler, re-enable the interrupts on i386 and amd64. The trap return path have to disable interrupts since the sequence of loading the machine state is not atomic. The trap() function which transfers the control to the special handler would enable the interrupt, but an iret loads the previous eflags with PSL_I clear. Then, the special handler calls trap() on its own, which now sees the original eflags with PSL_I set and does not enable interrupts. The end result is that signal delivery and process exiting code could be executed with interrupts disabled, which is generally wrong and triggers several assertions. For amd64, the interrupts are enabled conditionally based on PSL_I in the eflags of the outer frame, as it is already done for doreti_iret_fault. For i386, the interrupts are enabled unconditionally, the ast loop could have opened a window with interrupts enabled just before the iret anyway. Reported and tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week
-rw-r--r--sys/amd64/amd64/exception.S24
-rw-r--r--sys/i386/i386/exception.s1
2 files changed, 25 insertions, 0 deletions
diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
index 89ad638..8fa5202 100644
--- a/sys/amd64/amd64/exception.S
+++ b/sys/amd64/amd64/exception.S
@@ -818,6 +818,10 @@ doreti_iret_fault:
.globl ds_load_fault
ds_load_fault:
movl $T_PROTFLT,TF_TRAPNO(%rsp)
+ testl $PSL_I,TF_RFLAGS(%rsp)
+ jz 1f
+ sti
+1:
movq %rsp,%rdi
call trap
movw $KUDSEL,TF_DS(%rsp)
@@ -827,6 +831,10 @@ ds_load_fault:
.globl es_load_fault
es_load_fault:
movl $T_PROTFLT,TF_TRAPNO(%rsp)
+ testl $PSL_I,TF_RFLAGS(%rsp)
+ jz 1f
+ sti
+1:
movq %rsp,%rdi
call trap
movw $KUDSEL,TF_ES(%rsp)
@@ -835,6 +843,10 @@ es_load_fault:
ALIGN_TEXT
.globl fs_load_fault
fs_load_fault:
+ testl $PSL_I,TF_RFLAGS(%rsp)
+ jz 1f
+ sti
+1:
movl $T_PROTFLT,TF_TRAPNO(%rsp)
movq %rsp,%rdi
call trap
@@ -846,6 +858,10 @@ fs_load_fault:
gs_load_fault:
popfq
movl $T_PROTFLT,TF_TRAPNO(%rsp)
+ testl $PSL_I,TF_RFLAGS(%rsp)
+ jz 1f
+ sti
+1:
movq %rsp,%rdi
call trap
movw $KUG32SEL,TF_GS(%rsp)
@@ -855,6 +871,10 @@ gs_load_fault:
.globl fsbase_load_fault
fsbase_load_fault:
movl $T_PROTFLT,TF_TRAPNO(%rsp)
+ testl $PSL_I,TF_RFLAGS(%rsp)
+ jz 1f
+ sti
+1:
movq %rsp,%rdi
call trap
movq PCPU(CURTHREAD),%r8
@@ -866,6 +886,10 @@ fsbase_load_fault:
.globl gsbase_load_fault
gsbase_load_fault:
movl $T_PROTFLT,TF_TRAPNO(%rsp)
+ testl $PSL_I,TF_RFLAGS(%rsp)
+ jz 1f
+ sti
+1:
movq %rsp,%rdi
call trap
movq PCPU(CURTHREAD),%r8
diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s
index e969d32..6d4c17b 100644
--- a/sys/i386/i386/exception.s
+++ b/sys/i386/i386/exception.s
@@ -422,6 +422,7 @@ doreti_popl_es_fault:
pushl %fs
.globl doreti_popl_fs_fault
doreti_popl_fs_fault:
+ sti
movl $0,TF_ERR(%esp) /* XXX should be the error code */
movl $T_PROTFLT,TF_TRAPNO(%esp)
jmp alltraps_with_regs_pushed
OpenPOWER on IntegriCloud