Merge branch 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6

* 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6:
  [PATCH] x86: Don't probe for DDC on VBE1.2
  [PATCH] x86-64: Increase NMI watchdog probing timeout
  [PATCH] x86-64: Let oprofile reserve MSR on all CPUs
  [PATCH] x86-64: Disable local APIC timer use on AMD systems with C1E
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
index 2c5b5cc..8143c95 100644
--- a/arch/i386/boot/video.S
+++ b/arch/i386/boot/video.S
@@ -571,6 +571,16 @@
 	jmp	_m_s
 
 check_vesa:
+#ifdef CONFIG_FIRMWARE_EDID
+	leaw	modelist+1024, %di
+	movw	$0x4f00, %ax
+	int	$0x10
+	cmpw	$0x004f, %ax
+	jnz	setbad
+
+	movw	4(%di), %ax
+	movw	%ax, vbe_version
+#endif
 	leaw	modelist+1024, %di
 	subb	$VIDEO_FIRST_VESA>>8, %bh
 	movw	%bx, %cx			# Get mode information structure
@@ -1945,6 +1955,9 @@
 	rep
 	stosl
 
+	cmpw	$0x0200, vbe_version		# only do EDID on >= VBE2.0
+	jl	no_edid
+
 	pushw   %es				# save ES
 	xorw    %di, %di                        # Report Capability
 	pushw   %di
@@ -1987,6 +2000,7 @@
 svga_prefix:	.byte	VIDEO_FIRST_BIOS>>8	# Default prefix for BIOS modes
 graphic_mode:	.byte	0	# Graphic mode with a linear frame buffer
 dac_size:	.byte	6	# DAC bit depth
+vbe_version:	.word	0	# VBE bios version
 
 # Status messages
 keymsg:		.ascii	"Press <RETURN> to see video modes available, "
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index e884152..93aa911 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -272,32 +272,6 @@
 }
 
 /*
- * Detect systems with known broken BIOS implementations
- */
-static int __init lapic_check_broken_bios(struct dmi_system_id *d)
-{
-	printk(KERN_NOTICE "%s detected: disabling lapic timer.\n",
-		       d->ident);
-	local_apic_timer_disabled = 1;
-	return 0;
-}
-
-static struct dmi_system_id __initdata broken_bios_dmi_table[] = {
-	{
-		/*
-		 * BIOS exports only C1 state, but uses deeper power
-		 * modes behind the kernels back.
-		 */
-		  .callback = lapic_check_broken_bios,
-		  .ident = "HP nx6325",
-		  .matches = {
-			DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"),
-		  },
-	 },
-	 {}
-};
-
-/*
  * In this functions we calibrate APIC bus clocks to the external timer.
  *
  * We want to do the calibration only once since we want to have local timer
@@ -372,12 +346,12 @@
 	long delta, deltapm;
 	int pm_referenced = 0;
 
-	/* Detect know broken systems */
-	dmi_check_system(broken_bios_dmi_table);
+	if (boot_cpu_has(X86_FEATURE_LAPIC_TIMER_BROKEN))
+		local_apic_timer_disabled = 1;
 
 	/*
 	 * The local apic timer can be disabled via the kernel
-	 * commandline or from the dmi quirk above. Register the lapic
+	 * commandline or from the test above. Register the lapic
 	 * timer as a dummy clock event source on SMP systems, so the
 	 * broadcast mechanism is used. On UP systems simply ignore it.
 	 */
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index 41cfea5..2d47db4 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -22,6 +22,37 @@
 extern void vide(void);
 __asm__(".align 4\nvide: ret");
 
