]> rtime.felk.cvut.cz Git - lisovros/linux_canprio.git/commitdiff
Merge branch 'stable' of git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 16 Sep 2010 19:54:54 +0000 (12:54 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 16 Sep 2010 19:54:54 +0000 (12:54 -0700)
* '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()

12 files changed:
arch/tile/include/arch/chip_tile64.h
arch/tile/include/arch/chip_tilepro.h
arch/tile/include/asm/compat.h
arch/tile/include/asm/io.h
arch/tile/include/asm/processor.h
arch/tile/include/asm/ptrace.h
arch/tile/include/asm/sigcontext.h
arch/tile/include/asm/signal.h
arch/tile/include/asm/syscalls.h
arch/tile/kernel/process.c
arch/tile/kernel/signal.c
arch/tile/kernel/stack.c

index 1246573be59ee78b872ed5d8fa5d583cf16860ac..261aaba092d4bb424d336caa645b222a1fdb1068 100644 (file)
 /** 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
 
index e864c47fc89cce6cd7c366784e8d76d22a43e280..70017699a74ce0e37e30d0c7c8e62865e9577e3b 100644 (file)
 /** 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
 
index 345d81ce44bb81f51c47ebc0cdc8559a4f00b53a..8b60ec8b2d194f6e352df18eba598e3a61ef52f3 100644 (file)
@@ -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);
index 8c95bef3fa45a185a1ec5610bc7a1c21e6f96c13..ee43328713abf2ace9f76e885e9e26ce7b615b3a 100644 (file)
@@ -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;
 }
 
 /*
index d942d09b252e4012d251d6d09eaa1af6c7df7c3f..ccd5f84256886c7526edd78bc58ab621f14ef2ac 100644 (file)
@@ -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;
index acdae814e0161b967f6289e265f6aad1516b2aac..4a02bb07397993a2eb025ae7cd79caf618ae03d6 100644 (file)
@@ -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)
index 7cd7672e3ad4043072a6b6ac9c393491426f08a1..5e2d03336f5335ae99151a383a855e5db7cae6b0 100644 (file)
 #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 */
index eb0253f32202c0b52b65012b7c4a8c839aae47dc..c1ee1d61d44ca8a07c504b9af425df3a9c7185c7 100644 (file)
@@ -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);
index af165a74537f84ff1f377ce22951848bba58d9e0..ce99ffefeacff351c5523d574581e1092d57ca06 100644 (file)
@@ -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,
index 985cc28c74c5696f91adcf82d6347439999bfa41..84c29111756c2212f02cd5bc841691c1cc0a0fd9 100644 (file)
@@ -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],
index 45b66a3c991ffbc79a7f93e3f00543e50b20de8a..ce183aa1492c7abfaadfca95d54ec76bddc11455 100644 (file)
@@ -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.
index 38a68b0b45813474a791f18aabaa35eb33b8a38a..ea2e0ce28380a2d3fa59391cfc02cb4ca0022f1e 100644 (file)
@@ -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;
 }