summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-09-17 15:41:04 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-17 15:41:04 -0700
commitbc5e8fdfc622b03acf5ac974a1b8b26da6511c99 (patch)
tree912dbeaadd246bd053a9650c79d1bd98bbc71556
parent61ffcafafb3d985e1ab8463be0187b421614775c (diff)
x86-64/smp: fix random SIGSEGV issues
They seem to have been due to AMD errata 63/122; the fix is to disable TLB flush filtering in SMP configurations. Confirmed to fix the problem by Andrew Walrond <andrew@walrond.org> [ Let's see if we'll have a better fix eventually, this is the Q&D "let's get this fixed and out there" version ] Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/x86_64/kernel/setup.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 351d8d64c2f..238f73e1a83 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -831,11 +831,26 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
#endif
}
+#define HWCR 0xc0010015
+
static int __init init_amd(struct cpuinfo_x86 *c)
{
int r;
int level;
+#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);
+#endif
+
/* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
clear_bit(0*32+31, &c->x86_capability);