aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/signal_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/signal_32.c')
-rw-r--r--arch/powerpc/kernel/signal_32.c93
1 files changed, 52 insertions, 41 deletions
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index bebdf1a1a540..1844298f5ea4 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -265,27 +265,27 @@ struct rt_sigframe {
265unsigned long copy_fpr_to_user(void __user *to, 265unsigned long copy_fpr_to_user(void __user *to,
266 struct task_struct *task) 266 struct task_struct *task)
267{ 267{
268 double buf[ELF_NFPREG]; 268 u64 buf[ELF_NFPREG];
269 int i; 269 int i;
270 270
271 /* save FPR copy to local buffer then write to the thread_struct */ 271 /* save FPR copy to local buffer then write to the thread_struct */
272 for (i = 0; i < (ELF_NFPREG - 1) ; i++) 272 for (i = 0; i < (ELF_NFPREG - 1) ; i++)
273 buf[i] = task->thread.TS_FPR(i); 273 buf[i] = task->thread.TS_FPR(i);
274 memcpy(&buf[i], &task->thread.fpscr, sizeof(double)); 274 buf[i] = task->thread.fp_state.fpscr;
275 return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double)); 275 return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
276} 276}
277 277
278unsigned long copy_fpr_from_user(struct task_struct *task, 278unsigned long copy_fpr_from_user(struct task_struct *task,
279 void __user *from) 279 void __user *from)
280{ 280{
281 double buf[ELF_NFPREG]; 281 u64 buf[ELF_NFPREG];
282 int i; 282 int i;
283 283
284 if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double))) 284 if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
285 return 1; 285 return 1;
286 for (i = 0; i < (ELF_NFPREG - 1) ; i++) 286 for (i = 0; i < (ELF_NFPREG - 1) ; i++)
287 task->thread.TS_FPR(i) = buf[i]; 287 task->thread.TS_FPR(i) = buf[i];
288 memcpy(&task->thread.fpscr, &buf[i], sizeof(double)); 288 task->thread.fp_state.fpscr = buf[i];
289 289
290 return 0; 290 return 0;
291} 291}
@@ -293,25 +293,25 @@ unsigned long copy_fpr_from_user(struct task_struct *task,
293unsigned long copy_vsx_to_user(void __user *to, 293unsigned long copy_vsx_to_user(void __user *to,
294 struct task_struct *task) 294 struct task_struct *task)
295{ 295{
296 double buf[ELF_NVSRHALFREG]; 296 u64 buf[ELF_NVSRHALFREG];
297 int i; 297 int i;
298 298
299 /* save FPR copy to local buffer then write to the thread_struct */ 299 /* save FPR copy to local buffer then write to the thread_struct */
300 for (i = 0; i < ELF_NVSRHALFREG; i++) 300 for (i = 0; i < ELF_NVSRHALFREG; i++)
301 buf[i] = task->thread.fpr[i][TS_VSRLOWOFFSET]; 301 buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
302 return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double)); 302 return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
303} 303}
304 304
305unsigned long copy_vsx_from_user(struct task_struct *task, 305unsigned long copy_vsx_from_user(struct task_struct *task,
306 void __user *from) 306 void __user *from)
307{ 307{
308 double buf[ELF_NVSRHALFREG]; 308 u64 buf[ELF_NVSRHALFREG];
309 int i; 309 int i;
310 310
311 if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double))) 311 if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
312 return 1; 312 return 1;
313 for (i = 0; i < ELF_NVSRHALFREG ; i++) 313 for (i = 0; i < ELF_NVSRHALFREG ; i++)
314 task->thread.fpr[i][TS_VSRLOWOFFSET] = buf[i]; 314 task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
315 return 0; 315 return 0;
316} 316}
317 317
@@ -319,27 +319,27 @@ unsigned long copy_vsx_from_user(struct task_struct *task,
319unsigned long copy_transact_fpr_to_user(void __user *to, 319unsigned long copy_transact_fpr_to_user(void __user *to,
320 struct task_struct *task) 320 struct task_struct *task)
321{ 321{
322 double buf[ELF_NFPREG]; 322 u64 buf[ELF_NFPREG];
323 int i; 323 int i;
324 324
325 /* save FPR copy to local buffer then write to the thread_struct */ 325 /* save FPR copy to local buffer then write to the thread_struct */
326 for (i = 0; i < (ELF_NFPREG - 1) ; i++) 326 for (i = 0; i < (ELF_NFPREG - 1) ; i++)
327 buf[i] = task->thread.TS_TRANS_FPR(i); 327 buf[i] = task->thread.TS_TRANS_FPR(i);
328 memcpy(&buf[i], &task->thread.transact_fpscr, sizeof(double)); 328 buf[i] = task->thread.transact_fp.fpscr;
329 return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double)); 329 return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
330} 330}
331 331
332unsigned long copy_transact_fpr_from_user(struct task_struct *task, 332unsigned long copy_transact_fpr_from_user(struct task_struct *task,
333 void __user *from) 333 void __user *from)
334{ 334{
335 double buf[ELF_NFPREG]; 335 u64 buf[ELF_NFPREG];
336 int i; 336 int i;
337 337
338 if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double))) 338 if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
339 return 1; 339 return 1;
340 for (i = 0; i < (ELF_NFPREG - 1) ; i++) 340 for (i = 0; i < (ELF_NFPREG - 1) ; i++)
341 task->thread.TS_TRANS_FPR(i) = buf[i]; 341 task->thread.TS_TRANS_FPR(i) = buf[i];
342 memcpy(&task->thread.transact_fpscr, &buf[i], sizeof(double)); 342 task->thread.transact_fp.fpscr = buf[i];
343 343
344 return 0; 344 return 0;
345} 345}
@@ -347,25 +347,25 @@ unsigned long copy_transact_fpr_from_user(struct task_struct *task,
347unsigned long copy_transact_vsx_to_user(void __user *to, 347unsigned long copy_transact_vsx_to_user(void __user *to,
348 struct task_struct *task) 348 struct task_struct *task)
349{ 349{
350 double buf[ELF_NVSRHALFREG]; 350 u64 buf[ELF_NVSRHALFREG];
351 int i; 351 int i;
352 352
353 /* save FPR copy to local buffer then write to the thread_struct */ 353 /* save FPR copy to local buffer then write to the thread_struct */
354 for (i = 0; i < ELF_NVSRHALFREG; i++) 354 for (i = 0; i < ELF_NVSRHALFREG; i++)
355 buf[i] = task->thread.transact_fpr[i][TS_VSRLOWOFFSET]; 355 buf[i] = task->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET];
356 return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double)); 356 return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
357} 357}
358 358
359unsigned long copy_transact_vsx_from_user(struct task_struct *task, 359unsigned long copy_transact_vsx_from_user(struct task_struct *task,
360 void __user *from) 360 void __user *from)
361{ 361{
362 double buf[ELF_NVSRHALFREG]; 362 u64 buf[ELF_NVSRHALFREG];
363 int i; 363 int i;
364 364
365 if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double))) 365 if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
366 return 1; 366 return 1;
367 for (i = 0; i < ELF_NVSRHALFREG ; i++) 367 for (i = 0; i < ELF_NVSRHALFREG ; i++)
368 task->thread.transact_fpr[i][TS_VSRLOWOFFSET] = buf[i]; 368 task->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET] = buf[i];
369 return 0; 369 return 0;
370} 370}
371#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ 371#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
@@ -373,14 +373,14 @@ unsigned long copy_transact_vsx_from_user(struct task_struct *task,
373inline unsigned long copy_fpr_to_user(void __user *to, 373inline unsigned long copy_fpr_to_user(void __user *to,
374 struct task_struct *task) 374 struct task_struct *task)
375{ 375{
376 return __copy_to_user(to, task->thread.fpr, 376 return __copy_to_user(to, task->thread.fp_state.fpr,
377 ELF_NFPREG * sizeof(double)); 377 ELF_NFPREG * sizeof(double));
378} 378}
379 379
380inline unsigned long copy_fpr_from_user(struct task_struct *task, 380inline unsigned long copy_fpr_from_user(struct task_struct *task,
381 void __user *from) 381 void __user *from)
382{ 382{
383 return __copy_from_user(task->thread.fpr, from, 383 return __copy_from_user(task->thread.fp_state.fpr, from,
384 ELF_NFPREG * sizeof(double)); 384 ELF_NFPREG * sizeof(double));
385} 385}
386 386
@@ -388,14 +388,14 @@ inline unsigned long copy_fpr_from_user(struct task_struct *task,
388inline unsigned long copy_transact_fpr_to_user(void __user *to, 388inline unsigned long copy_transact_fpr_to_user(void __user *to,
389 struct task_struct *task) 389 struct task_struct *task)
390{ 390{
391 return __copy_to_user(to, task->thread.transact_fpr, 391 return __copy_to_user(to, task->thread.transact_fp.fpr,
392 ELF_NFPREG * sizeof(double)); 392 ELF_NFPREG * sizeof(double));
393} 393}
394 394
395inline unsigned long copy_transact_fpr_from_user(struct task_struct *task, 395inline unsigned long copy_transact_fpr_from_user(struct task_struct *task,
396 void __user *from) 396 void __user *from)
397{ 397{
398 return __copy_from_user(task->thread.transact_fpr, from, 398 return __copy_from_user(task->thread.transact_fp.fpr, from,
399 ELF_NFPREG * sizeof(double)); 399 ELF_NFPREG * sizeof(double));
400} 400}
401#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ 401#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
@@ -423,7 +423,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
423 /* save altivec registers */ 423 /* save altivec registers */
424 if (current->thread.used_vr) { 424 if (current->thread.used_vr) {
425 flush_altivec_to_thread(current); 425 flush_altivec_to_thread(current);
426 if (__copy_to_user(&frame->mc_vregs, current->thread.vr, 426 if (__copy_to_user(&frame->mc_vregs, &current->thread.vr_state,
427 ELF_NVRREG * sizeof(vector128))) 427 ELF_NVRREG * sizeof(vector128)))
428 return 1; 428 return 1;
429 /* set MSR_VEC in the saved MSR value to indicate that 429 /* set MSR_VEC in the saved MSR value to indicate that
@@ -457,7 +457,15 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
457 if (copy_vsx_to_user(&frame->mc_vsregs, current)) 457 if (copy_vsx_to_user(&frame->mc_vsregs, current))
458 return 1; 458 return 1;
459 msr |= MSR_VSX; 459 msr |= MSR_VSX;
460 } 460 } else if (!ctx_has_vsx_region)
461 /*
462 * With a small context structure we can't hold the VSX
463 * registers, hence clear the MSR value to indicate the state
464 * was not saved.
465 */
466 msr &= ~MSR_VSX;
467
468
461#endif /* CONFIG_VSX */ 469#endif /* CONFIG_VSX */
462#ifdef CONFIG_SPE 470#ifdef CONFIG_SPE
463 /* save spe registers */ 471 /* save spe registers */
@@ -534,17 +542,17 @@ static int save_tm_user_regs(struct pt_regs *regs,
534 /* save altivec registers */ 542 /* save altivec registers */
535 if (current->thread.used_vr) { 543 if (current->thread.used_vr) {
536 flush_altivec_to_thread(current); 544 flush_altivec_to_thread(current);
537 if (__copy_to_user(&frame->mc_vregs, current->thread.vr, 545 if (__copy_to_user(&frame->mc_vregs, &current->thread.vr_state,
538 ELF_NVRREG * sizeof(vector128))) 546 ELF_NVRREG * sizeof(vector128)))
539 return 1; 547 return 1;
540 if (msr & MSR_VEC) { 548 if (msr & MSR_VEC) {
541 if (__copy_to_user(&tm_frame->mc_vregs, 549 if (__copy_to_user(&tm_frame->mc_vregs,
542 current->thread.transact_vr, 550 &current->thread.transact_vr,
543 ELF_NVRREG * sizeof(vector128))) 551 ELF_NVRREG * sizeof(vector128)))
544 return 1; 552 return 1;
545 } else { 553 } else {
546 if (__copy_to_user(&tm_frame->mc_vregs, 554 if (__copy_to_user(&tm_frame->mc_vregs,
547 current->thread.vr, 555 &current->thread.vr_state,
548 ELF_NVRREG * sizeof(vector128))) 556 ELF_NVRREG * sizeof(vector128)))
549 return 1; 557 return 1;
550 } 558 }
@@ -692,11 +700,12 @@ static long restore_user_regs(struct pt_regs *regs,
692 regs->msr &= ~MSR_VEC; 700 regs->msr &= ~MSR_VEC;
693 if (msr & MSR_VEC) { 701 if (msr & MSR_VEC) {
694 /* restore altivec registers from the stack */ 702 /* restore altivec registers from the stack */
695 if (__copy_from_user(current->thread.vr, &sr->mc_vregs, 703 if (__copy_from_user(&current->thread.vr_state, &sr->mc_vregs,
696 sizeof(sr->mc_vregs))) 704 sizeof(sr->mc_vregs)))
697 return 1; 705 return 1;
698 } else if (current->thread.used_vr) 706 } else if (current->thread.used_vr)
699 memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128)); 707 memset(&current->thread.vr_state, 0,
708 ELF_NVRREG * sizeof(vector128));
700 709
701 /* Always get VRSAVE back */ 710 /* Always get VRSAVE back */
702 if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32])) 711 if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
@@ -722,7 +731,7 @@ static long restore_user_regs(struct pt_regs *regs,
722 return 1; 731 return 1;
723 } else if (current->thread.used_vsr) 732 } else if (current->thread.used_vsr)
724 for (i = 0; i < 32 ; i++) 733 for (i = 0; i < 32 ; i++)
725 current->thread.fpr[i][TS_VSRLOWOFFSET] = 0; 734 current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
726#endif /* CONFIG_VSX */ 735#endif /* CONFIG_VSX */
727 /* 736 /*
728 * force the process to reload the FP registers from 737 * force the process to reload the FP registers from
@@ -798,15 +807,16 @@ static long restore_tm_user_regs(struct pt_regs *regs,
798 regs->msr &= ~MSR_VEC; 807 regs->msr &= ~MSR_VEC;
799 if (msr & MSR_VEC) { 808 if (msr & MSR_VEC) {
800 /* restore altivec registers from the stack */ 809 /* restore altivec registers from the stack */
801 if (__copy_from_user(current->thread.vr, &sr->mc_vregs, 810 if (__copy_from_user(&current->thread.vr_state, &sr->mc_vregs,
802 sizeof(sr->mc_vregs)) || 811 sizeof(sr->mc_vregs)) ||
803 __copy_from_user(current->thread.transact_vr, 812 __copy_from_user(&current->thread.transact_vr,
804 &tm_sr->mc_vregs, 813 &tm_sr->mc_vregs,
805 sizeof(sr->mc_vregs))) 814 sizeof(sr->mc_vregs)))
806 return 1; 815 return 1;
807 } else if (current->thread.used_vr) { 816 } else if (current->thread.used_vr) {
808 memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128)); 817 memset(&current->thread.vr_state, 0,
809 memset(current->thread.transact_vr, 0, 818 ELF_NVRREG * sizeof(vector128));
819 memset(&current->thread.transact_vr, 0,
810 ELF_NVRREG * sizeof(vector128)); 820 ELF_NVRREG * sizeof(vector128));
811 } 821 }
812 822
@@ -838,8 +848,8 @@ static long restore_tm_user_regs(struct pt_regs *regs,
838 return 1; 848 return 1;
839 } else if (current->thread.used_vsr) 849 } else if (current->thread.used_vsr)
840 for (i = 0; i < 32 ; i++) { 850 for (i = 0; i < 32 ; i++) {
841 current->thread.fpr[i][TS_VSRLOWOFFSET] = 0; 851 current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
842 current->thread.transact_fpr[i][TS_VSRLOWOFFSET] = 0; 852 current->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET] = 0;
843 } 853 }
844#endif /* CONFIG_VSX */ 854#endif /* CONFIG_VSX */
845 855
@@ -891,7 +901,7 @@ static long restore_tm_user_regs(struct pt_regs *regs,
891#endif 901#endif
892 902
893#ifdef CONFIG_PPC64 903#ifdef CONFIG_PPC64
894int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s) 904int copy_siginfo_to_user32(struct compat_siginfo __user *d, const siginfo_t *s)
895{ 905{
896 int err; 906 int err;
897 907
@@ -1030,7 +1040,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
1030 if (__put_user(0, &rt_sf->uc.uc_link)) 1040 if (__put_user(0, &rt_sf->uc.uc_link))
1031 goto badframe; 1041 goto badframe;
1032 1042
1033 current->thread.fpscr.val = 0; /* turn off all fp exceptions */ 1043 current->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */
1034 1044
1035 /* create a stack frame for the caller of the handler */ 1045 /* create a stack frame for the caller of the handler */
1036 newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16); 1046 newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16);
@@ -1045,8 +1055,9 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
1045 regs->gpr[5] = (unsigned long) &rt_sf->uc; 1055 regs->gpr[5] = (unsigned long) &rt_sf->uc;
1046 regs->gpr[6] = (unsigned long) rt_sf; 1056 regs->gpr[6] = (unsigned long) rt_sf;
1047 regs->nip = (unsigned long) ka->sa.sa_handler; 1057 regs->nip = (unsigned long) ka->sa.sa_handler;
1048 /* enter the signal handler in big-endian mode */ 1058 /* enter the signal handler in native-endian mode */
1049 regs->msr &= ~MSR_LE; 1059 regs->msr &= ~MSR_LE;
1060 regs->msr |= (MSR_KERNEL & MSR_LE);
1050#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 1061#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1051 /* Remove TM bits from thread's MSR. The MSR in the sigcontext 1062 /* Remove TM bits from thread's MSR. The MSR in the sigcontext
1052 * just indicates to userland that we were doing a transaction, but we 1063 * just indicates to userland that we were doing a transaction, but we
@@ -1309,7 +1320,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
1309 unsigned char tmp; 1320 unsigned char tmp;
1310 unsigned long new_msr = regs->msr; 1321 unsigned long new_msr = regs->msr;
1311#ifdef CONFIG_PPC_ADV_DEBUG_REGS 1322#ifdef CONFIG_PPC_ADV_DEBUG_REGS
1312 unsigned long new_dbcr0 = current->thread.dbcr0; 1323 unsigned long new_dbcr0 = current->thread.debug.dbcr0;
1313#endif 1324#endif
1314 1325
1315 for (i=0; i<ndbg; i++) { 1326 for (i=0; i<ndbg; i++) {
@@ -1324,7 +1335,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
1324 } else { 1335 } else {
1325 new_dbcr0 &= ~DBCR0_IC; 1336 new_dbcr0 &= ~DBCR0_IC;
1326 if (!DBCR_ACTIVE_EVENTS(new_dbcr0, 1337 if (!DBCR_ACTIVE_EVENTS(new_dbcr0,
1327 current->thread.dbcr1)) { 1338 current->thread.debug.dbcr1)) {
1328 new_msr &= ~MSR_DE; 1339 new_msr &= ~MSR_DE;
1329 new_dbcr0 &= ~DBCR0_IDM; 1340 new_dbcr0 &= ~DBCR0_IDM;
1330 } 1341 }
@@ -1359,7 +1370,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
1359 the user is really doing something wrong. */ 1370 the user is really doing something wrong. */
1360 regs->msr = new_msr; 1371 regs->msr = new_msr;
1361#ifdef CONFIG_PPC_ADV_DEBUG_REGS 1372#ifdef CONFIG_PPC_ADV_DEBUG_REGS
1362 current->thread.dbcr0 = new_dbcr0; 1373 current->thread.debug.dbcr0 = new_dbcr0;
1363#endif 1374#endif
1364 1375
1365 if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx)) 1376 if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx))
@@ -1462,7 +1473,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
1462 1473
1463 regs->link = tramp; 1474 regs->link = tramp;
1464 1475
1465 current->thread.fpscr.val = 0; /* turn off all fp exceptions */ 1476 current->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */
1466 1477
1467 /* create a stack frame for the caller of the handler */ 1478 /* create a stack frame for the caller of the handler */
1468 newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE; 1479 newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;