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>
This commit is contained in:
parent
de8974e3f7
commit
6ebda44f36
@ -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)
|
static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
|
||||||
{
|
{
|
||||||
int faulted;
|
int faulted;
|
||||||
|
mm_segment_t old_fs;
|
||||||
|
|
||||||
/* *(unsigned int *)ip = new_code; */
|
/* *(unsigned int *)ip = new_code; */
|
||||||
safe_store_code(new_code, ip, faulted);
|
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))
|
if (unlikely(faulted))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
old_fs = get_fs();
|
||||||
|
set_fs(get_ds());
|
||||||
flush_icache_range(ip, ip + 8);
|
flush_icache_range(ip, ip + 8);
|
||||||
|
set_fs(old_fs);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/sigcontext.h>
|
#include <asm/sigcontext.h>
|
||||||
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
static struct hard_trap_info {
|
static struct hard_trap_info {
|
||||||
unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */
|
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)
|
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);
|
kgdb_nmicallback(raw_smp_processor_id(), NULL);
|
||||||
|
|
||||||
|
set_fs(old_fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kgdb_roundup_cpus(unsigned long flags)
|
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 die_args *args = (struct die_args *)ptr;
|
||||||
struct pt_regs *regs = args->regs;
|
struct pt_regs *regs = args->regs;
|
||||||
int trap = (regs->cp0_cause & 0x7c) >> 2;
|
int trap = (regs->cp0_cause & 0x7c) >> 2;
|
||||||
|
mm_segment_t old_fs;
|
||||||
|
|
||||||
#ifdef CONFIG_KPROBES
|
#ifdef CONFIG_KPROBES
|
||||||
/*
|
/*
|
||||||
@ -296,11 +305,17 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd,
|
|||||||
if (user_mode(regs))
|
if (user_mode(regs))
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
|
|
||||||
|
/* Kernel mode. Set correct address limit */
|
||||||
|
old_fs = get_fs();
|
||||||
|
set_fs(get_ds());
|
||||||
|
|
||||||
if (atomic_read(&kgdb_active) != -1)
|
if (atomic_read(&kgdb_active) != -1)
|
||||||
kgdb_nmicallback(smp_processor_id(), regs);
|
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;
|
return NOTIFY_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
if (atomic_read(&kgdb_setting_breakpoint))
|
if (atomic_read(&kgdb_setting_breakpoint))
|
||||||
if ((trap == 9) && (regs->cp0_epc == (unsigned long)breakinst))
|
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();
|
local_irq_enable();
|
||||||
__flush_cache_all();
|
__flush_cache_all();
|
||||||
|
|
||||||
|
set_fs(old_fs);
|
||||||
return NOTIFY_STOP;
|
return NOTIFY_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user