signal_64.c 26.4 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*
 *  PowerPC version 
 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
 *
 *  Derived from "arch/i386/kernel/signal.c"
 *    Copyright (C) 1991, 1992 Linus Torvalds
 *    1997-11-28  Modified for POSIX.1b signals by Richard Henderson
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version
 *  2 of the License, or (at your option) any later version.
 */

#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/unistd.h>
#include <linux/stddef.h>
#include <linux/elf.h>
#include <linux/ptrace.h>
26
#include <linux/ratelimit.h>
Linus Torvalds's avatar
Linus Torvalds committed
27 28 29

#include <asm/sigcontext.h>
#include <asm/ucontext.h>
30
#include <linux/uaccess.h>
Linus Torvalds's avatar
Linus Torvalds committed
31 32 33
#include <asm/pgtable.h>
#include <asm/unistd.h>
#include <asm/cacheflush.h>
34
#include <asm/syscalls.h>
Linus Torvalds's avatar
Linus Torvalds committed
35
#include <asm/vdso.h>
36
#include <asm/switch_to.h>
37
#include <asm/tm.h>
38
#include <asm/asm-prototypes.h>
Linus Torvalds's avatar
Linus Torvalds committed
39

40
#include "signal.h"
Linus Torvalds's avatar
Linus Torvalds committed
41 42


43
#define GP_REGS_SIZE	min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
Linus Torvalds's avatar
Linus Torvalds committed
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
#define FP_REGS_SIZE	sizeof(elf_fpregset_t)

#define TRAMP_TRACEBACK	3
#define TRAMP_SIZE	6

/*
 * When we have signals to deliver, we set up on the user stack,
 * going down from the original stack pointer:
 *	1) a rt_sigframe struct which contains the ucontext	
 *	2) a gap of __SIGNAL_FRAMESIZE bytes which acts as a dummy caller
 *	   frame for the signal handler.
 */

struct rt_sigframe {
	/* sys_rt_sigreturn requires the ucontext be the first field */
	struct ucontext uc;
60 61 62
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
	struct ucontext uc_transact;
#endif
Linus Torvalds's avatar
Linus Torvalds committed
63 64
	unsigned long _unused[2];
	unsigned int tramp[TRAMP_SIZE];
65 66
	struct siginfo __user *pinfo;
	void __user *puc;
Linus Torvalds's avatar
Linus Torvalds committed
67
	struct siginfo info;
68 69
	/* New 64 bit little-endian ABI allows redzone of 512 bytes below sp */
	char abigap[USER_REDZONE_SIZE];
Linus Torvalds's avatar
Linus Torvalds committed
70 71
} __attribute__ ((aligned (16)));

72 73 74 75 76
static const char fmt32[] = KERN_INFO \
	"%s[%d]: bad frame in %s: %08lx nip %08lx lr %08lx\n";
static const char fmt64[] = KERN_INFO \
	"%s[%d]: bad frame in %s: %016lx nip %016lx lr %016lx\n";

77 78 79 80 81 82 83 84 85 86 87 88 89
/*
 * This computes a quad word aligned pointer inside the vmx_reserve array
 * element. For historical reasons sigcontext might not be quad word aligned,
 * but the location we write the VMX regs to must be. See the comment in
 * sigcontext for more detail.
 */
#ifdef CONFIG_ALTIVEC
static elf_vrreg_t __user *sigcontext_vmx_regs(struct sigcontext __user *sc)
{
	return (elf_vrreg_t __user *) (((unsigned long)sc->vmx_reserve + 15) & ~0xful);
}
#endif

Linus Torvalds's avatar
Linus Torvalds committed
90 91 92 93
/*
 * Set up the sigcontext for the signal frame.
 */

94 95 96
static long setup_sigcontext(struct sigcontext __user *sc,
		struct task_struct *tsk, int signr, sigset_t *set,
		unsigned long handler, int ctx_has_vsx_region)
