compat_signal.c 16.2 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;

51 52 53 54 55 56 57 58 59 60 61 62 63
static inline void sigset_to_sigset32(unsigned long *set64,
				      compat_sigset_word *set32)
{
	set32[0] = (compat_sigset_word) set64[0];
	set32[1] = (compat_sigset_word)(set64[0] >> 32);
}

static inline void sigset32_to_sigset(compat_sigset_word *set32,
				      unsigned long *set64)
{
	set64[0] = (unsigned long) set32[0] | ((unsigned long) set32[1] << 32);
}

A
Al Viro 已提交
64
int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
L
Linus Torvalds 已提交
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 101 102 103 104 105 106 107 108 109 110 111 112 113
{
	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;
		}
	}
114
	return err ? -EFAULT : 0;
L
Linus Torvalds 已提交
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
}

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);
147 148
			to->si_addr = (void __force __user *)
				(u64) (tmp & PSW32_ADDR_INSN);
L
Linus Torvalds 已提交
149 150 151 152 153 154 155 156 157 158 159 160 161 162
			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;
		}
	}
163
	return err ? -EFAULT : 0;
L
Linus Torvalds 已提交
164 165
}

166 167 168 169
/* Store registers needed to create the signal frame */
static void store_sigregs(void)
{
	save_access_regs(current->thread.acrs);
170
	save_fpu_regs();
171 172 173 174 175 176 177 178
}

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

L
Linus Torvalds 已提交
179 180
static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
{
181 182
	_sigregs32 user_sregs;
	int i;
L
Linus Torvalds 已提交
183

184 185
	user_sregs.regs.psw.mask = (__u32)(regs->psw.mask >> 32);
	user_sregs.regs.psw.mask &= PSW32_MASK_USER | PSW32_MASK_RI;
186
	user_sregs.regs.psw.mask |= PSW32_USER_BITS;
187
	user_sregs.regs.psw.addr = (__u32) regs->psw.addr |
188
		(__u32)(regs->psw.mask & PSW_MASK_BA);
L
Linus Torvalds 已提交
189
	for (i = 0; i < NUM_GPRS; i++)
190 191 192
		user_sregs.regs.gprs[i] = (__u32) regs->gprs[i];
	memcpy(&user_sregs.regs.acrs, current->thread.acrs,
	       sizeof(user_sregs.regs.acrs));
193
	fpregs_store((_s390_fp_regs *) &user_sregs.fpregs, &current->thread.fpu);
194
	if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs32)))
195 196
		return -EFAULT;
	return 0;
L
Linus Torvalds 已提交
197 198 199 200
}

static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
{
201 202
	_sigregs32 user_sregs;
	int i;
L
Linus Torvalds 已提交
203 204

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

207
	if (__copy_from_user(&user_sregs, &sregs->regs, sizeof(user_sregs)))
208
		return -EFAULT;
209

210 211 212
	if (!is_ri_task(current) && (user_sregs.regs.psw.mask & PSW32_MASK_RI))
		return -EINVAL;

213 214
	/* Test the floating-point-control word. */
	if (test_fp_ctl(user_sregs.fpregs.fpc))
215 216 217
		return -EINVAL;

	/* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
218
	regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) |
219
		(__u64)(user_sregs.regs.psw.mask & PSW32_MASK_USER) << 32 |
220
		(__u64)(user_sregs.regs.psw.mask & PSW32_MASK_RI) << 32 |
221
		(__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_AMODE);
222
	/* Check for invalid user address space control. */
223 224
	if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)
		regs->psw.mask = PSW_ASC_PRIMARY |
225
			(regs->psw.mask & ~PSW_MASK_ASC);
226
	regs->psw.addr = (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_INSN);
L
Linus Torvalds 已提交
227
	for (i = 0; i < NUM_GPRS; i++)
228 229 230
		regs->gprs[i] = (__u64) user_sregs.regs.gprs[i];
	memcpy(&current->thread.acrs, &user_sregs.regs.acrs,
	       sizeof(current->thread.acrs));
