compat_signal.c 15.6 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
2
 *    Copyright IBM Corp. 2000, 2006
L
Linus Torvalds 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
 *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
 *               Gerhard Tonn (ton@de.ibm.com)                  
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 *
 *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
 */

#include <linux/compat.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/wait.h>
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/stddef.h>
#include <linux/tty.h>
#include <linux/personality.h>
#include <linux/binfmts.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
#include <asm/lowcore.h>
28
#include <asm/switch_to.h>
L
Linus Torvalds 已提交
29 30
#include "compat_linux.h"
#include "compat_ptrace.h"
31
#include "entry.h"
L
Linus Torvalds 已提交
32 33 34 35 36 37 38

typedef struct 
{
	__u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
	struct sigcontext32 sc;
	_sigregs32 sregs;
	int signo;
39 40
	_sigregs_ext32 sregs_ext;
	__u16 svc_insn;		/* Offset of svc_insn is NOT fixed! */
L
Linus Torvalds 已提交
41 42 43 44 45
} sigframe32;

typedef struct 
{
	__u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
46
	__u16 svc_insn;
L
Linus Torvalds 已提交
47 48 49 50
	compat_siginfo_t info;
	struct ucontext32 uc;
} rt_sigframe32;

A
Al Viro 已提交
51
int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
L
Linus Torvalds 已提交
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
{
	int err;

	/* If you change siginfo_t structure, please be sure
	   this code is fixed accordingly.
	   It should never copy any pad contained in the structure
	   to avoid security leaks, but must copy the generic
	   3 ints plus the relevant union member.  
	   This routine must convert siginfo from 64bit to 32bit as well
	   at the same time.  */
	err = __put_user(from->si_signo, &to->si_signo);
	err |= __put_user(from->si_errno, &to->si_errno);
	err |= __put_user((short)from->si_code, &to->si_code);
	if (from->si_code < 0)
		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
	else {
		switch (from->si_code >> 16) {
		case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
		case __SI_MESGQ >> 16:
			err |= __put_user(from->si_int, &to->si_int);
			/* fallthrough */
		case __SI_KILL >> 16:
			err |= __put_user(from->si_pid, &to->si_pid);
			err |= __put_user(from->si_uid, &to->si_uid);
			break;
		case __SI_CHLD >> 16:
			err |= __put_user(from->si_pid, &to->si_pid);
			err |= __put_user(from->si_uid, &to->si_uid);
			err |= __put_user(from->si_utime, &to->si_utime);
			err |= __put_user(from->si_stime, &to->si_stime);
			err |= __put_user(from->si_status, &to->si_status);
			break;
		case __SI_FAULT >> 16:
			err |= __put_user((unsigned long) from->si_addr,
					  &to->si_addr);
			break;
		case __SI_POLL >> 16:
			err |= __put_user(from->si_band, &to->si_band);
			err |= __put_user(from->si_fd, &to->si_fd);
			break;
		case __SI_TIMER >> 16:
			err |= __put_user(from->si_tid, &to->si_tid);
			err |= __put_user(from->si_overrun, &to->si_overrun);
			err |= __put_user(from->si_int, &to->si_int);
			break;
		default:
			break;
		}
	}
101
	return err ? -EFAULT : 0;
L
Linus Torvalds 已提交
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
}

int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
{
	int err;
	u32 tmp;

	err = __get_user(to->si_signo, &from->si_signo);
	err |= __get_user(to->si_errno, &from->si_errno);
	err |= __get_user(to->si_code, &from->si_code);

	if (to->si_code < 0)
		err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
	else {
		switch (to->si_code >> 16) {
		case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
		case __SI_MESGQ >> 16:
			err |= __get_user(to->si_int, &from->si_int);
			/* fallthrough */
		case __SI_KILL >> 16:
			err |= __get_user(to->si_pid, &from->si_pid);
			err |= __get_user(to->si_uid, &from->si_uid);
			break;
		case __SI_CHLD >> 16:
			err |= __get_user(to->si_pid, &from->si_pid);
			err |= __get_user(to->si_uid, &from->si_uid);
			err |= __get_user(to->si_utime, &from->si_utime);
			err |= __get_user(to->si_stime, &from->si_stime);
			err |= __get_user(to->si_status, &from->si_status);
			break;
		case __SI_FAULT >> 16:
			err |= __get_user(tmp, &from->si_addr);
134 135
			to->si_addr = (void __force __user *)
				(u64) (tmp & PSW32_ADDR_INSN);
L
Linus Torvalds 已提交
136 137 138 139 140 141 142 143 144 145 146 147 148 149
			break;
		case __SI_POLL >> 16:
			err |= __get_user(to->si_band, &from->si_band);
			err |= __get_user(to->si_fd, &from->si_fd);
			break;
		case __SI_TIMER >> 16:
			err |= __get_user(to->si_tid, &from->si_tid);
			err |= __get_user(to->si_overrun, &from->si_overrun);
			err |= __get_user(to->si_int, &from->si_int);
			break;
		default:
			break;
		}
	}
150
	return err ? -EFAULT : 0;
L
Linus Torvalds 已提交
151 152
}