Linus Torvalds's avatar
Linus Torvalds committed
97 98 99 100 101 102
{
	/* When CONFIG_ALTIVEC is set, we _always_ setup v_regs even if the
	 * process never used altivec yet (MSR_VEC is zero in pt_regs of
	 * the context). This is very important because we must ensure we
	 * don't lose the VRSAVE content that may have been set prior to
	 * the process doing its first vector operation
103
	 * Userland shall check AT_HWCAP to know whether it can rely on the
Linus Torvalds's avatar
Linus Torvalds committed
104 105 106
	 * v_regs pointer or not
	 */
#ifdef CONFIG_ALTIVEC
107
	elf_vrreg_t __user *v_regs = sigcontext_vmx_regs(sc);
108
	unsigned long vrsave;
Linus Torvalds's avatar
Linus Torvalds committed
109
#endif
110
	struct pt_regs *regs = tsk->thread.regs;
111
	unsigned long msr = regs->msr;
Linus Torvalds's avatar
Linus Torvalds committed
112 113
	long err = 0;

114 115
	BUG_ON(tsk != current);

Linus Torvalds's avatar
Linus Torvalds committed
116 117 118 119
#ifdef CONFIG_ALTIVEC
	err |= __put_user(v_regs, &sc->v_regs);

	/* save altivec registers */
120 121
	if (tsk->thread.used_vr) {
		flush_altivec_to_thread(tsk);
Linus Torvalds's avatar
Linus Torvalds committed
122
		/* Copy 33 vec registers (vr0..31 and vscr) to the stack */
123
		err |= __copy_to_user(v_regs, &tsk->thread.vr_state,
124
				      33 * sizeof(vector128));
Linus Torvalds's avatar
Linus Torvalds committed
125 126 127
		/* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg)
		 * contains valid data.
		 */
128
		msr |= MSR_VEC;
Linus Torvalds's avatar
Linus Torvalds committed
129 130 131 132
	}
	/* We always copy to/from vrsave, it's 0 if we don't have or don't
	 * use altivec.
	 */
133 134 135
	vrsave = 0;
	if (cpu_has_feature(CPU_FTR_ALTIVEC)) {
		vrsave = mfspr(SPRN_VRSAVE);
136
		tsk->thread.vrsave = vrsave;
137 138 139
	}

	err |= __put_user(vrsave, (u32 __user *)&v_regs[33]);
Linus Torvalds's avatar
Linus Torvalds committed
140 141 142
#else /* CONFIG_ALTIVEC */
	err |= __put_user(0, &sc->v_regs);
#endif /* CONFIG_ALTIVEC */
143
	flush_fp_to_thread(tsk);
144
	/* copy fpr regs and fpscr */
145
	err |= copy_fpr_to_user(&sc->fp_regs, tsk);
146 147 148 149 150 151

	/*
	 * Clear the MSR VSX bit to indicate there is no valid state attached
	 * to this context, except in the specific case below where we set it.
	 */
	msr &= ~MSR_VSX;
152
#ifdef CONFIG_VSX
153 154 155 156 157
	/*
	 * Copy VSX low doubleword to local buffer for formatting,
	 * then out to userspace.  Update v_regs to point after the
	 * VMX data.
	 */
158 159
	if (tsk->thread.used_vsr && ctx_has_vsx_region) {
		flush_vsx_to_thread(tsk);
160
		v_regs += ELF_NVRREG;
161
		err |= copy_vsx_to_user(v_regs, tsk);
162 163 164 165 166
		/* set MSR_VSX in the MSR value in the frame to
		 * indicate that sc->vs_reg) contains valid data.
		 */
		msr |= MSR_VSX;
	}
167
#endif /* CONFIG_VSX */
Linus Torvalds's avatar
Linus Torvalds committed
168
	err |= __put_user(&sc->gp_regs, &sc->regs);
169
	WARN_ON(!FULL_REGS(regs));
Linus Torvalds's avatar
Linus Torvalds committed
170
	err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE);
171
	err |= __put_user(msr, &sc->gp_regs[PT_MSR]);
Linus Torvalds's avatar
Linus Torvalds committed
172 173 174 175 176 177 178 179
	err |= __put_user(signr, &sc->signal);
	err |= __put_user(handler, &sc->handler);
	if (set != NULL)
		err |=  __put_user(set->sig[0], &sc->oldmask);

	return err;
}

180 181 182 183 184
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
/*
 * As above, but Transactional Memory is in use, so deliver sigcontexts
 * containing checkpointed and transactional register states.
 *
185 186 187 188 189 190
 * To do this, we treclaim (done before entering here) to gather both sets of
 * registers and set up the 'normal' sigcontext registers with rolled-back
 * register values such that a simple signal handler sees a correct
 * checkpointed register state.  If interested, a TM-aware sighandler can
 * examine the transactional registers in the 2nd sigcontext to determine the
 * real origin of the signal.
191 192 193
 */