231
	fpregs_load((_s390_fp_regs *) &user_sregs.fpregs, &current->thread.fpu);
L
Linus Torvalds 已提交
232

233
	clear_pt_regs_flag(regs, PIF_SYSCALL); /* No longer in a system call */
L
Linus Torvalds 已提交
234 235 236
	return 0;
}

237 238
static int save_sigregs_ext32(struct pt_regs *regs,
			      _sigregs_ext32 __user *sregs_ext)
239 240
{
	__u32 gprs_high[NUM_GPRS];
241
	__u64 vxrs[__NUM_VXRS_LOW];
242 243
	int i;

244
	/* Save high gprs to signal stack */
245 246
	for (i = 0; i < NUM_GPRS; i++)
		gprs_high[i] = regs->gprs[i] >> 32;
247 248
	if (__copy_to_user(&sregs_ext->gprs_high, &gprs_high,
			   sizeof(sregs_ext->gprs_high)))
249
		return -EFAULT;
250 251

	/* Save vector registers to signal stack */
252
	if (is_vx_task(current)) {
253
		for (i = 0; i < __NUM_VXRS_LOW; i++)
254
			vxrs[i] = *((__u64 *)(current->thread.fpu.vxrs + i) + 1);
255 256 257
		if (__copy_to_user(&sregs_ext->vxrs_low, vxrs,
				   sizeof(sregs_ext->vxrs_low)) ||
		    __copy_to_user(&sregs_ext->vxrs_high,
258
				   current->thread.fpu.vxrs + __NUM_VXRS_LOW,
259 260 261
				   sizeof(sregs_ext->vxrs_high)))
			return -EFAULT;
	}
262
	return 0;
263 264
}

265 266
static int restore_sigregs_ext32(struct pt_regs *regs,
				 _sigregs_ext32 __user *sregs_ext)
267 268
{
	__u32 gprs_high[NUM_GPRS];
269
	__u64 vxrs[__NUM_VXRS_LOW];
270
	int i;
271

272 273 274
	/* Restore high gprs from signal stack */
	if (__copy_from_user(&gprs_high, &sregs_ext->gprs_high,
			     sizeof(&sregs_ext->gprs_high)))
275
		return -EFAULT;
276 277
	for (i = 0; i < NUM_GPRS; i++)
		*(__u32 *)&regs->gprs[i] = gprs_high[i];
278 279

	/* Restore vector registers from signal stack */
280
	if (is_vx_task(current)) {
281 282
		if (__copy_from_user(vxrs, &sregs_ext->vxrs_low,
				     sizeof(sregs_ext->vxrs_low)) ||
283
		    __copy_from_user(current->thread.fpu.vxrs + __NUM_VXRS_LOW,
284 285 286 287
				     &sregs_ext->vxrs_high,
				     sizeof(sregs_ext->vxrs_high)))
			return -EFAULT;
		for (i = 0; i < __NUM_VXRS_LOW; i++)
288
			*((__u64 *)(current->thread.fpu.vxrs + i) + 1) = vxrs[i];
289
	}
290 291 292
	return 0;
}

293
COMPAT_SYSCALL_DEFINE0(sigreturn)
L
Linus Torvalds 已提交
294
{
M
Martin Schwidefsky 已提交
295
	struct pt_regs *regs = task_pt_regs(current);
L
Linus Torvalds 已提交
296
	sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15];
297
	compat_sigset_t cset;
L
Linus Torvalds 已提交
298 299
	sigset_t set;

