Merge master.kernel.org:/pub/scm/linux/kernel/git/chrisw/lsm-2.6
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index 73aeaf5..4c1ddf2 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -28,6 +28,22 @@
 	int mbytes = num_physpages >> (20-PAGE_SHIFT);
 	int r;
 
+#ifdef CONFIG_SMP
+	unsigned long value;
+
+	/* Disable TLB flush filter by setting HWCR.FFDIS on K8
+	 * bit 6 of msr C001_0015
+	 *
+	 * Errata 63 for SH-B3 steppings
+	 * Errata 122 for all steppings (F+ have it disabled by default)
+	 */
+	if (c->x86 == 15) {
+		rdmsrl(MSR_K7_HWCR, value);
+		value |= 1 << 6;
+		wrmsrl(MSR_K7_HWCR, value);
+	}
+#endif
+
 	/*
 	 *	FIXME: We should handle the K5 here. Set up the write
 	 *	range and also turn on MSR 83 bits 4 and 31 (write alloc,
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
index 08203b0..69541db 100644
--- a/arch/x86_64/kernel/mce.c
+++ b/arch/x86_64/kernel/mce.c
@@ -54,9 +54,12 @@
 {
 	unsigned next, entry;
 	mce->finished = 0;
-	smp_wmb();
+	wmb();
 	for (;;) {
 		entry = rcu_dereference(mcelog.next);
+		/* The rmb forces the compiler to reload next in each
+		    iteration */
+		rmb();
 		for (;;) {
 			/* When the buffer fills up discard new entries. Assume
 			   that the earlier errors are the more interesting. */
@@ -69,6 +72,7 @@
 				entry++;
 				continue;
 			}
+			break;
 		}
 		smp_rmb();
 		next = entry + 1;
@@ -76,9 +80,9 @@
 			break;
 	}
 	memcpy(mcelog.entry + entry, mce, sizeof(struct mce));
-	smp_wmb();
+	wmb();
 	mcelog.entry[entry].finished = 1;
-	smp_wmb();
+	wmb();
 
 	if (!test_and_set_bit(0, &console_logged))
 		notify_user = 1;
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 238f73e..257f5ba 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -831,8 +831,6 @@
 #endif
 }
 
-#define HWCR 0xc0010015
-
 static int __init init_amd(struct cpuinfo_x86 *c)
 {
 	int r;
@@ -841,14 +839,18 @@
 #ifdef CONFIG_SMP
 	unsigned long value;
 
-	// Disable TLB flush filter by setting HWCR.FFDIS:
-	// bit 6 of msr C001_0015
-	//
-	// Errata 63 for SH-B3 steppings
-	// Errata 122 for all(?) steppings
-	rdmsrl(HWCR, value);
-	value |= 1 << 6;
-	wrmsrl(HWCR, value);
+	/*
+	 * Disable TLB flush filter by setting HWCR.FFDIS on K8
+	 * bit 6 of msr C001_0015
+ 	 *
+	 * Errata 63 for SH-B3 steppings
+	 * Errata 122 for all steppings (F+ have it disabled by default)
+	 */
+	if (c->x86 == 15) {
+		rdmsrl(MSR_K8_HWCR, value);
+		value |= 1 << 6;
+		wrmsrl(MSR_K8_HWCR, value);
+	}
 #endif
 
 	/* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index a85ac18..9b38674 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -153,8 +153,10 @@
 	spin_lock_irqsave(&smu->lock, flags);
 
 	gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO, NULL, smu->doorbell);
-	if ((gpio & 7) != 7)
+	if ((gpio & 7) != 7) {
+		spin_unlock_irqrestore(&smu->lock, flags);
 		return IRQ_HANDLED;
+	}
 
 	cmd = smu->cmd_cur;
 	smu->cmd_cur = NULL;
diff --git a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h
index 4d727f3..5a7fe3c 100644
--- a/include/asm-x86_64/msr.h
+++ b/include/asm-x86_64/msr.h
@@ -234,6 +234,7 @@
 #define MSR_K8_TOP_MEM1		   0xC001001A
 #define MSR_K8_TOP_MEM2		   0xC001001D
 #define MSR_K8_SYSCFG		   0xC0010010
+#define MSR_K8_HWCR		   0xC0010015
 
 /* K6 MSRs */
 #define MSR_K6_EFER			0xC0000080
diff --git a/include/linux/sched.h b/include/linux/sched.h
index afe6c61..c3ba31f 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -107,14 +107,26 @@
 
 #include <asm/processor.h>
 
+/*
+ * Task state bitmask. NOTE! These bits are also
+ * encoded in fs/proc/array.c: get_task_state().
+ *
+ * We have two separate sets of flags: task->state
+ * is about runnability, while task->exit_state are
+ * about the task exiting. Confusing, but this way
+ * modifying one set can't modify the other one by
+ * mistake.
+ */
 #define TASK_RUNNING		0
 #define TASK_INTERRUPTIBLE	1
 #define TASK_UNINTERRUPTIBLE	2
-#define TASK_NONINTERACTIVE	4
-#define TASK_STOPPED		8
-#define TASK_TRACED		16
-#define EXIT_ZOMBIE		32
-#define EXIT_DEAD		64
+#define TASK_STOPPED		4
+#define TASK_TRACED		8
+/* in tsk->exit_state */
+#define EXIT_ZOMBIE		16
+#define EXIT_DEAD		32
+/* in tsk->state again */
+#define TASK_NONINTERACTIVE	64
 
 #define __set_task_state(tsk, state_value)		\
 	do { (tsk)->state = (state_value); } while (0)
diff --git a/kernel/signal.c b/kernel/signal.c
index 5a27470..619b027 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1763,7 +1763,8 @@
 				 * stop is always done with the siglock held,
 				 * so this check has no races.
 				 */
-				if (t->state < TASK_STOPPED) {
+				if (!t->exit_state &&
+				    !(t->state & (TASK_STOPPED|TASK_TRACED))) {
 					stop_count++;
 					signal_wake_up(t, 0);
 				}