]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
parisc: Enable TOC (transfer of contents) feature unconditionally
authorHelge Deller <deller@gmx.de>
Fri, 7 Jan 2022 13:05:11 +0000 (14:05 +0100)
committerHelge Deller <deller@gmx.de>
Tue, 11 Jan 2022 10:57:37 +0000 (11:57 +0100)
Before this patch, the TOC code used a pre-allocated stack of 16kb for
each possible CPU. That space overhead was the reason why the TOC
feature wasn't enabled by default for 32-bit kernels.

This patch rewrites the TOC code to use a per-cpu stack. That way we use
much less memory now and as such we enable the TOC feature by default on
all kernels.

Additionally the dump of the registers and the stacktrace wasn't
serialized, which led to multiple CPUs printing the stack backtrace at
once which rendered the output unreadable.
Now the backtraces are nicely serialized by a lock.

Signed-off-by: Helge Deller <deller@gmx.de>
arch/parisc/Kconfig
arch/parisc/kernel/Makefile
arch/parisc/kernel/asm-offsets.c
arch/parisc/kernel/toc.c
arch/parisc/kernel/toc_asm.S

index 011dc32fdb4d5a5e63ae740e6fe944bade41dd9d..f55ccd1161f3eb0d16c08c8bab270e1fdb078bb5 100644 (file)
@@ -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
index ed0b87908d71f5b8335b9a09ce9d87473262481d..8fb819bbbb17148b18c25755a8e696a24f0bf943 100644 (file)
@@ -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
index 396aa3b47712f18a41952eef4c3607dcd9436101..2a83ef36d21647d4dc9e8cc958c7abc2c68e00c8 100644 (file)
@@ -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();
index 18327611cf8f26299bc3f5bf9c1e8e4ed01e474f..be9a0bebe61e7395d218310cf8dec1536573ac4e 100644 (file)
@@ -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 */
index e94ba80441906586b9a84e75dcb2ad1d63db5838..570f5cef526e4cf426db8d4c24a2ce5b9aed9b57 100644 (file)
@@ -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)