static int rthal_nmi_watchdog_tick(struct pt_regs *regs, unsigned reason) #endif /* Linux >= 2.6.19 */ { int cpu = rthal_processor_id(); rthal_nmi_wd_t *wd = &rthal_nmi_wds[cpu]; unsigned long long now; if (wd->armed) { if (rthal_rdtsc() - wd->tick_date < rthal_maxlat_tsc) { ++wd->early_shots; wd->next_linux_check = wd->tick_date + rthal_maxlat_tsc; } else { printk("NMI early shots: %d\n", wd->early_shots); rthal_nmi_emergency(regs); } } now = rthal_rdtsc(); if ((long long)(now - wd->next_linux_check) >= 0) { CALL_LINUX_NMI; do { wd->next_linux_check += RTHAL_CPU_FREQ; } while ((long long)(now - wd->next_linux_check) >= 0); } if (wd->perfctr_msr == MSR_P4_IQ_COUNTER0) { /* * P4 quirks: * - An overflown perfctr will assert its interrupt * until the OVF flag in its CCCR is cleared. * - LVTPC is masked on interrupt and must be * unmasked by the LVTPC handler. */ wrmsr(MSR_P4_IQ_CCCR0, wd->p4_cccr_val, 0); apic_write(APIC_LVTPC, APIC_DM_NMI); } else if (rthal_nmi_perfctr_msr == MSR_P6_PERFCTR0) { /* Only P6 based Pentium M need to re-unmask * the apic vector but it doesn't hurt * other P6 variant */ apic_write(APIC_LVTPC, APIC_DM_NMI); } wrmsrl(wd->perfctr_msr, now - wd->next_linux_check); NMI_RETURN; }
asmlinkage void rthal_nmi_tick(struct pt_regs *regs) { rthal_nmi_emergency(regs); }