static long setup_tm_sigcontexts(struct sigcontext __user *sc,
				 struct sigcontext __user *tm_sc,
194
				 struct task_struct *tsk,
195 196 197 198 199 200 201 202 203 204 205
				 int signr, sigset_t *set, unsigned long handler)
{
	/* When CONFIG_ALTIVEC is set, we _always_ setup v_regs even if the
	 * process never used altivec yet (MSR_VEC is zero in pt_regs of
	 * the context). This is very important because we must ensure we
	 * don't lose the VRSAVE content that may have been set prior to
	 * the process doing its first vector operation
	 * Userland shall check AT_HWCAP to know wether it can rely on the
	 * v_regs pointer or not.
	 */
#ifdef CONFIG_ALTIVEC
206 207
	elf_vrreg_t __user *v_regs = sigcontext_vmx_regs(sc);
	elf_vrreg_t __user *tm_v_regs = sigcontext_vmx_regs(tm_sc);
208
#endif
209 210
	struct pt_regs *regs = tsk->thread.regs;
	unsigned long msr = tsk->thread.ckpt_regs.msr;
211 212
	long err = 0;

213 214
	BUG_ON(tsk != current);

215 216
	BUG_ON(!MSR_TM_ACTIVE(regs->msr));

217 218 219 220 221 222 223
	/* Remove TM bits from thread's MSR.  The MSR in the sigcontext
	 * just indicates to userland that we were doing a transaction, but we
	 * don't want to return in transactional state.  This also ensures
	 * that flush_fp_to_thread won't set TIF_RESTORE_TM again.
	 */
	regs->msr &= ~MSR_TS_MASK;

224 225 226 227 228
#ifdef CONFIG_ALTIVEC
	err |= __put_user(v_regs, &sc->v_regs);
	err |= __put_user(tm_v_regs, &tm_sc->v_regs);

	/* save altivec registers */
229
	if (tsk->thread.used_vr) {
230
		/* Copy 33 vec registers (vr0..31 and vscr) to the stack */
231
		err |= __copy_to_user(v_regs, &tsk->thread.ckvr_state,
232 233 234 235 236 237
				      33 * sizeof(vector128));
		/* If VEC was enabled there are transactional VRs valid too,
		 * else they're a copy of the checkpointed VRs.
		 */
		if (msr & MSR_VEC)
			err |= __copy_to_user(tm_v_regs,
238
					      &tsk->thread.vr_state,
239 240 241
					      33 * sizeof(vector128));
		else
			err |= __copy_to_user(tm_v_regs,
242
					      &tsk->thread.ckvr_state,
243 244 245 246 247 248 249 250 251 252
					      33 * sizeof(vector128));

		/* set MSR_VEC in the MSR value in the frame to indicate
		 * that sc->v_reg contains valid data.
		 */
		msr |= MSR_VEC;
	}
	/* We always copy to/from vrsave, it's 0 if we don't have or don't
	 * use altivec.
	 */
Paul Mackerras's avatar
Paul Mackerras committed
253
	if (cpu_has_feature(CPU_FTR_ALTIVEC))
254 255
		tsk->thread.ckvrsave = mfspr(SPRN_VRSAVE);
	err |= __put_user(tsk->thread.ckvrsave, (u32 __user *)&v_regs[33]);
256
	if (msr & MSR_VEC)
257
		err |= __put_user(tsk->thread.vrsave,
258 259
				  (u32 __user *)&tm_v_regs[33]);
	else
260
		err |= __put_user(tsk->thread.ckvrsave,
261 262 263 264 265 266 267 268
				  (u32 __user *)&tm_v_regs[33]);

#else /* CONFIG_ALTIVEC */
	err |= __put_user(0, &sc->v_regs);
	err |= __put_user(0, &tm_sc->v_regs);
#endif /* CONFIG_ALTIVEC */

	/* copy fpr regs and fpscr */
269
	err |= copy_ckfpr_to_user(&sc->fp_regs, tsk);
270
	if (msr & MSR_FP)
271
		err |= copy_fpr_to_user(&tm_sc->fp_regs, tsk);
272
	else
273
		err |= copy_ckfpr_to_user(&tm_sc->fp_regs, tsk);
274 275 276 277 278 279 280

#ifdef CONFIG_VSX
	/*
	 * Copy VSX low doubleword to local buffer for formatting,
	 * then out to userspace.  Update v_regs to point after the
	 * VMX data.
	 */
281
	if (tsk->thread.used_vsr) {
282 283 284
		v_regs += ELF_NVRREG;
		tm_v_regs += ELF_NVRREG;

285
		err |= copy_ckvsx_to_user(v_regs, tsk);
286 287

		if (msr & MSR_VSX)
288
			err |= copy_vsx_to_user(tm_v_regs, tsk);
289
		else
290
			err |= copy_ckvsx_to_user(tm_v_regs, tsk);
291 292 293 294 295 296 297 298 299 300 301 302 303

		/* set MSR_VSX in the MSR value in the frame to
		 * indicate that sc->vs_reg) contains valid data.
		 */
		msr |= MSR_VSX;
	}
#endif /* CONFIG_VSX */

	err |= __put_user(&sc->gp_regs, &sc->regs);
	err |= __put_user(&tm_sc->gp_regs, &tm_sc->regs);
	WARN_ON(!FULL_REGS(regs));
	err |= __copy_to_user(&tm_sc->gp_regs, regs, GP_REGS_SIZE);
	err |= __copy_to_user(&sc->gp_regs,
304
			      &tsk->thread.ckpt_regs, GP_REGS_SIZE);
305 306 307 308 309 310 311 312 313 314 315
	err |= __put_user(msr, &tm_sc->gp_regs[PT_MSR]);
	err |= __put_user(msr, &sc->gp_regs[PT_MSR]);
	err |= __put_user(signr, &sc->signal);
	err |= __put_user(handler, &sc->handler);
	if (set != NULL)
		err |=  __put_user(set->sig[0], &sc->oldmask);

	return err;
}
#endif

Linus Torvalds's avatar
Linus Torvalds committed
316 317 318 319
/*
 * Restore the sigcontext from the signal frame.
 */

