aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/nmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/kernel/nmi.c')
-rw-r--r--arch/x86_64/kernel/nmi.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index d42374a952d7..f6b881b23a70 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -682,16 +682,18 @@ void touch_nmi_watchdog (void)
682 touch_softlockup_watchdog(); 682 touch_softlockup_watchdog();
683} 683}
684 684
685void __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) 685int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
686{ 686{
687 int sum; 687 int sum;
688 int touched = 0; 688 int touched = 0;
689 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); 689 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
690 u64 dummy; 690 u64 dummy;
691 int rc=0;
691 692
692 /* check for other users first */ 693 /* check for other users first */
693 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) 694 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT)
694 == NOTIFY_STOP) { 695 == NOTIFY_STOP) {
696 rc = 1;
695 touched = 1; 697 touched = 1;
696 } 698 }
697 699
@@ -746,10 +748,18 @@ void __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
746 } 748 }
747 /* start the cycle over again */ 749 /* start the cycle over again */
748 wrmsrl(wd->perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); 750 wrmsrl(wd->perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz));
749 } 751 rc = 1;
752 } else if (nmi_watchdog == NMI_IO_APIC) {
753 /* don't know how to accurately check for this.
754 * just assume it was a watchdog timer interrupt
755 * This matches the old behaviour.
756 */
757 rc = 1;
758 } else
759 printk(KERN_WARNING "Unknown enabled NMI hardware?!\n");
750 } 760 }
751done: 761done:
752 return; 762 return rc;
753} 763}
754 764
755static __kprobes int dummy_nmi_callback(struct pt_regs * regs, int cpu) 765static __kprobes int dummy_nmi_callback(struct pt_regs * regs, int cpu)
@@ -761,15 +771,17 @@ static nmi_callback_t nmi_callback = dummy_nmi_callback;
761 771
762asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code) 772asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code)
763{ 773{
764 int cpu = safe_smp_processor_id();
765
766 nmi_enter(); 774 nmi_enter();
767 add_pda(__nmi_count,1); 775 add_pda(__nmi_count,1);
768 if (!rcu_dereference(nmi_callback)(regs, cpu)) 776 default_do_nmi(regs);
769 default_do_nmi(regs);
770 nmi_exit(); 777 nmi_exit();
771} 778}
772 779
780int do_nmi_callback(struct pt_regs * regs, int cpu)
781{
782 return rcu_dereference(nmi_callback)(regs, cpu);
783}
784
773void set_nmi_callback(nmi_callback_t callback) 785void set_nmi_callback(nmi_callback_t callback)
774{ 786{
775 vmalloc_sync_all(); 787 vmalloc_sync_all();