diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-12-17 18:22:27 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-12-17 18:22:27 -0500 |
commit | 376bddd34433065aeb9b9a140870537feecf90ef (patch) | |
tree | a40e2b84ad89f4b3ba968de65a4bf7ff6ccae835 /arch/sparc/kernel/process_64.c | |
parent | d526e85f60fce9aa2a1432cbd06e3cf20c1644c8 (diff) | |
parent | 667b504a2c411e4d5915a6e2260a3857ba9f797a (diff) |
Merge remote-tracking branch 'agust/next' into next
Brings some 52xx updates. Also manually merged tools/perf/perf.h.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/sparc/kernel/process_64.c')
-rw-r--r-- | arch/sparc/kernel/process_64.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index d778248ef3f8..c6e0c2910043 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c | |||
@@ -452,13 +452,16 @@ void flush_thread(void) | |||
452 | /* It's a bit more tricky when 64-bit tasks are involved... */ | 452 | /* It's a bit more tricky when 64-bit tasks are involved... */ |
453 | static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) | 453 | static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) |
454 | { | 454 | { |
455 | bool stack_64bit = test_thread_64bit_stack(psp); | ||
455 | unsigned long fp, distance, rval; | 456 | unsigned long fp, distance, rval; |
456 | 457 | ||
457 | if (!(test_thread_flag(TIF_32BIT))) { | 458 | if (stack_64bit) { |
458 | csp += STACK_BIAS; | 459 | csp += STACK_BIAS; |
459 | psp += STACK_BIAS; | 460 | psp += STACK_BIAS; |
460 | __get_user(fp, &(((struct reg_window __user *)psp)->ins[6])); | 461 | __get_user(fp, &(((struct reg_window __user *)psp)->ins[6])); |
461 | fp += STACK_BIAS; | 462 | fp += STACK_BIAS; |
463 | if (test_thread_flag(TIF_32BIT)) | ||
464 | fp &= 0xffffffff; | ||
462 | } else | 465 | } else |
463 | __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); | 466 | __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); |
464 | 467 | ||
@@ -472,7 +475,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) | |||
472 | rval = (csp - distance); | 475 | rval = (csp - distance); |
473 | if (copy_in_user((void __user *) rval, (void __user *) psp, distance)) | 476 | if (copy_in_user((void __user *) rval, (void __user *) psp, distance)) |
474 | rval = 0; | 477 | rval = 0; |
475 | else if (test_thread_flag(TIF_32BIT)) { | 478 | else if (!stack_64bit) { |
476 | if (put_user(((u32)csp), | 479 | if (put_user(((u32)csp), |
477 | &(((struct reg_window32 __user *)rval)->ins[6]))) | 480 | &(((struct reg_window32 __user *)rval)->ins[6]))) |
478 | rval = 0; | 481 | rval = 0; |
@@ -507,18 +510,18 @@ void synchronize_user_stack(void) | |||
507 | 510 | ||
508 | flush_user_windows(); | 511 | flush_user_windows(); |
509 | if ((window = get_thread_wsaved()) != 0) { | 512 | if ((window = get_thread_wsaved()) != 0) { |
510 | int winsize = sizeof(struct reg_window); | ||
511 | int bias = 0; | ||
512 | |||
513 | if (test_thread_flag(TIF_32BIT)) | ||
514 | winsize = sizeof(struct reg_window32); | ||
515 | else | ||
516 | bias = STACK_BIAS; | ||
517 | |||
518 | window -= 1; | 513 | window -= 1; |
519 | do { | 514 | do { |
520 | unsigned long sp = (t->rwbuf_stkptrs[window] + bias); | ||
521 | struct reg_window *rwin = &t->reg_window[window]; | 515 | struct reg_window *rwin = &t->reg_window[window]; |
516 | int winsize = sizeof(struct reg_window); | ||
517 | unsigned long sp; | ||
518 | |||
519 | sp = t->rwbuf_stkptrs[window]; | ||
520 | |||
521 | if (test_thread_64bit_stack(sp)) | ||
522 | sp += STACK_BIAS; | ||
523 | else | ||
524 | winsize = sizeof(struct reg_window32); | ||
522 | 525 | ||
523 | if (!copy_to_user((char __user *)sp, rwin, winsize)) { | 526 | if (!copy_to_user((char __user *)sp, rwin, winsize)) { |
524 | shift_window_buffer(window, get_thread_wsaved() - 1, t); | 527 | shift_window_buffer(window, get_thread_wsaved() - 1, t); |
@@ -544,13 +547,6 @@ void fault_in_user_windows(void) | |||
544 | { | 547 | { |
545 | struct thread_info *t = current_thread_info(); | 548 | struct thread_info *t = current_thread_info(); |
546 | unsigned long window; | 549 | unsigned long window; |
547 | int winsize = sizeof(struct reg_window); | ||
548 | int bias = 0; | ||
549 | |||
550 | if (test_thread_flag(TIF_32BIT)) | ||
551 | winsize = sizeof(struct reg_window32); | ||
552 | else | ||
553 | bias = STACK_BIAS; | ||
554 | 550 | ||
555 | flush_user_windows(); | 551 | flush_user_windows(); |
556 | window = get_thread_wsaved(); | 552 | window = get_thread_wsaved(); |
@@ -558,8 +554,16 @@ void fault_in_user_windows(void) | |||
558 | if (likely(window != 0)) { | 554 | if (likely(window != 0)) { |
559 | window -= 1; | 555 | window -= 1; |
560 | do { | 556 | do { |
561 | unsigned long sp = (t->rwbuf_stkptrs[window] + bias); | ||
562 | struct reg_window *rwin = &t->reg_window[window]; | 557 | struct reg_window *rwin = &t->reg_window[window]; |
558 | int winsize = sizeof(struct reg_window); | ||
559 | unsigned long sp; | ||
560 | |||
561 | sp = t->rwbuf_stkptrs[window]; | ||
562 | |||
563 | if (test_thread_64bit_stack(sp)) | ||
564 | sp += STACK_BIAS; | ||
565 | else | ||
566 | winsize = sizeof(struct reg_window32); | ||
563 | 567 | ||
564 | if (unlikely(sp & 0x7UL)) | 568 | if (unlikely(sp & 0x7UL)) |
565 | stack_unaligned(sp); | 569 | stack_unaligned(sp); |