]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - arch/x86/ia32/ia32_signal.c
x86: Rename trap_no to trap_nr in thread_struct
[mirror_ubuntu-bionic-kernel.git] / arch / x86 / ia32 / ia32_signal.c
CommitLineData
1da177e4
LT
1/*
2 * linux/arch/x86_64/ia32/ia32_signal.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 *
6 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
7 * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes
8 * 2000-12-* x86-64 compatibility mode signal handling by Andi Kleen
1da177e4
LT
9 */
10
11#include <linux/sched.h>
12#include <linux/mm.h>
13#include <linux/smp.h>
1da177e4 14#include <linux/kernel.h>
1da177e4
LT
15#include <linux/errno.h>
16#include <linux/wait.h>
1da177e4
LT
17#include <linux/unistd.h>
18#include <linux/stddef.h>
19#include <linux/personality.h>
20#include <linux/compat.h>
9fbbd4dd 21#include <linux/binfmts.h>
1da177e4
LT
22#include <asm/ucontext.h>
23#include <asm/uaccess.h>
24#include <asm/i387.h>
1da177e4
LT
25#include <asm/ptrace.h>
26#include <asm/ia32_unistd.h>
27#include <asm/user32.h>
28#include <asm/sigcontext32.h>
1da177e4 29#include <asm/proto.h>
af65d648 30#include <asm/vdso.h>
d98f9d84 31#include <asm/sigframe.h>
f28f0c23 32#include <asm/sighandling.h>
2f06de06 33#include <asm/sys_ia32.h>
d98f9d84 34
f28f0c23 35#define FIX_EFLAGS __FIX_EFLAGS
1da177e4
LT
36
37int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
38{
3b4b7570 39 int err = 0;
e7084fd5 40 bool ia32 = !is_ia32_task();
99b9cdf7
TG
41
42 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
1da177e4
LT
43 return -EFAULT;
44
3b4b7570
HS
45 put_user_try {
46 /* If you change siginfo_t structure, please make sure that
47 this code is fixed accordingly.
48 It should never copy any pad contained in the structure
49 to avoid security leaks, but must copy the generic
50 3 ints plus the relevant union member. */
51 put_user_ex(from->si_signo, &to->si_signo);
52 put_user_ex(from->si_errno, &to->si_errno);
53 put_user_ex((short)from->si_code, &to->si_code);
54
55 if (from->si_code < 0) {
56 put_user_ex(from->si_pid, &to->si_pid);
57 put_user_ex(from->si_uid, &to->si_uid);
58 put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
59 } else {
60 /*
61 * First 32bits of unions are always present:
62 * si_pid === si_band === si_tid === si_addr(LS half)
63 */
64 put_user_ex(from->_sifields._pad[0],
65 &to->_sifields._pad[0]);
66 switch (from->si_code >> 16) {
67 case __SI_FAULT >> 16:
68 break;
69 case __SI_CHLD >> 16:
e7084fd5
PA
70 if (ia32) {
71 put_user_ex(from->si_utime, &to->si_utime);
72 put_user_ex(from->si_stime, &to->si_stime);
73 } else {
74 put_user_ex(from->si_utime, &to->_sifields._sigchld_x32._utime);
75 put_user_ex(from->si_stime, &to->_sifields._sigchld_x32._stime);
76 }
3b4b7570
HS
77 put_user_ex(from->si_status, &to->si_status);
78 /* FALL THROUGH */
79 default:
80 case __SI_KILL >> 16:
81 put_user_ex(from->si_uid, &to->si_uid);
82 break;
83 case __SI_POLL >> 16:
84 put_user_ex(from->si_fd, &to->si_fd);
85 break;
86 case __SI_TIMER >> 16:
87 put_user_ex(from->si_overrun, &to->si_overrun);
88 put_user_ex(ptr_to_compat(from->si_ptr),
89 &to->si_ptr);
90 break;
91 /* This is not generated by the kernel as of now. */
92 case __SI_RT >> 16:
93 case __SI_MESGQ >> 16:
94 put_user_ex(from->si_uid, &to->si_uid);
95 put_user_ex(from->si_int, &to->si_int);
96 break;
97 }
1da177e4 98 }
3b4b7570
HS
99 } put_user_catch(err);
100
1da177e4
LT
101 return err;
102}
103
104int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
105{
3b4b7570 106 int err = 0;
1da177e4 107 u32 ptr32;
99b9cdf7
TG
108
109 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
1da177e4
LT
110 return -EFAULT;
111
3b4b7570
HS
112 get_user_try {
113 get_user_ex(to->si_signo, &from->si_signo);
114 get_user_ex(to->si_errno, &from->si_errno);
115 get_user_ex(to->si_code, &from->si_code);
1da177e4 116
3b4b7570
HS
117 get_user_ex(to->si_pid, &from->si_pid);
118 get_user_ex(to->si_uid, &from->si_uid);
119 get_user_ex(ptr32, &from->si_ptr);
120 to->si_ptr = compat_ptr(ptr32);
121 } get_user_catch(err);
1da177e4
LT
122
123 return err;
124}
125
99b9cdf7 126asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
1da177e4 127{
905f29e2
ON
128 sigset_t blocked;
129
1d001df1 130 current->saved_sigmask = current->blocked;
905f29e2
ON
131
132 mask &= _BLOCKABLE;
133 siginitset(&blocked, mask);
134 set_current_blocked(&blocked);
1da177e4 135
1d001df1
AK
136 current->state = TASK_INTERRUPTIBLE;
137 schedule();
905f29e2 138
5a8da0ea 139 set_restore_sigmask();
1d001df1 140 return -ERESTARTNOHAND;
1da177e4
LT
141}
142
99b9cdf7
TG
143asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
144 stack_ia32_t __user *uoss_ptr,
145 struct pt_regs *regs)
1da177e4 146{
99b9cdf7 147 stack_t uss, uoss;
3b4b7570 148 int ret, err = 0;
99b9cdf7
TG
149 mm_segment_t seg;
150
151 if (uss_ptr) {
1da177e4 152 u32 ptr;
99b9cdf7
TG
153
154 memset(&uss, 0, sizeof(stack_t));
3b4b7570
HS
155 if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)))
156 return -EFAULT;
157
158 get_user_try {
159 get_user_ex(ptr, &uss_ptr->ss_sp);
160 get_user_ex(uss.ss_flags, &uss_ptr->ss_flags);
161 get_user_ex(uss.ss_size, &uss_ptr->ss_size);
162 } get_user_catch(err);
163
164 if (err)
1da177e4
LT
165 return -EFAULT;
166 uss.ss_sp = compat_ptr(ptr);
167 }
99b9cdf7
TG
168 seg = get_fs();
169 set_fs(KERNEL_DS);
65ea5b03 170 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->sp);
99b9cdf7 171 set_fs(seg);
1da177e4 172 if (ret >= 0 && uoss_ptr) {
3b4b7570
HS
173 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)))
174 return -EFAULT;
175
176 put_user_try {
177 put_user_ex(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp);
178 put_user_ex(uoss.ss_flags, &uoss_ptr->ss_flags);
179 put_user_ex(uoss.ss_size, &uoss_ptr->ss_size);
180 } put_user_catch(err);
181
182 if (err)
1da177e4 183 ret = -EFAULT;
99b9cdf7
TG
184 }
185 return ret;
1da177e4
LT
186}
187
188/*
189 * Do a signal return; undo the signal stack.
190 */
a967bb3f
HS
191#define loadsegment_gs(v) load_gs_index(v)
192#define loadsegment_fs(v) loadsegment(fs, v)
193#define loadsegment_ds(v) loadsegment(ds, v)
194#define loadsegment_es(v) loadsegment(es, v)
195
196#define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
197#define set_user_seg(seg, v) loadsegment_##seg(v)
198
b78a5b52 199#define COPY(x) { \
3b4b7570 200 get_user_ex(regs->x, &sc->x); \
1da177e4 201}
1da177e4 202
8801ead4
HS
203#define GET_SEG(seg) ({ \
204 unsigned short tmp; \
205 get_user_ex(tmp, &sc->seg); \
206 tmp; \
207})
208
209#define COPY_SEG_CPL3(seg) do { \
210 regs->seg = GET_SEG(seg) | 3; \
211} while (0)
1da177e4 212
8c6e5ce0 213#define RELOAD_SEG(seg) { \
a967bb3f
HS
214 unsigned int pre = GET_SEG(seg); \
215 unsigned int cur = get_user_seg(seg); \
8c6e5ce0
HS
216 pre |= 3; \
217 if (pre != cur) \
a967bb3f 218 set_user_seg(seg, pre); \
8c6e5ce0 219}
99b9cdf7
TG
220
221static int ia32_restore_sigcontext(struct pt_regs *regs,
222 struct sigcontext_ia32 __user *sc,
047ce935 223 unsigned int *pax)
99b9cdf7 224{
a967bb3f 225 unsigned int tmpflags, err = 0;
ab513701 226 void __user *buf;
99b9cdf7
TG
227 u32 tmp;
228
229 /* Always make any pending restarted system calls return -EINTR */
230 current_thread_info()->restart_block.fn = do_no_restart_syscall;
231
3b4b7570
HS
232 get_user_try {
233 /*
234 * Reload fs and gs if they have changed in the signal
235 * handler. This does not handle long fs/gs base changes in
236 * the handler, but does not clobber them at least in the
237 * normal case.
238 */
a967bb3f 239 RELOAD_SEG(gs);
3b4b7570
HS
240 RELOAD_SEG(fs);
241 RELOAD_SEG(ds);
242 RELOAD_SEG(es);
243
244 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
245 COPY(dx); COPY(cx); COPY(ip);
246 /* Don't touch extended registers */
247
248 COPY_SEG_CPL3(cs);
249 COPY_SEG_CPL3(ss);
250
251 get_user_ex(tmpflags, &sc->flags);
252 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
253 /* disable syscall checks */
254 regs->orig_ax = -1;
255
256 get_user_ex(tmp, &sc->fpstate);
257 buf = compat_ptr(tmp);
258 err |= restore_i387_xstate_ia32(buf);
259
260 get_user_ex(*pax, &sc->ax);
261 } get_user_catch(err);
262
1da177e4 263 return err;
1da177e4
LT
264}
265
266asmlinkage long sys32_sigreturn(struct pt_regs *regs)
267{
3b0d29ee 268 struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
1da177e4 269 sigset_t set;
65ea5b03 270 unsigned int ax;
1da177e4
LT
271
272 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
273 goto badframe;
274 if (__get_user(set.sig[0], &frame->sc.oldmask)
275 || (_COMPAT_NSIG_WORDS > 1
99b9cdf7
TG
276 && __copy_from_user((((char *) &set.sig) + 4),
277 &frame->extramask,
1da177e4
LT
278 sizeof(frame->extramask))))
279 goto badframe;
280
281 sigdelsetmask(&set, ~_BLOCKABLE);
905f29e2 282 set_current_blocked(&set);
99b9cdf7 283
65ea5b03 284 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
1da177e4 285 goto badframe;
65ea5b03 286 return ax;
1da177e4
LT
287
288badframe:
289 signal_fault(regs, frame, "32bit sigreturn");
290 return 0;
99b9cdf7 291}
1da177e4
LT
292
293asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
294{
3b0d29ee 295 struct rt_sigframe_ia32 __user *frame;
1da177e4 296 sigset_t set;
65ea5b03 297 unsigned int ax;
1da177e4
LT
298 struct pt_regs tregs;
299
3b0d29ee 300 frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
1da177e4
LT
301
302 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
303 goto badframe;
304 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
305 goto badframe;
306
307 sigdelsetmask(&set, ~_BLOCKABLE);
905f29e2 308 set_current_blocked(&set);
99b9cdf7 309
65ea5b03 310 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
1da177e4
LT
311 goto badframe;
312
313 tregs = *regs;
314 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
315 goto badframe;
316
65ea5b03 317 return ax;
1da177e4
LT
318
319badframe:
99b9cdf7 320 signal_fault(regs, frame, "32bit rt sigreturn");
1da177e4 321 return 0;
99b9cdf7 322}
1da177e4
LT
323
324/*
325 * Set up a signal frame.
326 */
327
99b9cdf7 328static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
ab513701 329 void __user *fpstate,
99b9cdf7 330 struct pt_regs *regs, unsigned int mask)
1da177e4 331{
a967bb3f 332 int err = 0;
1da177e4 333
3b4b7570 334 put_user_try {
a967bb3f
HS
335 put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
336 put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
337 put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
338 put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
3b4b7570
HS
339
340 put_user_ex(regs->di, &sc->di);
341 put_user_ex(regs->si, &sc->si);
342 put_user_ex(regs->bp, &sc->bp);
343 put_user_ex(regs->sp, &sc->sp);
344 put_user_ex(regs->bx, &sc->bx);
345 put_user_ex(regs->dx, &sc->dx);
346 put_user_ex(regs->cx, &sc->cx);
347 put_user_ex(regs->ax, &sc->ax);
51e7dc70 348 put_user_ex(current->thread.trap_nr, &sc->trapno);
3b4b7570
HS
349 put_user_ex(current->thread.error_code, &sc->err);
350 put_user_ex(regs->ip, &sc->ip);
351 put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
352 put_user_ex(regs->flags, &sc->flags);
353 put_user_ex(regs->sp, &sc->sp_at_signal);
354 put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
355
356 put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
357
358 /* non-iBCS2 extensions.. */
359 put_user_ex(mask, &sc->oldmask);
360 put_user_ex(current->thread.cr2, &sc->cr2);
361 } put_user_catch(err);
1da177e4
LT
362
363 return err;
364}
365
366/*
367 * Determine which stack to use..
368 */
99b9cdf7 369static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
3c1c7f10 370 size_t frame_size,
ab513701 371 void **fpstate)
1da177e4 372{
65ea5b03 373 unsigned long sp;
1da177e4
LT
374
375 /* Default to using normal stack */
65ea5b03 376 sp = regs->sp;
1da177e4
LT
377
378 /* This is the X/Open sanctioned signal stack switching. */
379 if (ka->sa.sa_flags & SA_ONSTACK) {
65ea5b03
PA
380 if (sas_ss_flags(sp) == 0)
381 sp = current->sas_ss_sp + current->sas_ss_size;
1da177e4
LT
382 }
383
384 /* This is the legacy signal stack switching. */
8bee3f0a 385 else if ((regs->ss & 0xffff) != __USER32_DS &&
1da177e4 386 !(ka->sa.sa_flags & SA_RESTORER) &&
99b9cdf7 387 ka->sa.sa_restorer)
65ea5b03 388 sp = (unsigned long) ka->sa.sa_restorer;
1da177e4 389
3c1c7f10
SS
390 if (used_math()) {
391 sp = sp - sig_xstate_ia32_size;
392 *fpstate = (struct _fpstate_ia32 *) sp;
99ea1b93
HS
393 if (save_i387_xstate_ia32(*fpstate) < 0)
394 return (void __user *) -1L;
3c1c7f10
SS
395 }
396
65ea5b03 397 sp -= frame_size;
d347f372
MO
398 /* Align the stack pointer according to the i386 ABI,
399 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
65ea5b03
PA
400 sp = ((sp + 4) & -16ul) - 4;
401 return (void __user *) sp;
1da177e4
LT
402}
403
0928d6ef 404int ia32_setup_frame(int sig, struct k_sigaction *ka,
99b9cdf7 405 compat_sigset_t *set, struct pt_regs *regs)
1da177e4 406{
3b0d29ee 407 struct sigframe_ia32 __user *frame;
99b9cdf7 408 void __user *restorer;
1da177e4 409 int err = 0;
ab513701 410 void __user *fpstate = NULL;
1da177e4 411
99b9cdf7
TG
412 /* copy_to_user optimizes that into a single 8 byte store */
413 static const struct {
414 u16 poplmovl;
415 u32 val;
416 u16 int80;
99b9cdf7
TG
417 } __attribute__((packed)) code = {
418 0xb858, /* popl %eax ; movl $...,%eax */
419 __NR_ia32_sigreturn,
420 0x80cd, /* int $0x80 */
99b9cdf7
TG
421 };
422
3c1c7f10 423 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
1da177e4
LT
424
425 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
3d0aedd9 426 return -EFAULT;
1da177e4 427
2ba48e16 428 if (__put_user(sig, &frame->sig))
3d0aedd9 429 return -EFAULT;
1da177e4 430
2ba48e16 431 if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
3d0aedd9 432 return -EFAULT;
1da177e4
LT
433
434 if (_COMPAT_NSIG_WORDS > 1) {
2ba48e16
HS
435 if (__copy_to_user(frame->extramask, &set->sig[1],
436 sizeof(frame->extramask)))
3d0aedd9 437 return -EFAULT;
1da177e4 438 }
1da177e4 439
af65d648 440 if (ka->sa.sa_flags & SA_RESTORER) {
99b9cdf7 441 restorer = ka->sa.sa_restorer;
af65d648
RM
442 } else {
443 /* Return stub is in 32bit vsyscall page */
1a3e4ca4 444 if (current->mm->context.vdso)
af65d648
RM
445 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
446 sigreturn);
447 else
ade1af77 448 restorer = &frame->retcode;
af65d648 449 }
99b9cdf7 450
3b4b7570
HS
451 put_user_try {
452 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
453
454 /*
455 * These are actually not used anymore, but left because some
456 * gdb versions depend on them as a marker.
457 */
458 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
459 } put_user_catch(err);
460
1da177e4 461 if (err)
3d0aedd9 462 return -EFAULT;
1da177e4
LT
463
464 /* Set up registers for signal handler */
65ea5b03
PA
465 regs->sp = (unsigned long) frame;
466 regs->ip = (unsigned long) ka->sa.sa_handler;
1da177e4 467
536e3ee4 468 /* Make -mregparm=3 work */
65ea5b03
PA
469 regs->ax = sig;
470 regs->dx = 0;
471 regs->cx = 0;
536e3ee4 472
b6edbb1e
JF
473 loadsegment(ds, __USER32_DS);
474 loadsegment(es, __USER32_DS);
1da177e4 475
99b9cdf7
TG
476 regs->cs = __USER32_CS;
477 regs->ss = __USER32_DS;
1da177e4 478
1d001df1 479 return 0;
1da177e4
LT
480}
481
0928d6ef 482int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
99b9cdf7 483 compat_sigset_t *set, struct pt_regs *regs)
1da177e4 484{
3b0d29ee 485 struct rt_sigframe_ia32 __user *frame;
af65d648 486 void __user *restorer;
1da177e4 487 int err = 0;
ab513701 488 void __user *fpstate = NULL;
1da177e4 489
99b9cdf7
TG
490 /* __copy_to_user optimizes that into a single 8 byte store */
491 static const struct {
492 u8 movl;
493 u32 val;
494 u16 int80;
9cc3c49e 495 u8 pad;
99b9cdf7
TG
496 } __attribute__((packed)) code = {
497 0xb8,
498 __NR_ia32_rt_sigreturn,
499 0x80cd,
500 0,
501 };
502
3c1c7f10 503 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
1da177e4
LT
504
505 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
3d0aedd9 506 return -EFAULT;
1da177e4 507
3b4b7570
HS
508 put_user_try {
509 put_user_ex(sig, &frame->sig);
510 put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
511 put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
512 err |= copy_siginfo_to_user32(&frame->info, info);
1da177e4 513
3b4b7570
HS
514 /* Create the ucontext. */
515 if (cpu_has_xsave)
516 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
517 else
518 put_user_ex(0, &frame->uc.uc_flags);
519 put_user_ex(0, &frame->uc.uc_link);
520 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
521 put_user_ex(sas_ss_flags(regs->sp),
522 &frame->uc.uc_stack.ss_flags);
523 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
524 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
525 regs, set->sig[0]);
526 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
527
528 if (ka->sa.sa_flags & SA_RESTORER)
529 restorer = ka->sa.sa_restorer;
530 else
531 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
532 rt_sigreturn);
533 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
534
535 /*
536 * Not actually used anymore, but left because some gdb
537 * versions need it.
538 */
539 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
540 } put_user_catch(err);
1da177e4 541
1da177e4 542 if (err)
3d0aedd9 543 return -EFAULT;
1da177e4
LT
544
545 /* Set up registers for signal handler */
65ea5b03
PA
546 regs->sp = (unsigned long) frame;
547 regs->ip = (unsigned long) ka->sa.sa_handler;
1da177e4 548
a7aacdf9 549 /* Make -mregparm=3 work */
65ea5b03
PA
550 regs->ax = sig;
551 regs->dx = (unsigned long) &frame->info;
552 regs->cx = (unsigned long) &frame->uc;
a7aacdf9 553
b6edbb1e
JF
554 loadsegment(ds, __USER32_DS);
555 loadsegment(es, __USER32_DS);
99b9cdf7
TG
556
557 regs->cs = __USER32_CS;
558 regs->ss = __USER32_DS;
1da177e4 559
1d001df1 560 return 0;
1da177e4 561}