arch/powerpc/kexec/crash.c

Source file repositories/reference/linux-study-clean/arch/powerpc/kexec/crash.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/kexec/crash.c
Extension
.c
Size
16386 bytes
Lines
657
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (--msecs < 0) {
			/* No response, kdump image may not have been loaded */
			local_irq_restore(flags);
			return;
		}

		mdelay(1);
	}

	crash_ipi_callback(regs);
}

#else	/* ! CONFIG_SMP */

static void crash_kexec_prepare_cpus(void)
{
	/*
	 * move the secondaries to us so that we can copy
	 * the new kernel 0-0x100 safely
	 *
	 * do this if kexec in setup.c ?
	 */
#ifdef CONFIG_PPC64
	smp_release_cpus();
#else
	/* FIXME */
#endif
}

void crash_kexec_secondary(struct pt_regs *regs)
{
}
#endif	/* CONFIG_SMP */

/* wait for all the CPUs to hit real mode but timeout if they don't come in */
#if defined(CONFIG_SMP) && defined(CONFIG_PPC64)
noinstr static void __maybe_unused crash_kexec_wait_realmode(int cpu)
{
	unsigned int msecs;
	int i;

	msecs = REAL_MODE_TIMEOUT;
	for (i=0; i < nr_cpu_ids && msecs > 0; i++) {
		if (i == cpu)
			continue;

		while (paca_ptrs[i]->kexec_state < KEXEC_STATE_REAL_MODE) {
			barrier();
			if (!cpu_possible(i) || !cpu_online(i) || (msecs <= 0))
				break;
			msecs--;
			mdelay(1);
		}
	}
	mb();
}
#else
static inline void crash_kexec_wait_realmode(int cpu) {}
#endif	/* CONFIG_SMP && CONFIG_PPC64 */

void crash_kexec_prepare(void)
{
	/* Avoid hardlocking with irresponsive CPU holding logbuf_lock */
	printk_deferred_enter();

	/*
	 * This function is only called after the system
	 * has panicked or is otherwise in a critical state.
	 * The minimum amount of code to allow a kexec'd kernel
	 * to run successfully needs to happen here.
	 *
	 * In practice this means stopping other cpus in
	 * an SMP system.
	 * The kernel is broken so disable interrupts.
	 */
	hard_irq_disable();

	/*
	 * Make a note of crashing cpu. Will be used in machine_kexec
	 * such that another IPI will not be sent.
	 */
	crashing_cpu = smp_processor_id();

	crash_kexec_prepare_cpus();
}

/*
 * Register a function to be called on shutdown.  Only use this if you
 * can't reset your device in the second kernel.
 */

Annotation

Implementation Notes