diff options
author | kib <kib@FreeBSD.org> | 2010-05-12 10:29:35 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2010-05-12 10:29:35 +0000 |
commit | 7c190c1c89d45ca83db4120a8a5fe107a8a52050 (patch) | |
tree | eecf228988f4249cfce539021a39a53ebe7b9b01 | |
parent | 7b04e359b060fb4d6869ca817495df9327ef6090 (diff) | |
download | FreeBSD-src-7c190c1c89d45ca83db4120a8a5fe107a8a52050.zip FreeBSD-src-7c190c1c89d45ca83db4120a8a5fe107a8a52050.tar.gz |
Route all returns from the interrupts and faults through the doreti_iret
labeled iretq instruction.
Suppose that multithreaded process executes two threads, currently
scheduled on different processors. Let assume that thread A executes
using %cs or %ss pointing into the descriptor from LDT. If IPI comes
which handler does not return by jump to doreti, and meantime thread B
invalidates descriptor pointed to by %cs or %ss, then iretq from IPI
handler could fault.
Routing the return by doreti_iret allows kernel to catch the situation
and recover from it by sending signal to the usermode.
Tested by: pho
MFC after: 1 week
-rw-r--r-- | sys/amd64/amd64/apic_vector.S | 13 | ||||
-rw-r--r-- | sys/amd64/amd64/exception.S | 2 |
2 files changed, 8 insertions, 7 deletions
diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S index df94a47..f36ff49 100644 --- a/sys/amd64/amd64/apic_vector.S +++ b/sys/amd64/amd64/apic_vector.S @@ -41,6 +41,7 @@ #include "assym.s" + .extern doreti_iret /* * I/O Interrupt Entry Point. Rather than having one entry point for * each interrupt source, we use one entry point for each 32-bit word @@ -81,7 +82,7 @@ IDTVEC(spuriousint) /* No EOI cycle used here */ - iretq + jmp doreti_iret ISR_VEC(1, apic_isr1) ISR_VEC(2, apic_isr2) @@ -135,7 +136,7 @@ IDTVEC(invltlb) incl smp_tlb_wait popq %rax - iretq + jmp doreti_iret /* * Single page TLB shootdown @@ -155,7 +156,7 @@ IDTVEC(invlpg) incl smp_tlb_wait popq %rax - iretq + jmp doreti_iret /* * Page range TLB shootdown. @@ -181,7 +182,7 @@ IDTVEC(invlrng) popq %rdx popq %rax - iretq + jmp doreti_iret /* * Invalidate cache. @@ -200,7 +201,7 @@ IDTVEC(invlcache) incl smp_tlb_wait popq %rax - iretq + jmp doreti_iret /* * Handler for IPIs sent via the per-cpu IPI bitmap. @@ -247,7 +248,7 @@ IDTVEC(cpususpend) call cpususpend_handler POP_FRAME - iretq + jmp doreti_iret /* * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU. diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S index 7b1fed8..d18fb0d 100644 --- a/sys/amd64/amd64/exception.S +++ b/sys/amd64/amd64/exception.S @@ -553,7 +553,7 @@ nmi_restoreregs: movq TF_R14(%rsp),%r14 movq TF_R15(%rsp),%r15 addq $TF_RIP,%rsp - iretq + jmp doreti_iret ENTRY(fork_trampoline) movq %r12,%rdi /* function */ |