153 154 155 156
/* Store registers needed to create the signal frame */
static void store_sigregs(void)
{
	save_access_regs(current->thread.acrs);
157
	save_fpu_regs();
158 159 160 161 162 163 164 165
}

/* Load registers after signal return */
static void load_sigregs(void)
{
	restore_access_regs(current->thread.acrs);
}

L
Linus Torvalds 已提交
166 167
static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
{
168 169
	_sigregs32 user_sregs;
	int i;
L
Linus Torvalds 已提交
170

171 172
	user_sregs.regs.psw.mask = (__u32)(regs->psw.mask >> 32);
	user_sregs.regs.psw.mask &= PSW32_MASK_USER | PSW32_MASK_RI;
173
	user_sregs.regs.psw.mask |= PSW32_USER_BITS;
174
	user_sregs.regs.psw.addr = (__u32) regs->psw.addr |
175
		(__u32)(regs->psw.mask & PSW_MASK_BA);
L
Linus Torvalds 已提交
176
	for (i = 0; i < NUM_GPRS; i++)
177 178 179
		user_sregs.regs.gprs[i] = (__u32) regs->gprs[i];
	memcpy(&user_sregs.regs.acrs, current->thread.acrs,
	       sizeof(user_sregs.regs.acrs));
180
	fpregs_store((_s390_fp_regs *) &user_sregs.fpregs, &current->thread.fpu);
181
	if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs32)))
182 183
		return -EFAULT;
	return 0;
L
Linus Torvalds 已提交
184 185 186 187
}

static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
{
188 189
	_sigregs32 user_sregs;
	int i;
L
Linus Torvalds 已提交
190 191

	/* Alwys make any pending restarted system call return -EINTR */
192
	current->restart_block.fn = do_no_restart_syscall;
L
Linus Torvalds 已提交
193

194
	if (__copy_from_user(&user_sregs, &sregs->regs, sizeof(user_sregs)))
195
		return -EFAULT;
196

197 198 199
	if (!is_ri_task(current) && (user_sregs.regs.psw.mask & PSW32_MASK_RI))
		return -EINVAL;

200 201
	/* Test the floating-point-control word. */
	if (test_fp_ctl(user_sregs.fpregs.fpc))
202 203 204
		return -EINVAL;

	/* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
205
	regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) |
206
		(__u64)(user_sregs.regs.psw.mask & PSW32_MASK_USER) << 32 |
207
		(__u64)(user_sregs.regs.psw.mask & PSW32_MASK_RI) << 32 |
208
		(__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_AMODE);
209
	/* Check for invalid user address space control. */
210 211
	if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)
		regs->psw.mask = PSW_ASC_PRIMARY |
212
			(regs->psw.mask & ~PSW_MASK_ASC);
213
	regs->psw.addr = (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_INSN);
L
Linus Torvalds 已提交
214
	for (i = 0; i < NUM_GPRS; i++)
215 216 217
		regs->gprs[i] = (__u64) user_sregs.regs.gprs[i];
	memcpy(&current->thread.acrs, &user_sregs.regs.acrs,
	       sizeof(current->thread.acrs));
218
	fpregs_load((_s390_fp_regs *) &user_sregs.fpregs, &current->thread.fpu);
L
Linus Torvalds 已提交
219

220
	clear_pt_regs_flag(regs, PIF_SYSCALL); /* No longer in a system call */
L
Linus Torvalds 已提交
221 222 223
	return 0;
}

224 225
static int save_sigregs_ext32(struct pt_regs *regs,
			      _sigregs_ext32 __user *sregs_ext)
