Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 62476
b: refs/heads/master
c: 8f4e956
h: refs/heads/master
v: v3
  • Loading branch information
Andi Kleen authored and Linus Torvalds committed Jul 22, 2007
1 parent 240bf17 commit 8883187
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 19d36ccdc34f5ed444f8a6af0cbfdb6790eb1177
refs/heads/master: 8f4e956b313dcccbc7be6f10808952345e3b638c
15 changes: 15 additions & 0 deletions trunk/arch/i386/kernel/alternative.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <asm/alternative.h>
#include <asm/sections.h>
#include <asm/pgtable.h>
#include <asm/mce.h>
#include <asm/nmi.h>

#ifdef CONFIG_HOTPLUG_CPU
static int smp_alt_once;
Expand Down Expand Up @@ -373,6 +375,14 @@ void __init alternative_instructions(void)
{
unsigned long flags;

/* The patching is not fully atomic, so try to avoid local interruptions
that might execute the to be patched code.
Other CPUs are not running. */
stop_nmi();
#ifdef CONFIG_MCE
stop_mce();
#endif

local_irq_save(flags);
apply_alternatives(__alt_instructions, __alt_instructions_end);

Expand Down Expand Up @@ -405,6 +415,11 @@ void __init alternative_instructions(void)
#endif
apply_paravirt(__parainstructions, __parainstructions_end);
local_irq_restore(flags);

restart_nmi();
#ifdef CONFIG_MCE
restart_mce();
#endif
}

/*
Expand Down
14 changes: 14 additions & 0 deletions trunk/arch/i386/kernel/cpu/mcheck/mce.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,20 @@ void mcheck_init(struct cpuinfo_x86 *c)
}
}

static unsigned long old_cr4 __initdata;

void __init stop_mce(void)
{
old_cr4 = read_cr4();
clear_in_cr4(X86_CR4_MCE);
}

void __init restart_mce(void)
{
if (old_cr4 & X86_CR4_MCE)
set_in_cr4(X86_CR4_MCE);
}

static int __init mcheck_disable(char *str)
{
mce_disabled = 1;
Expand Down
17 changes: 16 additions & 1 deletion trunk/arch/i386/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,8 @@ static __kprobes void default_do_nmi(struct pt_regs * regs)
reassert_nmi();
}

static int ignore_nmis;

fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code)
{
int cpu;
Expand All @@ -785,11 +787,24 @@ fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code)

++nmi_count(cpu);

default_do_nmi(regs);
if (!ignore_nmis)
default_do_nmi(regs);

nmi_exit();
}

void stop_nmi(void)
{
acpi_nmi_disable();
ignore_nmis++;
}

void restart_nmi(void)
{
ignore_nmis--;
acpi_nmi_enable();
}

#ifdef CONFIG_KPROBES
fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
{
Expand Down
14 changes: 14 additions & 0 deletions trunk/arch/x86_64/kernel/mce.c
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,20 @@ static struct miscdevice mce_log_device = {
&mce_chrdev_ops,
};

static unsigned long old_cr4 __initdata;

void __init stop_mce(void)
{
old_cr4 = read_cr4();
clear_in_cr4(X86_CR4_MCE);
}

void __init restart_mce(void)
{
if (old_cr4 & X86_CR4_MCE)
set_in_cr4(X86_CR4_MCE);
}

/*
* Old style boot options parsing. Only for compatibility.
*/
Expand Down
17 changes: 16 additions & 1 deletion trunk/arch/x86_64/kernel/nmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,11 +384,14 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
return rc;
}

static unsigned ignore_nmis;

asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code)
{
nmi_enter();
add_pda(__nmi_count,1);
default_do_nmi(regs);
if (!ignore_nmis)
default_do_nmi(regs);
nmi_exit();
}

Expand All @@ -401,6 +404,18 @@ int do_nmi_callback(struct pt_regs * regs, int cpu)
return 0;
}

void stop_nmi(void)
{
acpi_nmi_disable();
ignore_nmis++;
}

void restart_nmi(void)
{
ignore_nmis--;
acpi_nmi_enable();
}

#ifdef CONFIG_SYSCTL

static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
Expand Down
4 changes: 4 additions & 0 deletions trunk/include/asm-i386/mce.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ extern void mcheck_init(struct cpuinfo_x86 *c);
#endif

extern int mce_disabled;

extern void stop_mce(void);
extern void restart_mce(void);

2 changes: 2 additions & 0 deletions trunk/include/asm-i386/nmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,7 @@ unsigned lapic_adjust_nmi_hz(unsigned hz);
int lapic_watchdog_ok(void);
void disable_lapic_nmi_watchdog(void);
void enable_lapic_nmi_watchdog(void);
void stop_nmi(void);
void restart_nmi(void);

#endif /* ASM_NMI_H */
3 changes: 3 additions & 0 deletions trunk/include/asm-x86_64/mce.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ extern void do_machine_check(struct pt_regs *, long);

extern int mce_notify_user(void);

extern void stop_mce(void);
extern void restart_mce(void);

#endif

#endif
2 changes: 2 additions & 0 deletions trunk/include/asm-x86_64/nmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,7 @@ unsigned lapic_adjust_nmi_hz(unsigned hz);
int lapic_watchdog_ok(void);
void disable_lapic_nmi_watchdog(void);
void enable_lapic_nmi_watchdog(void);
void stop_nmi(void);
void restart_nmi(void);

#endif /* ASM_NMI_H */

0 comments on commit 8883187

Please sign in to comment.