aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-19 13:38:42 -0800
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-19 13:38:42 -0800
commitcb553c480078759014096bc766dc76400e1d8397 (patch)
tree97262cd9252a7dc68f8701f8435b0d10b9e79536 /arch/mips/kernel
parent42eaf0d8f2e7b8201afc00b0ebe1bd89ea51d42d (diff)
parent040cf8cfe5f0674ddf256f98366137a7b90d421f (diff)
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: [MIPS] Update defconfigs [MIPS] Support for several more SNI RM models. [MIPS] Include <asm/bugs> to for declaration of check_bugs32. [MIPS] Add external declaration of pagetable_init() to pgalloc.h [MIPS] Make kernel_thread_helper() static [MIPS] Make __declare_dbe_table static and avoid it getting optimized away [MIPS] Use MIPS R2 instructions for bitops. [MIPS] signals: Share even more code. [MIPS] Fix CONFIG_MIPS32_N32=y CONFIG_MIPS32_O32=n build [MIPS] Iomap implementation. [MIPS] <asm/compat-signal.h> needs to include <asm/uaccess.h>. [MIPS] IP27: Fix warning. [MIPS] Fix sigset_t endianess swapping issues in 32-bit compat code.
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 1bf2c844891..8faf1b40cd6 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -53,9 +53,9 @@ obj-$(CONFIG_MIPS_BOARDS_GEN) += irq-msc01.o
obj-$(CONFIG_32BIT) += scall32-o32.o
obj-$(CONFIG_64BIT) += scall64-64.o
obj-$(CONFIG_BINFMT_IRIX) += binfmt_irix.o
-obj-$(CONFIG_MIPS32_COMPAT) += linux32.o signal32.o
+obj-$(CONFIG_MIPS32_COMPAT) += linux32.o ptrace32.o signal32.o
obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o
-obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o ptrace32.o
+obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o
obj-$(CONFIG_KGDB) += gdb-low.o gdb-stub.o
obj-$(CONFIG_PROC_FS) += proc.o
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index f59ef271d24..50ed6d58ae7 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -16,6 +16,7 @@
#include <linux/ptrace.h>
#include <linux/stddef.h>
+#include <asm/bugs.h>
#include <asm/cpu.h>
#include <asm/fpu.h>
#include <asm/mipsregs.h>
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 04e5b38d327..a669089e467 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -26,7 +26,6 @@
#include <linux/completion.h>
#include <linux/kallsyms.h>
-#include <asm/abi.h>
#include <asm/bootinfo.h>
#include <asm/cpu.h>
#include <asm/dsp.h>
@@ -66,38 +65,6 @@ ATTRIB_NORET void cpu_idle(void)
}
}
-/*
- * Native o32 and N64 ABI without DSP ASE
- */
-struct mips_abi mips_abi = {
- .do_signal = do_signal,
-#ifdef CONFIG_TRAD_SIGNALS
- .setup_frame = setup_frame,
-#endif
- .setup_rt_frame = setup_rt_frame
-};
-
-#ifdef CONFIG_MIPS32_O32
-/*
- * o32 compatibility on 64-bit kernels, without DSP ASE
- */
-struct mips_abi mips_abi_32 = {
- .do_signal = do_signal32,
- .setup_frame = setup_frame_32,
- .setup_rt_frame = setup_rt_frame_32
-};
-#endif /* CONFIG_MIPS32_O32 */
-
-#ifdef CONFIG_MIPS32_N32
-/*
- * N32 on 64-bit kernels, without DSP ASE
- */
-struct mips_abi mips_abi_n32 = {
- .do_signal = do_signal,
- .setup_rt_frame = setup_rt_frame_n32
-};
-#endif /* CONFIG_MIPS32_N32 */
-
asmlinkage void ret_from_fork(void);
void 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)
/*
* Create a kernel thread
*/
-ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
+static ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
{
do_exit(fn(arg));
}
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index b2e9ab1bb10..adbfb95e42d 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -398,7 +398,7 @@ badframe:
}
#ifdef CONFIG_TRAD_SIGNALS
-int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
int signr, sigset_t *set)
{
struct sigframe __user *frame;
@@ -443,7 +443,7 @@ give_sigsegv:
}
#endif
-int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
+static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
int signr, sigset_t *set, siginfo_t *info)
{
struct rt_sigframe __user *frame;
@@ -501,6 +501,14 @@ give_sigsegv:
return -EFAULT;
}
+struct mips_abi mips_abi = {
+#ifdef CONFIG_TRAD_SIGNALS
+ .setup_frame = setup_frame,
+#endif
+ .setup_rt_frame = setup_rt_frame,
+ .restart = __NR_restart_syscall
+};
+
static int handle_signal(unsigned long sig, siginfo_t *info,
struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
{
@@ -539,7 +547,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
return ret;
}
-void do_signal(struct pt_regs *regs)
+static void do_signal(struct pt_regs *regs)
{
struct k_sigaction ka;
sigset_t *oldset;
@@ -589,7 +597,7 @@ void do_signal(struct pt_regs *regs)
regs->cp0_epc -= 8;
}
if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
- regs->regs[2] = __NR_restart_syscall;
+ regs->regs[2] = current->thread.abi->restart;
regs->regs[7] = regs->regs[26];
regs->cp0_epc -= 4;
}
@@ -615,5 +623,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
{
/* deal with pending signal delivery */
if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
- current->thread.abi->do_signal(regs);
+ do_signal(regs);
}
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index c28cb21514c..02062fc59f7 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -104,7 +104,7 @@ typedef struct compat_siginfo {
*/
#define __NR_O32_sigreturn 4119
#define __NR_O32_rt_sigreturn 4193
-#define __NR_O32_restart_syscall 4253
+#define __NR_O32_restart_syscall 4253
/* 32-bit compatibility types */
@@ -150,7 +150,7 @@ struct sigframe32 {
u32 sf_ass[4]; /* argument save space for o32 */
u32 sf_code[2]; /* signal trampoline */
struct sigcontext32 sf_sc;
- sigset_t sf_mask;
+ compat_sigset_t sf_mask;
};
struct rt_sigframe32 {
@@ -166,7 +166,7 @@ struct sigframe32 {
u32 sf_ass[4]; /* argument save space for o32 */
u32 sf_pad[2];
struct sigcontext32 sf_sc; /* hw context */
- sigset_t sf_mask;
+ compat_sigset_t sf_mask;
u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
};
@@ -598,7 +598,7 @@ badframe:
force_sig(SIGSEGV, current);
}
-int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
+static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
int signr, sigset_t *set)
{
struct sigframe32 __user *frame;
@@ -644,7 +644,7 @@ give_sigsegv:
return -EFAULT;
}
-int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
+static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
int signr, sigset_t *set, siginfo_t *info)
{
struct rt_sigframe32 __user *frame;
@@ -704,110 +704,14 @@ give_sigsegv:
return -EFAULT;
}
-static inline int handle_signal(unsigned long sig, siginfo_t *info,
- struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs)
-{
- int ret;
-
- switch (regs->regs[0]) {
- case ERESTART_RESTARTBLOCK:
- case ERESTARTNOHAND:
- regs->regs[2] = EINTR;
- break;
- case ERESTARTSYS:
- if (!(ka->sa.sa_flags & SA_RESTART)) {
- regs->regs[2] = EINTR;
- break;
- }
- /* fallthrough */
- case ERESTARTNOINTR: /* Userland will reload $v0. */
- regs->regs[7] = regs->regs[26];
- regs->cp0_epc -= 8;
- }
-
- regs->regs[0] = 0; /* Don't deal with this again. */
-
- if (ka->sa.sa_flags & SA_SIGINFO)
- ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
- else
- ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
-
- spin_lock_irq(&current->sighand->siglock);
- sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
- if (!(ka->sa.sa_flags & SA_NODEFER))
- sigaddset(&current->blocked,sig);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- return ret;
-}
-
-void do_signal32(struct pt_regs *regs)
-{
- struct k_sigaction ka;
- sigset_t *oldset;
- siginfo_t info;
- int signr;
-
- /*
- * We want the common case to go fast, which is why we may in certain
- * cases get here from kernel mode. Just return without doing anything
- * if so.
- */
- if (!user_mode(regs))
- return;
-
- if (test_thread_flag(TIF_RESTORE_SIGMASK))
- oldset = &current->saved_sigmask;
- else
- oldset = &current->blocked;
-
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
- /* Whee! Actually deliver the signal. */
- if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
- /*
- * A signal was successfully delivered; the saved
- * sigmask will have been stored in the signal frame,
- * and will be restored by sigreturn, so we can simply
- * clear the TIF_RESTORE_SIGMASK flag.
- */
- if (test_thread_flag(TIF_RESTORE_SIGMASK))
- clear_thread_flag(TIF_RESTORE_SIGMASK);
- }
-
- return;
- }
-
- /*
- * Who's code doesn't conform to the restartable syscall convention
- * dies here!!! The li instruction, a single machine instruction,
- * must directly be followed by the syscall instruction.
- */
- if (regs->regs[0]) {
- if (regs->regs[2] == ERESTARTNOHAND ||
- regs->regs[2] == ERESTARTSYS ||
- regs->regs[2] == ERESTARTNOINTR) {
- regs->regs[7] = regs->regs[26];
- regs->cp0_epc -= 8;
- }
- if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
- regs->regs[2] = __NR_O32_restart_syscall;
- regs->regs[7] = regs->regs[26];
- regs->cp0_epc -= 4;
- }
- regs->regs[0] = 0; /* Don't deal with this again. */
- }
-
- /*
- * If there's no signal to deliver, we just put the saved sigmask
- * back
- */
- if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
- clear_thread_flag(TIF_RESTORE_SIGMASK);
- sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
- }
-}
+/*
+ * o32 compatibility on 64-bit kernels, without DSP ASE
+ */
+struct mips_abi mips_abi_32 = {
+ .setup_frame = setup_frame_32,
+ .setup_rt_frame = setup_rt_frame_32,
+ .restart = __NR_O32_restart_syscall
+};
asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
struct sigaction32 __user *oact,
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index 7ca2a078841..ecf1f7ecaad 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -29,6 +29,7 @@
#include <linux/compat.h>
#include <linux/bitops.h>
+#include <asm/abi.h>
#include <asm/asm.h>
#include <asm/cacheflush.h>
#include <asm/compat-signal.h>
@@ -169,7 +170,7 @@ badframe:
force_sig(SIGSEGV, current);
}
-int setup_rt_frame_n32(struct k_sigaction * ka,
+static int setup_rt_frame_n32(struct k_sigaction * ka,
struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
{
struct rt_sigframe_n32 __user *frame;
@@ -228,3 +229,8 @@ give_sigsegv:
force_sigsegv(signr, current);
return -EFAULT;
}
+
+struct mips_abi mips_abi_n32 = {
+ .setup_rt_frame = setup_rt_frame_n32,
+ .restart = __NR_N32_restart_syscall
+};
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 2a932cada24..f663c63d5dd 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)
extern const struct exception_table_entry __start___dbe_table[];
extern const struct exception_table_entry __stop___dbe_table[];
-void __declare_dbe_table(void)
-{
- __asm__ __volatile__(
- ".section\t__dbe_table,\"a\"\n\t"
- ".previous"
- );
-}
+__asm__(
+" .section __dbe_table, \"a\"\n"
+" .previous \n");
/* Given an address, look for it in the exception tables. */
static const struct exception_table_entry *search_dbe_tables(unsigned long addr)