+#define ENABLE_C1E_MASK         0x18000000
+#define CPUID_PROCESSOR_SIGNATURE       1
+#define CPUID_XFAM              0x0ff00000
+#define CPUID_XFAM_K8           0x00000000
+#define CPUID_XFAM_10H          0x00100000
+#define CPUID_XFAM_11H          0x00200000
+#define CPUID_XMOD              0x000f0000
+#define CPUID_XMOD_REV_F        0x00040000
+
+/* AMD systems with C1E don't have a working lAPIC timer. Check for that. */
+static __cpuinit int amd_apic_timer_broken(void)
+{
+	u32 lo, hi;
+	u32 eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
+	switch (eax & CPUID_XFAM) {
+	case CPUID_XFAM_K8:
+		if ((eax & CPUID_XMOD) < CPUID_XMOD_REV_F)
+			break;
+	case CPUID_XFAM_10H:
+	case CPUID_XFAM_11H:
+		rdmsr(MSR_K8_ENABLE_C1E, lo, hi);
+		if (lo & ENABLE_C1E_MASK)
+			return 1;
+                break;
+        default:
+                /* err on the side of caution */
+		return 1;
+        }
+	return 0;
+}
+
 static void __cpuinit init_amd(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
@@ -241,6 +272,9 @@
 
 	if (cpuid_eax(0x80000000) >= 0x80000006)
 		num_cache_leaves = 3;
+
+	if (amd_apic_timer_broken())
+		set_bit(X86_FEATURE_LAPIC_TIMER_BROKEN, c->x86_capability);
 }
 
 static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index 1470242..a98ba88 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -122,64 +122,129 @@
 /* checks for a bit availability (hack for oprofile) */
 int avail_to_resrv_perfctr_nmi_bit(unsigned int counter)
 {
+	int cpu;
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
-
-	return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner)));
+	for_each_possible_cpu (cpu) {
+		if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
+			return 0;
+	}
+	return 1;
 }
 
 /* checks the an msr for availability */
 int avail_to_resrv_perfctr_nmi(unsigned int msr)
 {
 	unsigned int counter;
+	int cpu;
 
 	counter = nmi_perfctr_msr_to_bit(msr);
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
 
-	return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner)));
+	for_each_possible_cpu (cpu) {
+		if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
+			return 0;
+	}
+	return 1;
+}
+
+static int __reserve_perfctr_nmi(int cpu, unsigned int msr)
+{
+	unsigned int counter;
+	if (cpu < 0)
+		cpu = smp_processor_id();
+
+	counter = nmi_perfctr_msr_to_bit(msr);
+	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+
+	if (!test_and_set_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
+		return 1;
+	return 0;
+}
+
+static void __release_perfctr_nmi(int cpu, unsigned int msr)
+{
+	unsigned int counter;
+	if (cpu < 0)
+		cpu = smp_processor_id();
+
+	counter = nmi_perfctr_msr_to_bit(msr);
+	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+
+	clear_bit(counter, &per_cpu(perfctr_nmi_owner, cpu));
 }
 
 int reserve_perfctr_nmi(unsigned int msr)
 {
-	unsigned int counter;
-
-	counter = nmi_perfctr_msr_to_bit(msr);
-	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
-
-	if (!test_and_set_bit(counter, &__get_cpu_var(perfctr_nmi_owner)))
-		return 1;
-	return 0;
+	int cpu, i;
+	for_each_possible_cpu (cpu) {
+		if (!__reserve_perfctr_nmi(cpu, msr)) {
+			for_each_possible_cpu (i) {
+				if (i >= cpu)
+					break;
+				__release_perfctr_nmi(i, msr);
+			}
+			return 0;
+		}
+	}
+	return 1;
 }
 
 void release_perfctr_nmi(unsigned int msr)
 {
-	unsigned int counter;
-
-	counter = nmi_perfctr_msr_to_bit(msr);
-	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
-
-	clear_bit(counter, &__get_cpu_var(perfctr_nmi_owner));
+	int cpu;
+	for_each_possible_cpu (cpu) {
+		__release_perfctr_nmi(cpu, msr);
+	}
 }
 
-int reserve_evntsel_nmi(unsigned int msr)
+int __reserve_evntsel_nmi(int cpu, unsigned int msr)
 {
 	unsigned int counter;
+	if (cpu < 0)
+		cpu = smp_processor_id();
 
 	counter = nmi_evntsel_msr_to_bit(msr);
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
 
-	if (!test_and_set_bit(counter, &__get_cpu_var(evntsel_nmi_owner)[0]))
+	if (!test_and_set_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0]))
 		return 1;
 	return 0;
 }
 
-void release_evntsel_nmi(unsigned int msr)
+static void __release_evntsel_nmi(int cpu, unsigned int msr)
 {
 	unsigned int counter;
+	if (cpu < 0)
+		cpu = smp_processor_id();
 
 	counter = nmi_evntsel_msr_to_bit(msr);
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
 
-	clear_bit(counter, &__get_cpu_var(evntsel_nmi_owner)[0]);
+	clear_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0]);
+}
+
+int reserve_evntsel_nmi(unsigned int msr)
+{
+	int cpu, i;
+	for_each_possible_cpu (cpu) {
+		if (!__reserve_evntsel_nmi(cpu, msr)) {
+			for_each_possible_cpu (i) {
+				if (i >= cpu)
+					break;
+				__release_evntsel_nmi(i, msr);
+			}
+			return 0;
+		}
+	}
+	return 1;
+}
+
+void release_evntsel_nmi(unsigned int msr)
+{
+	int cpu;
+	for_each_possible_cpu (cpu) {
+		__release_evntsel_nmi(cpu, msr);
+	}
 }
 
 static __cpuinit inline int nmi_known_cpu(void)
