summaryrefslogtreecommitdiffstats
path: root/sys/amd64/amd64/trap.c
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1997-06-07 04:36:10 +0000
committerbde <bde@FreeBSD.org>1997-06-07 04:36:10 +0000
commit6babbddd762aaa221ade16215d4b4e93bb669f79 (patch)
tree9369720c6fe0f8bc2adda5e0852adf5a669345ef /sys/amd64/amd64/trap.c
parent093956d0d4afe268c9113da9f84c22d843b9e750 (diff)
downloadFreeBSD-src-6babbddd762aaa221ade16215d4b4e93bb669f79.zip
FreeBSD-src-6babbddd762aaa221ade16215d4b4e93bb669f79.tar.gz
Preserve %fs and %gs across context switches. This has a relatively low
cost since it is only done in cpu_switch(), not for every exception. The extra state is kept in the pcb, and handled much like the npx state, with similar deficiencies (the state is not preserved across signal handlers, and error handling loses state).
Diffstat (limited to 'sys/amd64/amd64/trap.c')
-rw-r--r--sys/amd64/amd64/trap.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index f73c4f2..89dd34f 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)trap.c 7.4 (Berkeley) 5/13/91
- * $Id: trap.c,v 1.97 1997/05/31 09:27:29 peter Exp $
+ * $Id: trap.c,v 1.98 1997/06/02 08:19:03 dfr Exp $
*/
/*
@@ -352,6 +352,25 @@ trap(frame)
} while (0)
if (intr_nesting_level == 0) {
+ /*
+ * Invalid %fs's and %gs's can be created using
+ * procfs or PT_SETREGS or by invalidating the
+ * underlying LDT entry. This causes a fault
+ * in kernel mode when the kernel attempts to
+ * switch contexts. Lose the bad context
+ * (XXX) so that we can continue, and generate
+ * a signal.
+ */
+ if (frame.tf_eip == (int)cpu_switch_load_fs) {
+ curpcb->pcb_fs = 0;
+ psignal(p, SIGBUS);
+ return;
+ }
+ if (frame.tf_eip == (int)cpu_switch_load_gs) {
+ curpcb->pcb_gs = 0;
+ psignal(p, SIGBUS);
+ return;
+ }
MAYBE_DORETI_FAULT(doreti_iret,
doreti_iret_fault);
MAYBE_DORETI_FAULT(doreti_popl_ds,
OpenPOWER on IntegriCloud