diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/kernel/asm-offsets.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/entry_32.S | 26 | ||||
-rw-r--r-- | arch/x86/kernel/entry_64.S | 74 | ||||
-rw-r--r-- | arch/x86/kernel/process.c | 65 | ||||
-rw-r--r-- | arch/x86/kernel/process_32.c | 37 | ||||
-rw-r--r-- | arch/x86/kernel/process_64.c | 35 | ||||
-rw-r--r-- | arch/x86/kernel/signal.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/sys_i386_32.c | 40 | ||||
-rw-r--r-- | arch/x86/kernel/vm86_32.c | 6 |
10 files changed, 101 insertions, 191 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index a48ea05157d3..91ce48f05f9f 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -23,7 +23,7 @@ obj-y += time.o ioport.o ldt.o dumpstack.o nmi.o | |||
23 | obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o | 23 | obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o |
24 | obj-$(CONFIG_IRQ_WORK) += irq_work.o | 24 | obj-$(CONFIG_IRQ_WORK) += irq_work.o |
25 | obj-y += probe_roms.o | 25 | obj-y += probe_roms.o |
26 | obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o | 26 | obj-$(CONFIG_X86_32) += i386_ksyms_32.o |
27 | obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o | 27 | obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o |
28 | obj-y += syscall_$(BITS).o | 28 | obj-y += syscall_$(BITS).o |
29 | obj-$(CONFIG_X86_64) += vsyscall_64.o | 29 | obj-$(CONFIG_X86_64) += vsyscall_64.o |
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c index 68de2dc962ec..28610822fb3c 100644 --- a/arch/x86/kernel/asm-offsets.c +++ b/arch/x86/kernel/asm-offsets.c | |||
@@ -69,4 +69,7 @@ void common(void) { | |||
69 | OFFSET(BP_kernel_alignment, boot_params, hdr.kernel_alignment); | 69 | OFFSET(BP_kernel_alignment, boot_params, hdr.kernel_alignment); |
70 | OFFSET(BP_pref_address, boot_params, hdr.pref_address); | 70 | OFFSET(BP_pref_address, boot_params, hdr.pref_address); |
71 | OFFSET(BP_code32_start, boot_params, hdr.code32_start); | 71 | OFFSET(BP_code32_start, boot_params, hdr.code32_start); |
72 | |||
73 | BLANK(); | ||
74 | DEFINE(PTREGS_SIZE, sizeof(struct pt_regs)); | ||
72 | } | 75 | } |
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 0750e3ba87c0..8f9ed1afde8f 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
@@ -299,6 +299,13 @@ ENTRY(ret_from_fork) | |||
299 | CFI_ENDPROC | 299 | CFI_ENDPROC |
300 | END(ret_from_fork) | 300 | END(ret_from_fork) |
301 | 301 | ||
302 | ENTRY(ret_from_kernel_execve) | ||
303 | movl %eax, %esp | ||
304 | movl $0,PT_EAX(%esp) | ||
305 | GET_THREAD_INFO(%ebp) | ||
306 | jmp syscall_exit | ||
307 | END(ret_from_kernel_execve) | ||
308 | |||
302 | /* | 309 | /* |
303 | * Interrupt exit functions should be protected against kprobes | 310 | * Interrupt exit functions should be protected against kprobes |
304 | */ | 311 | */ |
@@ -323,8 +330,7 @@ ret_from_intr: | |||
323 | andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax | 330 | andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax |
324 | #else | 331 | #else |
325 | /* | 332 | /* |
326 | * We can be coming here from a syscall done in the kernel space, | 333 | * We can be coming here from child spawned by kernel_thread(). |
327 | * e.g. a failed kernel_execve(). | ||
328 | */ | 334 | */ |
329 | movl PT_CS(%esp), %eax | 335 | movl PT_CS(%esp), %eax |
330 | andl $SEGMENT_RPL_MASK, %eax | 336 | andl $SEGMENT_RPL_MASK, %eax |
@@ -732,7 +738,6 @@ ENDPROC(ptregs_##name) | |||
732 | PTREGSCALL1(iopl) | 738 | PTREGSCALL1(iopl) |
733 | PTREGSCALL0(fork) | 739 | PTREGSCALL0(fork) |
734 | PTREGSCALL0(vfork) | 740 | PTREGSCALL0(vfork) |
735 | PTREGSCALL3(execve) | ||
736 | PTREGSCALL2(sigaltstack) | 741 | PTREGSCALL2(sigaltstack) |
737 | PTREGSCALL0(sigreturn) | 742 | PTREGSCALL0(sigreturn) |
738 | PTREGSCALL0(rt_sigreturn) | 743 | PTREGSCALL0(rt_sigreturn) |
@@ -1015,15 +1020,20 @@ END(spurious_interrupt_bug) | |||
1015 | */ | 1020 | */ |
1016 | .popsection | 1021 | .popsection |
1017 | 1022 | ||
1018 | ENTRY(kernel_thread_helper) | 1023 | ENTRY(ret_from_kernel_thread) |
1019 | pushl $0 # fake return address for unwinder | ||
1020 | CFI_STARTPROC | 1024 | CFI_STARTPROC |
1021 | movl %edi,%eax | 1025 | pushl_cfi %eax |
1022 | call *%esi | 1026 | call schedule_tail |
1027 | GET_THREAD_INFO(%ebp) | ||
1028 | popl_cfi %eax | ||
1029 | pushl_cfi $0x0202 # Reset kernel eflags | ||
1030 | popfl_cfi | ||
1031 | movl PT_EBP(%esp),%eax | ||
1032 | call *PT_EBX(%esp) | ||
1023 | call do_exit | 1033 | call do_exit |
1024 | ud2 # padding for call trace | 1034 | ud2 # padding for call trace |
1025 | CFI_ENDPROC | 1035 | CFI_ENDPROC |
1026 | ENDPROC(kernel_thread_helper) | 1036 | ENDPROC(ret_from_kernel_thread) |
1027 | 1037 | ||
1028 | #ifdef CONFIG_XEN | 1038 | #ifdef CONFIG_XEN |
1029 | /* Xen doesn't set %esp to be precisely what the normal sysenter | 1039 | /* Xen doesn't set %esp to be precisely what the normal sysenter |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 44531acd9a81..cdc790c78f32 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -554,7 +554,7 @@ ENTRY(ret_from_fork) | |||
554 | RESTORE_REST | 554 | RESTORE_REST |
555 | 555 | ||
556 | testl $3, CS-ARGOFFSET(%rsp) # from kernel_thread? | 556 | testl $3, CS-ARGOFFSET(%rsp) # from kernel_thread? |
557 | jz retint_restore_args | 557 | jz 1f |
558 | 558 | ||
559 | testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET | 559 | testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET |
560 | jnz int_ret_from_sys_call | 560 | jnz int_ret_from_sys_call |
@@ -562,6 +562,16 @@ ENTRY(ret_from_fork) | |||
562 | RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET | 562 | RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET |
563 | jmp ret_from_sys_call # go to the SYSRET fastpath | 563 | jmp ret_from_sys_call # go to the SYSRET fastpath |
564 | 564 | ||
565 | 1: | ||
566 | subq $REST_SKIP, %rsp # move the stack pointer back | ||
567 | CFI_ADJUST_CFA_OFFSET REST_SKIP | ||
568 | movq %rbp, %rdi | ||
569 | call *%rbx | ||
570 | # exit | ||
571 | mov %eax, %edi | ||
572 | call do_exit | ||
573 | ud2 # padding for call trace | ||
574 | |||
565 | CFI_ENDPROC | 575 | CFI_ENDPROC |
566 | END(ret_from_fork) | 576 | END(ret_from_fork) |
567 | 577 | ||
@@ -862,7 +872,6 @@ ENTRY(stub_execve) | |||
862 | PARTIAL_FRAME 0 | 872 | PARTIAL_FRAME 0 |
863 | SAVE_REST | 873 | SAVE_REST |
864 | FIXUP_TOP_OF_STACK %r11 | 874 | FIXUP_TOP_OF_STACK %r11 |
865 | movq %rsp, %rcx | ||
866 | call sys_execve | 875 | call sys_execve |
867 | RESTORE_TOP_OF_STACK %r11 | 876 | RESTORE_TOP_OF_STACK %r11 |
868 | movq %rax,RAX(%rsp) | 877 | movq %rax,RAX(%rsp) |
@@ -912,8 +921,7 @@ ENTRY(stub_x32_execve) | |||
912 | PARTIAL_FRAME 0 | 921 | PARTIAL_FRAME 0 |
913 | SAVE_REST | 922 | SAVE_REST |
914 | FIXUP_TOP_OF_STACK %r11 | 923 | FIXUP_TOP_OF_STACK %r11 |
915 | movq %rsp, %rcx | 924 | call compat_sys_execve |
916 | call sys32_execve | ||
917 | RESTORE_TOP_OF_STACK %r11 | 925 | RESTORE_TOP_OF_STACK %r11 |
918 | movq %rax,RAX(%rsp) | 926 | movq %rax,RAX(%rsp) |
919 | RESTORE_REST | 927 | RESTORE_REST |
@@ -1318,51 +1326,19 @@ bad_gs: | |||
1318 | jmp 2b | 1326 | jmp 2b |
1319 | .previous | 1327 | .previous |
1320 | 1328 | ||
1321 | ENTRY(kernel_thread_helper) | 1329 | ENTRY(ret_from_kernel_execve) |
1322 | pushq $0 # fake return address | 1330 | movq %rdi, %rsp |
1323 | CFI_STARTPROC | 1331 | movl $0, RAX(%rsp) |
1324 | /* | 1332 | // RESTORE_REST |
1325 | * Here we are in the child and the registers are set as they were | 1333 | movq 0*8(%rsp), %r15 |
1326 | * at kernel_thread() invocation in the parent. | 1334 | movq 1*8(%rsp), %r14 |
1327 | */ | 1335 | movq 2*8(%rsp), %r13 |
1328 | call *%rsi | 1336 | movq 3*8(%rsp), %r12 |
1329 | # exit | 1337 | movq 4*8(%rsp), %rbp |
1330 | mov %eax, %edi | 1338 | movq 5*8(%rsp), %rbx |
1331 | call do_exit | 1339 | addq $(6*8), %rsp |
1332 | ud2 # padding for call trace | 1340 | jmp int_ret_from_sys_call |
1333 | CFI_ENDPROC | 1341 | END(ret_from_kernel_execve) |
1334 | END(kernel_thread_helper) | ||
1335 | |||
1336 | /* | ||
1337 | * execve(). This function needs to use IRET, not SYSRET, to set up all state properly. | ||
1338 | * | ||
1339 | * C extern interface: | ||
1340 | * extern long execve(const char *name, char **argv, char **envp) | ||
1341 | * | ||
1342 | * asm input arguments: | ||
1343 | * rdi: name, rsi: argv, rdx: envp | ||
1344 | * | ||
1345 | * We want to fallback into: | ||
1346 | * extern long sys_execve(const char *name, char **argv,char **envp, struct pt_regs *regs) | ||
1347 | * | ||
1348 | * do_sys_execve asm fallback arguments: | ||
1349 | * rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack | ||
1350 | */ | ||
1351 | ENTRY(kernel_execve) | ||
1352 | CFI_STARTPROC | ||
1353 | FAKE_STACK_FRAME $0 | ||
1354 | SAVE_ALL | ||
1355 | movq %rsp,%rcx | ||
1356 | call sys_execve | ||
1357 | movq %rax, RAX(%rsp) | ||
1358 | RESTORE_REST | ||
1359 | testq %rax,%rax | ||
1360 | je int_ret_from_sys_call | ||
1361 | RESTORE_ARGS | ||
1362 | UNFAKE_STACK_FRAME | ||
1363 | ret | ||
1364 | CFI_ENDPROC | ||
1365 | END(kernel_execve) | ||
1366 | 1342 | ||
1367 | /* Call softirq on interrupt stack. Interrupts are off. */ | 1343 | /* Call softirq on interrupt stack. Interrupts are off. */ |
1368 | ENTRY(call_softirq) | 1344 | ENTRY(call_softirq) |
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index dc3567e083f9..b644e1c765dc 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -293,71 +293,6 @@ sys_clone(unsigned long clone_flags, unsigned long newsp, | |||
293 | } | 293 | } |
294 | 294 | ||
295 | /* | 295 | /* |
296 | * This gets run with %si containing the | ||
297 | * function to call, and %di containing | ||
298 | * the "args". | ||
299 | */ | ||
300 | extern void kernel_thread_helper(void); | ||
301 | |||
302 | /* | ||
303 | * Create a kernel thread | ||
304 | */ | ||
305 | int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
306 | { | ||
307 | struct pt_regs regs; | ||
308 | |||
309 | memset(®s, 0, sizeof(regs)); | ||
310 | |||
311 | regs.si = (unsigned long) fn; | ||
312 | regs.di = (unsigned long) arg; | ||
313 | |||
314 | #ifdef CONFIG_X86_32 | ||
315 | regs.ds = __USER_DS; | ||
316 | regs.es = __USER_DS; | ||
317 | regs.fs = __KERNEL_PERCPU; | ||
318 | regs.gs = __KERNEL_STACK_CANARY; | ||
319 | #else | ||
320 | regs.ss = __KERNEL_DS; | ||
321 | #endif | ||
322 | |||
323 | regs.orig_ax = -1; | ||
324 | regs.ip = (unsigned long) kernel_thread_helper; | ||
325 | regs.cs = __KERNEL_CS | get_kernel_rpl(); | ||
326 | regs.flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1; | ||
327 | |||
328 | /* Ok, create the new process.. */ | ||
329 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); | ||
330 | } | ||
331 | EXPORT_SYMBOL(kernel_thread); | ||
332 | |||
333 | /* | ||
334 | * sys_execve() executes a new program. | ||
335 | */ | ||
336 | long sys_execve(const char __user *name, | ||
337 | const char __user *const __user *argv, | ||
338 | const char __user *const __user *envp, struct pt_regs *regs) | ||
339 | { | ||
340 | long error; | ||
341 | char *filename; | ||
342 | |||
343 | filename = getname(name); | ||
344 | error = PTR_ERR(filename); | ||
345 | if (IS_ERR(filename)) | ||
346 | return error; | ||
347 | error = do_execve(filename, argv, envp, regs); | ||
348 | |||
349 | #ifdef CONFIG_X86_32 | ||
350 | if (error == 0) { | ||
351 | /* Make sure we don't return using sysenter.. */ | ||
352 | set_thread_flag(TIF_IRET); | ||
353 | } | ||
354 | #endif | ||
355 | |||
356 | putname(filename); | ||
357 | return error; | ||
358 | } | ||
359 | |||
360 | /* | ||
361 | * Idle related variables and functions | 296 | * Idle related variables and functions |
362 | */ | 297 | */ |
363 | unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE; | 298 | unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE; |
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index b9ff83c7135b..44e0bff38e72 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <asm/switch_to.h> | 57 | #include <asm/switch_to.h> |
58 | 58 | ||
59 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 59 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
60 | asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread"); | ||
60 | 61 | ||
61 | /* | 62 | /* |
62 | * Return saved PC of a blocked thread. | 63 | * Return saved PC of a blocked thread. |
@@ -127,23 +128,39 @@ void release_thread(struct task_struct *dead_task) | |||
127 | } | 128 | } |
128 | 129 | ||
129 | int copy_thread(unsigned long clone_flags, unsigned long sp, | 130 | int copy_thread(unsigned long clone_flags, unsigned long sp, |
130 | unsigned long unused, | 131 | unsigned long arg, |
131 | struct task_struct *p, struct pt_regs *regs) | 132 | struct task_struct *p, struct pt_regs *regs) |
132 | { | 133 | { |
133 | struct pt_regs *childregs; | 134 | struct pt_regs *childregs = task_pt_regs(p); |
134 | struct task_struct *tsk; | 135 | struct task_struct *tsk; |
135 | int err; | 136 | int err; |
136 | 137 | ||
137 | childregs = task_pt_regs(p); | 138 | p->thread.sp = (unsigned long) childregs; |
139 | p->thread.sp0 = (unsigned long) (childregs+1); | ||
140 | |||
141 | if (unlikely(!regs)) { | ||
142 | /* kernel thread */ | ||
143 | memset(childregs, 0, sizeof(struct pt_regs)); | ||
144 | p->thread.ip = (unsigned long) ret_from_kernel_thread; | ||
145 | task_user_gs(p) = __KERNEL_STACK_CANARY; | ||
146 | childregs->ds = __USER_DS; | ||
147 | childregs->es = __USER_DS; | ||
148 | childregs->fs = __KERNEL_PERCPU; | ||
149 | childregs->bx = sp; /* function */ | ||
150 | childregs->bp = arg; | ||
151 | childregs->orig_ax = -1; | ||
152 | childregs->cs = __KERNEL_CS | get_kernel_rpl(); | ||
153 | childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1; | ||
154 | p->fpu_counter = 0; | ||
155 | p->thread.io_bitmap_ptr = NULL; | ||
156 | memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps)); | ||
157 | return 0; | ||
158 | } | ||
138 | *childregs = *regs; | 159 | *childregs = *regs; |
139 | childregs->ax = 0; | 160 | childregs->ax = 0; |
140 | childregs->sp = sp; | 161 | childregs->sp = sp; |
141 | 162 | ||
142 | p->thread.sp = (unsigned long) childregs; | ||
143 | p->thread.sp0 = (unsigned long) (childregs+1); | ||
144 | |||
145 | p->thread.ip = (unsigned long) ret_from_fork; | 163 | p->thread.ip = (unsigned long) ret_from_fork; |
146 | |||
147 | task_user_gs(p) = get_user_gs(regs); | 164 | task_user_gs(p) = get_user_gs(regs); |
148 | 165 | ||
149 | p->fpu_counter = 0; | 166 | p->fpu_counter = 0; |
@@ -190,6 +207,12 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) | |||
190 | regs->cs = __USER_CS; | 207 | regs->cs = __USER_CS; |
191 | regs->ip = new_ip; | 208 | regs->ip = new_ip; |
192 | regs->sp = new_sp; | 209 | regs->sp = new_sp; |
210 | regs->flags = X86_EFLAGS_IF; | ||
211 | /* | ||
212 | * force it to the iret return path by making it look as if there was | ||
213 | * some work pending. | ||
214 | */ | ||
215 | set_thread_flag(TIF_NOTIFY_RESUME); | ||
193 | } | 216 | } |
194 | EXPORT_SYMBOL_GPL(start_thread); | 217 | EXPORT_SYMBOL_GPL(start_thread); |
195 | 218 | ||
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 8a6d20ce1978..16c6365e2b86 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -146,29 +146,18 @@ static inline u32 read_32bit_tls(struct task_struct *t, int tls) | |||
146 | } | 146 | } |
147 | 147 | ||
148 | int copy_thread(unsigned long clone_flags, unsigned long sp, | 148 | int copy_thread(unsigned long clone_flags, unsigned long sp, |
149 | unsigned long unused, | 149 | unsigned long arg, |
150 | struct task_struct *p, struct pt_regs *regs) | 150 | struct task_struct *p, struct pt_regs *regs) |
151 | { | 151 | { |
152 | int err; | 152 | int err; |
153 | struct pt_regs *childregs; | 153 | struct pt_regs *childregs; |
154 | struct task_struct *me = current; | 154 | struct task_struct *me = current; |
155 | 155 | ||
156 | childregs = ((struct pt_regs *) | 156 | p->thread.sp0 = (unsigned long)task_stack_page(p) + THREAD_SIZE; |
157 | (THREAD_SIZE + task_stack_page(p))) - 1; | 157 | childregs = task_pt_regs(p); |
158 | *childregs = *regs; | ||
159 | |||
160 | childregs->ax = 0; | ||
161 | if (user_mode(regs)) | ||
162 | childregs->sp = sp; | ||
163 | else | ||
164 | childregs->sp = (unsigned long)childregs; | ||
165 | |||
166 | p->thread.sp = (unsigned long) childregs; | 158 | p->thread.sp = (unsigned long) childregs; |
167 | p->thread.sp0 = (unsigned long) (childregs+1); | ||
168 | p->thread.usersp = me->thread.usersp; | 159 | p->thread.usersp = me->thread.usersp; |
169 | |||
170 | set_tsk_thread_flag(p, TIF_FORK); | 160 | set_tsk_thread_flag(p, TIF_FORK); |
171 | |||
172 | p->fpu_counter = 0; | 161 | p->fpu_counter = 0; |
173 | p->thread.io_bitmap_ptr = NULL; | 162 | p->thread.io_bitmap_ptr = NULL; |
174 | 163 | ||
@@ -178,6 +167,24 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
178 | p->thread.fs = p->thread.fsindex ? 0 : me->thread.fs; | 167 | p->thread.fs = p->thread.fsindex ? 0 : me->thread.fs; |
179 | savesegment(es, p->thread.es); | 168 | savesegment(es, p->thread.es); |
180 | savesegment(ds, p->thread.ds); | 169 | savesegment(ds, p->thread.ds); |
170 | memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps)); | ||
171 | |||
172 | if (unlikely(!regs)) { | ||
173 | /* kernel thread */ | ||
174 | memset(childregs, 0, sizeof(struct pt_regs)); | ||
175 | childregs->sp = (unsigned long)childregs; | ||
176 | childregs->ss = __KERNEL_DS; | ||
177 | childregs->bx = sp; /* function */ | ||
178 | childregs->bp = arg; | ||
179 | childregs->orig_ax = -1; | ||
180 | childregs->cs = __KERNEL_CS | get_kernel_rpl(); | ||
181 | childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1; | ||
182 | return 0; | ||
183 | } | ||
184 | *childregs = *regs; | ||
185 | |||
186 | childregs->ax = 0; | ||
187 | childregs->sp = sp; | ||
181 | 188 | ||
182 | err = -ENOMEM; | 189 | err = -ENOMEM; |
183 | memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps)); | 190 | memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps)); |
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index b33144c8b309..29ad351804e9 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
@@ -840,10 +840,6 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) | |||
840 | if (thread_info_flags & _TIF_USER_RETURN_NOTIFY) | 840 | if (thread_info_flags & _TIF_USER_RETURN_NOTIFY) |
841 | fire_user_return_notifiers(); | 841 | fire_user_return_notifiers(); |
842 | 842 | ||
843 | #ifdef CONFIG_X86_32 | ||
844 | clear_thread_flag(TIF_IRET); | ||
845 | #endif /* CONFIG_X86_32 */ | ||
846 | |||
847 | rcu_user_enter(); | 843 | rcu_user_enter(); |
848 | } | 844 | } |
849 | 845 | ||
diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c deleted file mode 100644 index 0b0cb5fede19..000000000000 --- a/arch/x86/kernel/sys_i386_32.c +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* | ||
2 | * This file contains various random system calls that | ||
3 | * have a non-standard calling sequence on the Linux/i386 | ||
4 | * platform. | ||
5 | */ | ||
6 | |||
7 | #include <linux/errno.h> | ||
8 | #include <linux/sched.h> | ||
9 | #include <linux/mm.h> | ||
10 | #include <linux/fs.h> | ||
11 | #include <linux/smp.h> | ||
12 | #include <linux/sem.h> | ||
13 | #include <linux/msg.h> | ||
14 | #include <linux/shm.h> | ||
15 | #include <linux/stat.h> | ||
16 | #include <linux/syscalls.h> | ||
17 | #include <linux/mman.h> | ||
18 | #include <linux/file.h> | ||
19 | #include <linux/utsname.h> | ||
20 | #include <linux/ipc.h> | ||
21 | |||
22 | #include <linux/uaccess.h> | ||
23 | #include <linux/unistd.h> | ||
24 | |||
25 | #include <asm/syscalls.h> | ||
26 | |||
27 | /* | ||
28 | * Do a system call from kernel instead of calling sys_execve so we | ||
29 | * end up with proper pt_regs. | ||
30 | */ | ||
31 | int kernel_execve(const char *filename, | ||
32 | const char *const argv[], | ||
33 | const char *const envp[]) | ||
34 | { | ||
35 | long __res; | ||
36 | asm volatile ("int $0x80" | ||
37 | : "=a" (__res) | ||
38 | : "0" (__NR_execve), "b" (filename), "c" (argv), "d" (envp) : "memory"); | ||
39 | return __res; | ||
40 | } | ||
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index 54abcc0baf23..5c9687b1bde6 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c | |||
@@ -561,9 +561,9 @@ int handle_vm86_trap(struct kernel_vm86_regs *regs, long error_code, int trapno) | |||
561 | if ((trapno == 3) || (trapno == 1)) { | 561 | if ((trapno == 3) || (trapno == 1)) { |
562 | KVM86->regs32->ax = VM86_TRAP + (trapno << 8); | 562 | KVM86->regs32->ax = VM86_TRAP + (trapno << 8); |
563 | /* setting this flag forces the code in entry_32.S to | 563 | /* setting this flag forces the code in entry_32.S to |
564 | call save_v86_state() and change the stack pointer | 564 | the path where we call save_v86_state() and change |
565 | to KVM86->regs32 */ | 565 | the stack pointer to KVM86->regs32 */ |
566 | set_thread_flag(TIF_IRET); | 566 | set_thread_flag(TIF_NOTIFY_RESUME); |
567 | return 0; | 567 | return 0; |
568 | } | 568 | } |
569 | do_int(regs, trapno, (unsigned char __user *) (regs->pt.ss << 4), SP(regs)); | 569 | do_int(regs, trapno, (unsigned char __user *) (regs->pt.ss << 4), SP(regs)); |