···160160static inline void *161161get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)162162{163163- unsigned long sp, almask;163163+ unsigned long sp;164164165165 /* Default to using normal stack */166166 sp = regs->regs[29];···176176 if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))177177 sp = current->sas_ss_sp + current->sas_ss_size;178178179179- if (PLAT_TRAMPOLINE_STUFF_LINE)180180- almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1);181181- else182182- almask = ALMASK;179179+ return (void *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK));180180+}183181184184- return (void *)((sp - frame_size) & almask);182182+static inline int install_sigtramp(unsigned int __user *tramp,183183+ unsigned int syscall)184184+{185185+ int err;186186+187187+ /*188188+ * Set up the return code ...189189+ *190190+ * li v0, __NR__foo_sigreturn191191+ * syscall192192+ */193193+194194+ err = __put_user(0x24020000 + syscall, tramp + 0);195195+ err |= __put_user(0x0000000c , tramp + 1);196196+ if (ICACHE_REFILLS_WORKAROUND_WAR) {197197+ err |= __put_user(0, tramp + 2);198198+ err |= __put_user(0, tramp + 3);199199+ err |= __put_user(0, tramp + 4);200200+ err |= __put_user(0, tramp + 5);201201+ err |= __put_user(0, tramp + 6);202202+ err |= __put_user(0, tramp + 7);203203+ }204204+ flush_cache_sigtramp((unsigned long) tramp);205205+206206+ return err;185207}
+27-32
arch/mips/kernel/signal.c
···88 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.99 */1010#include <linux/config.h>1111+#include <linux/cache.h>1112#include <linux/sched.h>1213#include <linux/mm.h>1314#include <linux/personality.h>···3130#include <asm/uaccess.h>3231#include <asm/ucontext.h>3332#include <asm/cpu-features.h>3333+#include <asm/war.h>34343535#include "signal-common.h"3636···159157 return do_sigaltstack(uss, uoss, usp);160158}161159162162-#if PLAT_TRAMPOLINE_STUFF_LINE163163-#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))164164-#else165165-#define __tramp166166-#endif167167-160160+/*161161+ * Horribly complicated - with the bloody RM9000 workarounds enabled162162+ * the signal trampolines is moving to the end of the structure so we can163163+ * increase the alignment without breaking software compatibility.164164+ */168165#ifdef CONFIG_TRAD_SIGNALS169166struct sigframe {170167 u32 sf_ass[4]; /* argument save space for o32 */171171- u32 sf_code[2] __tramp; /* signal trampoline */172172- struct sigcontext sf_sc __tramp;168168+#if ICACHE_REFILLS_WORKAROUND_WAR169169+ u32 sf_pad[2];170170+#else171171+ u32 sf_code[2]; /* signal trampoline */172172+#endif173173+ struct sigcontext sf_sc;173174 sigset_t sf_mask;175175+#if ICACHE_REFILLS_WORKAROUND_WAR176176+ u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */177177+#endif174178};175179#endif176180177181struct rt_sigframe {178182 u32 rs_ass[4]; /* argument save space for o32 */179179- u32 rs_code[2] __tramp; /* signal trampoline */180180- struct siginfo rs_info __tramp;183183+#if ICACHE_REFILLS_WORKAROUND_WAR184184+ u32 rs_pad[2];185185+#else186186+ u32 rs_code[2]; /* signal trampoline */187187+#endif188188+ struct siginfo rs_info;181189 struct ucontext rs_uc;190190+#if ICACHE_REFILLS_WORKAROUND_WAR191191+ u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */192192+#endif182193};183194184195#ifdef CONFIG_TRAD_SIGNALS···288273 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))289274 goto give_sigsegv;290275291291- /*292292- * Set up the return code ...293293- *294294- * li v0, __NR_sigreturn295295- * syscall296296- */297297- if (PLAT_TRAMPOLINE_STUFF_LINE)298298- __clear_user(frame->sf_code, PLAT_TRAMPOLINE_STUFF_LINE);299299- err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0);300300- err |= __put_user(0x0000000c , frame->sf_code + 1);301301- flush_cache_sigtramp((unsigned long) frame->sf_code);276276+ install_sigtramp(frame->sf_code, __NR_sigreturn);302277303278 err |= setup_sigcontext(regs, &frame->sf_sc);304279 err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));···334329 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))335330 goto give_sigsegv;336331337337- /*338338- * Set up the return code ...339339- *340340- * li v0, __NR_rt_sigreturn341341- * syscall342342- */343343- if (PLAT_TRAMPOLINE_STUFF_LINE)344344- __clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);345345- err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0);346346- err |= __put_user(0x0000000c , frame->rs_code + 1);347347- flush_cache_sigtramp((unsigned long) frame->rs_code);332332+ install_sigtramp(frame->rs_code, __NR_rt_sigreturn);348333349334 /* Create siginfo. */350335 err |= copy_siginfo_to_user(&frame->rs_info, info);
+16
arch/mips/kernel/signal32.c
···77 * Copyright (C) 1994 - 2000 Ralf Baechle88 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.99 */1010+#include <linux/cache.h>1011#include <linux/sched.h>1112#include <linux/mm.h>1213#include <linux/smp.h>···3130#include <asm/ucontext.h>3231#include <asm/system.h>3332#include <asm/fpu.h>3333+#include <asm/war.h>34343535#define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3)3636···394392395393struct sigframe {396394 u32 sf_ass[4]; /* argument save space for o32 */395395+#if ICACHE_REFILLS_WORKAROUND_WAR396396+ u32 sf_pad[2];397397+#else397398 u32 sf_code[2]; /* signal trampoline */399399+#endif398400 struct sigcontext32 sf_sc;399401 sigset_t sf_mask;402402+#if ICACHE_REFILLS_WORKAROUND_WAR403403+ u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */404404+#endif400405};401406402407struct rt_sigframe32 {403408 u32 rs_ass[4]; /* argument save space for o32 */409409+#if ICACHE_REFILLS_WORKAROUND_WAR410410+ u32 rs_pad[2];411411+#else404412 u32 rs_code[2]; /* signal trampoline */413413+#endif405414 compat_siginfo_t rs_info;406415 struct ucontext32 rs_uc;416416+#if ICACHE_REFILLS_WORKAROUND_WAR417417+ u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */418418+#endif407419};408420409421int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from)
+13-19
arch/mips/kernel/signal_n32.c
···1515 * along with this program; if not, write to the Free Software1616 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.1717 */1818+#include <linux/cache.h>1919+#include <linux/sched.h>1820#include <linux/sched.h>1921#include <linux/mm.h>2022#include <linux/smp.h>···3836#include <asm/system.h>3937#include <asm/fpu.h>4038#include <asm/cpu-features.h>3939+#include <asm/war.h>41404241#include "signal-common.h"4342···6562 sigset_t uc_sigmask; /* mask last for extensibility */6663};67646868-#if PLAT_TRAMPOLINE_STUFF_LINE6969-#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))7070-#else7171-#define __tramp7272-#endif7373-7465struct rt_sigframe_n32 {7566 u32 rs_ass[4]; /* argument save space for o32 */7676- u32 rs_code[2] __tramp; /* signal trampoline */7777- struct siginfo rs_info __tramp;6767+#if ICACHE_REFILLS_WORKAROUND_WAR6868+ u32 rs_pad[2];6969+#else7070+ u32 rs_code[2]; /* signal trampoline */7171+#endif7272+ struct siginfo rs_info;7873 struct ucontextn32 rs_uc;7474+#if ICACHE_REFILLS_WORKAROUND_WAR7575+ u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */7676+#endif7977};80788179save_static_function(sysn32_rt_sigreturn);···141137 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))142138 goto give_sigsegv;143139144144- /*145145- * Set up the return code ...146146- *147147- * li v0, __NR_rt_sigreturn148148- * syscall149149- */150150- if (PLAT_TRAMPOLINE_STUFF_LINE)151151- __clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);152152- err |= __put_user(0x24020000 + __NR_N32_rt_sigreturn, frame->rs_code + 0);153153- err |= __put_user(0x0000000c , frame->rs_code + 1);154154- flush_cache_sigtramp((unsigned long) frame->rs_code);140140+ install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn);155141156142 /* Create siginfo. */157143 err |= copy_siginfo_to_user(&frame->rs_info, info);
-11
include/asm-mips/cpu-features.h
···109109#define cpu_has_dsp (cpu_data[0].ases & MIPS_ASE_DSP)110110#endif111111112112-/*113113- * Certain CPUs may throw bizarre exceptions if not the whole cacheline114114- * contains valid instructions. For these we ensure proper alignment of115115- * signal trampolines and pad them to the size of a full cache lines with116116- * nops. This is also used in structure definitions so can't be a test macro117117- * like the others.118118- */119119-#ifndef PLAT_TRAMPOLINE_STUFF_LINE120120-#define PLAT_TRAMPOLINE_STUFF_LINE 0UL121121-#endif122122-123112#ifdef CONFIG_32BIT124113# ifndef cpu_has_nofpuex125114# define cpu_has_nofpuex (cpu_data[0].options & MIPS_CPU_NOFPUEX)
-6
include/asm-mips/mach-ja/cpu-feature-overrides.h
···3737#define cpu_icache_line_size() 323838#define cpu_scache_line_size() 3239394040-/*4141- * On the RM9000 we need to ensure that I-cache lines being fetches only4242- * contain valid instructions are funny things will happen.4343- */4444-#define PLAT_TRAMPOLINE_STUFF_LINE 32UL4545-4640#endif /* __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H */
···4040#define cpu_icache_line_size() 324141#define cpu_scache_line_size() 3242424343-/*4444- * On the RM9000 we need to ensure that I-cache lines being fetches only4545- * contain valid instructions are funny things will happen.4646- */4747-#define PLAT_TRAMPOLINE_STUFF_LINE 32UL4848-4943#endif /* __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H */
···3737#define cpu_icache_line_size() 323838#define cpu_scache_line_size() 3239394040-/*4141- * On the RM9000 we need to ensure that I-cache lines being fetches only4242- * contain valid instructions are funny things will happen.4343- */4444-#define PLAT_TRAMPOLINE_STUFF_LINE 32UL4545-4640#endif /* __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H */
+14
include/asm-mips/war.h
···177177#endif178178179179/*180180+ * The RM9000 has a bug (though PMC-Sierra opposes it being called that)181181+ * where invalid instructions in the same I-cache line worth of instructions182182+ * being fetched may case spurious exceptions.183183+ */184184+#if defined(CONFIG_MOMENCO_JAGUAR_ATX) || defined(CONFIG_MOMENCO_OCELOT_3) || \185185+ defined(CONFIG_PMC_YOSEMITE)186186+#define ICACHE_REFILLS_WORKAROUND_WAR 1187187+#endif188188+189189+190190+/*180191 * ON the R10000 upto version 2.6 (not sure about 2.7) there is a bug that181192 * may cause ll / sc and lld / scd sequences to execute non-atomically.182193 */···198187/*199188 * Workarounds default to off200189 */190190+#ifndef ICACHE_REFILLS_WORKAROUND_WAR191191+#define ICACHE_REFILLS_WORKAROUND_WAR 0192192+#endif201193#ifndef R4600_V1_INDEX_ICACHEOP_WAR202194#define R4600_V1_INDEX_ICACHEOP_WAR 0203195#endif