320
static long restore_sigcontext(struct task_struct *tsk, sigset_t *set, int sig,
Linus Torvalds's avatar
Linus Torvalds committed
321 322 323 324 325 326 327 328
			      struct sigcontext __user *sc)
{
#ifdef CONFIG_ALTIVEC
	elf_vrreg_t __user *v_regs;
#endif
	unsigned long err = 0;
	unsigned long save_r13 = 0;
	unsigned long msr;
329
	struct pt_regs *regs = tsk->thread.regs;
330 331 332
#ifdef CONFIG_VSX
	int i;
#endif
Linus Torvalds's avatar
Linus Torvalds committed
333

334 335
	BUG_ON(tsk != current);

Linus Torvalds's avatar
Linus Torvalds committed
336 337 338 339
	/* If this is not a signal return, we preserve the TLS in r13 */
	if (!sig)
		save_r13 = regs->gpr[13];

340 341 342
	/* copy the GPRs */
	err |= __copy_from_user(regs->gpr, sc->gp_regs, sizeof(regs->gpr));
	err |= __get_user(regs->nip, &sc->gp_regs[PT_NIP]);
343 344 345 346
	/* get MSR separately, transfer the LE bit if doing signal return */
	err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
	if (sig)
		regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
347 348 349 350 351
	err |= __get_user(regs->orig_gpr3, &sc->gp_regs[PT_ORIG_R3]);
	err |= __get_user(regs->ctr, &sc->gp_regs[PT_CTR]);
	err |= __get_user(regs->link, &sc->gp_regs[PT_LNK]);
	err |= __get_user(regs->xer, &sc->gp_regs[PT_XER]);
	err |= __get_user(regs->ccr, &sc->gp_regs[PT_CCR]);
352
	/* skip SOFTE */
Al Viro's avatar
Al Viro committed
353
	regs->trap = 0;
354 355 356
	err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]);
	err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]);
	err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]);
Linus Torvalds's avatar
Linus Torvalds committed
357 358 359 360 361 362

	if (!sig)
		regs->gpr[13] = save_r13;
	if (set != NULL)
		err |=  __get_user(set->sig[0], &sc->oldmask);

363 364
	/*
	 * Force reload of FP/VEC.
365
	 * This has to be done before copying stuff into tsk->thread.fpr/vr
366 367
	 * for the reasons explained in the previous comment.
	 */
368
	regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1 | MSR_VEC | MSR_VSX);
369

Linus Torvalds's avatar
Linus Torvalds committed
370 371 372 373
#ifdef CONFIG_ALTIVEC
	err |= __get_user(v_regs, &sc->v_regs);
	if (err)
		return err;
374 375
	if (v_regs && !access_ok(VERIFY_READ, v_regs, 34 * sizeof(vector128)))
		return -EFAULT;
Linus Torvalds's avatar
Linus Torvalds committed
376
	/* Copy 33 vec registers (vr0..31 and vscr) from the stack */
377
	if (v_regs != NULL && (msr & MSR_VEC) != 0) {
378
		err |= __copy_from_user(&tsk->thread.vr_state, v_regs,
Linus Torvalds's avatar
Linus Torvalds committed
379
					33 * sizeof(vector128));
380 381 382
		tsk->thread.used_vr = true;
	} else if (tsk->thread.used_vr) {
		memset(&tsk->thread.vr_state, 0, 33 * sizeof(vector128));
383
	}
Linus Torvalds's avatar
Linus Torvalds committed
384
	/* Always get VRSAVE back */
385
	if (v_regs != NULL)
386
		err |= __get_user(tsk->thread.vrsave, (u32 __user *)&v_regs[33]);
Linus Torvalds's avatar
Linus Torvalds committed
387
	else
388
		tsk->thread.vrsave = 0;
Paul Mackerras's avatar
Paul Mackerras committed
389
	if (cpu_has_feature(CPU_FTR_ALTIVEC))
390
		mtspr(SPRN_VRSAVE, tsk->thread.vrsave);
Linus Torvalds's avatar
Linus Torvalds committed
391
#endif /* CONFIG_ALTIVEC */
392
	/* restore floating point */
393
	err |= copy_fpr_from_user(tsk, &sc->fp_regs);
394
#ifdef CONFIG_VSX
395 396 397 398 399 400
	/*
	 * Get additional VSX data. Update v_regs to point after the
	 * VMX data.  Copy VSX low doubleword from userspace to local
	 * buffer for formatting, then into the taskstruct.
	 */
	v_regs += ELF_NVRREG;
401
	if ((msr & MSR_VSX) != 0) {
402 403 404
		err |= copy_vsx_from_user(tsk, v_regs);
		tsk->thread.used_vsr = true;
	} else {
405
		for (i = 0; i < 32 ; i++)
406 407
			tsk->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
	}
408
#endif
Linus Torvalds's avatar
Linus Torvalds committed
409 410 411
	return err;
}

412 413 414 415 416
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
/*
 * Restore the two sigcontexts from the frame of a transactional processes.
 */

417
static long restore_tm_sigcontexts(struct task_struct *tsk,
418 419 420 421 422 423 424 425
				   struct sigcontext __user *sc,
				   struct sigcontext __user *tm_sc)
{
#ifdef CONFIG_ALTIVEC
	elf_vrreg_t __user *v_regs, *tm_v_regs;
#endif
	unsigned long err = 0;
	unsigned long msr;
426
	struct pt_regs *regs = tsk->thread.regs;
427 428 429
#ifdef CONFIG_VSX
	int i;
#endif
430 431 432

