Exemple #1
0
static void nmi_shootdown_cpus(void)
{
    unsigned long msecs;

    local_irq_disable();

    crashing_cpu = smp_processor_id();
    local_irq_count(crashing_cpu) = 0;

    atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
    /* Would it be better to replace the trap vector here? */
    set_nmi_callback(crash_nmi_callback);
    /* Ensure the new callback function is set before sending out the NMI. */
    wmb();

    smp_send_nmi_allbutself();

    msecs = 1000; /* Wait at most a second for the other cpus to stop */
    while ( (atomic_read(&waiting_for_crash_ipi) > 0) && msecs )
    {
        mdelay(1);
        msecs--;
    }

    __stop_this_cpu();
    disable_IO_APIC();

    local_irq_enable();
}
Exemple #2
0
/*
 * Stop all CPUs and turn off local APICs and the IO-APIC, so other OSs see a 
 * clean IRQ state.
 */
void smp_send_stop(void)
{
    int timeout = 10;

    smp_call_function(stop_this_cpu, NULL, 0);

    /* Wait 10ms for all other CPUs to go offline. */
    while ( (num_online_cpus() > 1) && (timeout-- > 0) )
        mdelay(1);

    local_irq_disable();
    __stop_this_cpu();
    disable_IO_APIC();
    hpet_disable();
    local_irq_enable();
}
static void nmi_shootdown_cpus(void)
{
    unsigned long msecs;

    local_irq_disable();

    if ( hpet_broadcast_is_available() )
        hpet_disable_legacy_broadcast();

    crashing_cpu = smp_processor_id();
    local_irq_count(crashing_cpu) = 0;

    atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
    /* Would it be better to replace the trap vector here? */
    set_nmi_callback(crash_nmi_callback);
    /* Ensure the new callback function is set before sending out the NMI. */
    wmb();

    smp_send_nmi_allbutself();

    msecs = 1000; /* Wait at most a second for the other cpus to stop */
    while ( (atomic_read(&waiting_for_crash_ipi) > 0) && msecs )
    {
        mdelay(1);
        msecs--;
    }

    /* Crash shutdown any IOMMU functionality as the crashdump kernel is not
     * happy when booting if interrupt/dma remapping is still enabled */
    iommu_crash_shutdown();

    __stop_this_cpu();

    /* This is a bit of a hack due to the problems with the x2apic_enabled
     * variable, but we can't do any better without a significant refactoring
     * of the APIC code */
    x2apic_enabled = (current_local_apic_mode() == APIC_MODE_X2APIC);

    disable_IO_APIC();
    hpet_disable();
}
Exemple #4
0
static int crash_nmi_callback(struct cpu_user_regs *regs, int cpu)
{
    /* Don't do anything if this handler is invoked on crashing cpu.
     * Otherwise, system will completely hang. Crashing cpu can get
     * an NMI if system was initially booted with nmi_watchdog parameter.
     */
    if ( cpu == crashing_cpu )
        return 1;
    local_irq_disable();

    kexec_crash_save_cpu();

    __stop_this_cpu();

    atomic_dec(&waiting_for_crash_ipi);

    for ( ; ; )
        halt();

    return 1;
}
Exemple #5
0
static void stop_this_cpu(void *dummy)
{
    __stop_this_cpu();
    for ( ; ; )
        halt();
}