diff -ur stock/linux-2.4.0-test11-pre5/arch/i386/Makefile linux-2.4.0-test11-pre5-reportintel/arch/i386/Makefile
--- stock/linux-2.4.0-test11-pre5/arch/i386/Makefile	Wed Nov 15 11:24:19 2000
+++ linux-2.4.0-test11-pre5-reportintel/arch/i386/Makefile	Thu Nov 16 13:06:43 2000
@@ -54,6 +54,10 @@
 CFLAGS += -march=i686
 endif
 
+ifdef CONFIG_MPENTIUM4
+CFLAGS += -march=i686
+endif
+
 ifdef CONFIG_MK6
 CFLAGS += $(shell if $(CC) -march=k6 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=k6"; else echo "-march=i586"; fi)
 endif
diff -ur stock/linux-2.4.0-test11-pre5/arch/i386/config.in linux-2.4.0-test11-pre5-reportintel/arch/i386/config.in
--- stock/linux-2.4.0-test11-pre5/arch/i386/config.in	Wed Nov 15 11:24:19 2000
+++ linux-2.4.0-test11-pre5-reportintel/arch/i386/config.in	Thu Nov 16 13:02:10 2000
@@ -34,6 +34,7 @@
 	 Pentium-MMX			CONFIG_M586MMX \
 	 Pentium-Pro/Celeron/Pentium-II	CONFIG_M686 \
 	 Pentium-III			CONFIG_M686FXSR \
+	 Pentium-4			CONFIG_MPENTIUM4 \
 	 K6/K6-II/K6-III		CONFIG_MK6 \
 	 Athlon/K7			CONFIG_MK7 \
 	 Crusoe				CONFIG_MCRUSOE \
@@ -85,6 +86,15 @@
 fi
 if [ "$CONFIG_M686FXSR" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
+   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_GOOD_APIC y
+   define_bool CONFIG_X86_PGE y
+   define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
+   define_bool CONFIG_X86_FXSR y
+   define_bool CONFIG_X86_XMM y
+fi
+if [ "$CONFIG_MPENTIUM4" = "y" ]; then
+   define_int  CONFIG_X86_L1_CACHE_SHIFT 7
    define_bool CONFIG_X86_TSC y
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_PGE y
diff -ur stock/linux-2.4.0-test11-pre5/arch/i386/kernel/mpparse.c linux-2.4.0-test11-pre5-reportintel/arch/i386/kernel/mpparse.c
--- stock/linux-2.4.0-test11-pre5/arch/i386/kernel/mpparse.c	Wed Nov 15 11:24:19 2000
+++ linux-2.4.0-test11-pre5-reportintel/arch/i386/kernel/mpparse.c	Thu Nov 16 12:59:39 2000
@@ -97,6 +97,8 @@
 			return("Pentium(tm) Pro");
 
 		case 0x0F:
+			if (model == 0x00)
+				return("Pentium 4(tm)");
 			if (model == 0x0F)
 				return("Special controller");
 	}
diff -ur stock/linux-2.4.0-test11-pre5/arch/i386/kernel/setup.c linux-2.4.0-test11-pre5-reportintel/arch/i386/kernel/setup.c
--- stock/linux-2.4.0-test11-pre5/arch/i386/kernel/setup.c	Wed Nov 15 11:24:19 2000
+++ linux-2.4.0-test11-pre5-reportintel/arch/i386/kernel/setup.c	Thu Nov 16 13:12:46 2000
@@ -1485,6 +1485,7 @@
 #endif
 	extern void mcheck_init(struct cpuinfo_x86 *c);
 	char *p = NULL;
+	unsigned int l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
 
 #ifndef CONFIG_M686
 	/*
@@ -1506,43 +1507,80 @@
 
 	if (c->cpuid_level > 1) {
 		/* supports eax=2  call */
-		int edx = cpuid_edx(2);
+		int i, j, n;
+		int regs[4];
+		unsigned char *dp = (unsigned char *)regs;
 
-		/* We need only the LSB */
-		edx &= 0xff;
+		/* Number of times to iterate */
+		n = cpuid_eax(2) & 0xFF;
 
-		switch (edx) {
-		case 0x40:
-			c->x86_cache_size = 0;
-			break;
-			
-		case 0x41: /* 4-way 128 */
-			c->x86_cache_size = 128;
-			break;
-			
-		case 0x42: /* 4-way 256 */
-		case 0x82: /* 8-way 256 */
-			c->x86_cache_size = 256;
-			break;
-			
-		case 0x43: /* 4-way 512 */
-			c->x86_cache_size = 512;
-			break;
-			
-		case 0x44: /* 4-way 1024 */
-		case 0x84: /* 8-way 1024 */
-			c->x86_cache_size = 1024;
-			break;
+		for ( i = 0 ; i < n ; i++ ) {
+			cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
 			
-		case 0x45: /* 4-way 2048 */
-		case 0x85: /* 8-way 2048 */
-			c->x86_cache_size = 2048;
-			break;
-			
-		default:
-			c->x86_cache_size = 0;
-			break;
+			/* If bit 31 is set, this is an unknown format */
+			for ( j = 0 ; j < 3 ; j++ ) {
+				if ( regs[j] < 0 ) regs[j] = 0;
+			}
+
+			/* Byte 0 is level count, not a descriptor */
+			for ( j = 1 ; j < 16 ; j++ ) {
+				unsigned char des = dp[j];
+				unsigned char dl, dh;
+				unsigned int cs;
+
+				dh = des >> 4;
+				dl = des & 0x0F;
+
+				switch ( dh )
+				{
+				case 2:
+					if ( dl ) {
+						/* L3 cache */
+						cs = (dl-1) << 9;
+						l3 += cs;
+					}
+					break;
+				case 4:
+				case 8:
+					if ( dl ) {
+						/* L2 cache */
+						cs = 128 << (dl-1);
+						l2 += cs;
+					}
+					break;
+				case 6:
+					if (dl > 5) {
+						/* L1 D cache */
+						cs = 8<<(dl-6);
+						l1d += cs;
+					}
+					break;
+				case 7:
+					/* L1 I cache */
+					cs = dl ? (16 << (dl-1)) : 12;
+					l1i += cs;
+					break;
+				default:
+					/* TLB, or something else we don't know about */
+					break;
+				}
+			}
 		}
+		if ( l1i || l1d )
+			printk("CPU: L1 I cache: %dK, L1 D cache: %dK\n",
+			       l1i, l1d);
+		if ( l2 )
+			printk("CPU: L2 cache: %dK\n", l2);
+		if ( l3 )
+			printk("CPU: L3 cache: %dK\n", l3);
+
+		/*
+		 * This assumes the L3 cache is shared; it typically lives in
+		 * the northbridge.  The L1 caches are included by the L2
+		 * cache, and so should not be included for the purpose of
+		 * SMP switching weights.
+		 */
+		c->x86_cache_size = l2 ? l2 : (l1i+l1d);
 	}
 
 	/* SEP CPUID bug: Pentium Pro reports SEP but doesn't have it */
@@ -1555,19 +1593,19 @@
 	if (c->x86 == 6) {
 		switch (c->x86_model) {
 		case 5:
-			if (c->x86_cache_size == 0)
+			if (l2 == 0)
 				p = "Celeron (Covington)";
-			if (c->x86_cache_size == 256)
+			if (l2 == 256)
 				p = "Mobile Pentium II (Dixon)";
 			break;
 			
 		case 6:
-			if (c->x86_cache_size == 128)
+			if (l2 == 128)
 				p = "Celeron (Mendocino)";
 			break;
 			
 		case 8:
-			if (c->x86_cache_size == 128)
+			if (l2 == 128)
 				p = "Celeron (Coppermine)";
 			break;
 		}
@@ -2028,7 +2066,7 @@
 		/* Intel-defined */
 	        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
 	        "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
-	        "pat", "pse36", "pn", "clflsh", NULL, "dtes", NULL, "mmx",
+	        "pat", "pse36", "pn", "clflsh", NULL, "dtes", "acpi", "mmx",
 	        "fxsr", "sse", "sse2", "selfsnoop", NULL, "acc", "ia64", NULL,
 
 		/* AMD-defined */
diff -ur stock/linux-2.4.0-test11-pre5/arch/i386/kernel/smpboot.c linux-2.4.0-test11-pre5-reportintel/arch/i386/kernel/smpboot.c
--- stock/linux-2.4.0-test11-pre5/arch/i386/kernel/smpboot.c	Sun Oct  1 20:35:15 2000
+++ linux-2.4.0-test11-pre5-reportintel/arch/i386/kernel/smpboot.c	Thu Nov 16 12:57:32 2000
@@ -455,7 +455,7 @@
 	cpu_init();
 	smp_callin();
 	while (!atomic_read(&smp_commenced))
-		/* nothing */ ;
+		rep_nop();
 	/*
 	 * low-memory mappings have been cleared, flush them from
 	 * the local TLBs too.
diff -ur stock/linux-2.4.0-test11-pre5/include/asm-i386/processor.h linux-2.4.0-test11-pre5-reportintel/include/asm-i386/processor.h
--- stock/linux-2.4.0-test11-pre5/include/asm-i386/processor.h	Wed Nov 15 11:24:21 2000
+++ linux-2.4.0-test11-pre5-reportintel/include/asm-i386/processor.h	Thu Nov 16 13:05:01 2000
@@ -473,4 +473,10 @@
 
 #define MICROCODE_IOCFREE	_IO('6',0) /* because it is for P6 */
 
+/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
+extern inline void rep_nop(void)
+{
+	__asm__ __volatile__("rep;nop");
+}
+
 #endif /* __ASM_I386_PROCESSOR_H */
diff -ur stock/linux-2.4.0-test11-pre5/init/main.c linux-2.4.0-test11-pre5-reportintel/init/main.c
--- stock/linux-2.4.0-test11-pre5/init/main.c	Thu Oct 26 13:49:15 2000
+++ linux-2.4.0-test11-pre5-reportintel/init/main.c	Thu Nov 16 12:58:14 2000
@@ -333,7 +333,7 @@
 		/* wait for "start of" clock tick */
 		ticks = jiffies;
 		while (ticks == jiffies)
-			/* nothing */;
+			rep_nop();
 		/* Go .. */
 		ticks = jiffies;
 		__delay(loops_per_sec);
@@ -349,7 +349,8 @@
 	while ( lps_precision-- && (loopbit >>= 1) ) {
 		loops_per_sec |= loopbit;
 		ticks = jiffies;
-		while (ticks == jiffies);
+		while (ticks == jiffies)
+			rep_nop();
 		ticks = jiffies;
 		__delay(loops_per_sec);
 		if (jiffies != ticks)	/* longer than 1 tick */
