aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeonid Yegoshin <Leonid.Yegoshin@imgtec.com>2013-12-16 07:06:55 -0500
committerRalf Baechle <ralf@linux-mips.org>2014-03-26 18:09:18 -0400
commit6ebda44f366478d1eea180d93154e7d97b591f50 (patch)
tree88a32637a7ad46a690692a3603b369c4f9485515
parentde8974e3f76c00231cf6839797b4766d5a926ca3 (diff)
MIPS: kernel: {ftrace,kgdb}: Set correct address limit for cache flushes
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>
-rw-r--r--arch/mips/kernel/ftrace.c4
-rw-r--r--arch/mips/kernel/kgdb.c18
2 files changed, 21 insertions, 1 deletions
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c
index 185ba258361b..ddcc3500248d 100644
--- a/arch/mips/kernel/ftrace.c
+++ b/arch/mips/kernel/ftrace.c
@@ -90,6 +90,7 @@ static inline void ftrace_dyn_arch_init_insns(void)
90static int ftrace_modify_code(unsigned long ip, unsigned int new_code) 90static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
91{ 91{
92 int faulted; 92 int faulted;
93 mm_segment_t old_fs;
93 94
94 /* *(unsigned int *)ip = new_code; */ 95 /* *(unsigned int *)ip = new_code; */
95 safe_store_code(new_code, ip, faulted); 96 safe_store_code(new_code, ip, faulted);
@@ -97,7 +98,10 @@ static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
97 if (unlikely(faulted)) 98 if (unlikely(faulted))
98 return -EFAULT; 99 return -EFAULT;
99 100
101 old_fs = get_fs();
102 set_fs(get_ds());
100 flush_icache_range(ip, ip + 8); 103 flush_icache_range(ip, ip + 8);
104 set_fs(old_fs);
101 105
102 return 0; 106 return 0;
103} 107}
diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c
index fcaac2f132f0..7afcc2f22c0d 100644
--- a/arch/mips/kernel/kgdb.c
+++ b/arch/mips/kernel/kgdb.c
@@ -32,6 +32,7 @@
32#include <asm/cacheflush.h> 32#include <asm/cacheflush.h>
33#include <asm/processor.h> 33#include <asm/processor.h>
34#include <asm/sigcontext.h> 34#include <asm/sigcontext.h>
35#include <asm/uaccess.h>
35 36
36static struct hard_trap_info { 37static struct hard_trap_info {
37 unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */ 38 unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */
@@ -208,7 +209,14 @@ void arch_kgdb_breakpoint(void)
208 209
209static void kgdb_call_nmi_hook(void *ignored) 210static void kgdb_call_nmi_hook(void *ignored)
210{ 211{
212 mm_segment_t old_fs;
213
214 old_fs = get_fs();
215 set_fs(get_ds());
216
211 kgdb_nmicallback(raw_smp_processor_id(), NULL); 217 kgdb_nmicallback(raw_smp_processor_id(), NULL);
218
219 set_fs(old_fs);
212} 220}
213 221
214void kgdb_roundup_cpus(unsigned long flags) 222void kgdb_roundup_cpus(unsigned long flags)
@@ -282,6 +290,7 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd,
282 struct die_args *args = (struct die_args *)ptr; 290 struct die_args *args = (struct die_args *)ptr;
283 struct pt_regs *regs = args->regs; 291 struct pt_regs *regs = args->regs;
284 int trap = (regs->cp0_cause & 0x7c) >> 2; 292 int trap = (regs->cp0_cause & 0x7c) >> 2;
293 mm_segment_t old_fs;
285 294
286#ifdef CONFIG_KPROBES 295#ifdef CONFIG_KPROBES
287 /* 296 /*
@@ -296,11 +305,17 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd,
296 if (user_mode(regs)) 305 if (user_mode(regs))
297 return NOTIFY_DONE; 306 return NOTIFY_DONE;
298 307
308 /* Kernel mode. Set correct address limit */
309 old_fs = get_fs();
310 set_fs(get_ds());
311
299 if (atomic_read(&kgdb_active) != -1) 312 if (atomic_read(&kgdb_active) != -1)
300 kgdb_nmicallback(smp_processor_id(), regs); 313 kgdb_nmicallback(smp_processor_id(), regs);
301 314
302 if (kgdb_handle_exception(trap, compute_signal(trap), cmd, regs)) 315 if (kgdb_handle_exception(trap, compute_signal(trap), cmd, regs)) {
316 set_fs(old_fs);
303 return NOTIFY_DONE; 317 return NOTIFY_DONE;
318 }
304 319
305 if (atomic_read(&kgdb_setting_breakpoint)) 320 if (atomic_read(&kgdb_setting_breakpoint))
306 if ((trap == 9) && (regs->cp0_epc == (unsigned long)breakinst)) 321 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,
310 local_irq_enable(); 325 local_irq_enable();
311 __flush_cache_all(); 326 __flush_cache_all();
312 327
328 set_fs(old_fs);
313 return NOTIFY_STOP; 329 return NOTIFY_STOP;
314} 330}
315 331