forked from Minki/linux
Merge branch 'stable' of git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
* 'stable' of git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile: arch/tile: fix formatting bug in register dumps arch/tile: fix memcpy_fromio()/memcpy_toio() signatures arch/tile: Save and restore extra user state for tilegx arch/tile: Change struct sigcontext to be more useful arch/tile: finish const-ifying sys_execve()
This commit is contained in:
commit
8be7eb359d
@ -150,6 +150,9 @@
|
||||
/** Is the PROC_STATUS SPR supported? */
|
||||
#define CHIP_HAS_PROC_STATUS_SPR() 0
|
||||
|
||||
/** Is the DSTREAM_PF SPR supported? */
|
||||
#define CHIP_HAS_DSTREAM_PF() 0
|
||||
|
||||
/** Log of the number of mshims we have. */
|
||||
#define CHIP_LOG_NUM_MSHIMS() 2
|
||||
|
||||
|
@ -150,6 +150,9 @@
|
||||
/** Is the PROC_STATUS SPR supported? */
|
||||
#define CHIP_HAS_PROC_STATUS_SPR() 1
|
||||
|
||||
/** Is the DSTREAM_PF SPR supported? */
|
||||
#define CHIP_HAS_DSTREAM_PF() 0
|
||||
|
||||
/** Log of the number of mshims we have. */
|
||||
#define CHIP_LOG_NUM_MSHIMS() 2
|
||||
|
||||
|
@ -214,8 +214,9 @@ extern int compat_setup_rt_frame(int sig, struct k_sigaction *ka,
|
||||
struct compat_sigaction;
|
||||
struct compat_siginfo;
|
||||
struct compat_sigaltstack;
|
||||
long compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
|
||||
compat_uptr_t __user *envp);
|
||||
long compat_sys_execve(const char __user *path,
|
||||
const compat_uptr_t __user *argv,
|
||||
const compat_uptr_t __user *envp);
|
||||
long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
|
||||
struct compat_sigaction __user *oact,
|
||||
size_t sigsetsize);
|
||||
|
@ -164,22 +164,22 @@ static inline void _tile_writeq(u64 val, unsigned long addr)
|
||||
#define iowrite32 writel
|
||||
#define iowrite64 writeq
|
||||
|
||||
static inline void *memcpy_fromio(void *dst, void *src, int len)
|
||||
static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
|
||||
size_t len)
|
||||
{
|
||||
int x;
|
||||
BUG_ON((unsigned long)src & 0x3);
|
||||
for (x = 0; x < len; x += 4)
|
||||
*(u32 *)(dst + x) = readl(src + x);
|
||||
return dst;
|
||||
}
|
||||
|
||||
static inline void *memcpy_toio(void *dst, void *src, int len)
|
||||
static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
|
||||
size_t len)
|
||||
{
|
||||
int x;
|
||||
BUG_ON((unsigned long)dst & 0x3);
|
||||
for (x = 0; x < len; x += 4)
|
||||
writel(*(u32 *)(src + x), dst + x);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -103,6 +103,18 @@ struct thread_struct {
|
||||
/* Any other miscellaneous processor state bits */
|
||||
unsigned long proc_status;
|
||||
#endif
|
||||
#if !CHIP_HAS_FIXED_INTVEC_BASE()
|
||||
/* Interrupt base for PL0 interrupts */
|
||||
unsigned long interrupt_vector_base;
|
||||
#endif
|
||||
#if CHIP_HAS_TILE_RTF_HWM()
|
||||
/* Tile cache retry fifo high-water mark */
|
||||
unsigned long tile_rtf_hwm;
|
||||
#endif
|
||||
#if CHIP_HAS_DSTREAM_PF()
|
||||
/* Data stream prefetch control */
|
||||
unsigned long dstream_pf;
|
||||
#endif
|
||||
#ifdef CONFIG_HARDWALL
|
||||
/* Is this task tied to an activated hardwall? */
|
||||
struct hardwall_info *hardwall;
|
||||
|
@ -51,10 +51,7 @@ typedef uint_reg_t pt_reg_t;
|
||||
|
||||
/*
|
||||
* This struct defines the way the registers are stored on the stack during a
|
||||
* system call/exception. It should be a multiple of 8 bytes to preserve
|
||||
* normal stack alignment rules.
|
||||
*
|
||||
* Must track <sys/ucontext.h> and <sys/procfs.h>
|
||||
* system call or exception. "struct sigcontext" has the same shape.
|
||||
*/
|
||||
struct pt_regs {
|
||||
/* Saved main processor registers; 56..63 are special. */
|
||||
@ -80,11 +77,6 @@ struct pt_regs {
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/* Flag bits in pt_regs.flags */
|
||||
#define PT_FLAGS_DISABLE_IRQ 1 /* on return to kernel, disable irqs */
|
||||
#define PT_FLAGS_CALLER_SAVES 2 /* caller-save registers are valid */
|
||||
#define PT_FLAGS_RESTORE_REGS 4 /* restore callee-save regs on return */
|
||||
|
||||
#define PTRACE_GETREGS 12
|
||||
#define PTRACE_SETREGS 13
|
||||
#define PTRACE_GETFPREGS 14
|
||||
@ -101,6 +93,11 @@ struct pt_regs {
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/* Flag bits in pt_regs.flags */
|
||||
#define PT_FLAGS_DISABLE_IRQ 1 /* on return to kernel, disable irqs */
|
||||
#define PT_FLAGS_CALLER_SAVES 2 /* caller-save registers are valid */
|
||||
#define PT_FLAGS_RESTORE_REGS 4 /* restore callee-save regs on return */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#define instruction_pointer(regs) ((regs)->pc)
|
||||
|
@ -15,13 +15,21 @@
|
||||
#ifndef _ASM_TILE_SIGCONTEXT_H
|
||||
#define _ASM_TILE_SIGCONTEXT_H
|
||||
|
||||
/* NOTE: we can't include <linux/ptrace.h> due to #include dependencies. */
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
/* Must track <sys/ucontext.h> */
|
||||
#include <arch/abi.h>
|
||||
|
||||
/*
|
||||
* struct sigcontext has the same shape as struct pt_regs,
|
||||
* but is simplified since we know the fault is from userspace.
|
||||
*/
|
||||
struct sigcontext {
|
||||
struct pt_regs regs;
|
||||
uint_reg_t gregs[53]; /* General-purpose registers. */
|
||||
uint_reg_t tp; /* Aliases gregs[TREG_TP]. */
|
||||
uint_reg_t sp; /* Aliases gregs[TREG_SP]. */
|
||||
uint_reg_t lr; /* Aliases gregs[TREG_LR]. */
|
||||
uint_reg_t pc; /* Program counter. */
|
||||
uint_reg_t ics; /* In Interrupt Critical Section? */
|
||||
uint_reg_t faultnum; /* Fault number. */
|
||||
uint_reg_t pad[5];
|
||||
};
|
||||
|
||||
#endif /* _ASM_TILE_SIGCONTEXT_H */
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <asm-generic/signal.h>
|
||||
|
||||
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
|
||||
struct pt_regs;
|
||||
int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *);
|
||||
int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
|
||||
void do_signal(struct pt_regs *regs);
|
||||
|
@ -62,10 +62,12 @@ long sys_fork(void);
|
||||
long _sys_fork(struct pt_regs *regs);
|
||||
long sys_vfork(void);
|
||||
long _sys_vfork(struct pt_regs *regs);
|
||||
long sys_execve(char __user *filename, char __user * __user *argv,
|
||||
char __user * __user *envp);
|
||||
long _sys_execve(char __user *filename, char __user * __user *argv,
|
||||
char __user * __user *envp, struct pt_regs *regs);
|
||||
long sys_execve(const char __user *filename,
|
||||
const char __user *const __user *argv,
|
||||
const char __user *const __user *envp);
|
||||
long _sys_execve(const char __user *filename,
|
||||
const char __user *const __user *argv,
|
||||
const char __user *const __user *envp, struct pt_regs *regs);
|
||||
|
||||
/* kernel/signal.c */
|
||||
long sys_sigaltstack(const stack_t __user *, stack_t __user *);
|
||||
@ -86,10 +88,13 @@ int _sys_cmpxchg_badaddr(unsigned long address, struct pt_regs *);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
long compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
|
||||
compat_uptr_t __user *envp);
|
||||
long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
|
||||
compat_uptr_t __user *envp, struct pt_regs *regs);
|
||||
long compat_sys_execve(const char __user *path,
|
||||
const compat_uptr_t __user *argv,
|
||||
const compat_uptr_t __user *envp);
|
||||
long _compat_sys_execve(const char __user *path,
|
||||
const compat_uptr_t __user *argv,
|
||||
const compat_uptr_t __user *envp,
|
||||
struct pt_regs *regs);
|
||||
long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
|
||||
struct compat_sigaltstack __user *uoss_ptr);
|
||||
long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
|
||||
|
@ -408,6 +408,15 @@ static void save_arch_state(struct thread_struct *t)
|
||||
#if CHIP_HAS_PROC_STATUS_SPR()
|
||||
t->proc_status = __insn_mfspr(SPR_PROC_STATUS);
|
||||
#endif
|
||||
#if !CHIP_HAS_FIXED_INTVEC_BASE()
|
||||
t->interrupt_vector_base = __insn_mfspr(SPR_INTERRUPT_VECTOR_BASE_0);
|
||||
#endif
|
||||
#if CHIP_HAS_TILE_RTF_HWM()
|
||||
t->tile_rtf_hwm = __insn_mfspr(SPR_TILE_RTF_HWM);
|
||||
#endif
|
||||
#if CHIP_HAS_DSTREAM_PF()
|
||||
t->dstream_pf = __insn_mfspr(SPR_DSTREAM_PF);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void restore_arch_state(const struct thread_struct *t)
|
||||
@ -428,14 +437,14 @@ static void restore_arch_state(const struct thread_struct *t)
|
||||
#if CHIP_HAS_PROC_STATUS_SPR()
|
||||
__insn_mtspr(SPR_PROC_STATUS, t->proc_status);
|
||||
#endif
|
||||
#if !CHIP_HAS_FIXED_INTVEC_BASE()
|
||||
__insn_mtspr(SPR_INTERRUPT_VECTOR_BASE_0, t->interrupt_vector_base);
|
||||
#endif
|
||||
#if CHIP_HAS_TILE_RTF_HWM()
|
||||
/*
|
||||
* Clear this whenever we switch back to a process in case
|
||||
* the previous process was monkeying with it. Even if enabled
|
||||
* in CBOX_MSR1 via TILE_RTF_HWM_MIN, it's still just a
|
||||
* performance hint, so isn't worth a full save/restore.
|
||||
*/
|
||||
__insn_mtspr(SPR_TILE_RTF_HWM, 0);
|
||||
__insn_mtspr(SPR_TILE_RTF_HWM, t->tile_rtf_hwm);
|
||||
#endif
|
||||
#if CHIP_HAS_DSTREAM_PF()
|
||||
__insn_mtspr(SPR_DSTREAM_PF, t->dstream_pf);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -561,8 +570,9 @@ out:
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
|
||||
compat_uptr_t __user *envp, struct pt_regs *regs)
|
||||
long _compat_sys_execve(const char __user *path,
|
||||
const compat_uptr_t __user *argv,
|
||||
const compat_uptr_t __user *envp, struct pt_regs *regs)
|
||||
{
|
||||
long error;
|
||||
char *filename;
|
||||
@ -657,7 +667,7 @@ void show_regs(struct pt_regs *regs)
|
||||
regs->regs[51], regs->regs[52], regs->tp);
|
||||
pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr);
|
||||
#else
|
||||
for (i = 0; i < 52; i += 3)
|
||||
for (i = 0; i < 52; i += 4)
|
||||
pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT
|
||||
" r%-2d: "REGFMT" r%-2d: "REGFMT"\n",
|
||||
i, regs->regs[i], i+1, regs->regs[i+1],
|
||||
|
@ -61,13 +61,19 @@ int restore_sigcontext(struct pt_regs *regs,
|
||||
/* Always make any pending restarted system calls return -EINTR */
|
||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
||||
|
||||
/*
|
||||
* Enforce that sigcontext is like pt_regs, and doesn't mess
|
||||
* up our stack alignment rules.
|
||||
*/
|
||||
BUILD_BUG_ON(sizeof(struct sigcontext) != sizeof(struct pt_regs));
|
||||
BUILD_BUG_ON(sizeof(struct sigcontext) % 8 != 0);
|
||||
|
||||
for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
|
||||
err |= __get_user(((long *)regs)[i],
|
||||
&((long __user *)(&sc->regs))[i]);
|
||||
err |= __get_user(regs->regs[i], &sc->gregs[i]);
|
||||
|
||||
regs->faultnum = INT_SWINT_1_SIGRETURN;
|
||||
|
||||
err |= __get_user(*pr0, &sc->regs.regs[0]);
|
||||
err |= __get_user(*pr0, &sc->gregs[0]);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -112,8 +118,7 @@ int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
|
||||
int i, err = 0;
|
||||
|
||||
for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
|
||||
err |= __put_user(((long *)regs)[i],
|
||||
&((long __user *)(&sc->regs))[i]);
|
||||
err |= __put_user(regs->regs[i], &sc->gregs[i]);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -203,19 +208,17 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
* Set up registers for signal handler.
|
||||
* Registers that we don't modify keep the value they had from
|
||||
* user-space at the time we took the signal.
|
||||
* We always pass siginfo and mcontext, regardless of SA_SIGINFO,
|
||||
* since some things rely on this (e.g. glibc's debug/segfault.c).
|
||||
*/
|
||||
regs->pc = (unsigned long) ka->sa.sa_handler;
|
||||
regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
|
||||
regs->sp = (unsigned long) frame;
|
||||
regs->lr = restorer;
|
||||
regs->regs[0] = (unsigned long) usig;
|
||||
|
||||
if (ka->sa.sa_flags & SA_SIGINFO) {
|
||||
/* Need extra arguments, so mark to restore caller-saves. */
|
||||
regs->regs[1] = (unsigned long) &frame->info;
|
||||
regs->regs[2] = (unsigned long) &frame->uc;
|
||||
regs->flags |= PT_FLAGS_CALLER_SAVES;
|
||||
}
|
||||
regs->regs[1] = (unsigned long) &frame->info;
|
||||
regs->regs[2] = (unsigned long) &frame->uc;
|
||||
regs->flags |= PT_FLAGS_CALLER_SAVES;
|
||||
|
||||
/*
|
||||
* Notify any tracer that was single-stepping it.
|
||||
|
@ -175,7 +175,7 @@ static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt)
|
||||
pr_err(" <received signal %d>\n",
|
||||
frame->info.si_signo);
|
||||
}
|
||||
return &frame->uc.uc_mcontext.regs;
|
||||
return (struct pt_regs *)&frame->uc.uc_mcontext;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user