MIPS: kernel: {ftrace,kgdb}: Set correct address limit for cache flushes
authorLeonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Mon, 16 Dec 2013 12:06:55 +0000 (12:06 +0000)
committerRalf Baechle <ralf@linux-mips.org>
Wed, 26 Mar 2014 22:09:18 +0000 (23:09 +0100)
When flushing the icache, make sure the address limit is correct
so the appropriate 'cache' instruction will be used. This has no
impact on cores operating in non-eva mode. However, when EVA is
enabled, we ensure that 'cache' will be used instead of 'cachee'.

Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
arch/mips/kernel/ftrace.c
arch/mips/kernel/kgdb.c

index 185ba25..ddcc350 100644 (file)
@@ -90,6 +90,7 @@ static inline void ftrace_dyn_arch_init_insns(void)
 static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
 {
        int faulted;
+       mm_segment_t old_fs;
 
        /* *(unsigned int *)ip = new_code; */
        safe_store_code(new_code, ip, faulted);
@@ -97,7 +98,10 @@ static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
        if (unlikely(faulted))
                return -EFAULT;
 
+       old_fs = get_fs();
+       set_fs(get_ds());
        flush_icache_range(ip, ip + 8);
+       set_fs(old_fs);
 
        return 0;
 }
index fcaac2f..7afcc2f 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/cacheflush.h>
 #include <asm/processor.h>
 #include <asm/sigcontext.h>
+#include <asm/uaccess.h>
 
 static struct hard_trap_info {
        unsigned char tt;       /* Trap type code for MIPS R3xxx and R4xxx */
@@ -208,7 +209,14 @@ void arch_kgdb_breakpoint(void)
 
 static void kgdb_call_nmi_hook(void *ignored)
 {
+       mm_segment_t old_fs;
+
+       old_fs = get_fs();
+       set_fs(get_ds());
+
        kgdb_nmicallback(raw_smp_processor_id(), NULL);
+
+       set_fs(old_fs);
 }
 
 void kgdb_roundup_cpus(unsigned long flags)
@@ -282,6 +290,7 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd,
        struct die_args *args = (struct die_args *)ptr;
        struct pt_regs *regs = args->regs;
        int trap = (regs->cp0_cause & 0x7c) >> 2;
+       mm_segment_t old_fs;
 
 #ifdef CONFIG_KPROBES
        /*
@@ -296,11 +305,17 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd,
        if (user_mode(regs))
                return NOTIFY_DONE;
 
+       /* Kernel mode. Set correct address limit */
+       old_fs = get_fs();
+       set_fs(get_ds());
+
        if (atomic_read(&kgdb_active) != -1)
                kgdb_nmicallback(smp_processor_id(), regs);
 
-       if (kgdb_handle_exception(trap, compute_signal(trap), cmd, regs))
+       if (kgdb_handle_exception(trap, compute_signal(trap), cmd, regs)) {
+               set_fs(old_fs);
                return NOTIFY_DONE;
+       }
 
        if (atomic_read(&kgdb_setting_breakpoint))
                if ((trap == 9) && (regs->cp0_epc == (unsigned long)breakinst))
@@ -310,6 +325,7 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd,
        local_irq_enable();
        __flush_cache_all();
 
+       set_fs(old_fs);
        return NOTIFY_STOP;
 }