aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/Makefile2
-rw-r--r--arch/x86/kernel/asm-offsets.c3
-rw-r--r--arch/x86/kernel/entry_32.S26
-rw-r--r--arch/x86/kernel/entry_64.S74
-rw-r--r--arch/x86/kernel/process.c65
-rw-r--r--arch/x86/kernel/process_32.c37
-rw-r--r--arch/x86/kernel/process_64.c35
-rw-r--r--arch/x86/kernel/signal.c4
-rw-r--r--arch/x86/kernel/sys_i386_32.c40
-rw-r--r--arch/x86/kernel/vm86_32.c6
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
23obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o 23obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o
24obj-$(CONFIG_IRQ_WORK) += irq_work.o 24obj-$(CONFIG_IRQ_WORK) += irq_work.o
25obj-y += probe_roms.o 25obj-y += probe_roms.o
26obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o 26obj-$(CONFIG_X86_32) += i386_ksyms_32.o
27obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o 27obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o
28obj-y += syscall_$(BITS).o 28obj-y += syscall_$(BITS).o
29obj-$(CONFIG_X86_64) += vsyscall_64.o 29obj-$(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
300END(ret_from_fork) 300END(ret_from_fork)
301 301
302ENTRY(ret_from_kernel_execve)
303 movl %eax, %esp
304 movl $0,PT_EAX(%esp)
305 GET_THREAD_INFO(%ebp)
306 jmp syscall_exit
307END(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)
732PTREGSCALL1(iopl) 738PTREGSCALL1(iopl)
733PTREGSCALL0(fork) 739PTREGSCALL0(fork)
734PTREGSCALL0(vfork) 740PTREGSCALL0(vfork)
735PTREGSCALL3(execve)
736PTREGSCALL2(sigaltstack) 741PTREGSCALL2(sigaltstack)
737PTREGSCALL0(sigreturn) 742PTREGSCALL0(sigreturn)
738PTREGSCALL0(rt_sigreturn) 743PTREGSCALL0(rt_sigreturn)
@@ -1015,15 +1020,20 @@ END(spurious_interrupt_bug)
1015 */ 1020 */
1016 .popsection 1021 .popsection
1017 1022
1018ENTRY(kernel_thread_helper) 1023ENTRY(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
1026ENDPROC(kernel_thread_helper) 1036ENDPROC(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
5651:
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
566END(ret_from_fork) 576END(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
1321ENTRY(kernel_thread_helper) 1329ENTRY(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 1341END(ret_from_kernel_execve)
1334END(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 */
1351ENTRY(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
1365END(kernel_execve)
1366 1342
1367/* Call softirq on interrupt stack. Interrupts are off. */ 1343/* Call softirq on interrupt stack. Interrupts are off. */
1368ENTRY(call_softirq) 1344ENTRY(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 */
300extern void kernel_thread_helper(void);
301
302/*
303 * Create a kernel thread
304 */
305int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
306{
307 struct pt_regs regs;
308
309 memset(&regs, 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, &regs, 0, NULL, NULL);
330}
331EXPORT_SYMBOL(kernel_thread);
332
333/*
334 * sys_execve() executes a new program.
335 */
336long 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 */
363unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE; 298unsigned 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
59asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); 59asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
60asmlinkage 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
129int copy_thread(unsigned long clone_flags, unsigned long sp, 130int 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}
194EXPORT_SYMBOL_GPL(start_thread); 217EXPORT_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
148int copy_thread(unsigned long clone_flags, unsigned long sp, 148int 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 */
31int 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));