	BUG_ON(tsk != current);

433 434
	/* copy the GPRs */
	err |= __copy_from_user(regs->gpr, tm_sc->gp_regs, sizeof(regs->gpr));
435
	err |= __copy_from_user(&tsk->thread.ckpt_regs, sc->gp_regs,
436 437 438 439 440 441 442 443 444 445 446
				sizeof(regs->gpr));

	/*
	 * TFHAR is restored from the checkpointed 'wound-back' ucontext's NIP.
	 * TEXASR was set by the signal delivery reclaim, as was TFIAR.
	 * Users doing anything abhorrent like thread-switching w/ signals for
	 * TM-Suspended code will have to back TEXASR/TFIAR up themselves.
	 * For the case of getting a signal and simply returning from it,
	 * we don't need to re-copy them here.
	 */
	err |= __get_user(regs->nip, &tm_sc->gp_regs[PT_NIP]);
447
	err |= __get_user(tsk->thread.tm_tfhar, &sc->gp_regs[PT_NIP]);
448 449 450

	/* get MSR separately, transfer the LE bit if doing signal return */
	err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
451 452 453 454
	/* Don't allow reserved mode. */
	if (MSR_TM_RESV(msr))
		return -EINVAL;

455
	/* pull in MSR TS bits from user context */
456 457
	regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK);

458 459 460 461 462 463 464 465 466 467 468
	/*
	 * Ensure that TM is enabled in regs->msr before we leave the signal
	 * handler. It could be the case that (a) user disabled the TM bit
	 * through the manipulation of the MSR bits in uc_mcontext or (b) the
	 * TM bit was disabled because a sufficient number of context switches
	 * happened whilst in the signal handler and load_tm overflowed,
	 * disabling the TM bit. In either case we can end up with an illegal
	 * TM state leading to a TM Bad Thing when we return to userspace.
	 */
	regs->msr |= MSR_TM;

469
	/* pull in MSR LE from user context */
470 471 472 473 474 475 476
	regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);

	/* The following non-GPR non-FPR non-VR state is also checkpointed: */
	err |= __get_user(regs->ctr, &tm_sc->gp_regs[PT_CTR]);
	err |= __get_user(regs->link, &tm_sc->gp_regs[PT_LNK]);
	err |= __get_user(regs->xer, &tm_sc->gp_regs[PT_XER]);
	err |= __get_user(regs->ccr, &tm_sc->gp_regs[PT_CCR]);
477
	err |= __get_user(tsk->thread.ckpt_regs.ctr,
478
			  &sc->gp_regs[PT_CTR]);
479
	err |= __get_user(tsk->thread.ckpt_regs.link,
480
			  &sc->gp_regs[PT_LNK]);
481
	err |= __get_user(tsk->thread.ckpt_regs.xer,
482
			  &sc->gp_regs[PT_XER]);
483
	err |= __get_user(tsk->thread.ckpt_regs.ccr,
484 485 486 487 488 489 490 491 492 493
			  &sc->gp_regs[PT_CCR]);

	/* These regs are not checkpointed; they can go in 'regs'. */
	err |= __get_user(regs->trap, &sc->gp_regs[PT_TRAP]);
	err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]);
	err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]);
	err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]);

	/*
	 * Force reload of FP/VEC.
494
	 * This has to be done before copying stuff into tsk->thread.fpr/vr
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
	 * for the reasons explained in the previous comment.
	 */
	regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1 | MSR_VEC | MSR_VSX);

#ifdef CONFIG_ALTIVEC
	err |= __get_user(v_regs, &sc->v_regs);
	err |= __get_user(tm_v_regs, &tm_sc->v_regs);
	if (err)
		return err;
	if (v_regs && !access_ok(VERIFY_READ, v_regs, 34 * sizeof(vector128)))
		return -EFAULT;
	if (tm_v_regs && !access_ok(VERIFY_READ,
				    tm_v_regs, 34 * sizeof(vector128)))
		return -EFAULT;
	/* Copy 33 vec registers (vr0..31 and vscr) from the stack */
510
	if (v_regs != NULL && tm_v_regs != NULL && (msr & MSR_VEC) != 0) {
511
		err |= __copy_from_user(&tsk->thread.ckvr_state, v_regs,
512
					33 * sizeof(vector128));
513
		err |= __copy_from_user(&tsk->thread.vr_state, tm_v_regs,
514
					33 * sizeof(vector128));
515
		current->thread.used_vr = true;
516
	}
517 518
	else if (tsk->thread.used_vr) {
		memset(&tsk->thread.vr_state, 0, 33 * sizeof(vector128));
519
		memset(&tsk->thread.ckvr_state, 0, 33 * sizeof(vector128));
520 521
	}
	/* Always get VRSAVE back */
