cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

crash.c (9035B)


      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}