@@ -263,7 +328,7 @@
 	for_each_possible_cpu(cpu)
 		prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count;
 	local_irq_enable();
-	mdelay((10*1000)/nmi_hz); // wait 10 ticks
+	mdelay((20*1000)/nmi_hz); // wait 20 ticks
 
 	for_each_possible_cpu(cpu) {
 #ifdef CONFIG_SMP
@@ -507,10 +572,10 @@
 
 	perfctr_msr = MSR_K7_PERFCTR0;
 	evntsel_msr = MSR_K7_EVNTSEL0;
-	if (!reserve_perfctr_nmi(perfctr_msr))
+	if (!__reserve_perfctr_nmi(-1, perfctr_msr))
 		goto fail;
 
-	if (!reserve_evntsel_nmi(evntsel_msr))
+	if (!__reserve_evntsel_nmi(-1, evntsel_msr))
 		goto fail1;
 
 	wrmsrl(perfctr_msr, 0UL);
@@ -533,7 +598,7 @@
 	wd->check_bit = 1ULL<<63;
 	return 1;
 fail1:
-	release_perfctr_nmi(perfctr_msr);
+	__release_perfctr_nmi(-1, perfctr_msr);
 fail:
 	return 0;
 }
@@ -544,8 +609,8 @@
 
 	wrmsr(wd->evntsel_msr, 0, 0);
 
-	release_evntsel_nmi(wd->evntsel_msr);
-	release_perfctr_nmi(wd->perfctr_msr);
+	__release_evntsel_nmi(-1, wd->evntsel_msr);
+	__release_perfctr_nmi(-1, wd->perfctr_msr);
 }
 
 #define P6_EVNTSEL0_ENABLE	(1 << 22)
@@ -563,10 +628,10 @@
 
 	perfctr_msr = MSR_P6_PERFCTR0;
 	evntsel_msr = MSR_P6_EVNTSEL0;
-	if (!reserve_perfctr_nmi(perfctr_msr))
+	if (!__reserve_perfctr_nmi(-1, perfctr_msr))
 		goto fail;
 
-	if (!reserve_evntsel_nmi(evntsel_msr))
+	if (!__reserve_evntsel_nmi(-1, evntsel_msr))
 		goto fail1;
 
 	wrmsrl(perfctr_msr, 0UL);
@@ -590,7 +655,7 @@
 	wd->check_bit = 1ULL<<39;
 	return 1;
 fail1:
-	release_perfctr_nmi(perfctr_msr);
+	__release_perfctr_nmi(-1, perfctr_msr);
 fail:
 	return 0;
 }
@@ -601,8 +666,8 @@
 
 	wrmsr(wd->evntsel_msr, 0, 0);
 