226 227
{
	__u32 gprs_high[NUM_GPRS];
228
	__u64 vxrs[__NUM_VXRS_LOW];
229 230
	int i;

231
	/* Save high gprs to signal stack */
232 233
	for (i = 0; i < NUM_GPRS; i++)
		gprs_high[i] = regs->gprs[i] >> 32;
234 235
	if (__copy_to_user(&sregs_ext->gprs_high, &gprs_high,
			   sizeof(sregs_ext->gprs_high)))
236
		return -EFAULT;
237 238

	/* Save vector registers to signal stack */
239
	if (is_vx_task(current)) {
240
		for (i = 0; i < __NUM_VXRS_LOW; i++)
241
			vxrs[i] = *((__u64 *)(current->thread.fpu.vxrs + i) + 1);
242 243 244
		if (__copy_to_user(&sregs_ext->vxrs_low, vxrs,
				   sizeof(sregs_ext->vxrs_low)) ||
		    __copy_to_user(&sregs_ext->vxrs_high,
245
				   current->thread.fpu.vxrs + __NUM_VXRS_LOW,
246 247 248
				   sizeof(sregs_ext->vxrs_high)))
			return -EFAULT;
	}
249
	return 0;
250 251
}

252 253
static int restore_sigregs_ext32(struct pt_regs *regs,
				 _sigregs_ext32 __user *sregs_ext)
254 255
{
	__u32 gprs_high[NUM_GPRS];
256
	__u64 vxrs[__NUM_VXRS_LOW];
257
	int i;
258

259 260 261
	/* Restore high gprs from signal stack */
	if (__copy_from_user(&gprs_high, &sregs_ext->gprs_high,
			     sizeof(&sregs_ext->gprs_high)))
262
		return -EFAULT;
263 264
	for (i = 0; i < NUM_GPRS; i++)
		*(__u32 *)&regs->gprs[i] = gprs_high[i];
265 266

	/* Restore vector registers from signal stack */
267
	if (is_vx_task(current)) {
268 269
		if (__copy_from_user(vxrs, &sregs_ext->vxrs_low,
				     sizeof(sregs_ext->vxrs_low)) ||
270
		    __copy_from_user(current->thread.fpu.vxrs + __NUM_VXRS_LOW,
271 272 273 274
				     &sregs_ext->vxrs_high,
				     sizeof(sregs_ext->vxrs_high)))
			return -EFAULT;
		for (i = 0; i < __NUM_VXRS_LOW; i++)
275
			*((__u64 *)(current->thread.fpu.vxrs + i) + 1) = vxrs[i];
276
	}
277 278 279
	return 0;
}

280
COMPAT_SYSCALL_DEFINE0(sigreturn)
L
Linus Torvalds 已提交
281
{
M
Martin Schwidefsky 已提交
282
	struct pt_regs *regs = task_pt_regs(current);
L
Linus Torvalds 已提交
283 284 285 286 287
	sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15];
	sigset_t set;

	if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
		goto badframe;
288
	set_current_blocked(&set);
289
	save_fpu_regs();
L
Linus Torvalds 已提交
290 291
	if (restore_sigregs32(regs, &frame->sregs))
		goto badframe;
292
	if (restore_sigregs_ext32(regs, &frame->sregs_ext))
293
		goto badframe;
294
	load_sigregs();
L
Linus Torvalds 已提交
295 296 297 298 299 300
	return regs->gprs[2];
badframe:
	force_sig(SIGSEGV, current);
	return 0;
}

301
COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
L
Linus Torvalds 已提交
302
{
M
Martin Schwidefsky 已提交
303
	struct pt_regs *regs = task_pt_regs(current);
L
Linus Torvalds 已提交
304 305 306 307 308
	rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15];
	sigset_t set;

	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
		goto badframe;
309
	set_current_blocked(&set);
310 311
	if (compat_restore_altstack(&frame->uc.uc_stack))
		goto badframe;
312
	save_fpu_regs();
L
Linus Torvalds 已提交
313 314
	if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
		goto badframe;
315
	if (restore_sigregs_ext32(regs, &frame->uc.uc_mcontext_ext))
316
		goto badframe;
317
	load_sigregs();
L
Linus Torvalds 已提交
318 319
	return regs->gprs[2];
badframe:
M
Martin Schwidefsky 已提交
320 321
	force_sig(SIGSEGV, current);
	return 0;
L
Linus Torvalds 已提交
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
}	

/*
 * Set up a signal frame.
 */


/*
 * Determine which stack to use..
 */
