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] Fix sigset_t endianess swapping issues in 32-bit compat code. [MIPS] Fix uniprocessor Sibyte builds. [MIPS] Make entry.S a little more readable. [MIPS] Remove stray instruction from __get_user_asm_ll32. [MIPS] 32-bit: Fix warning about cast for fetching pointer from userspace. [MIPS] DECstation: Fix irq handling [MIPS] signals: make common _BLOCKABLE macro [MIPS] signal: Move sigframe definition for native O32/N64 into signal.c [MIPS] signal: Move {restore,setup}_sigcontext prototypes to their user [MIPS] signal: Fix warnings in o32 compat code. [MIPS] IP27: Enable N32 support in defconfig. Revert "[MIPS] Fix warning in get_user when fetching pointer object from userspace." [MIPS] Don't claim we support dma_declare_coherent_memory - we don't. [MIPS] Unify dma-{coherent,noncoherent.ip27,ip32} [MIPS] Improve branch prediction in ll/sc atomic operations.
This commit is contained in:
@@ -21,24 +21,21 @@
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PREEMPT
|
||||
.macro preempt_stop
|
||||
local_irq_disable
|
||||
.endm
|
||||
#define resume_kernel restore_all
|
||||
#else
|
||||
#define __ret_from_irq ret_from_exception
|
||||
#endif
|
||||
|
||||
.text
|
||||
.align 5
|
||||
#ifndef CONFIG_PREEMPT
|
||||
FEXPORT(ret_from_exception)
|
||||
local_irq_disable # preempt stop
|
||||
b __ret_from_irq
|
||||
#endif
|
||||
FEXPORT(ret_from_irq)
|
||||
LONG_S s0, TI_REGS($28)
|
||||
#ifdef CONFIG_PREEMPT
|
||||
FEXPORT(ret_from_exception)
|
||||
#else
|
||||
b _ret_from_irq
|
||||
FEXPORT(ret_from_exception)
|
||||
preempt_stop
|
||||
#endif
|
||||
FEXPORT(_ret_from_irq)
|
||||
FEXPORT(__ret_from_irq)
|
||||
LONG_L t0, PT_STATUS(sp) # returning to kernel mode?
|
||||
andi t0, t0, KU_USER
|
||||
beqz t0, resume_kernel
|
||||
|
@@ -39,6 +39,7 @@
|
||||
#include <net/sock.h>
|
||||
#include <net/scm.h>
|
||||
|
||||
#include <asm/compat-signal.h>
|
||||
#include <asm/ipc.h>
|
||||
#include <asm/sim.h>
|
||||
#include <asm/uaccess.h>
|
||||
@@ -736,3 +737,49 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs)
|
||||
return do_fork(clone_flags, newsp, ®s, 0,
|
||||
parent_tidptr, child_tidptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implement the event wait interface for the eventpoll file. It is the kernel
|
||||
* part of the user space epoll_pwait(2).
|
||||
*/
|
||||
asmlinkage long compat_sys_epoll_pwait(int epfd,
|
||||
struct epoll_event __user *events, int maxevents, int timeout,
|
||||
const compat_sigset_t __user *sigmask, size_t sigsetsize)
|
||||
{
|
||||
int error;
|
||||
sigset_t ksigmask, sigsaved;
|
||||
|
||||
/*
|
||||
* If the caller wants a certain signal mask to be set during the wait,
|
||||
* we apply it here.
|
||||
*/
|
||||
if (sigmask) {
|
||||
if (sigsetsize != sizeof(sigset_t))
|
||||
return -EINVAL;
|
||||
if (!access_ok(VERIFY_READ, sigmask, sizeof(ksigmask)))
|
||||
return -EFAULT;
|
||||
if (__copy_conv_sigset_from_user(&ksigmask, sigmask))
|
||||
return -EFAULT;
|
||||
sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
|
||||
sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
|
||||
}
|
||||
|
||||
error = sys_epoll_wait(epfd, events, maxevents, timeout);
|
||||
|
||||
/*
|
||||
* If we changed the signal mask, we need to restore the original one.
|
||||
* In case we've got a signal while waiting, we do not restore the
|
||||
* signal mask yet, and we allow do_signal() to deliver the signal on
|
||||
* the way back to userspace, before the signal mask is restored.
|
||||
*/
|
||||
if (sigmask) {
|
||||
if (error == -EINTR) {
|
||||
memcpy(¤t->saved_sigmask, &sigsaved,
|
||||
sizeof(sigsaved));
|
||||
set_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
} else
|
||||
sigprocmask(SIG_SETMASK, &sigsaved, NULL);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@@ -470,4 +470,4 @@ sys_call_table:
|
||||
PTR sys_get_robust_list
|
||||
PTR sys_kexec_load /* 5270 */
|
||||
PTR sys_getcpu
|
||||
PTR sys_epoll_pwait
|
||||
PTR compat_sys_epoll_pwait
|
||||
|
@@ -396,4 +396,4 @@ EXPORT(sysn32_call_table)
|
||||
PTR compat_sys_get_robust_list
|
||||
PTR compat_sys_kexec_load
|
||||
PTR sys_getcpu
|
||||
PTR sys_epoll_pwait
|
||||
PTR compat_sys_epoll_pwait
|
||||
|
@@ -19,37 +19,7 @@
|
||||
# define DEBUGP(fmt, args...)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Horribly complicated - with the bloody RM9000 workarounds enabled
|
||||
* the signal trampolines is moving to the end of the structure so we can
|
||||
* increase the alignment without breaking software compatibility.
|
||||
*/
|
||||
#if ICACHE_REFILLS_WORKAROUND_WAR == 0
|
||||
|
||||
struct sigframe {
|
||||
u32 sf_ass[4]; /* argument save space for o32 */
|
||||
u32 sf_code[2]; /* signal trampoline */
|
||||
struct sigcontext sf_sc;
|
||||
sigset_t sf_mask;
|
||||
};
|
||||
|
||||
#else /* ICACHE_REFILLS_WORKAROUND_WAR */
|
||||
|
||||
struct sigframe {
|
||||
u32 sf_ass[4]; /* argument save space for o32 */
|
||||
u32 sf_pad[2];
|
||||
struct sigcontext sf_sc; /* hw context */
|
||||
sigset_t sf_mask;
|
||||
u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
|
||||
};
|
||||
|
||||
#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
|
||||
|
||||
/*
|
||||
* handle hardware context
|
||||
*/
|
||||
extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
|
||||
extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
|
||||
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
||||
|
||||
/*
|
||||
* Determine which stack to use..
|
||||
|
@@ -34,10 +34,20 @@
|
||||
|
||||
#include "signal-common.h"
|
||||
|
||||
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
||||
|
||||
/*
|
||||
* Horribly complicated - with the bloody RM9000 workarounds enabled
|
||||
* the signal trampolines is moving to the end of the structure so we can
|
||||
* increase the alignment without breaking software compatibility.
|
||||
*/
|
||||
#if ICACHE_REFILLS_WORKAROUND_WAR == 0
|
||||
|
||||
struct sigframe {
|
||||
u32 sf_ass[4]; /* argument save space for o32 */
|
||||
u32 sf_code[2]; /* signal trampoline */
|
||||
struct sigcontext sf_sc;
|
||||
sigset_t sf_mask;
|
||||
};
|
||||
|
||||
struct rt_sigframe {
|
||||
u32 rs_ass[4]; /* argument save space for o32 */
|
||||
u32 rs_code[2]; /* signal trampoline */
|
||||
@@ -47,6 +57,14 @@ struct rt_sigframe {
|
||||
|
||||
#else
|
||||
|
||||
struct sigframe {
|
||||
u32 sf_ass[4]; /* argument save space for o32 */
|
||||
u32 sf_pad[2];
|
||||
struct sigcontext sf_sc; /* hw context */
|
||||
sigset_t sf_mask;
|
||||
u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
|
||||
};
|
||||
|
||||
struct rt_sigframe {
|
||||
u32 rs_ass[4]; /* argument save space for o32 */
|
||||
u32 rs_pad[2];
|
||||
|
@@ -8,6 +8,7 @@
|
||||
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
|
||||
*/
|
||||
#include <linux/cache.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/smp.h>
|
||||
@@ -24,6 +25,7 @@
|
||||
|
||||
#include <asm/abi.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/compat-signal.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/sim.h>
|
||||
@@ -104,8 +106,6 @@ typedef struct compat_siginfo {
|
||||
#define __NR_O32_rt_sigreturn 4193
|
||||
#define __NR_O32_restart_syscall 4253
|
||||
|
||||
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
||||
|
||||
/* 32-bit compatibility types */
|
||||
|
||||
#define _NSIG_BPW32 32
|
||||
@@ -139,8 +139,20 @@ struct ucontext32 {
|
||||
sigset_t32 uc_sigmask; /* mask last for extensibility */
|
||||
};
|
||||
|
||||
/*
|
||||
* Horribly complicated - with the bloody RM9000 workarounds enabled
|
||||
* the signal trampolines is moving to the end of the structure so we can
|
||||
* increase the alignment without breaking software compatibility.
|
||||
*/
|
||||
#if ICACHE_REFILLS_WORKAROUND_WAR == 0
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
struct rt_sigframe32 {
|
||||
u32 rs_ass[4]; /* argument save space for o32 */
|
||||
u32 rs_code[2]; /* signal trampoline */
|
||||
@@ -150,6 +162,14 @@ struct rt_sigframe32 {
|
||||
|
||||
#else /* ICACHE_REFILLS_WORKAROUND_WAR */
|
||||
|
||||
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;
|
||||
u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
|
||||
};
|
||||
|
||||
struct rt_sigframe32 {
|
||||
u32 rs_ass[4]; /* argument save space for o32 */
|
||||
u32 rs_pad[2];
|
||||
@@ -493,13 +513,13 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
|
||||
|
||||
asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
|
||||
{
|
||||
struct sigframe __user *frame;
|
||||
struct sigframe32 __user *frame;
|
||||
sigset_t blocked;
|
||||
|
||||
frame = (struct sigframe __user *) regs.regs[29];
|
||||
frame = (struct sigframe32 __user *) regs.regs[29];
|
||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
|
||||
if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
|
||||
goto badframe;
|
||||
|
||||
sigdelsetmask(&blocked, ~_BLOCKABLE);
|
||||
@@ -536,7 +556,7 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
|
||||
frame = (struct rt_sigframe32 __user *) regs.regs[29];
|
||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
|
||||
if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
|
||||
goto badframe;
|
||||
|
||||
sigdelsetmask(&set, ~_BLOCKABLE);
|
||||
@@ -581,7 +601,7 @@ badframe:
|
||||
int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||
int signr, sigset_t *set)
|
||||
{
|
||||
struct sigframe __user *frame;
|
||||
struct sigframe32 __user *frame;
|
||||
int err = 0;
|
||||
|
||||
frame = get_sigframe(ka, regs, sizeof(*frame));
|
||||
@@ -591,7 +611,8 @@ int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||
err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
|
||||
|
||||
err |= setup_sigcontext32(regs, &frame->sf_sc);
|
||||
err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
|
||||
err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
|
||||
|
||||
if (err)
|
||||
goto give_sigsegv;
|
||||
|
||||
@@ -650,7 +671,7 @@ int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||
err |= __put_user(current->sas_ss_size,
|
||||
&frame->rs_uc.uc_stack.ss_size);
|
||||
err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
|
||||
err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
|
||||
err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
|
||||
|
||||
if (err)
|
||||
goto give_sigsegv;
|
||||
|
@@ -31,6 +31,7 @@
|
||||
|
||||
#include <asm/asm.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/compat-signal.h>
|
||||
#include <asm/sim.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/ucontext.h>
|
||||
@@ -47,7 +48,9 @@
|
||||
#define __NR_N32_rt_sigreturn 6211
|
||||
#define __NR_N32_restart_syscall 6214
|
||||
|
||||
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
||||
extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
|
||||
extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
|
||||
|
||||
|
||||
/* IRIX compatible stack_t */
|
||||
typedef struct sigaltstack32 {
|
||||
@@ -61,7 +64,7 @@ struct ucontextn32 {
|
||||
s32 uc_link;
|
||||
stack32_t uc_stack;
|
||||
struct sigcontext uc_mcontext;
|
||||
sigset_t uc_sigmask; /* mask last for extensibility */
|
||||
compat_sigset_t uc_sigmask; /* mask last for extensibility */
|
||||
};
|
||||
|
||||
#if ICACHE_REFILLS_WORKAROUND_WAR == 0
|
||||
@@ -127,7 +130,7 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
|
||||
frame = (struct rt_sigframe_n32 __user *) regs.regs[29];
|
||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
|
||||
if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
|
||||
goto badframe;
|
||||
|
||||
sigdelsetmask(&set, ~_BLOCKABLE);
|
||||
@@ -193,7 +196,7 @@ int setup_rt_frame_n32(struct k_sigaction * ka,
|
||||
err |= __put_user(current->sas_ss_size,
|
||||
&frame->rs_uc.uc_stack.ss_size);
|
||||
err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
|
||||
err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
|
||||
err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
|
||||
|
||||
if (err)
|
||||
goto give_sigsegv;
|
||||
|
Reference in New Issue
Block a user