522
	if (v_regs != NULL && tm_v_regs != NULL) {
523
		err |= __get_user(tsk->thread.ckvrsave,
524 525
				  (u32 __user *)&v_regs[33]);
		err |= __get_user(tsk->thread.vrsave,
526 527 528
				  (u32 __user *)&tm_v_regs[33]);
	}
	else {
529
		tsk->thread.vrsave = 0;
530
		tsk->thread.ckvrsave = 0;
531
	}
Paul Mackerras's avatar
Paul Mackerras committed
532
	if (cpu_has_feature(CPU_FTR_ALTIVEC))
533
		mtspr(SPRN_VRSAVE, tsk->thread.vrsave);
534 535
#endif /* CONFIG_ALTIVEC */
	/* restore floating point */
536
	err |= copy_fpr_from_user(tsk, &tm_sc->fp_regs);
537
	err |= copy_ckfpr_from_user(tsk, &sc->fp_regs);
538 539 540 541 542 543 544 545 546
#ifdef CONFIG_VSX
	/*
	 * Get additional VSX data. Update v_regs to point after the
	 * VMX data.  Copy VSX low doubleword from userspace to local
	 * buffer for formatting, then into the taskstruct.
	 */
	if (v_regs && ((msr & MSR_VSX) != 0)) {
		v_regs += ELF_NVRREG;
		tm_v_regs += ELF_NVRREG;
547
		err |= copy_vsx_from_user(tsk, tm_v_regs);
548
		err |= copy_ckvsx_from_user(tsk, v_regs);
549
		tsk->thread.used_vsr = true;
550 551
	} else {
		for (i = 0; i < 32 ; i++) {
552
			tsk->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
553
			tsk->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
554 555 556 557
		}
	}
#endif
	tm_enable();
558
	/* Make sure the transaction is marked as failed */
559
	tsk->thread.tm_texasr |= TEXASR_FS;
560
	/* This loads the checkpointed FP/VEC state, if used */
561
	tm_recheckpoint(&tsk->thread, msr);
562

563
	msr_check_and_set(msr & (MSR_FP | MSR_VEC));
564
	if (msr & MSR_FP) {
565
		load_fp_state(&tsk->thread.fp_state);
566
		regs->msr |= (MSR_FP | tsk->thread.fpexc_mode);
567 568
	}
	if (msr & MSR_VEC) {
569
		load_vr_state(&tsk->thread.vr_state);
570 571 572 573 574 575 576
		regs->msr |= MSR_VEC;
	}

	return err;
}
#endif

Linus Torvalds's avatar
Linus Torvalds committed
577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602
/*
 * Setup the trampoline code on the stack
 */
static long setup_trampoline(unsigned int syscall, unsigned int __user *tramp)
{
	int i;
	long err = 0;

	/* addi r1, r1, __SIGNAL_FRAMESIZE  # Pop the dummy stackframe */
	err |= __put_user(0x38210000UL | (__SIGNAL_FRAMESIZE & 0xffff), &tramp[0]);
	/* li r0, __NR_[rt_]sigreturn| */
	err |= __put_user(0x38000000UL | (syscall & 0xffff), &tramp[1]);
	/* sc */
	err |= __put_user(0x44000002UL, &tramp[2]);

	/* Minimal traceback info */
	for (i=TRAMP_TRACEBACK; i < TRAMP_SIZE ;i++)
		err |= __put_user(0, &tramp[i]);

	if (!err)
		flush_icache_range((unsigned long) &tramp[0],
			   (unsigned long) &tramp[TRAMP_SIZE]);

	return err;
}

603 604 605 606 607 608 609
/*
 * Userspace code may pass a ucontext which doesn't include VSX added
 * at the end.  We need to check for this case.
 */
#define UCONTEXTSIZEWITHOUTVSX \
		(sizeof(struct ucontext) - 32*sizeof(long))

Linus Torvalds's avatar
Linus Torvalds committed
610 611 612 613 614 615 616 617 618
/*
 * Handle {get,set,swap}_context operations
 */