300
	if (__copy_from_user(&cset.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
L
Linus Torvalds 已提交
301
		goto badframe;
302
	sigset32_to_sigset(cset.sig, set.sig);
303
	set_current_blocked(&set);
304
	save_fpu_regs();
L
Linus Torvalds 已提交
305 306
	if (restore_sigregs32(regs, &frame->sregs))
		goto badframe;
307
	if (restore_sigregs_ext32(regs, &frame->sregs_ext))
308
		goto badframe;
309
	load_sigregs();
L
Linus Torvalds 已提交
310 311 312 313 314 315
	return regs->gprs[2];
badframe:
	force_sig(SIGSEGV, current);
	return 0;
}

316
COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
L
Linus Torvalds 已提交
317
{
M
Martin Schwidefsky 已提交
318
	struct pt_regs *regs = task_pt_regs(current);
L
Linus Torvalds 已提交
319
	rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15];
320
	compat_sigset_t cset;
L
Linus Torvalds 已提交
321 322
	sigset_t set;

323
	if (__copy_from_user(&cset, &frame->uc.uc_sigmask, sizeof(cset)))
L
Linus Torvalds 已提交
324
		goto badframe;
325
	sigset32_to_sigset(cset.sig, set.sig);
326
	set_current_blocked(&set);
327 328
	if (compat_restore_altstack(&frame->uc.uc_stack))
		goto badframe;
329
	save_fpu_regs();
L
Linus Torvalds 已提交
330 331
	if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
		goto badframe;
332
	if (restore_sigregs_ext32(regs, &frame->uc.uc_mcontext_ext))
333
		goto badframe;
334
	load_sigregs();
L
Linus Torvalds 已提交
335 336
	return regs->gprs[2];
badframe:
M
Martin Schwidefsky 已提交
337 338
	force_sig(SIGSEGV, current);
	return 0;
L
Linus Torvalds 已提交
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
}	

/*
 * 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]);

357 358 359 360
	/* 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 已提交
361 362
	/* This is the X/Open sanctioned signal stack switching.  */
	if (ka->sa.sa_flags & SA_ONSTACK) {
363
		if (! sas_ss_flags(sp))
L
Linus Torvalds 已提交
364 365 366 367 368 369
			sp = current->sas_ss_sp + current->sas_ss_size;
	}

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

370 371
static int setup_frame32(struct ksignal *ksig, sigset_t *set,
			 struct pt_regs *regs)
L
Linus Torvalds 已提交
372
{
373
	int sig = ksig->sig;
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
	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);
389
	if (frame == (void __user *) -1UL)
390
		return -EFAULT;
391

392 393 394 395 396
	/* Set up backchain. */
	if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
		return -EFAULT;

	/* Create struct sigcontext32 on the signal stack */
397
	sigset_to_sigset32(set->sig, sc.oldmask);
398 399
	sc.sregs = (__u32)(unsigned long __force) &frame->sregs;
	if (__copy_to_user(&frame->sc, &sc, sizeof(frame->sc)))
400
		return -EFAULT;
L
Linus Torvalds 已提交
401

402 403 404 405
	/* Store registers needed to create the signal frame */
	store_sigregs();

	/* Create _sigregs32 on the signal stack */
L
Linus Torvalds 已提交
406
	if (save_sigregs32(regs, &frame->sregs))
407
		return -EFAULT;
408 409 410

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

	/* Create _sigregs_ext32 on the signal stack */
	if (save_sigregs_ext32(regs, &frame->sregs_ext))
415
		return -EFAULT;
L
Linus Torvalds 已提交
416 417 418

	/* Set up to return from userspace.  If provided, use a stub
	   already in userspace.  */
419
	if (ksig->ka.sa.sa_flags & SA_RESTORER) {
420 421
		restorer = (unsigned long __force)
			ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
L
Linus Torvalds 已提交
422
	} else {
423
		/* Signal frames without vectors registers are short ! */
424
		__u16 __user *svc = (void __user *) frame + frame_size - 2;
425
		if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, svc))
426
			return -EFAULT;
427
		restorer = (unsigned long __force) svc | PSW32_ADDR_AMODE;
L
Linus Torvalds 已提交
428 429 430
        }

	/* Set up registers for signal handler */
431
	regs->gprs[14] = restorer;
432
	regs->gprs[15] = (__force __u64) frame;
433 434
	/* Force 31 bit amode and default user address space control. */
	regs->psw.mask = PSW_MASK_BA |