static inline void __user *
get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
{
	unsigned long sp;

	/* Default to using normal stack */
	sp = (unsigned long) A(regs->gprs[15]);

340 341 342 343
	/* Overflow on alternate signal stack gives SIGSEGV. */
	if (on_sig_stack(sp) && !on_sig_stack((sp - frame_size) & -8UL))
		return (void __user *) -1UL;

L
Linus Torvalds 已提交
344 345
	/* This is the X/Open sanctioned signal stack switching.  */
	if (ka->sa.sa_flags & SA_ONSTACK) {
346
		if (! sas_ss_flags(sp))
L
Linus Torvalds 已提交
347 348 349 350 351 352
			sp = current->sas_ss_sp + current->sas_ss_size;
	}

	return (void __user *)((sp - frame_size) & -8ul);
}

353 354
static int setup_frame32(struct ksignal *ksig, sigset_t *set,
			 struct pt_regs *regs)
L
Linus Torvalds 已提交
355
{
356
	int sig = ksig->sig;
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
	sigframe32 __user *frame;
	struct sigcontext32 sc;
	unsigned long restorer;
	size_t frame_size;

	/*
	 * gprs_high are always present for 31-bit compat tasks.
	 * The space for vector registers is only allocated if
	 * the machine supports it
	 */
	frame_size = sizeof(*frame) - sizeof(frame->sregs_ext.__reserved);
	if (!MACHINE_HAS_VX)
		frame_size -= sizeof(frame->sregs_ext.vxrs_low) +
			      sizeof(frame->sregs_ext.vxrs_high);
	frame = get_sigframe(&ksig->ka, regs, frame_size);
372
	if (frame == (void __user *) -1UL)
373
		return -EFAULT;
374

375 376 377 378 379 380 381 382
	/* Set up backchain. */
	if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
		return -EFAULT;

	/* Create struct sigcontext32 on the signal stack */
	memcpy(&sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32);
	sc.sregs = (__u32)(unsigned long __force) &frame->sregs;
	if (__copy_to_user(&frame->sc, &sc, sizeof(frame->sc)))
383
		return -EFAULT;
L
Linus Torvalds 已提交
384

385 386 387 388
	/* Store registers needed to create the signal frame */
	store_sigregs();

	/* Create _sigregs32 on the signal stack */
L
Linus Torvalds 已提交
389
	if (save_sigregs32(regs, &frame->sregs))
390
		return -EFAULT;
391 392 393

	/* Place signal number on stack to allow backtrace from handler.  */
	if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo))
394
		return -EFAULT;
395 396 397

	/* Create _sigregs_ext32 on the signal stack */
	if (save_sigregs_ext32(regs, &frame->sregs_ext))
398
		return -EFAULT;
L
Linus Torvalds 已提交
399 400 401

	/* Set up to return from userspace.  If provided, use a stub
	   already in userspace.  */
402
	if (ksig->ka.sa.sa_flags & SA_RESTORER) {
403 404
		restorer = (unsigned long __force)
			ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
L
Linus Torvalds 已提交
405
	} else {
406
		/* Signal frames without vectors registers are short ! */
407
		__u16 __user *svc = (void __user *) frame + frame_size - 2;
408
		if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, svc))
409
			return -EFAULT;
410
		restorer = (unsigned long __force) svc | PSW32_ADDR_AMODE;
L
Linus Torvalds 已提交
411 412 413
        }

	/* Set up registers for signal handler */
414
	regs->gprs[14] = restorer;
415
	regs->gprs[15] = (__force __u64) frame;
416 417
	/* Force 31 bit amode and default user address space control. */
	regs->psw.mask = PSW_MASK_BA |
418
		(PSW_USER_BITS & PSW_MASK_ASC) |
419
		(regs->psw.mask & ~PSW_MASK_ASC);
420
	regs->psw.addr = (__force __u64) ksig->ka.sa.sa_handler;
L
Linus Torvalds 已提交
421

422
	regs->gprs[2] = sig;
423
	regs->gprs[3] = (__force __u64) &frame->sc;
L
Linus Torvalds 已提交
424 425 426

	/* We forgot to include these in the sigcontext.
	   To avoid breaking binary compatibility, they are passed as args. */
M
Martin Schwidefsky 已提交
427 428 429 430 431
	if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
	    sig == SIGTRAP || sig == SIGFPE) {
		/* set extra registers only for synchronous signals */
		regs->gprs[4] = regs->int_code & 127;
		regs->gprs[5] = regs->int_parm_long;
432
		regs->gprs[6] = task_thread_info(current)->last_break;
M
Martin Schwidefsky 已提交
433
	}
