linux/arch/powerpc/kexec/crash.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Architecture specific (PPC64) functions for kexec based crash dumps.
   4 *
   5 * Copyright (C) 2005, IBM Corp.
   6 *
   7 * Created by: Haren Myneni
   8 */
   9
  10#include <linux/kernel.h>
  11#include <linux/smp.h>
  12#include <linux/reboot.h>
  13#include <linux/kexec.h>
  14#include <linux/export.h>
  15#include <linux/crash_dump.h>
  16#include <linux/delay.h>
  17#include <linux/irq.h>
  18#include <linux/types.h>
  19
  20#include <asm/processor.h>
  21#include <asm/machdep.h>
  22#include <asm/kexec.h>
  23#include <asm/smp.h>
  24#include <asm/setjmp.h>
  25#include <asm/debug.h>
  26#include <asm/interrupt.h>
  27
  28/*
  29 * The primary CPU waits a while for all secondary CPUs to enter. This is to
  30 * avoid sending an IPI if the secondary CPUs are entering
  31 * crash_kexec_secondary on their own (eg via a system reset).
  32 *
  33 * The secondary timeout has to be longer than the primary. Both timeouts are
  34 * in milliseconds.
  35 */
  36#define PRIMARY_TIMEOUT         500
  37#define SECONDARY_TIMEOUT       1000
  38
  39#define IPI_TIMEOUT             10000
  40#define REAL_MODE_TIMEOUT       10000
  41
  42static int time_to_dump;
  43/*
  44 * crash_wake_offline should be set to 1 by platforms that intend to wake
  45 * up offline cpus prior to jumping to a kdump kernel. Currently powernv
  46 * sets it to 1, since we want to avoid things from happening when an
  47 * offline CPU wakes up due to something like an HMI (malfunction error),
  48 * which propagates to all threads.
  49 */
  50int crash_wake_offline;
  51
  52#define CRASH_HANDLER_MAX 3
  53/* List of shutdown handles */
  54static crash_shutdown_t crash_shutdown_handles[CRASH_HANDLER_MAX];
  55static DEFINE_SPINLOCK(crash_handlers_lock);
  56
  57static unsigned long crash_shutdown_buf[JMP_BUF_LEN];
  58static int crash_shutdown_cpu = -1;
  59
  60static int handle_fault(struct pt_regs *regs)
  61{
  62        if (crash_shutdown_cpu == smp_processor_id())
  63                longjmp(crash_shutdown_buf, 1);
  64        return 0;
  65}
  66
  67#ifdef CONFIG_SMP
  68
  69static atomic_t cpus_in_crash;
  70void crash_ipi_callback(struct pt_regs *regs)
  71{
  72        static cpumask_t cpus_state_saved = CPU_MASK_NONE;
  73
  74        int cpu = smp_processor_id();
  75
  76        hard_irq_disable();
  77        if (!cpumask_test_cpu(cpu, &cpus_state_saved)) {
  78                crash_save_cpu(regs, cpu);
  79                cpumask_set_cpu(cpu, &cpus_state_saved);
  80        }
  81
  82        atomic_inc(&cpus_in_crash);
  83        smp_mb__after_atomic();
  84
  85        /*
  86         * Starting the kdump boot.
  87         * This barrier is needed to make sure that all CPUs are stopped.
  88         */
  89        while (!time_to_dump)
  90                cpu_relax();
  91
  92        if (ppc_md.kexec_cpu_down)
  93                ppc_md.kexec_cpu_down(1, 1);
  94
  95#ifdef CONFIG_PPC64
  96        kexec_smp_wait();
  97#else
  98        for (;;);       /* FIXME */
  99#endif
 100
 101        /* NOTREACHED */
 102}
 103
 104static void crash_kexec_prepare_cpus(int cpu)
 105{
 106        unsigned int msecs;
 107        volatile unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */
 108        volatile int tries = 0;
 109        int (*old_handler)(struct pt_regs *regs);
 110
 111        printk(KERN_EMERG "Sending IPI to other CPUs\n");
 112
 113        if (crash_wake_offline)
 114                ncpus = num_present_cpus() - 1;
 115
 116        crash_send_ipi(crash_ipi_callback);
 117        smp_wmb();
 118
 119again:
 120        /*
 121         * FIXME: Until we will have the way to stop other CPUs reliably,
 122         * the crash CPU will send an IPI and wait for other CPUs to
 123         * respond.
 124         */
 125        msecs = IPI_TIMEOUT;
 126        while ((atomic_read(&cpus_in_crash) < ncpus) && (--msecs > 0))
 127                mdelay(1);
 128
 129        /* Would it be better to replace the trap vector here? */
 130
 131        if (atomic_read(&cpus_in_crash) >= ncpus) {
 132                printk(KERN_EMERG "IPI complete\n");
 133                return;
 134        }
 135
 136        printk(KERN_EMERG "ERROR: %d cpu(s) not responding\n",
 137                ncpus - atomic_read(&cpus_in_crash));
 138
 139        /*
 140         * If we have a panic timeout set then we can't wait indefinitely
 141         * for someone to activate system reset. We also give up on the
 142         * second time through if system reset fail to work.
 143         */
 144        if ((panic_timeout > 0) || (tries > 0))
 145                return;
 146
 147        /*
 148         * A system reset will cause all CPUs to take an 0x100 exception.
 149         * The primary CPU returns here via setjmp, and the secondary
 150         * CPUs reexecute the crash_kexec_secondary path.
 151         */
 152        old_handler = __debugger;
 153        __debugger = handle_fault;
 154        crash_shutdown_cpu = smp_processor_id();
 155
 156        if (setjmp(crash_shutdown_buf) == 0) {
 157                printk(KERN_EMERG "Activate system reset (dumprestart) "
 158                                  "to stop other cpu(s)\n");
 159
 160                /*
 161                 * A system reset will force all CPUs to execute the
 162                 * crash code again. We need to reset cpus_in_crash so we
 163                 * wait for everyone to do this.
 164                 */
 165                atomic_set(&cpus_in_crash, 0);
 166                smp_mb();
 167
 168                while (atomic_read(&cpus_in_crash) < ncpus)
 169                        cpu_relax();
 170        }
 171
 172        crash_shutdown_cpu = -1;
 173        __debugger = old_handler;
 174
 175        tries++;
 176        goto again;
 177}
 178
 179/*
 180 * This function will be called by secondary cpus.
 181 */
 182void crash_kexec_secondary(struct pt_regs *regs)
 183{
 184        unsigned long flags;
 185        int msecs = SECONDARY_TIMEOUT;
 186
 187        local_irq_save(flags);
 188
 189        /* Wait for the primary crash CPU to signal its progress */
 190        while (crashing_cpu < 0) {
 191                if (--msecs < 0) {
 192                        /* No response, kdump image may not have been loaded */
 193                        local_irq_restore(flags);
 194                        return;
 195                }
 196
 197                mdelay(1);
 198        }
 199
 200        crash_ipi_callback(regs);
 201}
 202
 203#else   /* ! CONFIG_SMP */
 204
 205static void crash_kexec_prepare_cpus(int cpu)
 206{
 207        /*
 208         * move the secondaries to us so that we can copy
 209         * the new kernel 0-0x100 safely
 210         *
 211         * do this if kexec in setup.c ?
 212         */
 213#ifdef CONFIG_PPC64
 214        smp_release_cpus();
 215#else
 216        /* FIXME */
 217#endif
 218}
 219
 220void crash_kexec_secondary(struct pt_regs *regs)
 221{
 222}
 223#endif  /* CONFIG_SMP */
 224
 225/* wait for all the CPUs to hit real mode but timeout if they don't come in */
 226#if defined(CONFIG_SMP) && defined(CONFIG_PPC64)
 227noinstr static void __maybe_unused crash_kexec_wait_realmode(int cpu)
 228{
 229        unsigned int msecs;
 230        int i;
 231
 232        msecs = REAL_MODE_TIMEOUT;
 233        for (i=0; i < nr_cpu_ids && msecs > 0; i++) {
 234                if (i == cpu)
 235                        continue;
 236
 237                while (paca_ptrs[i]->kexec_state < KEXEC_STATE_REAL_MODE) {
 238                        barrier();
 239                        if (!cpu_possible(i) || !cpu_online(i) || (msecs <= 0))
 240                                break;
 241                        msecs--;
 242                        mdelay(1);
 243                }
 244        }
 245        mb();
 246}
 247#else
 248static inline void crash_kexec_wait_realmode(int cpu) {}
 249#endif  /* CONFIG_SMP && CONFIG_PPC64 */
 250
 251/*
 252 * Register a function to be called on shutdown.  Only use this if you
 253 * can't reset your device in the second kernel.
 254 */
 255int crash_shutdown_register(crash_shutdown_t handler)
 256{
 257        unsigned int i, rc;
 258
 259        spin_lock(&crash_handlers_lock);
 260        for (i = 0 ; i < CRASH_HANDLER_MAX; i++)
 261                if (!crash_shutdown_handles[i]) {
 262                        /* Insert handle at first empty entry */
 263                        crash_shutdown_handles[i] = handler;
 264                        rc = 0;
 265                        break;
 266                }
 267
 268        if (i == CRASH_HANDLER_MAX) {
 269                printk(KERN_ERR "Crash shutdown handles full, "
 270                       "not registered.\n");
 271                rc = 1;
 272        }
 273
 274        spin_unlock(&crash_handlers_lock);
 275        return rc;
 276}
 277EXPORT_SYMBOL(crash_shutdown_register);
 278
 279int crash_shutdown_unregister(crash_shutdown_t handler)
 280{
 281        unsigned int i, rc;
 282
 283        spin_lock(&crash_handlers_lock);
 284        for (i = 0 ; i < CRASH_HANDLER_MAX; i++)
 285                if (crash_shutdown_handles[i] == handler)
 286                        break;
 287
 288        if (i == CRASH_HANDLER_MAX) {
 289                printk(KERN_ERR "Crash shutdown handle not found\n");
 290                rc = 1;
 291        } else {
 292                /* Shift handles down */
 293                for (; i < (CRASH_HANDLER_MAX - 1); i++)
 294                        crash_shutdown_handles[i] =
 295                                crash_shutdown_handles[i+1];
 296                /*
 297                 * Reset last entry to NULL now that it has been shifted down,
 298                 * this will allow new handles to be added here.
 299                 */
 300                crash_shutdown_handles[i] = NULL;
 301                rc = 0;
 302        }
 303
 304        spin_unlock(&crash_handlers_lock);
 305        return rc;
 306}
 307EXPORT_SYMBOL(crash_shutdown_unregister);
 308
 309void default_machine_crash_shutdown(struct pt_regs *regs)
 310{
 311        unsigned int i;
 312        int (*old_handler)(struct pt_regs *regs);
 313
 314        /* Avoid hardlocking with irresponsive CPU holding logbuf_lock */
 315        printk_deferred_enter();
 316
 317        /*
 318         * This function is only called after the system
 319         * has panicked or is otherwise in a critical state.
 320         * The minimum amount of code to allow a kexec'd kernel
 321         * to run successfully needs to happen here.
 322         *
 323         * In practice this means stopping other cpus in
 324         * an SMP system.
 325         * The kernel is broken so disable interrupts.
 326         */
 327        hard_irq_disable();
 328
 329        /*
 330         * Make a note of crashing cpu. Will be used in machine_kexec
 331         * such that another IPI will not be sent.
 332         */
 333        crashing_cpu = smp_processor_id();
 334
 335        /*
 336         * If we came in via system reset, wait a while for the secondary
 337         * CPUs to enter.
 338         */
 339        if (TRAP(regs) == INTERRUPT_SYSTEM_RESET)
 340                mdelay(PRIMARY_TIMEOUT);
 341
 342        crash_kexec_prepare_cpus(crashing_cpu);
 343
 344        crash_save_cpu(regs, crashing_cpu);
 345
 346        time_to_dump = 1;
 347
 348        crash_kexec_wait_realmode(crashing_cpu);
 349
 350        machine_kexec_mask_interrupts();
 351
 352        /*
 353         * Call registered shutdown routines safely.  Swap out
 354         * __debugger_fault_handler, and replace on exit.
 355         */
 356        old_handler = __debugger_fault_handler;
 357        __debugger_fault_handler = handle_fault;
 358        crash_shutdown_cpu = smp_processor_id();
 359        for (i = 0; i < CRASH_HANDLER_MAX && crash_shutdown_handles[i]; i++) {
 360                if (setjmp(crash_shutdown_buf) == 0) {
 361                        /*
 362                         * Insert syncs and delay to ensure
 363                         * instructions in the dangerous region don't
 364                         * leak away from this protected region.
 365                         */
 366                        asm volatile("sync; isync");
 367                        /* dangerous region */
 368                        crash_shutdown_handles[i]();
 369                        asm volatile("sync; isync");
 370                }
 371        }
 372        crash_shutdown_cpu = -1;
 373        __debugger_fault_handler = old_handler;
 374
 375        if (ppc_md.kexec_cpu_down)
 376                ppc_md.kexec_cpu_down(1, 0);
 377}
 378