diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/kernel/nmi.c | 52 | ||||
-rw-r--r-- | arch/x86_64/kernel/nmi.c | 48 |
2 files changed, 100 insertions, 0 deletions
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index acd3fdea2a21..28065d0b71a9 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c | |||
@@ -846,6 +846,58 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu) | |||
846 | return 0; | 846 | return 0; |
847 | } | 847 | } |
848 | 848 | ||
849 | /* | ||
850 | * proc handler for /proc/sys/kernel/nmi_watchdog | ||
851 | */ | ||
852 | int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, | ||
853 | void __user *buffer, size_t *length, loff_t *ppos) | ||
854 | { | ||
855 | int old_state; | ||
856 | |||
857 | nmi_watchdog_enabled = (atomic_read(&nmi_active) > 0) ? 1 : 0; | ||
858 | old_state = nmi_watchdog_enabled; | ||
859 | proc_dointvec(table, write, file, buffer, length, ppos); | ||
860 | if (!!old_state == !!nmi_watchdog_enabled) | ||
861 | return 0; | ||
862 | |||
863 | if (atomic_read(&nmi_active) < 0) { | ||
864 | printk(KERN_WARNING "NMI watchdog is permanently disabled\n"); | ||
865 | return -EINVAL; | ||
866 | } | ||
867 | |||
868 | if (nmi_watchdog == NMI_DEFAULT) { | ||
869 | if (nmi_known_cpu() > 0) | ||
870 | nmi_watchdog = NMI_LOCAL_APIC; | ||
871 | else | ||
872 | nmi_watchdog = NMI_IO_APIC; | ||
873 | } | ||
874 | |||
875 | if (nmi_watchdog == NMI_LOCAL_APIC) | ||
876 | { | ||
877 | if (nmi_watchdog_enabled) | ||
878 | enable_lapic_nmi_watchdog(); | ||
879 | else | ||
880 | disable_lapic_nmi_watchdog(); | ||
881 | } else if (nmi_watchdog == NMI_IO_APIC) { | ||
882 | /* FIXME | ||
883 | * for some reason these functions don't work | ||
884 | */ | ||
885 | printk("Can not enable/disable NMI on IO APIC\n"); | ||
886 | return -EINVAL; | ||
887 | #if 0 | ||
888 | if (nmi_watchdog_enabled) | ||
889 | enable_timer_nmi_watchdog(); | ||
890 | else | ||
891 | disable_timer_nmi_watchdog(); | ||
892 | #endif | ||
893 | } else { | ||
894 | printk( KERN_WARNING | ||
895 | "NMI watchdog doesn't know what hardware to touch\n"); | ||
896 | return -EIO; | ||
897 | } | ||
898 | return 0; | ||
899 | } | ||
900 | |||
849 | #endif | 901 | #endif |
850 | 902 | ||
851 | EXPORT_SYMBOL(nmi_active); | 903 | EXPORT_SYMBOL(nmi_active); |
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 9d175dcf3a2d..3a17411a9a19 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c | |||
@@ -750,6 +750,54 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu) | |||
750 | return 0; | 750 | return 0; |
751 | } | 751 | } |
752 | 752 | ||
753 | /* | ||
754 | * proc handler for /proc/sys/kernel/nmi | ||
755 | */ | ||
756 | int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, | ||
757 | void __user *buffer, size_t *length, loff_t *ppos) | ||
758 | { | ||
759 | int old_state; | ||
760 | |||
761 | nmi_watchdog_enabled = (atomic_read(&nmi_active) > 0) ? 1 : 0; | ||
762 | old_state = nmi_watchdog_enabled; | ||
763 | proc_dointvec(table, write, file, buffer, length, ppos); | ||
764 | if (!!old_state == !!nmi_watchdog_enabled) | ||
765 | return 0; | ||
766 | |||
767 | if (atomic_read(&nmi_active) < 0) { | ||
768 | printk( KERN_WARNING "NMI watchdog is permanently disabled\n"); | ||
769 | return -EINVAL; | ||
770 | } | ||
771 | |||
772 | /* if nmi_watchdog is not set yet, then set it */ | ||
773 | nmi_watchdog_default(); | ||
774 | |||
775 | if (nmi_watchdog == NMI_LOCAL_APIC) | ||
776 | { | ||
777 | if (nmi_watchdog_enabled) | ||
778 | enable_lapic_nmi_watchdog(); | ||
779 | else | ||
780 | disable_lapic_nmi_watchdog(); | ||
781 | } else if (nmi_watchdog == NMI_IO_APIC) { | ||
782 | /* FIXME | ||
783 | * for some reason these functions don't work | ||
784 | */ | ||
785 | printk("Can not enable/disable NMI on IO APIC\n"); | ||
786 | return -EIO; | ||
787 | #if 0 | ||
788 | if (nmi_watchdog_enabled) | ||
789 | enable_timer_nmi_watchdog(); | ||
790 | else | ||
791 | disable_timer_nmi_watchdog(); | ||
792 | #endif | ||
793 | } else { | ||
794 | printk(KERN_WARNING | ||
795 | "NMI watchdog doesn't know what hardware to touch\n"); | ||
796 | return -EIO; | ||
797 | } | ||
798 | return 0; | ||
799 | } | ||
800 | |||
753 | #endif | 801 | #endif |
754 | 802 | ||
755 | EXPORT_SYMBOL(nmi_active); | 803 | EXPORT_SYMBOL(nmi_active); |