lkml.org 
[lkml]   [2001]   [Jan]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] enable K7 nmi watchdog
    This patch (against 2.4.0-ac8) _may_ enable the NMI watchdog on
    some K7 systems. It won't help if you have an old K7 without a
    local APIC, or if your BIOS disables it.

    This is a quick hack to test the mechanism -- I'll submit a
    cleaner patch later if this one works.

    If you try this, please cc: me the result (positive or negative)
    and a copy of the kernel's boot log.

    /Mikael

    --- linux-2.4.0-ac8/arch/i386/kernel/nmi.c.~1~ Sat Jan 13 14:57:09 2001
    +++ linux-2.4.0-ac8/arch/i386/kernel/nmi.c Sat Jan 13 16:00:27 2001
    @@ -64,6 +64,10 @@
    (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
    (boot_cpu_data.x86 == 6))
    nmi_watchdog = nmi;
    + if ((nmi == NMI_LOCAL_APIC) &&
    + (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
    + (boot_cpu_data.x86 == 6))
    + nmi_watchdog = nmi;
    /*
    * We can enable the IO-APIC watchdog
    * unconditionally.
    @@ -80,10 +84,34 @@
    * Original code written by Keith Owens.
    */

    +#define MSR_K7_EVNTSEL0 0xC001000
    +#define MSR_K7_PERFCTR0 0xC001004
    +
    void setup_apic_nmi_watchdog (void)
    {
    int value;

    + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
    + boot_cpu_data.x86 == 6) {
    + unsigned evntsel = (1<<20)|(3<<16); /* INT, OS, USR */
    +#if 1 /* listed in old docs */
    + evntsel |= 0x76; /* CYCLES_PROCESSOR_IS_RUNNING */
    +#else /* try this if the above doesn't work */
    + evntsel |= 0xC0; /* RETIRED_INSTRUCTIONS */
    +#endif
    + wrmsr(MSR_K7_EVNTSEL0, 0, 0);
    + wrmsr(MSR_K7_PERFCTR0, 0, 0);
    + wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
    + printk("setting K7_PERFCTR0 to %08lx\n", -(cpu_khz/HZ*1000));
    + wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/HZ*1000), 0);
    + printk("setting K7 LVTPC to DM_NMI\n");
    + apic_write(APIC_LVTPC, APIC_DM_NMI);
    + evntsel |= (1<<22); /* ENable */
    + printk("setting K7_EVNTSEL0 to %08x\n", evntsel);
    + wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
    + return;
    + }
    +
    /* clear performance counters 0, 1 */

    wrmsr(MSR_IA32_EVNTSEL0, 0, 0);
    @@ -162,7 +190,14 @@
    last_irq_sums[cpu] = sum;
    alert_counter[cpu] = 0;
    }
    - if (cpu_has_apic && (nmi_watchdog == NMI_LOCAL_APIC))
    - wrmsr(MSR_IA32_PERFCTR1, -(cpu_khz/HZ*1000), 0);
    + if (cpu_has_apic && (nmi_watchdog == NMI_LOCAL_APIC)) {
    + /* XXX: nmi_watchdog should carry this info */
    + unsigned msr;
    + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
    + msr = MSR_K7_PERFCTR0;
    + else
    + msr = MSR_IA32_PERFCTR1;
    + wrmsr(msr, -(cpu_khz/HZ*1000), 0);
    + }
    }

    --- linux-2.4.0-ac8/arch/i386/kernel/setup.c.~1~ Sat Jan 13 14:57:09 2001
    +++ linux-2.4.0-ac8/arch/i386/kernel/setup.c Sat Jan 13 14:57:48 2001
    @@ -1926,14 +1926,6 @@
    c->x86 = 4;
    }

    - /*
    - * Athlons have an APIC, but the APIC-programming
    - * MSRs are in different places. If you want NMI-watchdog
    - * on Athlons, please fix setup_apic_nmi_watchdog().
    - */
    - if (c->x86_vendor == X86_VENDOR_AMD)
    - clear_bit(X86_FEATURE_APIC, &c->x86_capability);
    -
    /* AMD-defined flags: level 0x80000001 */
    xlvl = cpuid_eax(0x80000000);
    if ( (xlvl & 0xffff0000) == 0x80000000 ) {
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2005-03-22 13:28    [W:3.319 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site