-	release_evntsel_nmi(wd->evntsel_msr);
-	release_perfctr_nmi(wd->perfctr_msr);
+	__release_evntsel_nmi(-1, wd->evntsel_msr);
+	__release_perfctr_nmi(-1, wd->perfctr_msr);
 }
 
 /* Note that these events don't tick when the CPU idles. This means
@@ -668,10 +733,10 @@
 		cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4);
 	}
 
-	if (!reserve_perfctr_nmi(perfctr_msr))
+	if (!__reserve_perfctr_nmi(-1, perfctr_msr))
 		goto fail;
 
-	if (!reserve_evntsel_nmi(evntsel_msr))
+	if (!__reserve_evntsel_nmi(-1, evntsel_msr))
 		goto fail1;
 
 	evntsel = P4_ESCR_EVENT_SELECT(0x3F)
@@ -695,7 +760,7 @@
 	wd->check_bit = 1ULL<<39;
 	return 1;
 fail1:
-	release_perfctr_nmi(perfctr_msr);
+	__release_perfctr_nmi(-1, perfctr_msr);
 fail:
 	return 0;
 }
@@ -707,8 +772,8 @@
 	wrmsr(wd->cccr_msr, 0, 0);
 	wrmsr(wd->evntsel_msr, 0, 0);
 
-	release_evntsel_nmi(wd->evntsel_msr);
-	release_perfctr_nmi(wd->perfctr_msr);
+	__release_evntsel_nmi(-1, wd->evntsel_msr);
+	__release_perfctr_nmi(-1, wd->perfctr_msr);
 }
 
 #define ARCH_PERFMON_NMI_EVENT_SEL	ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL
@@ -736,10 +801,10 @@
 	perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0;
 	evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0;
 
-	if (!reserve_perfctr_nmi(perfctr_msr))
+	if (!__reserve_perfctr_nmi(-1, perfctr_msr))
 		goto fail;
 
-	if (!reserve_evntsel_nmi(evntsel_msr))
+	if (!__reserve_evntsel_nmi(-1, evntsel_msr))
 		goto fail1;
 
 	wrmsrl(perfctr_msr, 0UL);
@@ -764,7 +829,7 @@
 	wd->check_bit = 1ULL << (eax.split.bit_width - 1);
 	return 1;
 fail1:
-	release_perfctr_nmi(perfctr_msr);
+	__release_perfctr_nmi(-1, perfctr_msr);
 fail:
 	return 0;
 }
@@ -787,8 +852,8 @@
 		return;
 
 	wrmsr(wd->evntsel_msr, 0, 0);
-	release_evntsel_nmi(wd->evntsel_msr);
-	release_perfctr_nmi(wd->perfctr_msr);
+	__release_evntsel_nmi(-1, wd->evntsel_msr);
+	__release_perfctr_nmi(-1, wd->perfctr_msr);
 }
 
 void setup_apic_nmi_watchdog (void *unused)
diff --git a/arch/x86_64/boot/video.S b/arch/x86_64/boot/video.S
index d6ff88f..6090516 100644
--- a/arch/x86_64/boot/video.S
+++ b/arch/x86_64/boot/video.S
@@ -571,6 +571,16 @@
 	jmp	_m_s
 
 check_vesa:
+#ifdef CONFIG_FIRMWARE_EDID
+	leaw	modelist+1024, %di
+	movw	$0x4f00, %ax
+	int	$0x10
+	cmpw	$0x004f, %ax
+	jnz	setbad
+
+	movw	4(%di), %ax
+	movw	%ax, vbe_version
+#endif
 	leaw	modelist+1024, %di
 	subb	$VIDEO_FIRST_VESA>>8, %bh
 	movw	%bx, %cx			# Get mode information structure
@@ -1945,6 +1955,9 @@
 	rep
 	stosl
 
+	cmpw	$0x0200, vbe_version		# only do EDID on >= VBE2.0
+	jl	no_edid
+
 	pushw   %es				# save ES
 	xorw    %di, %di                        # Report Capability
 	pushw   %di
@@ -1987,6 +2000,7 @@
 svga_prefix:	.byte	VIDEO_FIRST_BIOS>>8	# Default prefix for BIOS modes
 graphic_mode:	.byte	0	# Graphic mode with a linear frame buffer
 dac_size:	.byte	6	# DAC bit depth
+vbe_version:	.word	0	# VBE bios version
 
 # Status messages
 keymsg:		.ascii	"Press <RETURN> to see video modes available, "
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index 82d9d85..a90996c 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -108,64 +108,128 @@
 /* checks for a bit availability (hack for oprofile) */
 int avail_to_resrv_perfctr_nmi_bit(unsigned int counter)
 {
+	int cpu;
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
-
-	return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner)));
+	for_each_possible_cpu (cpu) {
+		if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
+			return 0;
+	}
+	return 1;
 }
 
 /* checks the an msr for availability */
 int avail_to_resrv_perfctr_nmi(unsigned int msr)
 {
 	unsigned int counter;
+	int cpu;
 
 	counter = nmi_perfctr_msr_to_bit(msr);
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
 
-	return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner)));
+	for_each_possible_cpu (cpu) {
+		if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
+			return 0;
+	}
+	return 1;
+}
+
+static int __reserve_perfctr_nmi(int cpu, unsigned int msr)
+{
+	unsigned int counter;
+	if (cpu < 0)
+		cpu = smp_processor_id();
+
+	counter = nmi_perfctr_msr_to_bit(msr);
+	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+
+	if (!test_and_set_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
+		return 1;
+	return 0;
+}
+
+static void __release_perfctr_nmi(int cpu, unsigned int msr)
+{
+	unsigned int counter;
+	if (cpu < 0)
+		cpu = smp_processor_id();
+
+	counter = nmi_perfctr_msr_to_bit(msr);
+	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+
+	clear_bit(counter, &per_cpu(perfctr_nmi_owner, cpu));
 }
 
 int reserve_perfctr_nmi(unsigned int msr)
 {
-	unsigned int counter;
-
-	counter = nmi_perfctr_msr_to_bit(msr);
-	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
-
-	if (!test_and_set_bit(counter, &__get_cpu_var(perfctr_nmi_owner)))
-		return 1;
-	return 0;
+	int cpu, i;
+	for_each_possible_cpu (cpu) {
+		if (!__reserve_perfctr_nmi(cpu, msr)) {
+			for_each_possible_cpu (i) {
+				if (i >= cpu)
+					break;
+				__release_perfctr_nmi(i, msr);
+			}
+			return 0;
+		}
+	}
+	return 1;
 }
 
 void release_perfctr_nmi(unsigned int msr)
 {
-	unsigned int counter;
-
-	counter = nmi_perfctr_msr_to_bit(msr);
-	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
-
-	clear_bit(counter, &__get_cpu_var(perfctr_nmi_owner));
+	int cpu;
+	for_each_possible_cpu (cpu)
+		__release_perfctr_nmi(cpu, msr);
 }
 
-int reserve_evntsel_nmi(unsigned int msr)
+int __reserve_evntsel_nmi(int cpu, unsigned int msr)
 {
 	unsigned int counter;
+	if (cpu < 0)
+		cpu = smp_processor_id();
 
 	counter = nmi_evntsel_msr_to_bit(msr);
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
 
-	if (!test_and_set_bit(counter, &__get_cpu_var(evntsel_nmi_owner)))
+	if (!test_and_set_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0]))
 		return 1;
 	return 0;
 }
 
