diff options
Diffstat (limited to 'arch/mips/kernel/signal32.c')
| -rw-r--r-- | arch/mips/kernel/signal32.c | 55 |
1 files changed, 14 insertions, 41 deletions
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 03abaf048f09..a0ed0e052b2e 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <asm/system.h> | 32 | #include <asm/system.h> |
| 33 | #include <asm/fpu.h> | 33 | #include <asm/fpu.h> |
| 34 | #include <asm/war.h> | 34 | #include <asm/war.h> |
| 35 | #include <asm/vdso.h> | ||
| 35 | 36 | ||
| 36 | #include "signal-common.h" | 37 | #include "signal-common.h" |
| 37 | 38 | ||
| @@ -47,8 +48,6 @@ extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user | |||
| 47 | /* | 48 | /* |
| 48 | * Including <asm/unistd.h> would give use the 64-bit syscall numbers ... | 49 | * Including <asm/unistd.h> would give use the 64-bit syscall numbers ... |
| 49 | */ | 50 | */ |
| 50 | #define __NR_O32_sigreturn 4119 | ||
| 51 | #define __NR_O32_rt_sigreturn 4193 | ||
| 52 | #define __NR_O32_restart_syscall 4253 | 51 | #define __NR_O32_restart_syscall 4253 |
| 53 | 52 | ||
| 54 | /* 32-bit compatibility types */ | 53 | /* 32-bit compatibility types */ |
| @@ -77,47 +76,20 @@ struct ucontext32 { | |||
| 77 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ | 76 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ |
| 78 | }; | 77 | }; |
| 79 | 78 | ||
| 80 | /* | ||
| 81 | * Horribly complicated - with the bloody RM9000 workarounds enabled | ||
| 82 | * the signal trampolines is moving to the end of the structure so we can | ||
| 83 | * increase the alignment without breaking software compatibility. | ||
| 84 | */ | ||
| 85 | #if ICACHE_REFILLS_WORKAROUND_WAR == 0 | ||
| 86 | |||
| 87 | struct sigframe32 { | 79 | struct sigframe32 { |
| 88 | u32 sf_ass[4]; /* argument save space for o32 */ | 80 | u32 sf_ass[4]; /* argument save space for o32 */ |
| 89 | u32 sf_code[2]; /* signal trampoline */ | 81 | u32 sf_pad[2]; /* Was: signal trampoline */ |
| 90 | struct sigcontext32 sf_sc; | 82 | struct sigcontext32 sf_sc; |
| 91 | compat_sigset_t sf_mask; | 83 | compat_sigset_t sf_mask; |
| 92 | }; | 84 | }; |
| 93 | 85 | ||
| 94 | struct rt_sigframe32 { | 86 | struct rt_sigframe32 { |
| 95 | u32 rs_ass[4]; /* argument save space for o32 */ | 87 | u32 rs_ass[4]; /* argument save space for o32 */ |
| 96 | u32 rs_code[2]; /* signal trampoline */ | 88 | u32 rs_pad[2]; /* Was: signal trampoline */ |
| 97 | compat_siginfo_t rs_info; | 89 | compat_siginfo_t rs_info; |
| 98 | struct ucontext32 rs_uc; | 90 | struct ucontext32 rs_uc; |
| 99 | }; | 91 | }; |
| 100 | 92 | ||
| 101 | #else /* ICACHE_REFILLS_WORKAROUND_WAR */ | ||
| 102 | |||
| 103 | struct sigframe32 { | ||
| 104 | u32 sf_ass[4]; /* argument save space for o32 */ | ||
| 105 | u32 sf_pad[2]; | ||
| 106 | struct sigcontext32 sf_sc; /* hw context */ | ||
| 107 | compat_sigset_t sf_mask; | ||
| 108 | u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */ | ||
| 109 | }; | ||
| 110 | |||
| 111 | struct rt_sigframe32 { | ||
| 112 | u32 rs_ass[4]; /* argument save space for o32 */ | ||
| 113 | u32 rs_pad[2]; | ||
| 114 | compat_siginfo_t rs_info; | ||
| 115 | struct ucontext32 rs_uc; | ||
| 116 | u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */ | ||
| 117 | }; | ||
| 118 | |||
| 119 | #endif /* !ICACHE_REFILLS_WORKAROUND_WAR */ | ||
| 120 | |||
| 121 | /* | 93 | /* |
| 122 | * sigcontext handlers | 94 | * sigcontext handlers |
| 123 | */ | 95 | */ |
| @@ -598,8 +570,8 @@ badframe: | |||
| 598 | force_sig(SIGSEGV, current); | 570 | force_sig(SIGSEGV, current); |
| 599 | } | 571 | } |
| 600 | 572 | ||
| 601 | static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | 573 | static int setup_frame_32(void *sig_return, struct k_sigaction *ka, |
| 602 | int signr, sigset_t *set) | 574 | struct pt_regs *regs, int signr, sigset_t *set) |
| 603 | { | 575 | { |
| 604 | struct sigframe32 __user *frame; | 576 | struct sigframe32 __user *frame; |
| 605 | int err = 0; | 577 | int err = 0; |
| @@ -608,8 +580,6 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | |||
| 608 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) | 580 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) |
| 609 | goto give_sigsegv; | 581 | goto give_sigsegv; |
| 610 | 582 | ||
| 611 | err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn); | ||
| 612 | |||
| 613 | err |= setup_sigcontext32(regs, &frame->sf_sc); | 583 | err |= setup_sigcontext32(regs, &frame->sf_sc); |
| 614 | err |= __copy_conv_sigset_to_user(&frame->sf_mask, set); | 584 | err |= __copy_conv_sigset_to_user(&frame->sf_mask, set); |
| 615 | 585 | ||
| @@ -630,7 +600,7 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | |||
| 630 | regs->regs[ 5] = 0; | 600 | regs->regs[ 5] = 0; |
| 631 | regs->regs[ 6] = (unsigned long) &frame->sf_sc; | 601 | regs->regs[ 6] = (unsigned long) &frame->sf_sc; |
| 632 | regs->regs[29] = (unsigned long) frame; | 602 | regs->regs[29] = (unsigned long) frame; |
| 633 | regs->regs[31] = (unsigned long) frame->sf_code; | 603 | regs->regs[31] = (unsigned long) sig_return; |
| 634 | regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; | 604 | regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; |
| 635 | 605 | ||
| 636 | DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", | 606 | DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", |
| @@ -644,8 +614,9 @@ give_sigsegv: | |||
| 644 | return -EFAULT; | 614 | return -EFAULT; |
| 645 | } | 615 | } |
| 646 | 616 | ||
| 647 | static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | 617 | static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka, |
| 648 | int signr, sigset_t *set, siginfo_t *info) | 618 | struct pt_regs *regs, int signr, sigset_t *set, |
| 619 | siginfo_t *info) | ||
| 649 | { | 620 | { |
| 650 | struct rt_sigframe32 __user *frame; | 621 | struct rt_sigframe32 __user *frame; |
| 651 | int err = 0; | 622 | int err = 0; |
| @@ -655,8 +626,6 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | |||
| 655 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) | 626 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) |
| 656 | goto give_sigsegv; | 627 | goto give_sigsegv; |
| 657 | 628 | ||
| 658 | err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn); | ||
| 659 | |||
| 660 | /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */ | 629 | /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */ |
| 661 | err |= copy_siginfo_to_user32(&frame->rs_info, info); | 630 | err |= copy_siginfo_to_user32(&frame->rs_info, info); |
| 662 | 631 | ||
| @@ -690,7 +659,7 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | |||
| 690 | regs->regs[ 5] = (unsigned long) &frame->rs_info; | 659 | regs->regs[ 5] = (unsigned long) &frame->rs_info; |
| 691 | regs->regs[ 6] = (unsigned long) &frame->rs_uc; | 660 | regs->regs[ 6] = (unsigned long) &frame->rs_uc; |
| 692 | regs->regs[29] = (unsigned long) frame; | 661 | regs->regs[29] = (unsigned long) frame; |
| 693 | regs->regs[31] = (unsigned long) frame->rs_code; | 662 | regs->regs[31] = (unsigned long) sig_return; |
| 694 | regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; | 663 | regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; |
| 695 | 664 | ||
| 696 | DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", | 665 | DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", |
| @@ -709,7 +678,11 @@ give_sigsegv: | |||
| 709 | */ | 678 | */ |
| 710 | struct mips_abi mips_abi_32 = { | 679 | struct mips_abi mips_abi_32 = { |
| 711 | .setup_frame = setup_frame_32, | 680 | .setup_frame = setup_frame_32, |
| 681 | .signal_return_offset = | ||
| 682 | offsetof(struct mips_vdso, o32_signal_trampoline), | ||
| 712 | .setup_rt_frame = setup_rt_frame_32, | 683 | .setup_rt_frame = setup_rt_frame_32, |
| 684 | .rt_signal_return_offset = | ||
| 685 | offsetof(struct mips_vdso, o32_rt_signal_trampoline), | ||
| 713 | .restart = __NR_O32_restart_syscall | 686 | .restart = __NR_O32_restart_syscall |
| 714 | }; | 687 | }; |
| 715 | 688 | ||
