summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/parisc/Kconfig14
-rw-r--r--arch/parisc/kernel/Makefile3
-rw-r--r--arch/parisc/kernel/asm-offsets.c3
-rw-r--r--arch/parisc/kernel/toc.c18
-rw-r--r--arch/parisc/kernel/toc_asm.S33
5 files changed, 30 insertions, 41 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 011dc32fdb4d..f55ccd1161f3 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -287,20 +287,6 @@ config SMP
If you don't know what to do here, say N.
-config TOC
- bool "Support TOC switch"
- default y if 64BIT || !SMP
- help
- Most PA-RISC machines have either a switch at the back of the machine
- or a command in BMC to trigger a TOC interrupt. If you say Y here a
- handler will be installed which will either show a backtrace on all
- CPUs, or enter a possible configured debugger like kgdb/kdb.
-
- Note that with this option enabled, the kernel will use an additional 16KB
- per possible CPU as a special stack for the TOC handler.
-
- If you don't want to debug the Kernel, say N.
-
config PARISC_CPU_TOPOLOGY
bool "Support cpu topology definition"
depends on SMP
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
index ed0b87908d71..8fb819bbbb17 100644
--- a/arch/parisc/kernel/Makefile
+++ b/arch/parisc/kernel/Makefile
@@ -10,7 +10,7 @@ obj-y := cache.o pacache.o setup.o pdt.o traps.o time.o irq.o \
ptrace.o hardware.o inventory.o drivers.o alternative.o \
signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \
process.o processor.o pdc_cons.o pdc_chassis.o unwind.o \
- patch.o
+ patch.o toc.o toc_asm.o
ifdef CONFIG_FUNCTION_TRACER
# Do not profile debug and lowlevel utilities
@@ -39,4 +39,3 @@ obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_KEXEC_CORE) += kexec.o relocate_kernel.o
obj-$(CONFIG_KEXEC_FILE) += kexec_file.o
-obj-$(CONFIG_TOC) += toc.o toc_asm.o
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c
index 396aa3b47712..2a83ef36d216 100644
--- a/arch/parisc/kernel/asm-offsets.c
+++ b/arch/parisc/kernel/asm-offsets.c
@@ -36,6 +36,9 @@
int main(void)
{
DEFINE(TASK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags));
+#ifdef CONFIG_SMP
+ DEFINE(TASK_TI_CPU, offsetof(struct task_struct, thread_info.cpu));
+#endif
DEFINE(TASK_STACK, offsetof(struct task_struct, stack));
DEFINE(TASK_PAGEFAULT_DISABLED, offsetof(struct task_struct, pagefault_disabled));
BLANK();
diff --git a/arch/parisc/kernel/toc.c b/arch/parisc/kernel/toc.c
index 18327611cf8f..be9a0bebe61e 100644
--- a/arch/parisc/kernel/toc.c
+++ b/arch/parisc/kernel/toc.c
@@ -9,8 +9,10 @@
#include <asm/pdc.h>
#include <asm/pdc_chassis.h>
+#include <asm/ldcw.h>
-unsigned int __aligned(16) toc_lock = 1;
+static unsigned int __aligned(16) toc_lock = 1;
+DEFINE_PER_CPU_PAGE_ALIGNED(char [16384], toc_stack);
static void toc20_to_pt_regs(struct pt_regs *regs, struct pdc_toc_pim_20 *toc)
{
@@ -63,7 +65,8 @@ void notrace __noreturn __cold toc_intr(struct pt_regs *regs)
struct pdc_toc_pim_20 pim_data20;
struct pdc_toc_pim_11 pim_data11;
- nmi_enter();
+ /* verify we wrote regs to the correct stack */
+ BUG_ON(regs != (struct pt_regs *)&per_cpu(toc_stack, raw_smp_processor_id()));
if (boot_cpu_data.cpu_type >= pcxu) {
if (pdc_pim_toc20(&pim_data20))
@@ -76,14 +79,25 @@ void notrace __noreturn __cold toc_intr(struct pt_regs *regs)
}
#ifdef CONFIG_KGDB
+ nmi_enter();
+
if (atomic_read(&kgdb_active) != -1)
kgdb_nmicallback(raw_smp_processor_id(), regs);
kgdb_handle_exception(9, SIGTRAP, 0, regs);
#endif
+
+ /* serialize output, otherwise all CPUs write backtrace at once */
+ while (__ldcw(&toc_lock) == 0)
+ ; /* wait */
show_regs(regs);
+ toc_lock = 1; /* release lock for next CPU */
+
+ if (raw_smp_processor_id() != 0)
+ while (1) ; /* all but monarch CPU will wait endless. */
/* give other CPUs time to show their backtrace */
mdelay(2000);
+
machine_restart("TOC");
/* should never reach this */
diff --git a/arch/parisc/kernel/toc_asm.S b/arch/parisc/kernel/toc_asm.S
index e94ba8044190..570f5cef526e 100644
--- a/arch/parisc/kernel/toc_asm.S
+++ b/arch/parisc/kernel/toc_asm.S
@@ -5,34 +5,25 @@
.level 1.1
#include <asm/assembly.h>
-#include <asm/psw.h>
#include <linux/threads.h>
#include <linux/linkage.h>
.text
.import toc_intr,code
- .import toc_lock,data
+ .import toc_stack,data
.align 16
ENTRY_CFI(toc_handler)
- /*
- * synchronize CPUs and obtain offset
- * for stack setup.
- */
- load32 PA(toc_lock),%r1
-0: ldcw,co 0(%r1),%r2
- cmpib,= 0,%r2,0b
- nop
- addi 1,%r2,%r4
- stw %r4,0(%r1)
- addi -1,%r2,%r4
-
load32 PA(toc_stack),%sp
- /*
- * deposit CPU number into stack address,
- * so every CPU will have its own stack.
- */
- SHLREG %r4,14,%r4
+
+#ifdef CONFIG_SMP
+ /* get per-cpu toc_stack address. */
+ mfctl %cr30, %r1
+ tophys %r1,%r2 /* task_struct */
+ LDREG TASK_TI_CPU(%r2),%r4 /* cpu */
+ load32 PA(__per_cpu_offset),%r1
+ LDREGX %r4(%r1),%r4
add %r4,%sp,%sp
+#endif
/*
* setup pt_regs on stack and save the
@@ -82,7 +73,3 @@ ENDPROC_CFI(toc_handler)
*/
SYM_DATA(toc_handler_csum, .long 0)
SYM_DATA(toc_handler_size, .long . - toc_handler)
-
- __PAGE_ALIGNED_BSS
- .align 64
-SYM_DATA(toc_stack, .block 16384*NR_CPUS)