int sys_swapcontext(struct ucontext __user *old_ctx,
		    struct ucontext __user *new_ctx,
		    long ctx_size, long r6, long r7, long r8, struct pt_regs *regs)
{
	unsigned char tmp;
	sigset_t set;
619
	unsigned long new_msr = 0;
620
	int ctx_has_vsx_region = 0;
Linus Torvalds's avatar
Linus Torvalds committed
621

622 623
	BUG_ON(regs != current->thread.regs);

624
	if (new_ctx &&
625
	    get_user(new_msr, &new_ctx->uc_mcontext.gp_regs[PT_MSR]))
626 627 628 629
		return -EFAULT;
	/*
	 * Check that the context is not smaller than the original
	 * size (with VMX but without VSX)
Linus Torvalds's avatar
Linus Torvalds committed
630
	 */
631
	if (ctx_size < UCONTEXTSIZEWITHOUTVSX)
Linus Torvalds's avatar
Linus Torvalds committed
632
		return -EINVAL;
633 634 635 636 637 638 639
	/*
	 * If the new context state sets the MSR VSX bits but
	 * it doesn't provide VSX state.
	 */
	if ((ctx_size < sizeof(struct ucontext)) &&
	    (new_msr & MSR_VSX))
		return -EINVAL;
640 641 642 643
	/* Does the context have enough room to store VSX data? */
	if (ctx_size >= sizeof(struct ucontext))
		ctx_has_vsx_region = 1;

Linus Torvalds's avatar
Linus Torvalds committed
644
	if (old_ctx != NULL) {
645
		if (!access_ok(VERIFY_WRITE, old_ctx, ctx_size)
646
		    || setup_sigcontext(&old_ctx->uc_mcontext, current, 0, NULL, 0,
647
					ctx_has_vsx_region)
Linus Torvalds's avatar
Linus Torvalds committed
648 649 650 651 652 653
		    || __copy_to_user(&old_ctx->uc_sigmask,
				      &current->blocked, sizeof(sigset_t)))
			return -EFAULT;
	}
	if (new_ctx == NULL)
		return 0;
654
	if (!access_ok(VERIFY_READ, new_ctx, ctx_size)
Linus Torvalds's avatar
Linus Torvalds committed
655
	    || __get_user(tmp, (u8 __user *) new_ctx)
656
	    || __get_user(tmp, (u8 __user *) new_ctx + ctx_size - 1))
Linus Torvalds's avatar
Linus Torvalds committed
657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672
		return -EFAULT;

	/*
	 * If we get a fault copying the context into the kernel's
	 * image of the user's registers, we can't just return -EFAULT
	 * because the user's registers will be corrupted.  For instance
	 * the NIP value may have been updated but not some of the
	 * other registers.  Given that we have done the access_ok
	 * and successfully read the first and last bytes of the region
	 * above, this should only happen in an out-of-memory situation
	 * or if another thread unmaps the region containing the context.
	 * We kill the task with a SIGSEGV in this situation.
	 */

	if (__copy_from_user(&set, &new_ctx->uc_sigmask, sizeof(set)))
		do_exit(SIGSEGV);
673
	set_current_blocked(&set);
674
	if (restore_sigcontext(current, NULL, 0, &new_ctx->uc_mcontext))
Linus Torvalds's avatar
Linus Torvalds committed
675 676 677
		do_exit(SIGSEGV);

	/* This returns like rt_sigreturn */
678
	set_thread_flag(TIF_RESTOREALL);
Linus Torvalds's avatar
Linus Torvalds committed
679 680 681 682 683 684 685 686 687 688 689 690 691 692
	return 0;
}


/*
 * Do a signal return; undo the signal stack.
 */

int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
		     unsigned long r6, unsigned long r7, unsigned long r8,
		     struct pt_regs *regs)
{
	struct ucontext __user *uc = (struct ucontext __user *)regs->gpr[1];
	sigset_t set;
693 694 695
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
	unsigned long msr;
#endif
Linus Torvalds's avatar
Linus Torvalds committed
696

697 698
	BUG_ON(current->thread.regs != regs);

Linus Torvalds's avatar
Linus Torvalds committed
699
	/* Always make any pending restarted system calls return -EINTR */
700
	current->restart_block.fn = do_no_restart_syscall;
Linus Torvalds's avatar
Linus Torvalds committed
701 702 703 704 705 706

	if (!access_ok(VERIFY_READ, uc, sizeof(*uc)))
		goto badframe;

	if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
		goto badframe;
707
	set_current_blocked(&set);
708

709
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
710 711 712 713 714 715 716 717 718 719 720 721 722
	/*
	 * If there is a transactional state then throw it away.
	 * The purpose of a sigreturn is to destroy all traces of the
	 * signal frame, this includes any transactional state created
	 * within in. We only check for suspended as we can never be
	 * active in the kernel, we are active, there is nothing better to
	 * do than go ahead and Bad Thing later.
	 * The cause is not important as there will never be a
	 * recheckpoint so it's not user visible.
	 */
	if (MSR_TM_SUSPENDED(mfmsr()))
		tm_reclaim_current(0);

723 724
	if (__get_user(msr, &uc->uc_mcontext.gp_regs[PT_MSR]))
		goto badframe;
725
	if (MSR_TM_ACTIVE(msr)) {
726 727 728 729
		/* We recheckpoint on return. */
		struct ucontext __user *uc_transact;
		if (__get_user(uc_transact, &uc->uc_link))
			goto badframe;
730
		if (restore_tm_sigcontexts(current, &uc->uc_mcontext,
731 732 733 734 735 736
					   &uc_transact->uc_mcontext))
			goto badframe;
	}
	else
	/* Fall through, for non-TM restore */
#endif
737
	if (restore_sigcontext(current, NULL, 1, &uc->uc_mcontext))
Linus Torvalds's avatar
Linus Torvalds committed
738 739
		goto badframe;

740 741
	if (restore_altstack(&uc->uc_stack))
		goto badframe;
Linus Torvalds's avatar
Linus Torvalds committed
742

743 744
	set_thread_flag(TIF_RESTOREALL);
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
745 746

badframe:
747 748 749 750
	if (show_unhandled_signals)
		printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
				   current->comm, current->pid, "rt_sigreturn",
				   (long)uc, regs->nip, regs->link);
751

