diff options
Diffstat (limited to 'arch/sh/kernel/process.c')
-rw-r--r-- | arch/sh/kernel/process.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index e7607366ac4..6b4f5748d0b 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -7,7 +7,7 @@ * * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima * Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC - * Copyright (C) 2002 - 2006 Paul Mundt + * Copyright (C) 2002 - 2007 Paul Mundt */ #include <linux/module.h> #include <linux/mm.h> @@ -15,8 +15,12 @@ #include <linux/pm.h> #include <linux/kallsyms.h> #include <linux/kexec.h> +#include <linux/kdebug.h> +#include <linux/tick.h> #include <asm/uaccess.h> #include <asm/mmu_context.h> +#include <asm/pgalloc.h> +#include <asm/system.h> #include <asm/ubc.h> static int hlt_counter; @@ -57,12 +61,15 @@ void cpu_idle(void) if (!idle) idle = default_idle; + tick_nohz_stop_sched_tick(); while (!need_resched()) idle(); + tick_nohz_restart_sched_tick(); preempt_enable_no_resched(); schedule(); preempt_disable(); + check_pgt_cache(); } } @@ -299,7 +306,8 @@ static void ubc_set_tracing(int asid, unsigned long pc) ctrl_outl(0, UBC_BAMRA); if (current_cpu_data.type == CPU_SH7729 || - current_cpu_data.type == CPU_SH7710) { + current_cpu_data.type == CPU_SH7710 || + current_cpu_data.type == CPU_SH7712) { ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA); ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR); } else { @@ -493,7 +501,11 @@ asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5, struct pt_regs *regs = RELOC_HIDE(&__regs, 0); /* Rewind */ - regs->pc -= 2; + regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); + + if (notify_die(DIE_TRAP, "debug trap", regs, 0, regs->tra & 0xff, + SIGTRAP) == NOTIFY_STOP) + return; force_sig(SIGTRAP, current); } @@ -508,7 +520,11 @@ asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5, struct pt_regs *regs = RELOC_HIDE(&__regs, 0); /* Rewind */ - regs->pc -= 2; + regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); + + if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff, + SIGTRAP) == NOTIFY_STOP) + return; #ifdef CONFIG_BUG if (__kernel_text_address(instruction_pointer(regs))) { |