435
		(PSW_USER_BITS & PSW_MASK_ASC) |
436
		(regs->psw.mask & ~PSW_MASK_ASC);
437
	regs->psw.addr = (__force __u64) ksig->ka.sa.sa_handler;
L
Linus Torvalds 已提交
438

439
	regs->gprs[2] = sig;
440
	regs->gprs[3] = (__force __u64) &frame->sc;
L
Linus Torvalds 已提交
441 442 443

	/* We forgot to include these in the sigcontext.
	   To avoid breaking binary compatibility, they are passed as args. */
M
Martin Schwidefsky 已提交
444 445 446 447 448
	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;
449
		regs->gprs[6] = task_thread_info(current)->last_break;
M
Martin Schwidefsky 已提交
450
	}
L
Linus Torvalds 已提交
451

452
	return 0;
L
Linus Torvalds 已提交
453 454
}

455 456
static int setup_rt_frame32(struct ksignal *ksig, sigset_t *set,
			    struct pt_regs *regs)
L
Linus Torvalds 已提交
457
{
458
	compat_sigset_t cset;
459 460 461 462 463 464 465 466 467 468 469 470 471 472
	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) {
473
		if (is_vx_task(current))
474 475 476 477 478
			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);
479
	if (frame == (void __user *) -1UL)
480
		return -EFAULT;
481

482 483
	/* Set up backchain. */
	if (__put_user(regs->gprs[15], (unsigned int __force __user *) frame))
484
		return -EFAULT;
L
Linus Torvalds 已提交
485 486 487

	/* Set up to return from userspace.  If provided, use a stub
	   already in userspace.  */
488
	if (ksig->ka.sa.sa_flags & SA_RESTORER) {
489 490
		restorer = (unsigned long __force)
			ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
L
Linus Torvalds 已提交
491
	} else {
492 493
		__u16 __user *svc = &frame->svc_insn;
		if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, svc))
494
			return -EFAULT;
495
		restorer = (unsigned long __force) svc | PSW32_ADDR_AMODE;
L
Linus Torvalds 已提交
496 497
	}

498 499 500 501 502 503 504 505
	/* 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. */
506
	sigset_to_sigset32(set->sig, cset.sig);
507 508 509 510
	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) ||
511
	    __copy_to_user(&frame->uc.uc_sigmask, &cset, sizeof(cset)) ||
512
	    save_sigregs_ext32(regs, &frame->uc.uc_mcontext_ext))
513
		return -EFAULT;
L
Linus Torvalds 已提交
514 515

	/* Set up registers for signal handler */
516
	regs->gprs[14] = restorer;
517
	regs->gprs[15] = (__force __u64) frame;
518 519
	/* Force 31 bit amode and default user address space control. */
	regs->psw.mask = PSW_MASK_BA |
520
		(PSW_USER_BITS & PSW_MASK_ASC) |
521
		(regs->psw.mask & ~PSW_MASK_ASC);
522
	regs->psw.addr = (__u64 __force) ksig->ka.sa.sa_handler;
L
Linus Torvalds 已提交
523

524
	regs->gprs[2] = ksig->sig;
525 526
	regs->gprs[3] = (__force __u64) &frame->info;
	regs->gprs[4] = (__force __u64) &frame->uc;
527
	regs->gprs[5] = task_thread_info(current)->last_break;
528
	return 0;
L
Linus Torvalds 已提交
529 530 531 532 533 534
}

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

535 536
void handle_signal32(struct ksignal *ksig, sigset_t *oldset,
		     struct pt_regs *regs)
L
Linus Torvalds 已提交
537
{
538 539
	int ret;

L
Linus Torvalds 已提交
540
	/* Set up the stack frame */
541 542
	if (ksig->ka.sa.sa_flags & SA_SIGINFO)
		ret = setup_rt_frame32(ksig, oldset, regs);
L
Linus Torvalds 已提交
543
	else
544 545 546
		ret = setup_frame32(ksig, oldset, regs);

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