lkml.org 
[lkml]   [2002]   [Jun]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
SubjectRE: Cache-attribute conflict bug in the kernel exposed on newer . ..
Date
Below is the short-term patch we have been testing.
In our testing so far across multiple cards and systems,
it appears to remove the failures. As I said before,
it theoretically leaves a small hole open
that we have not seen exploited in practice after much testing.

My gut feeling is that distributions looking to release a fix
very soon will be well served by the short-term patch.

Meanwhile, the community can hammer[1] out any lingering
issues with the long-term solution -- which the distributions can
choose to pick up on their next update.


[1] Why is it every time some one from AMD uses the verb "to hammer",
we have to say "no pun intended" ? ;-)

-Rich ...
[richard.brunner@amd.com -- (360)-867-0654]
[Senior Member, Technical Staff, SW R&D @ AMD]


--- linux/arch/i386/kernel/setup.c Fri Jun 7 12:46:23 2002
+++ linux-2.4.19pre9work/arch/i386/kernel/setup.c Mon Jun 10 18:08:56 2002
@@ -71,6 +71,11 @@
* CacheSize bug workaround updates for AMD, Intel & VIA Cyrix.
* Dave Jones <davej@suse.de>, September, October 2001.
*
+ * Short-term fix for a conflicting cache attribute bug in the kernel
+ * that is exposed by advanced speculative caching on new AMD Athlon
+ * processors.
+ * Richard Brunner <richard.brunner@amd.com> and Mark Langsdorf
+ * <mark.langsdorf@amd.com>, June 2002
*/

/*
@@ -169,7 +174,11 @@
static int disable_x86_ht __initdata = 0;

int enable_acpi_smp_table;
-
+#ifdef CONFIG_AGP
+int disable_adv_spec_cache __initdata = 1;
+#else
+int disable_adv_spec_cache __initdata = 0;
+#endif /* CONFIG_AGP */
/*
* This is set up by the setup-routine at boot-time
*/
@@ -727,6 +736,36 @@
print_memory_map(who);
} /* setup_memory_region */

+int __init amd_adv_spec_cache_feature(void)
+{
+ char vendor_id[16];
+ int ident;
+ int family, model;
+
+ /* Must have CPUID */
+ if(!have_cpuid_p())
+ return 0;
+ if(cpuid_eax(0)<1)
+ return 0;
+
+ /* Must be x86 architecture */
+ cpuid(0, &ident,
+ (int *)&vendor_id[0],
+ (int *)&vendor_id[8],
+ (int *)&vendor_id[4]);
+
+ if (memcmp(vendor_id, "AuthenticAMD", 12))
+ return 0;
+
+ ident = cpuid_eax(1);
+ family = (ident >> 8) & 0xf;
+ model = (ident >> 4) & 0xf;
+ if (((family == 6) && (model >= 6)) || (family == 15))
+ /* Feature present */
+ return 1;
+
+ return 0;
+}

static void __init parse_cmdline_early (char ** cmdline_p)
{
@@ -793,6 +832,17 @@
*/
else if (!memcmp(from, "highmem=", 8))
highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT;
+ /*
+ * unsafe-gart-alias overrides the short-term fix for a
+ * conflicting cache attribute bug in the kernel that is
+ * exposed by advanced speculative caching in newer AMD
+ * Athlon processors. Overriding the fix will allow
+ * higher performance but the kernel bug can cause system
+ * lock-ups if the system uses an AGP card. unsafe-gart-alias
+ * can be turned on for higher performance in servers.
+ */
+ else if (!memcmp(from, "unsafe-gart-alias", 17))
+ disable_adv_spec_cache = 0;
nextchar:
c = *(from++);
if (!c)
@@ -1057,6 +1107,14 @@
#ifdef CONFIG_SMP
smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
#endif
+ /*
+ * short-term fix for a conflicting cache attribute bug in the
+ * kernel that is exposed by advanced speculative caching on
+ * newer AMD Athlon processors.
+ */
+ if (disable_adv_spec_cache && amd_adv_spec_cache_feature() )
+ clear_bit(X86_FEATURE_PSE, &boot_cpu_data.x86_capability);
+
paging_init();
#ifdef CONFIG_X86_LOCAL_APIC
/*
@@ -1225,6 +1283,27 @@
l2size, ecx & 0xFF);
}

+/*=======================================================================
+ * amd_adv_spec_cache_disable
+ * Setting a special MSR bit that disables a small part of advanced
+ * speculative caching as part of a short-term fix for a conflicting cache
+ * attribute bug in the kernel that is exposed by advanced speculative
+ * caching in newer AMD Athlon processors.
+ =======================================================================*/
+static void amd_adv_spec_cache_disable(void)
+{
+ __asm__ __volatile__ (
+ " movl $0x9c5a203a,%%edi \n" /* msr enable */
+ " movl $0xc0011022,%%ecx \n" /* msr addr */
+ " rdmsr \n" /* get reg val */
+ " orl $0x00010000,%%eax \n" /* set bit 16 */
+ " wrmsr \n" /* put it back */
+ " xorl %%edi, %%edi \n" /* clear msr enable */
+ : /* no outputs */
+ : /* no inputs, either */
+ : "%eax","%ecx","%edx","%edi" /* clobbered regs */ );
+}
+
/*
* B step AMD K6 before B 9730xxxx have hardware bugs that can cause
* misexecution of code under Linux. Owners of such processors should
@@ -1353,13 +1432,19 @@
break;

case 6: /* An Athlon/Duron */
-
/* Bit 15 of Athlon specific MSR 15, needs to be 0
* to enable SSE on Palomino/Morgan CPU's.
* If the BIOS didn't enable it already, enable it
* here.
+ *
+ * Avoiding the use of 4MB/2MB pages along with
+ * setting a special MSR bit that disables a small
+ * part of advanced speculative caching as part of a
+ * short-term fix for a conflicting cache attribute
+ * bug in the kernel that is exposed by advanced
+ * speculative caching in newer AMD Atlon processors.
*/
- if (c->x86_model == 6 || c->x86_model == 7) {
+ if (c->x86_model >= 6) {
if (!test_bit(X86_FEATURE_XMM,
&c->x86_capability)) {
printk(KERN_INFO
@@ -1370,9 +1455,20 @@
set_bit(X86_FEATURE_XMM,
&c->x86_capability);
}
+ if (!test_bit(X86_FEATURE_PSE, &boot_cpu_data.x86_capability)) {
+ amd_adv_spec_cache_disable();
+ printk(KERN_INFO
+ "Disabling advanced speculative caching\n");
+ }
+ }
+ break;
+ case 15:
+ if (!test_bit(X86_FEATURE_PSE, &boot_cpu_data.x86_capability)) {
+ amd_adv_spec_cache_disable();
+ printk(KERN_INFO "Disabling advanced speculative caching\n");
}
break;
-
}

display_cacheinfo(c);
@@ -2634,6 +2730,12 @@
&c->x86_capability[0]);
c->x86 = (tfms >> 8) & 15;
c->x86_model = (tfms >> 4) & 15;
+ if ( (c->x86_vendor == X86_VENDOR_AMD) &&
+ (c->x86 == 0xf)) {
+ /* AMD Extended Family and Model Values */
+ c->x86 += (tfms >> 20) & 0xff;
+ c->x86_model += (tfms >> 12) & 0xf0;
+ }
c->x86_mask = tfms & 15;
} else {
/* Have CPUID level 0 only - unheard of */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:26    [W:0.032 / U:8.384 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site