-void release_evntsel_nmi(unsigned int msr)
+static void __release_evntsel_nmi(int cpu, unsigned int msr)
 {
 	unsigned int counter;
+	if (cpu < 0)
+		cpu = smp_processor_id();
 
 	counter = nmi_evntsel_msr_to_bit(msr);
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
 
-	clear_bit(counter, &__get_cpu_var(evntsel_nmi_owner));
+	clear_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0]);
+}
+
+int reserve_evntsel_nmi(unsigned int msr)
+{
+	int cpu, i;
+	for_each_possible_cpu (cpu) {
+		if (!__reserve_evntsel_nmi(cpu, msr)) {
+			for_each_possible_cpu (i) {
+				if (i >= cpu)
+					break;
+				__release_evntsel_nmi(i, msr);
+			}
+			return 0;
+		}
+	}
+	return 1;
+}
+
+void release_evntsel_nmi(unsigned int msr)
+{
+	int cpu;
+	for_each_possible_cpu (cpu) {
+		__release_evntsel_nmi(cpu, msr);
+	}
 }
 
 static __cpuinit inline int nmi_known_cpu(void)
@@ -253,7 +317,7 @@
 	for (cpu = 0; cpu < NR_CPUS; cpu++)
 		counts[cpu] = cpu_pda(cpu)->__nmi_count;
 	local_irq_enable();
-	mdelay((10*1000)/nmi_hz); // wait 10 ticks
+	mdelay((20*1000)/nmi_hz); // wait 20 ticks
 
 	for_each_online_cpu(cpu) {
 		if (!per_cpu(nmi_watchdog_ctlblk, cpu).enabled)
@@ -472,10 +536,10 @@
 
 	perfctr_msr = MSR_K7_PERFCTR0;
 	evntsel_msr = MSR_K7_EVNTSEL0;
-	if (!reserve_perfctr_nmi(perfctr_msr))
+	if (!__reserve_perfctr_nmi(-1, perfctr_msr))
 		goto fail;
 
-	if (!reserve_evntsel_nmi(evntsel_msr))
+	if (!__reserve_evntsel_nmi(-1, evntsel_msr))
 		goto fail1;
 
 	/* Simulator may not support it */
@@ -501,9 +565,9 @@
 	wd->check_bit = 1ULL<<63;
 	return 1;
 fail2:
-	release_evntsel_nmi(evntsel_msr);
+	__release_evntsel_nmi(-1, evntsel_msr);
 fail1:
-	release_perfctr_nmi(perfctr_msr);
+	__release_perfctr_nmi(-1, perfctr_msr);
 fail:
 	return 0;
 }