Linus Torvalds's avatar
Linus Torvalds committed
752 753 754 755
	force_sig(SIGSEGV, current);
	return 0;
}

756 757
int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
		struct task_struct *tsk)
Linus Torvalds's avatar
Linus Torvalds committed
758 759 760 761
{
	struct rt_sigframe __user *frame;
	unsigned long newsp = 0;
	long err = 0;
762 763 764
	struct pt_regs *regs = tsk->thread.regs;

	BUG_ON(tsk != current);
Linus Torvalds's avatar
Linus Torvalds committed
765

766
	frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 0);
767
	if (unlikely(frame == NULL))
Linus Torvalds's avatar
Linus Torvalds committed
768 769 770 771
		goto badframe;

	err |= __put_user(&frame->info, &frame->pinfo);
	err |= __put_user(&frame->uc, &frame->puc);
772
	err |= copy_siginfo_to_user(&frame->info, &ksig->info);
Linus Torvalds's avatar
Linus Torvalds committed
773 774 775 776 777
	if (err)
		goto badframe;

	/* Create the ucontext.  */
	err |= __put_user(0, &frame->uc.uc_flags);
778
	err |= __save_altstack(&frame->uc.uc_stack, regs->gpr[1]);
779 780 781 782 783 784 785 786
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
	if (MSR_TM_ACTIVE(regs->msr)) {
		/* The ucontext_t passed to userland points to the second
		 * ucontext_t (for transactional state) with its uc_link ptr.
		 */
		err |= __put_user(&frame->uc_transact, &frame->uc.uc_link);
		err |= setup_tm_sigcontexts(&frame->uc.uc_mcontext,
					    &frame->uc_transact.uc_mcontext,
787
					    tsk, ksig->sig, NULL,
788
					    (unsigned long)ksig->ka.sa.sa_handler);
789 790 791 792
	} else
#endif
	{
		err |= __put_user(0, &frame->uc.uc_link);
793
		err |= setup_sigcontext(&frame->uc.uc_mcontext, tsk, ksig->sig,
794
					NULL, (unsigned long)ksig->ka.sa.sa_handler,
795 796
					1);
	}
Linus Torvalds's avatar
Linus Torvalds committed
797 798 799 800
	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
	if (err)
		goto badframe;

801
	/* Make sure signal handler doesn't get spurious FP exceptions */
802
	tsk->thread.fp_state.fpscr = 0;
803

Linus Torvalds's avatar
Linus Torvalds committed
804
	/* Set up to return from userspace. */
805 806
	if (vdso64_rt_sigtramp && tsk->mm->context.vdso_base) {
		regs->link = tsk->mm->context.vdso_base + vdso64_rt_sigtramp;
Linus Torvalds's avatar
Linus Torvalds committed
807 808 809 810 811 812 813 814
	} else {
		err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
		if (err)
			goto badframe;
		regs->link = (unsigned long) &frame->tramp[0];
	}

	/* Allocate a dummy caller frame for the signal handler. */
815
	newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
Linus Torvalds's avatar
Linus Torvalds committed
816 817 818
	err |= put_user(regs->gpr[1], (unsigned long __user *)newsp);

	/* Set up "regs" so we "return" to the signal handler. */
819
	if (is_elf2_task()) {
820
		regs->nip = (unsigned long) ksig->ka.sa.sa_handler;
821 822 823 824 825 826 827 828
		regs->gpr[12] = regs->nip;
	} else {
		/* Handler is *really* a pointer to the function descriptor for
		 * the signal routine.  The first entry in the function
		 * descriptor is the entry address of signal and the second
		 * entry is the TOC value we need to use.
		 */
		func_descr_t __user *funct_desc_ptr =
829
			(func_descr_t __user *) ksig->ka.sa.sa_handler;
830 831 832 833 834

		err |= get_user(regs->nip, &funct_desc_ptr->entry);
		err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
	}

835
	/* enter the signal handler in native-endian mode */
836
	regs->msr &= ~MSR_LE;
837
	regs->msr |= (MSR_KERNEL & MSR_LE);
Linus Torvalds's avatar
Linus Torvalds committed
838
	regs->gpr[1] = newsp;
839
	regs->gpr[3] = ksig->sig;
Linus Torvalds's avatar
Linus Torvalds committed
840
	regs->result = 0;
841
	if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
Linus Torvalds's avatar
Linus Torvalds committed
842 843 844 845 846 847 848 849 850
		err |= get_user(regs->gpr[4], (unsigned long __user *)&frame->pinfo);
		err |= get_user(regs->gpr[5], (unsigned long __user *)&frame->puc);
		regs->gpr[6] = (unsigned long) frame;
	} else {
		regs->gpr[4] = (unsigned long)&frame->uc.uc_mcontext;
	}
	if (err)
		goto badframe;

851
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
852 853

badframe:
854 855
	if (show_unhandled_signals)
		printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
856
				   tsk->comm, tsk->pid, "setup_rt_frame",
857
				   (long)frame, regs->nip, regs->link);
858

859
	return 1;
Linus Torvalds's avatar
Linus Torvalds committed
860
}