summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2015-06-12 15:06:17 +0000
committerjhb <jhb@FreeBSD.org>2015-06-12 15:06:17 +0000
commitac9b7e1fd0939df8bcb1d237a4cd8bfb43076d05 (patch)
treed0e113e21245b14fcdea80f821b0809f90afe233 /sys/i386
parent06a33e037a9c3052fb620cec8e73cf611b1bde7b (diff)
downloadFreeBSD-src-ac9b7e1fd0939df8bcb1d237a4cd8bfb43076d05.zip
FreeBSD-src-ac9b7e1fd0939df8bcb1d237a4cd8bfb43076d05.tar.gz
Ensure that the upper 16 bits of segment registers manually saved in
trapframes are cleared by explicitly pushing a zero and then moving the segment register into the low 16 bits. Certain Intel processors treat a push of a segment register as a move of the segment register into the low 16 bits leaving the upper 16 bits of the word in the stack unchanged. Reviewed by: kib MFC after: 1 month
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/exception.s36
-rw-r--r--sys/i386/include/asmacros.h9
2 files changed, 30 insertions, 15 deletions
diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s
index 39a8828..70c6d9d 100644
--- a/sys/i386/i386/exception.s
+++ b/sys/i386/i386/exception.s
@@ -157,9 +157,12 @@ IDTVEC(xmm)
.type alltraps,@function
alltraps:
pushal
- pushl %ds
- pushl %es
- pushl %fs
+ pushl $0
+ movl %ds,(%esp)
+ pushl $0
+ movl %es,(%esp)
+ pushl $0
+ movl %fs,(%esp)
alltraps_with_regs_pushed:
SET_KERNEL_SREGS
cld
@@ -233,9 +236,12 @@ IDTVEC(lcall_syscall)
pushl $7 /* sizeof "lcall 7,0" */
subl $4,%esp /* skip over tf_trapno */
pushal
- pushl %ds
- pushl %es
- pushl %fs
+ pushl $0
+ movl %ds,(%esp)
+ pushl $0
+ movl %es,(%esp)
+ pushl $0
+ movl %fs,(%esp)
SET_KERNEL_SREGS
cld
FAKE_MCOUNT(TF_EIP(%esp))
@@ -259,9 +265,12 @@ IDTVEC(int0x80_syscall)
pushl $2 /* sizeof "int 0x80" */
subl $4,%esp /* skip over tf_trapno */
pushal
- pushl %ds
- pushl %es
- pushl %fs
+ pushl $0
+ movl %ds,(%esp)
+ pushl $0
+ movl %es,(%esp)
+ pushl $0
+ movl %fs,(%esp)
SET_KERNEL_SREGS
cld
FAKE_MCOUNT(TF_EIP(%esp))
@@ -416,13 +425,16 @@ doreti_iret:
doreti_iret_fault:
subl $8,%esp
pushal
- pushl %ds
+ pushl $0
+ movl %ds,(%esp)
.globl doreti_popl_ds_fault
doreti_popl_ds_fault:
- pushl %es
+ pushl $0
+ movl %es,(%esp)
.globl doreti_popl_es_fault
doreti_popl_es_fault:
- pushl %fs
+ pushl $0
+ movl %fs,(%esp)
.globl doreti_popl_fs_fault
doreti_popl_fs_fault:
sti
diff --git a/sys/i386/include/asmacros.h b/sys/i386/include/asmacros.h
index 716915c..91c25f7 100644
--- a/sys/i386/include/asmacros.h
+++ b/sys/i386/include/asmacros.h
@@ -146,9 +146,12 @@
pushl $0 ; /* dummy error code */ \
pushl $0 ; /* dummy trap type */ \
pushal ; /* 8 ints */ \
- pushl %ds ; /* save data and extra segments ... */ \
- pushl %es ; \
- pushl %fs
+ pushl $0 ; /* save data and extra segments ... */ \
+ mov %ds,(%esp) ; \
+ pushl $0 ; \
+ mov %es,(%esp) ; \
+ pushl $0 ; \
+ mov %fs,(%esp)
#define POP_FRAME \
popl %fs ; \
OpenPOWER on IntegriCloud