Skip to content

Commit

Permalink
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
Linus Torvalds committed Feb 14, 2007
2 parents 58a3bb5 + 431dc80 commit 463020c
Show file tree
Hide file tree
Showing 31 changed files with 701 additions and 1,118 deletions.
5 changes: 0 additions & 5 deletions arch/mips/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -598,8 +598,6 @@ config SGI_IP32
select ARC
select ARC32
select BOOT_ELF32
select OWN_DMA
select DMA_IP32
select DMA_NONCOHERENT
select HW_HAS_PCI
select R5000_CPU_SCACHE
Expand Down Expand Up @@ -883,9 +881,6 @@ config DMA_NONCOHERENT
config DMA_NEED_PCI_MAP_STATE
bool

config OWN_DMA
bool

config EARLY_PRINTK
bool

Expand Down
2 changes: 1 addition & 1 deletion arch/mips/configs/ip27_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ CONFIG_BINFMT_ELF=y
CONFIG_MIPS32_COMPAT=y
CONFIG_COMPAT=y
CONFIG_MIPS32_O32=y
# CONFIG_MIPS32_N32 is not set
CONFIG_MIPS32_N32=y
CONFIG_BINFMT_ELF32=y

#
Expand Down
4 changes: 0 additions & 4 deletions arch/mips/dec/int-handler.S
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,6 @@
srlv t3,t1,t2

handle_it:
LONG_L s0, TI_REGS($28)
LONG_S sp, TI_REGS($28)
PTR_LA ra, ret_from_irq
j dec_irq_dispatch
nop

Expand All @@ -277,7 +274,6 @@ fpu:
#endif

spurious:
PTR_LA ra, _ret_from_irq
j spurious_interrupt
nop
END(plat_irq_dispatch)
Expand Down
19 changes: 8 additions & 11 deletions arch/mips/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
FEXPORT(ret_from_irq)
LONG_S s0, TI_REGS($28)
#ifdef CONFIG_PREEMPT
FEXPORT(ret_from_exception)
#else
b _ret_from_irq
#ifndef CONFIG_PREEMPT
FEXPORT(ret_from_exception)
preempt_stop
local_irq_disable # preempt stop
b __ret_from_irq
#endif
FEXPORT(_ret_from_irq)
FEXPORT(ret_from_irq)
LONG_S s0, TI_REGS($28)
FEXPORT(__ret_from_irq)
LONG_L t0, PT_STATUS(sp) # returning to kernel mode?
andi t0, t0, KU_USER
beqz t0, resume_kernel
Expand Down
47 changes: 47 additions & 0 deletions arch/mips/kernel/linux32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -736,3 +737,49 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs)
return do_fork(clone_flags, newsp, &regs, 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(&current->saved_sigmask, &sigsaved,
sizeof(sigsaved));
set_thread_flag(TIF_RESTORE_SIGMASK);
} else
sigprocmask(SIG_SETMASK, &sigsaved, NULL);
}

return error;
}
2 changes: 1 addition & 1 deletion arch/mips/kernel/scall64-64.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion arch/mips/kernel/scall64-n32.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
32 changes: 1 addition & 31 deletions arch/mips/kernel/signal-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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..
Expand Down
22 changes: 20 additions & 2 deletions arch/mips/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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];
Expand Down
39 changes: 30 additions & 9 deletions arch/mips/kernel/signal32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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>
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand All @@ -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];
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -581,7 +601,7 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
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));
Expand All @@ -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;

Expand Down Expand Up @@ -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;
Expand Down
11 changes: 7 additions & 4 deletions arch/mips/kernel/signal_n32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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 {
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit 463020c

Please sign in to comment.