Commit a85071ff authored by Linus Torvalds's avatar Linus Torvalds

Make the default values for DS/ES be the _user_ segment descriptors

on x86 - the kernel doesn't really care (as long as it's all flat 32-bit),
and it means that the return path for sysenter/sysexit can avoid re-loading
the segment registers.

NOTE! This means that _all_ kernel code (not just the sysenter path) must
be appropriately changed, since the kernel knows the conventions and doesn't
save/restore DS/ES internally on context switches etc.
parent cb2bf78e
...@@ -91,18 +91,21 @@ VM_MASK = 0x00020000 ...@@ -91,18 +91,21 @@ VM_MASK = 0x00020000
pushl %edx; \ pushl %edx; \
pushl %ecx; \ pushl %ecx; \
pushl %ebx; \ pushl %ebx; \
movl $(__KERNEL_DS), %edx; \ movl $(__USER_DS), %edx; \
movl %edx, %ds; \ movl %edx, %ds; \
movl %edx, %es; movl %edx, %es;
#define RESTORE_REGS \ #define RESTORE_INT_REGS \
popl %ebx; \ popl %ebx; \
popl %ecx; \ popl %ecx; \
popl %edx; \ popl %edx; \
popl %esi; \ popl %esi; \
popl %edi; \ popl %edi; \
popl %ebp; \ popl %ebp; \
popl %eax; \ popl %eax
#define RESTORE_REGS \
RESTORE_INT_REGS; \
1: popl %ds; \ 1: popl %ds; \
2: popl %es; \ 2: popl %es; \
.section .fixup,"ax"; \ .section .fixup,"ax"; \
...@@ -271,9 +274,9 @@ ENTRY(sysenter_entry) ...@@ -271,9 +274,9 @@ ENTRY(sysenter_entry)
movl TI_FLAGS(%ebx), %ecx movl TI_FLAGS(%ebx), %ecx
testw $_TIF_ALLWORK_MASK, %cx testw $_TIF_ALLWORK_MASK, %cx
jne syscall_exit_work jne syscall_exit_work
RESTORE_REGS RESTORE_INT_REGS
movl 4(%esp),%edx movl 12(%esp),%edx
movl 16(%esp),%ecx movl 24(%esp),%ecx
sti sti
sysexit sysexit
...@@ -428,7 +431,7 @@ error_code: ...@@ -428,7 +431,7 @@ error_code:
movl %esp, %edx movl %esp, %edx
pushl %esi # push the error code pushl %esi # push the error code
pushl %edx # push the pt_regs pointer pushl %edx # push the pt_regs pointer
movl $(__KERNEL_DS), %edx movl $(__USER_DS), %edx
movl %edx, %ds movl %edx, %ds
movl %edx, %es movl %edx, %es
call *%edi call *%edi
......
...@@ -235,12 +235,15 @@ is386: movl $2,%ecx # set MP ...@@ -235,12 +235,15 @@ is386: movl $2,%ecx # set MP
lidt idt_descr lidt idt_descr
ljmp $(__KERNEL_CS),$1f ljmp $(__KERNEL_CS),$1f
1: movl $(__KERNEL_DS),%eax # reload all the segment registers 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
movl %eax,%ds # after changing gdt. movl %eax,%ss # after changing gdt.
movl $(__USER_DS),%eax # DS/ES contains default USER segment
movl %eax,%ds
movl %eax,%es movl %eax,%es
xorl %eax,%eax # Clear FS/GS and LDT
movl %eax,%fs movl %eax,%fs
movl %eax,%gs movl %eax,%gs
movl %eax,%ss
xorl %eax,%eax
lldt %ax lldt %ax
cld # gcc2 wants the direction flag cleared at all times cld # gcc2 wants the direction flag cleared at all times
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
......
...@@ -219,8 +219,8 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) ...@@ -219,8 +219,8 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
regs.ebx = (unsigned long) fn; regs.ebx = (unsigned long) fn;
regs.edx = (unsigned long) arg; regs.edx = (unsigned long) arg;
regs.xds = __KERNEL_DS; regs.xds = __USER_DS;
regs.xes = __KERNEL_DS; regs.xes = __USER_DS;
regs.orig_eax = -1; regs.orig_eax = -1;
regs.eip = (unsigned long) kernel_thread_helper; regs.eip = (unsigned long) kernel_thread_helper;
regs.xcs = __KERNEL_CS; regs.xcs = __KERNEL_CS;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment