[PATCH] i386/x86-64: Remove un/set_nmi_callback and reserve/release_lapic_nmi functions
Removes the un/set_nmi_callback and reserve/release_lapic_nmi functions as they are no longer needed. The various subsystems are modified to register with the die_notifier instead. Also includes compile fixes by Andrew Morton. Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Andi Kleen <ak@suse.de>
This commit is contained in:
@@ -22,6 +22,8 @@
|
||||
#include <asm/nmi.h>
|
||||
#include <asm/hw_irq.h>
|
||||
#include <asm/apic.h>
|
||||
#include <asm/kdebug.h>
|
||||
|
||||
#include <mach_ipi.h>
|
||||
|
||||
|
||||
@@ -93,9 +95,18 @@ static void crash_save_self(struct pt_regs *regs)
|
||||
#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
|
||||
static atomic_t waiting_for_crash_ipi;
|
||||
|
||||
static int crash_nmi_callback(struct pt_regs *regs, int cpu)
|
||||
static int crash_nmi_callback(struct notifier_block *self,
|
||||
unsigned long val, void *data)
|
||||
{
|
||||
struct pt_regs *regs;
|
||||
struct pt_regs fixed_regs;
|
||||
int cpu;
|
||||
|
||||
if (val != DIE_NMI)
|
||||
return NOTIFY_OK;
|
||||
|
||||
regs = ((struct die_args *)data)->regs;
|
||||
cpu = raw_smp_processor_id();
|
||||
|
||||
/* Don't do anything if this handler is invoked on crashing cpu.
|
||||
* Otherwise, system will completely hang. Crashing cpu can get
|
||||
@@ -125,13 +136,18 @@ static void smp_send_nmi_allbutself(void)
|
||||
send_IPI_allbutself(NMI_VECTOR);
|
||||
}
|
||||
|
||||
static struct notifier_block crash_nmi_nb = {
|
||||
.notifier_call = crash_nmi_callback,
|
||||
};
|
||||
|
||||
static void nmi_shootdown_cpus(void)
|
||||
{
|
||||
unsigned long msecs;
|
||||
|
||||
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);
|
||||
if (register_die_notifier(&crash_nmi_nb))
|
||||
return; /* return what? */
|
||||
/* Ensure the new callback function is set before sending
|
||||
* out the NMI
|
||||
*/
|
||||
|
@@ -42,20 +42,6 @@ static DEFINE_PER_CPU(unsigned long, evntsel_nmi_owner[3]);
|
||||
*/
|
||||
#define NMI_MAX_COUNTER_BITS 66
|
||||
|
||||
/*
|
||||
* lapic_nmi_owner tracks the ownership of the lapic NMI hardware:
|
||||
* - it may be reserved by some other driver, or not
|
||||
* - when not reserved by some other driver, it may be used for
|
||||
* the NMI watchdog, or not
|
||||
*
|
||||
* This is maintained separately from nmi_active because the NMI
|
||||
* watchdog may also be driven from the I/O APIC timer.
|
||||
*/
|
||||
static DEFINE_SPINLOCK(lapic_nmi_owner_lock);
|
||||
static unsigned int lapic_nmi_owner;
|
||||
#define LAPIC_NMI_WATCHDOG (1<<0)
|
||||
#define LAPIC_NMI_RESERVED (1<<1)
|
||||
|
||||
/* nmi_active:
|
||||
* >0: the lapic NMI watchdog is active, but can be disabled
|
||||
* <0: the lapic NMI watchdog has not been set up, and cannot
|
||||
@@ -325,33 +311,6 @@ static void enable_lapic_nmi_watchdog(void)
|
||||
touch_nmi_watchdog();
|
||||
}
|
||||
|
||||
int reserve_lapic_nmi(void)
|
||||
{
|
||||
unsigned int old_owner;
|
||||
|
||||
spin_lock(&lapic_nmi_owner_lock);
|
||||
old_owner = lapic_nmi_owner;
|
||||
lapic_nmi_owner |= LAPIC_NMI_RESERVED;
|
||||
spin_unlock(&lapic_nmi_owner_lock);
|
||||
if (old_owner & LAPIC_NMI_RESERVED)
|
||||
return -EBUSY;
|
||||
if (old_owner & LAPIC_NMI_WATCHDOG)
|
||||
disable_lapic_nmi_watchdog();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void release_lapic_nmi(void)
|
||||
{
|
||||
unsigned int new_owner;
|
||||
|
||||
spin_lock(&lapic_nmi_owner_lock);
|
||||
new_owner = lapic_nmi_owner & ~LAPIC_NMI_RESERVED;
|
||||
lapic_nmi_owner = new_owner;
|
||||
spin_unlock(&lapic_nmi_owner_lock);
|
||||
if (new_owner & LAPIC_NMI_WATCHDOG)
|
||||
enable_lapic_nmi_watchdog();
|
||||
}
|
||||
|
||||
void disable_timer_nmi_watchdog(void)
|
||||
{
|
||||
BUG_ON(nmi_watchdog != NMI_IO_APIC);
|
||||
@@ -866,6 +825,15 @@ done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int do_nmi_callback(struct pt_regs * regs, int cpu)
|
||||
{
|
||||
#ifdef CONFIG_SYSCTL
|
||||
if (unknown_nmi_panic)
|
||||
return unknown_nmi_panic_callback(regs, cpu);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
|
||||
static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
|
||||
@@ -873,37 +841,8 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
|
||||
unsigned char reason = get_nmi_reason();
|
||||
char buf[64];
|
||||
|
||||
if (!(reason & 0xc0)) {
|
||||
sprintf(buf, "NMI received for unknown reason %02x\n", reason);
|
||||
die_nmi(regs, buf);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* proc handler for /proc/sys/kernel/unknown_nmi_panic
|
||||
*/
|
||||
int proc_unknown_nmi_panic(ctl_table *table, int write, struct file *file,
|
||||
void __user *buffer, size_t *length, loff_t *ppos)
|
||||
{
|
||||
int old_state;
|
||||
|
||||
old_state = unknown_nmi_panic;
|
||||
proc_dointvec(table, write, file, buffer, length, ppos);
|
||||
if (!!old_state == !!unknown_nmi_panic)
|
||||
return 0;
|
||||
|
||||
if (unknown_nmi_panic) {
|
||||
if (reserve_lapic_nmi() < 0) {
|
||||
unknown_nmi_panic = 0;
|
||||
return -EBUSY;
|
||||
} else {
|
||||
set_nmi_callback(unknown_nmi_panic_callback);
|
||||
}
|
||||
} else {
|
||||
release_lapic_nmi();
|
||||
unset_nmi_callback();
|
||||
}
|
||||
sprintf(buf, "NMI received for unknown reason %02x\n", reason);
|
||||
die_nmi(regs, buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -917,7 +856,5 @@ EXPORT_SYMBOL(reserve_perfctr_nmi);
|
||||
EXPORT_SYMBOL(release_perfctr_nmi);
|
||||
EXPORT_SYMBOL(reserve_evntsel_nmi);
|
||||
EXPORT_SYMBOL(release_evntsel_nmi);
|
||||
EXPORT_SYMBOL(reserve_lapic_nmi);
|
||||
EXPORT_SYMBOL(release_lapic_nmi);
|
||||
EXPORT_SYMBOL(disable_timer_nmi_watchdog);
|
||||
EXPORT_SYMBOL(enable_timer_nmi_watchdog);
|
||||
|
@@ -706,13 +706,6 @@ void die_nmi (struct pt_regs *regs, const char *msg)
|
||||
do_exit(SIGSEGV);
|
||||
}
|
||||
|
||||
static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static nmi_callback_t nmi_callback = dummy_nmi_callback;
|
||||
|
||||
static void default_do_nmi(struct pt_regs * regs)
|
||||
{
|
||||
unsigned char reason = 0;
|
||||
@@ -732,9 +725,10 @@ static void default_do_nmi(struct pt_regs * regs)
|
||||
*/
|
||||
if (nmi_watchdog_tick(regs, reason))
|
||||
return;
|
||||
if (!do_nmi_callback(regs, smp_processor_id()))
|
||||
#endif
|
||||
if (!rcu_dereference(nmi_callback)(regs, smp_processor_id()))
|
||||
unknown_nmi_error(reason, regs);
|
||||
|
||||
return;
|
||||
}
|
||||
if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
|
||||
@@ -765,19 +759,6 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code)
|
||||
nmi_exit();
|
||||
}
|
||||
|
||||
void set_nmi_callback(nmi_callback_t callback)
|
||||
{
|
||||
vmalloc_sync_all();
|
||||
rcu_assign_pointer(nmi_callback, callback);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(set_nmi_callback);
|
||||
|
||||
void unset_nmi_callback(void)
|
||||
{
|
||||
nmi_callback = dummy_nmi_callback;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(unset_nmi_callback);
|
||||
|
||||
#ifdef CONFIG_KPROBES
|
||||
fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
|
||||
{
|
||||
|
Reference in New Issue
Block a user