@@ -514,8 +578,8 @@
 
 	wrmsr(wd->evntsel_msr, 0, 0);
 
-	release_evntsel_nmi(wd->evntsel_msr);
-	release_perfctr_nmi(wd->perfctr_msr);
+	__release_evntsel_nmi(-1, wd->evntsel_msr);
+	__release_perfctr_nmi(-1, wd->perfctr_msr);
 }
 
 /* Note that these events don't tick when the CPU idles. This means
@@ -581,10 +645,10 @@
 		cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4);
 	}
 
-	if (!reserve_perfctr_nmi(perfctr_msr))
+	if (!__reserve_perfctr_nmi(-1, perfctr_msr))
 		goto fail;
 
-	if (!reserve_evntsel_nmi(evntsel_msr))
+	if (!__reserve_evntsel_nmi(-1, evntsel_msr))
 		goto fail1;
 
 	evntsel = P4_ESCR_EVENT_SELECT(0x3F)
@@ -609,7 +673,7 @@
 	wd->check_bit = 1ULL<<39;
 	return 1;
 fail1:
-	release_perfctr_nmi(perfctr_msr);
+	__release_perfctr_nmi(-1, perfctr_msr);
 fail:
 	return 0;
 }
@@ -621,8 +685,8 @@
 	wrmsr(wd->cccr_msr, 0, 0);
 	wrmsr(wd->evntsel_msr, 0, 0);
 
-	release_evntsel_nmi(wd->evntsel_msr);
-	release_perfctr_nmi(wd->perfctr_msr);
+	__release_evntsel_nmi(-1, wd->evntsel_msr);
+	__release_perfctr_nmi(-1, wd->perfctr_msr);
 }
 
 #define ARCH_PERFMON_NMI_EVENT_SEL	ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL
@@ -650,10 +714,10 @@
 	perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0;
 	evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0;
 
-	if (!reserve_perfctr_nmi(perfctr_msr))
+	if (!__reserve_perfctr_nmi(-1, perfctr_msr))
 		goto fail;
 
-	if (!reserve_evntsel_nmi(evntsel_msr))
+	if (!__reserve_evntsel_nmi(-1, evntsel_msr))
 		goto fail1;
 
 	wrmsrl(perfctr_msr, 0UL);
@@ -680,7 +744,7 @@
 	wd->check_bit = 1ULL << (eax.split.bit_width - 1);
 	return 1;
 fail1:
-	release_perfctr_nmi(perfctr_msr);
+	__release_perfctr_nmi(-1, perfctr_msr);
 fail:
 	return 0;
 }
@@ -704,8 +768,8 @@
 
 	wrmsr(wd->evntsel_msr, 0, 0);
 
-	release_evntsel_nmi(wd->evntsel_msr);
-	release_perfctr_nmi(wd->perfctr_msr);
+	__release_evntsel_nmi(-1, wd->evntsel_msr);
+	__release_perfctr_nmi(-1, wd->perfctr_msr);
 }
 
 void setup_apic_nmi_watchdog(void *unused)
diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h
index 3f92b94..d1b8e4a 100644
--- a/include/asm-i386/cpufeature.h
+++ b/include/asm-i386/cpufeature.h
@@ -75,6 +75,7 @@
 #define X86_FEATURE_ARCH_PERFMON (3*32+11) /* Intel Architectural PerfMon */
 #define X86_FEATURE_PEBS	(3*32+12)  /* Precise-Event Based Sampling */
 #define X86_FEATURE_BTS		(3*32+13)  /* Branch Trace Store */
+#define X86_FEATURE_LAPIC_TIMER_BROKEN (3*32+ 14) /* lapic timer broken in C1 */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3	(4*32+ 0) /* Streaming SIMD Extensions-3 */
diff --git a/include/asm-i386/msr.h b/include/asm-i386/msr.h
index ec3b680..2ad3f30 100644
--- a/include/asm-i386/msr.h
+++ b/include/asm-i386/msr.h
@@ -275,6 +275,8 @@
 #define MSR_K7_FID_VID_CTL		0xC0010041
 #define MSR_K7_FID_VID_STATUS		0xC0010042
 
+#define MSR_K8_ENABLE_C1E		0xC0010055
+
 /* extended feature register */
 #define MSR_EFER 			0xc0000080