L
Linus Torvalds 已提交
434

435
	return 0;
L
Linus Torvalds 已提交
436 437
}

438 439
static int setup_rt_frame32(struct ksignal *ksig, sigset_t *set,
			    struct pt_regs *regs)
L
Linus Torvalds 已提交
440
{
441 442 443 444 445 446 447 448 449 450 451 452 453 454
	rt_sigframe32 __user *frame;
	unsigned long restorer;
	size_t frame_size;
	u32 uc_flags;

	frame_size = sizeof(*frame) -
		     sizeof(frame->uc.uc_mcontext_ext.__reserved);
	/*
	 * gprs_high are always present for 31-bit compat tasks.
	 * The space for vector registers is only allocated if
	 * the machine supports it
	 */
	uc_flags = UC_GPRS_HIGH;
	if (MACHINE_HAS_VX) {
455
		if (is_vx_task(current))
456 457 458 459 460
			uc_flags |= UC_VXRS;
	} else
		frame_size -= sizeof(frame->uc.uc_mcontext_ext.vxrs_low) +
			      sizeof(frame->uc.uc_mcontext_ext.vxrs_high);
	frame = get_sigframe(&ksig->ka, regs, frame_size);
461
	if (frame == (void __user *) -1UL)
462
		return -EFAULT;
463

464 465
	/* Set up backchain. */
	if (__put_user(regs->gprs[15], (unsigned int __force __user *) frame))
466
		return -EFAULT;
L
Linus Torvalds 已提交
467 468 469

	/* Set up to return from userspace.  If provided, use a stub
	   already in userspace.  */
470
	if (ksig->ka.sa.sa_flags & SA_RESTORER) {
471 472
		restorer = (unsigned long __force)
			ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
L
Linus Torvalds 已提交
473
	} else {
474 475
		__u16 __user *svc = &frame->svc_insn;
		if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, svc))
476
			return -EFAULT;
477
		restorer = (unsigned long __force) svc | PSW32_ADDR_AMODE;
L
Linus Torvalds 已提交
478 479
	}

480 481 482 483 484 485 486 487 488 489 490 491 492 493
	/* Create siginfo on the signal stack */
	if (copy_siginfo_to_user32(&frame->info, &ksig->info))
		return -EFAULT;

	/* Store registers needed to create the signal frame */
	store_sigregs();

	/* Create ucontext on the signal stack. */
	if (__put_user(uc_flags, &frame->uc.uc_flags) ||
	    __put_user(0, &frame->uc.uc_link) ||
	    __compat_save_altstack(&frame->uc.uc_stack, regs->gprs[15]) ||
	    save_sigregs32(regs, &frame->uc.uc_mcontext) ||
	    __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)) ||
	    save_sigregs_ext32(regs, &frame->uc.uc_mcontext_ext))
494
		return -EFAULT;
L
Linus Torvalds 已提交
495 496

	/* Set up registers for signal handler */
497
	regs->gprs[14] = restorer;
498
	regs->gprs[15] = (__force __u64) frame;
499 500
	/* Force 31 bit amode and default user address space control. */
	regs->psw.mask = PSW_MASK_BA |
501
		(PSW_USER_BITS & PSW_MASK_ASC) |
502
		(regs->psw.mask & ~PSW_MASK_ASC);
503
	regs->psw.addr = (__u64 __force) ksig->ka.sa.sa_handler;
L
Linus Torvalds 已提交
504

505
	regs->gprs[2] = ksig->sig;
506 507
	regs->gprs[3] = (__force __u64) &frame->info;
	regs->gprs[4] = (__force __u64) &frame->uc;
508
	regs->gprs[5] = task_thread_info(current)->last_break;
509
	return 0;
L
Linus Torvalds 已提交
510 511 512 513 514 515
}

/*
 * OK, we're invoking a handler
 */	

516 517
void handle_signal32(struct ksignal *ksig, sigset_t *oldset,
		     struct pt_regs *regs)
L
Linus Torvalds 已提交
518
{
519 520
	int ret;

L
Linus Torvalds 已提交
521
	/* Set up the stack frame */
522 523
	if (ksig->ka.sa.sa_flags & SA_SIGINFO)
		ret = setup_rt_frame32(ksig, oldset, regs);
L
Linus Torvalds 已提交
524
	else
525 526 527
		ret = setup_frame32(ksig, oldset, regs);

	signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLE_STEP));
L
Linus Torvalds 已提交
528 529
}