aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/Makefile4
-rw-r--r--arch/mips/kernel/cpu-probe.c1
-rw-r--r--arch/mips/kernel/process.c35
-rw-r--r--arch/mips/kernel/signal.c18
-rw-r--r--arch/mips/kernel/signal32.c122
-rw-r--r--arch/mips/kernel/signal_n32.c8
-rw-r--r--arch/mips/kernel/traps.c10
7 files changed, 40 insertions, 158 deletions
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 1bf2c8448912..8faf1b40cd66 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -53,9 +53,9 @@ obj-$(CONFIG_MIPS_BOARDS_GEN) += irq-msc01.o
53obj-$(CONFIG_32BIT) += scall32-o32.o 53obj-$(CONFIG_32BIT) += scall32-o32.o
54obj-$(CONFIG_64BIT) += scall64-64.o 54obj-$(CONFIG_64BIT) += scall64-64.o
55obj-$(CONFIG_BINFMT_IRIX) += binfmt_irix.o 55obj-$(CONFIG_BINFMT_IRIX) += binfmt_irix.o
56obj-$(CONFIG_MIPS32_COMPAT) += linux32.o signal32.o 56obj-$(CONFIG_MIPS32_COMPAT) += linux32.o ptrace32.o signal32.o
57obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o 57obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o
58obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o ptrace32.o 58obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o
59 59
60obj-$(CONFIG_KGDB) += gdb-low.o gdb-stub.o 60obj-$(CONFIG_KGDB) += gdb-low.o gdb-stub.o
61obj-$(CONFIG_PROC_FS) += proc.o 61obj-$(CONFIG_PROC_FS) += proc.o
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index f59ef271d247..50ed6d58ae71 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -16,6 +16,7 @@
16#include <linux/ptrace.h> 16#include <linux/ptrace.h>
17#include <linux/stddef.h> 17#include <linux/stddef.h>
18 18
19#include <asm/bugs.h>
19#include <asm/cpu.h> 20#include <asm/cpu.h>
20#include <asm/fpu.h> 21#include <asm/fpu.h>
21#include <asm/mipsregs.h> 22#include <asm/mipsregs.h>
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 04e5b38d327d..a669089e4672 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -26,7 +26,6 @@
26#include <linux/completion.h> 26#include <linux/completion.h>
27#include <linux/kallsyms.h> 27#include <linux/kallsyms.h>
28 28
29#include <asm/abi.h>
30#include <asm/bootinfo.h> 29#include <asm/bootinfo.h>
31#include <asm/cpu.h> 30#include <asm/cpu.h>
32#include <asm/dsp.h> 31#include <asm/dsp.h>
@@ -66,38 +65,6 @@ ATTRIB_NORET void cpu_idle(void)
66 } 65 }
67} 66}
68 67
69/*
70 * Native o32 and N64 ABI without DSP ASE
71 */
72struct mips_abi mips_abi = {
73 .do_signal = do_signal,
74#ifdef CONFIG_TRAD_SIGNALS
75 .setup_frame = setup_frame,
76#endif
77 .setup_rt_frame = setup_rt_frame
78};
79
80#ifdef CONFIG_MIPS32_O32
81/*
82 * o32 compatibility on 64-bit kernels, without DSP ASE
83 */
84struct mips_abi mips_abi_32 = {
85 .do_signal = do_signal32,
86 .setup_frame = setup_frame_32,
87 .setup_rt_frame = setup_rt_frame_32
88};
89#endif /* CONFIG_MIPS32_O32 */
90
91#ifdef CONFIG_MIPS32_N32
92/*
93 * N32 on 64-bit kernels, without DSP ASE
94 */
95struct mips_abi mips_abi_n32 = {
96 .do_signal = do_signal,
97 .setup_rt_frame = setup_rt_frame_n32
98};
99#endif /* CONFIG_MIPS32_N32 */
100
101asmlinkage void ret_from_fork(void); 68asmlinkage void ret_from_fork(void);
102 69
103void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) 70void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
@@ -246,7 +213,7 @@ int dump_task_fpu (struct task_struct *t, elf_fpregset_t *fpr)
246/* 213/*
247 * Create a kernel thread 214 * Create a kernel thread
248 */ 215 */
249ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *)) 216static ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
250{ 217{
251 do_exit(fn(arg)); 218 do_exit(fn(arg));
252} 219}
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index b2e9ab1bb101..adbfb95e42d0 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -398,7 +398,7 @@ badframe:
398} 398}
399 399
400#ifdef CONFIG_TRAD_SIGNALS 400#ifdef CONFIG_TRAD_SIGNALS
401int setup_frame(struct k_sigaction * ka, struct pt_regs *regs, 401static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
402 int signr, sigset_t *set) 402 int signr, sigset_t *set)
403{ 403{
404 struct sigframe __user *frame; 404 struct sigframe __user *frame;
@@ -443,7 +443,7 @@ give_sigsegv:
443} 443}
444#endif 444#endif
445 445
446int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, 446static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
447 int signr, sigset_t *set, siginfo_t *info) 447 int signr, sigset_t *set, siginfo_t *info)
448{ 448{
449 struct rt_sigframe __user *frame; 449 struct rt_sigframe __user *frame;
@@ -501,6 +501,14 @@ give_sigsegv:
501 return -EFAULT; 501 return -EFAULT;
502} 502}
503 503
504struct mips_abi mips_abi = {
505#ifdef CONFIG_TRAD_SIGNALS
506 .setup_frame = setup_frame,
507#endif
508 .setup_rt_frame = setup_rt_frame,
509 .restart = __NR_restart_syscall
510};
511
504static int handle_signal(unsigned long sig, siginfo_t *info, 512static int handle_signal(unsigned long sig, siginfo_t *info,
505 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) 513 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
506{ 514{
@@ -539,7 +547,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
539 return ret; 547 return ret;
540} 548}
541 549
542void do_signal(struct pt_regs *regs) 550static void do_signal(struct pt_regs *regs)
543{ 551{
544 struct k_sigaction ka; 552 struct k_sigaction ka;
545 sigset_t *oldset; 553 sigset_t *oldset;
@@ -589,7 +597,7 @@ void do_signal(struct pt_regs *regs)
589 regs->cp0_epc -= 8; 597 regs->cp0_epc -= 8;
590 } 598 }
591 if (regs->regs[2] == ERESTART_RESTARTBLOCK) { 599 if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
592 regs->regs[2] = __NR_restart_syscall; 600 regs->regs[2] = current->thread.abi->restart;
593 regs->regs[7] = regs->regs[26]; 601 regs->regs[7] = regs->regs[26];
594 regs->cp0_epc -= 4; 602 regs->cp0_epc -= 4;
595 } 603 }
@@ -615,5 +623,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
615{ 623{
616 /* deal with pending signal delivery */ 624 /* deal with pending signal delivery */
617 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 625 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
618 current->thread.abi->do_signal(regs); 626 do_signal(regs);
619} 627}
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index c28cb21514c8..02062fc59f77 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -104,7 +104,7 @@ typedef struct compat_siginfo {
104 */ 104 */
105#define __NR_O32_sigreturn 4119 105#define __NR_O32_sigreturn 4119
106#define __NR_O32_rt_sigreturn 4193 106#define __NR_O32_rt_sigreturn 4193
107#define __NR_O32_restart_syscall 4253 107#define __NR_O32_restart_syscall 4253
108 108
109/* 32-bit compatibility types */ 109/* 32-bit compatibility types */
110 110
@@ -150,7 +150,7 @@ struct sigframe32 {
150 u32 sf_ass[4]; /* argument save space for o32 */ 150 u32 sf_ass[4]; /* argument save space for o32 */
151 u32 sf_code[2]; /* signal trampoline */ 151 u32 sf_code[2]; /* signal trampoline */
152 struct sigcontext32 sf_sc; 152 struct sigcontext32 sf_sc;
153 sigset_t sf_mask; 153 compat_sigset_t sf_mask;
154}; 154};
155 155
156struct rt_sigframe32 { 156struct rt_sigframe32 {
@@ -166,7 +166,7 @@ struct sigframe32 {
166 u32 sf_ass[4]; /* argument save space for o32 */ 166 u32 sf_ass[4]; /* argument save space for o32 */
167 u32 sf_pad[2]; 167 u32 sf_pad[2];
168 struct sigcontext32 sf_sc; /* hw context */ 168 struct sigcontext32 sf_sc; /* hw context */
169 sigset_t sf_mask; 169 compat_sigset_t sf_mask;
170 u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */ 170 u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
171}; 171};
172 172
@@ -598,7 +598,7 @@ badframe:
598 force_sig(SIGSEGV, current); 598 force_sig(SIGSEGV, current);
599} 599}
600 600
601int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, 601static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
602 int signr, sigset_t *set) 602 int signr, sigset_t *set)
603{ 603{
604 struct sigframe32 __user *frame; 604 struct sigframe32 __user *frame;
@@ -644,7 +644,7 @@ give_sigsegv:
644 return -EFAULT; 644 return -EFAULT;
645} 645}
646 646
647int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, 647static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
648 int signr, sigset_t *set, siginfo_t *info) 648 int signr, sigset_t *set, siginfo_t *info)
649{ 649{
650 struct rt_sigframe32 __user *frame; 650 struct rt_sigframe32 __user *frame;
@@ -704,110 +704,14 @@ give_sigsegv:
704 return -EFAULT; 704 return -EFAULT;
705} 705}
706 706
707static inline int handle_signal(unsigned long sig, siginfo_t *info, 707/*
708 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs) 708 * o32 compatibility on 64-bit kernels, without DSP ASE
709{ 709 */
710 int ret; 710struct mips_abi mips_abi_32 = {
711 711 .setup_frame = setup_frame_32,
712 switch (regs->regs[0]) { 712 .setup_rt_frame = setup_rt_frame_32,
713 case ERESTART_RESTARTBLOCK: 713 .restart = __NR_O32_restart_syscall
714 case ERESTARTNOHAND: 714};
715 regs->regs[2] = EINTR;
716 break;
717 case ERESTARTSYS:
718 if (!(ka->sa.sa_flags & SA_RESTART)) {
719 regs->regs[2] = EINTR;
720 break;
721 }
722 /* fallthrough */
723 case ERESTARTNOINTR: /* Userland will reload $v0. */
724 regs->regs[7] = regs->regs[26];
725 regs->cp0_epc -= 8;
726 }
727
728 regs->regs[0] = 0; /* Don't deal with this again. */
729
730 if (ka->sa.sa_flags & SA_SIGINFO)
731 ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
732 else
733 ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
734
735 spin_lock_irq(&current->sighand->siglock);
736 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
737 if (!(ka->sa.sa_flags & SA_NODEFER))
738 sigaddset(&current->blocked,sig);
739 recalc_sigpending();
740 spin_unlock_irq(&current->sighand->siglock);
741
742 return ret;
743}
744
745void do_signal32(struct pt_regs *regs)
746{
747 struct k_sigaction ka;
748 sigset_t *oldset;
749 siginfo_t info;
750 int signr;
751
752 /*
753 * We want the common case to go fast, which is why we may in certain
754 * cases get here from kernel mode. Just return without doing anything
755 * if so.
756 */
757 if (!user_mode(regs))
758 return;
759
760 if (test_thread_flag(TIF_RESTORE_SIGMASK))
761 oldset = &current->saved_sigmask;
762 else
763 oldset = &current->blocked;
764
765 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
766 if (signr > 0) {
767 /* Whee! Actually deliver the signal. */
768 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
769 /*
770 * A signal was successfully delivered; the saved
771 * sigmask will have been stored in the signal frame,
772 * and will be restored by sigreturn, so we can simply
773 * clear the TIF_RESTORE_SIGMASK flag.
774 */
775 if (test_thread_flag(TIF_RESTORE_SIGMASK))
776 clear_thread_flag(TIF_RESTORE_SIGMASK);
777 }
778
779 return;
780 }
781
782 /*
783 * Who's code doesn't conform to the restartable syscall convention
784 * dies here!!! The li instruction, a single machine instruction,
785 * must directly be followed by the syscall instruction.
786 */
787 if (regs->regs[0]) {
788 if (regs->regs[2] == ERESTARTNOHAND ||
789 regs->regs[2] == ERESTARTSYS ||
790 regs->regs[2] == ERESTARTNOINTR) {
791 regs->regs[7] = regs->regs[26];
792 regs->cp0_epc -= 8;
793 }
794 if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
795 regs->regs[2] = __NR_O32_restart_syscall;
796 regs->regs[7] = regs->regs[26];
797 regs->cp0_epc -= 4;
798 }
799 regs->regs[0] = 0; /* Don't deal with this again. */
800 }
801
802 /*
803 * If there's no signal to deliver, we just put the saved sigmask
804 * back
805 */
806 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
807 clear_thread_flag(TIF_RESTORE_SIGMASK);
808 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
809 }
810}
811 715
812asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, 716asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
813 struct sigaction32 __user *oact, 717 struct sigaction32 __user *oact,
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index 7ca2a078841f..ecf1f7ecaad9 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -29,6 +29,7 @@
29#include <linux/compat.h> 29#include <linux/compat.h>
30#include <linux/bitops.h> 30#include <linux/bitops.h>
31 31
32#include <asm/abi.h>
32#include <asm/asm.h> 33#include <asm/asm.h>
33#include <asm/cacheflush.h> 34#include <asm/cacheflush.h>
34#include <asm/compat-signal.h> 35#include <asm/compat-signal.h>
@@ -169,7 +170,7 @@ badframe:
169 force_sig(SIGSEGV, current); 170 force_sig(SIGSEGV, current);
170} 171}
171 172
172int setup_rt_frame_n32(struct k_sigaction * ka, 173static int setup_rt_frame_n32(struct k_sigaction * ka,
173 struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) 174 struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
174{ 175{
175 struct rt_sigframe_n32 __user *frame; 176 struct rt_sigframe_n32 __user *frame;
@@ -228,3 +229,8 @@ give_sigsegv:
228 force_sigsegv(signr, current); 229 force_sigsegv(signr, current);
229 return -EFAULT; 230 return -EFAULT;
230} 231}
232
233struct mips_abi mips_abi_n32 = {
234 .setup_rt_frame = setup_rt_frame_n32,
235 .restart = __NR_N32_restart_syscall
236};
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 2a932cada244..f663c63d5dd3 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -340,13 +340,9 @@ NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs)
340extern const struct exception_table_entry __start___dbe_table[]; 340extern const struct exception_table_entry __start___dbe_table[];
341extern const struct exception_table_entry __stop___dbe_table[]; 341extern const struct exception_table_entry __stop___dbe_table[];
342 342
343void __declare_dbe_table(void) 343__asm__(
344{ 344" .section __dbe_table, \"a\"\n"
345 __asm__ __volatile__( 345" .previous \n");
346 ".section\t__dbe_table,\"a\"\n\t"
347 ".previous"
348 );
349}
350 346
351/* Given an address, look for it in the exception tables. */ 347/* Given an address, look for it in the exception tables. */
352static const struct exception_table_entry *search_dbe_tables(unsigned long addr) 348static const struct exception_table_entry *search_dbe_tables(unsigned long addr)