From ced918eb748ce30b3aace549fd17540e40ffdca0 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 17 Feb 2010 16:47:10 +0000 Subject: i8253: Convert i8253_lock to raw_spinlock i8253_lock needs to be a real spinlock in preempt-rt, i.e. it can not be converted to a sleeping lock. Convert it to raw_spinlock and fix up all users. Signed-off-by: Thomas Gleixner Acked-by: Ralf Baechle Acked-by: Dmitry Torokhov Acked-by: Takashi Iwai Cc: Jens Axboe LKML-Reference: <20100217163751.030764372@linutronix.de> --- arch/mips/kernel/i8253.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c index ed5c441615e4..94794062a177 100644 --- a/arch/mips/kernel/i8253.c +++ b/arch/mips/kernel/i8253.c @@ -15,7 +15,7 @@ #include #include -DEFINE_SPINLOCK(i8253_lock); +DEFINE_RAW_SPINLOCK(i8253_lock); EXPORT_SYMBOL(i8253_lock); /* @@ -26,7 +26,7 @@ EXPORT_SYMBOL(i8253_lock); static void init_pit_timer(enum clock_event_mode mode, struct clock_event_device *evt) { - spin_lock(&i8253_lock); + raw_spin_lock(&i8253_lock); switch(mode) { case CLOCK_EVT_MODE_PERIODIC: @@ -55,7 +55,7 @@ static void init_pit_timer(enum clock_event_mode mode, /* Nothing to do here */ break; } - spin_unlock(&i8253_lock); + raw_spin_unlock(&i8253_lock); } /* @@ -65,10 +65,10 @@ static void init_pit_timer(enum clock_event_mode mode, */ static int pit_next_event(unsigned long delta, struct clock_event_device *evt) { - spin_lock(&i8253_lock); + raw_spin_lock(&i8253_lock); outb_p(delta & 0xff , PIT_CH0); /* LSB */ outb(delta >> 8 , PIT_CH0); /* MSB */ - spin_unlock(&i8253_lock); + raw_spin_unlock(&i8253_lock); return 0; } @@ -137,7 +137,7 @@ static cycle_t pit_read(struct clocksource *cs) static int old_count; static u32 old_jifs; - spin_lock_irqsave(&i8253_lock, flags); + raw_spin_lock_irqsave(&i8253_lock, flags); /* * Although our caller may have the read side of xtime_lock, * this is now a seqlock, and we are cheating in this routine @@ -183,7 +183,7 @@ static cycle_t pit_read(struct clocksource *cs) old_count = count; old_jifs = jifs; - spin_unlock_irqrestore(&i8253_lock, flags); + raw_spin_unlock_irqrestore(&i8253_lock, flags); count = (LATCH - 1) - count; -- cgit v1.2.3 From ce384d83d00ee457c3931d3fdb9fa2c38e345a3c Mon Sep 17 00:00:00 2001 From: Yury Polyanskiy Date: Mon, 26 Apr 2010 00:53:10 -0400 Subject: MIPS: die() does not call die notifier chain The MIPS implementation of die() forgets to call notify_die() and thus notifiers registered via register_die_notifier() are not called. This results in kgdb not being activated on exceptions. The only subtlety is that notify_die declares its regs argument w/o const, so the const had to be removed from mips die() as well. [Ralf: Fixed build error for SGI IP22 and IP28 platforms.] Signed-off-by: Yury Polyanskiy Cc: linux-mips@linux-mips.org Patchworks: http://patchwork.linux-mips.org/patch/1142/ Acked-by: Jason Wessel Signed-off-by: Ralf Baechle --- --- arch/mips/kernel/traps.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 1a4dd657ccb9..36460c7b7cc8 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -352,9 +352,10 @@ void show_registers(const struct pt_regs *regs) static DEFINE_SPINLOCK(die_lock); -void __noreturn die(const char * str, const struct pt_regs * regs) +void __noreturn die(const char * str, struct pt_regs * regs) { static int die_counter; + int sig = SIGSEGV; #ifdef CONFIG_MIPS_MT_SMTC unsigned long dvpret = dvpe(); #endif /* CONFIG_MIPS_MT_SMTC */ @@ -365,6 +366,10 @@ void __noreturn die(const char * str, const struct pt_regs * regs) #ifdef CONFIG_MIPS_MT_SMTC mips_mt_regdump(dvpret); #endif /* CONFIG_MIPS_MT_SMTC */ + + if (notify_die(DIE_OOPS, str, regs, 0, current->thread.trap_no, SIGSEGV) == NOTIFY_STOP) + sig = 0; + printk("%s[#%d]:\n", str, ++die_counter); show_registers(regs); add_taint(TAINT_DIE); @@ -379,7 +384,7 @@ void __noreturn die(const char * str, const struct pt_regs * regs) panic("Fatal exception"); } - do_exit(SIGSEGV); + do_exit(sig); } extern struct exception_table_entry __start___dbe_table[]; -- cgit v1.2.3 From 4f81b01a30ffb338068d611e27da18c08db55464 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 27 Apr 2010 22:53:30 +0200 Subject: MIPS: Use CKSEG1ADDR for uncached handler "MIPS: Calculate proper ebase value for 64-bit kernels" 9af43ea080dd5d6c7b34f38261780e5dd43537bc (lmo) rsp. f6be75d03c8870be91e6e2a195648ece04b6bb16 (kernel.org) broke some 64-bit MIPS systems. Before this we were using XKPHYS/cached as ebase and computed the uncached xphsys/unchached address for that area. After that commit ebase became a 32-bit compat address and convert does not work anymore. We now should use CKSEG1 for this. CKSEG1ADDR does just that in 32-bit and 64-bit. Signed-off-by: Sebastian Andrzej Siewior To: Ralf Baechle Patchwork: http://patchwork.linux-mips.org/patch/1149/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/traps.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 36460c7b7cc8..d612c6dcb746 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1562,12 +1562,7 @@ static char panic_null_cerr[] __cpuinitdata = void __cpuinit set_uncached_handler(unsigned long offset, void *addr, unsigned long size) { -#ifdef CONFIG_32BIT - unsigned long uncached_ebase = KSEG1ADDR(ebase); -#endif -#ifdef CONFIG_64BIT - unsigned long uncached_ebase = TO_UNCAC(ebase); -#endif + unsigned long uncached_ebase = CKSEG1ADDR(ebase); if (!addr) panic(panic_null_cerr); -- cgit v1.2.3 From 46afb8296c2494bfce17064124b253eb9b176ef9 Mon Sep 17 00:00:00 2001 From: Chandrakala Chavva Date: Mon, 10 May 2010 17:11:54 -0700 Subject: MIPS: N32: Use compat version for sys_ppoll. The sys_ppoll() takes struct 'struct timespec'. This is different for the N32 and N64 ABIs. Use the compat version to do the proper conversions. Signed-off-by: David Daney To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1210/ Signed-off-by: Ralf Baechle --- --- arch/mips/kernel/scall64-n32.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 44337ba03717..a5297e2a353a 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -385,7 +385,7 @@ EXPORT(sysn32_call_table) PTR sys_fchmodat PTR sys_faccessat PTR compat_sys_pselect6 - PTR sys_ppoll /* 6265 */ + PTR compat_sys_ppoll /* 6265 */ PTR sys_unshare PTR sys_splice PTR sys_sync_file_range -- cgit v1.2.3 From dcc7871128e99458ca86186b7bc8bf27ff0c47b5 Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:21 -0500 Subject: kgdb: core changes to support kdb These are the minimum changes to the kgdb core in order to enable an API to connect a new front end (kdb) to the debug core. This patch introduces the dbg_kdb_mode variable controls where the user level I/O is routed. It will be routed to the gdbstub (kgdb) or to the kdb front end which is a simple shell available over the kgdboc connection. You can switch back and forth between kdb or the gdb stub mode of operation dynamically. From gdb stub mode you can blindly type "$3#33", or from the kdb mode you can enter "kgdb" to switch to the gdb stub. The logic in the debug core depends on kdb to look for the typical gdb connection sequences and return immediately with KGDB_PASS_EVENT if a gdb serial command sequence is detected. That should allow a reasonably seamless transition between kdb -> gdb without leaving the kernel exception state. The two gdb serial queries that kdb is responsible for detecting are the "?" and "qSupported" packets. CC: Ingo Molnar Signed-off-by: Jason Wessel Acked-by: Martin Hicks --- arch/mips/kernel/kgdb.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index 50c9bb880667..6ed4c83c869b 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c @@ -180,6 +180,11 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) *(ptr++) = regs->cp0_epc; } +void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) +{ + regs->cp0_epc = pc; +} + /* * Calls linux_debug_hook before the kernel dies. If KGDB is enabled, * then try to fall into the debugger -- cgit v1.2.3 From 5dd11d5d47d248850c58292513f0e164ba98b01e Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:26 -0500 Subject: mips,kgdb: kdb low level trap catch and stack trace The only way the debugger can handle a trap in inside rcu_lock, notify_die, or atomic_notifier_call_chain without a recursive fault is to have a low level "first opportunity handler" do_trap_or_bp() handler. Generally this will be something the vast majority of folks will not need, but for those who need it, it is added as a kernel .config option called KGDB_LOW_LEVEL_TRAP. Also added was a die notification for oops such that kdb can catch an oops for analysis. There appeared to be no obvious way to pass the struct pt_regs from the original exception back to the stack back tracer, so a special case was added to show_stack() for when kdb is active because you generally desire to generally look at the back trace of the original exception. Signed-off-by: Jason Wessel Acked-by: Ralf Baechle --- arch/mips/kernel/kgdb.c | 22 +++++++++++++++++++++- arch/mips/kernel/traps.c | 13 +++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index 6ed4c83c869b..9b78ff6e9b84 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c @@ -203,7 +203,7 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, if (atomic_read(&kgdb_active) != -1) kgdb_nmicallback(smp_processor_id(), regs); - if (kgdb_handle_exception(trap, compute_signal(trap), 0, regs)) + if (kgdb_handle_exception(trap, compute_signal(trap), cmd, regs)) return NOTIFY_DONE; if (atomic_read(&kgdb_setting_breakpoint)) @@ -217,6 +217,26 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, return NOTIFY_STOP; } +#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP +int kgdb_ll_trap(int cmd, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .str = str, + .err = err, + .trapnr = trap, + .signr = sig, + + }; + + if (!kgdb_io_module_registered) + return NOTIFY_DONE; + + return kgdb_mips_notify(NULL, cmd, &args); +} +#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ + static struct notifier_block kgdb_notifier = { .notifier_call = kgdb_mips_notify, }; diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index d612c6dcb746..950bde8813fc 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -185,6 +186,11 @@ void show_stack(struct task_struct *task, unsigned long *sp) regs.regs[29] = task->thread.reg29; regs.regs[31] = 0; regs.cp0_epc = task->thread.reg31; +#ifdef CONFIG_KGDB_KDB + } else if (atomic_read(&kgdb_active) != -1 && + kdb_current_regs) { + memcpy(®s, kdb_current_regs, sizeof(regs)); +#endif /* CONFIG_KGDB_KDB */ } else { prepare_frametrace(®s); } @@ -360,6 +366,8 @@ void __noreturn die(const char * str, struct pt_regs * regs) unsigned long dvpret = dvpe(); #endif /* CONFIG_MIPS_MT_SMTC */ + notify_die(DIE_OOPS, str, (struct pt_regs *)regs, SIGSEGV, 0, 0); + console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); @@ -704,6 +712,11 @@ static void do_trap_or_bp(struct pt_regs *regs, unsigned int code, siginfo_t info; char b[40]; +#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP + if (kgdb_ll_trap(DIE_TRAP, str, regs, code, 0, 0) == NOTIFY_STOP) + return; +#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ + if (notify_die(DIE_TRAP, str, regs, code, 0, 0) == NOTIFY_STOP) return; -- cgit v1.2.3 From ed1bbdefc39477a1301fb466139ffb0c00f0d006 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 26 Mar 2010 23:03:07 +0100 Subject: MIPS: Use set_cpus_allowed_ptr From: Julia Lawall Use set_cpus_allowed_ptr rather than set_cpus_allowed. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression E1,E2; @@ - set_cpus_allowed(E1, cpumask_of_cpu(E2)) + set_cpus_allowed_ptr(E1, cpumask_of(E2)) @@ expression E; identifier I; @@ - set_cpus_allowed(E, I) + set_cpus_allowed_ptr(E, &I) // Signed-off-by: Julia Lawall To: peterz@infradead.org To: mingo@elte.hu To: tglx@linutronix.de To: oleg@redhat.com To: linux-mips@linux-mips.org To: linux-kernel@vger.kernel.org To: kernel-janitors@vger.kernel.org Patchwork: http://patchwork.linux-mips.org/patch/1087/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/cpufreq/loongson2_cpufreq.c | 4 ++-- arch/mips/kernel/mips-mt-fpaff.c | 4 ++-- arch/mips/kernel/traps.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/cpufreq/loongson2_cpufreq.c b/arch/mips/kernel/cpufreq/loongson2_cpufreq.c index 2f6a0b147ab8..ae5db206347c 100644 --- a/arch/mips/kernel/cpufreq/loongson2_cpufreq.c +++ b/arch/mips/kernel/cpufreq/loongson2_cpufreq.c @@ -65,7 +65,7 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy, return -ENODEV; cpus_allowed = current->cpus_allowed; - set_cpus_allowed(current, cpumask_of_cpu(cpu)); + set_cpus_allowed_ptr(current, cpumask_of(cpu)); if (cpufreq_frequency_table_target (policy, &loongson2_clockmod_table[0], target_freq, relation, @@ -91,7 +91,7 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy, /* notifiers */ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - set_cpus_allowed(current, cpus_allowed); + set_cpus_allowed_ptr(current, &cpus_allowed); /* setting the cpu frequency */ clk_set_rate(cpuclk, freq); diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c index cbc6182b0065..f5981c499109 100644 --- a/arch/mips/kernel/mips-mt-fpaff.c +++ b/arch/mips/kernel/mips-mt-fpaff.c @@ -100,10 +100,10 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len, if (test_ti_thread_flag(ti, TIF_FPUBOUND) && cpus_intersects(new_mask, mt_fpu_cpumask)) { cpus_and(effective_mask, new_mask, mt_fpu_cpumask); - retval = set_cpus_allowed(p, effective_mask); + retval = set_cpus_allowed_ptr(p, &effective_mask); } else { clear_ti_thread_flag(ti, TIF_FPUBOUND); - retval = set_cpus_allowed(p, new_mask); + retval = set_cpus_allowed_ptr(p, &new_mask); } out_unlock: diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index d612c6dcb746..7e5e38c24cdc 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -854,7 +854,7 @@ static void mt_ase_fp_affinity(void) = current->cpus_allowed; cpus_and(tmask, current->cpus_allowed, mt_fpu_cpumask); - set_cpus_allowed(current, tmask); + set_cpus_allowed_ptr(current, &tmask); set_thread_flag(TIF_FPUBOUND); } } -- cgit v1.2.3 From 0103d23f44b1e9f8d2e89cc197e21192f6914f24 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sun, 2 May 2010 14:43:52 -0700 Subject: MIPS: nofpu and nodsp only affect CPU0 The "nofpu" and "nodsp" kernel command line options currently do not affect CPUs that are brought online later in the boot process or hotplugged at runtime. It is desirable to apply the nofpu/nodsp options to all CPUs in the system, so that surprising results are not seen when a process migrates from one CPU to another. [Ralf: Moved definitions of mips_fpu_disabled, fpu_disable, mips_dsp_disabled and dsp_disable from setup.c to cpu-probe.c to allow making mips_fpu_disabled and mips_dsp_disabled static.] Signed-off-by: Kevin Cernekee Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: http://patchwork.linux-mips.org/patch/1169/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/cpu-probe.c | 30 ++++++++++++++++++++++++++++++ arch/mips/kernel/setup.c | 21 --------------------- 2 files changed, 30 insertions(+), 21 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index be5bb16be4e0..3562b854f2cd 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -125,6 +125,30 @@ static int __init wait_disable(char *s) __setup("nowait", wait_disable); +static int __cpuinitdata mips_fpu_disabled; + +static int __init fpu_disable(char *s) +{ + cpu_data[0].options &= ~MIPS_CPU_FPU; + mips_fpu_disabled = 1; + + return 1; +} + +__setup("nofpu", fpu_disable); + +int __cpuinitdata mips_dsp_disabled; + +static int __init dsp_disable(char *s) +{ + cpu_data[0].ases &= ~MIPS_ASE_DSP; + mips_dsp_disabled = 1; + + return 1; +} + +__setup("nodsp", dsp_disable); + void __init check_wait(void) { struct cpuinfo_mips *c = ¤t_cpu_data; @@ -982,6 +1006,12 @@ __cpuinit void cpu_probe(void) */ BUG_ON(current_cpu_type() != c->cputype); + if (mips_fpu_disabled) + c->options &= ~MIPS_CPU_FPU; + + if (mips_dsp_disabled) + c->ases &= ~MIPS_ASE_DSP; + if (c->options & MIPS_CPU_FPU) { c->fpu_id = cpu_get_fpu_id(); diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index f9513f9e61d3..85aef3fc6716 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -569,27 +569,6 @@ void __init setup_arch(char **cmdline_p) plat_smp_setup(); } -static int __init fpu_disable(char *s) -{ - int i; - - for (i = 0; i < NR_CPUS; i++) - cpu_data[i].options &= ~MIPS_CPU_FPU; - - return 1; -} - -__setup("nofpu", fpu_disable); - -static int __init dsp_disable(char *s) -{ - cpu_data[0].ases &= ~MIPS_ASE_DSP; - - return 1; -} - -__setup("nodsp", dsp_disable); - unsigned long kernelsp[NR_CPUS]; unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3; -- cgit v1.2.3