2001-02-02 20:23:19

by Maciej W. Rozycki

[permalink] [raw]
Subject: CPU capabilities -- an update proposal

Hi,

Following is the current state of my CPU capabilities rework. It
introduces a new global variable, common_x86_capability, which holds the
common set of flags for CPUs. The boot_cpu_data is used appropriately
again, i.e. it's treated as current_cpu_data before smp_store_cpu_info()
is called (it doesn't matter for UP). I defined a set of macros named
boot_has_* for the purpose of accessing boot_cpu_data. I did not create
current_has_* macros to access current_cpu_data as I think this might
encourage people to use them instead of cpu_has_* incorrectly.

I tried to select the right version, either boot_has_* or cpu_has_*,
throught the kernel tree. Almost all places were unambiguous. The one
problematic file is arch/i386/kernel/mtrr.c -- set_mtrr_prepare() and
set_mtrr_done() make use of boot_cpu_data.x86_capability and are called
both before and after smp_store_cpu_info() is called. Richard, is there
any way to change it? I guess we don't need to test for PGE at all -- if
a CPU has MTRRs it should have the cr4 register and writing a zero to an
undefined bit is explicitly allowed.

I'm going to add a few lines of comments to include/asm-i386/processor.h
to point it out explicitly when each set of macros should be used.

I'm looking forward to any comments, suggestions, possible fixes. The
patch applies to 2.4.1-ac1 as well.

Maciej

--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: [email protected], PGP key available +

patch-2.4.0-ac12-cpu_caps-4
diff -up --recursive --new-file linux-2.4.0-ac12.macro/arch/i386/kernel/apic.c linux-2.4.0-ac12/arch/i386/kernel/apic.c
--- linux-2.4.0-ac12.macro/arch/i386/kernel/apic.c Sun Jan 28 09:40:31 2001
+++ linux-2.4.0-ac12/arch/i386/kernel/apic.c Wed Jan 31 21:26:13 2001
@@ -214,7 +214,7 @@ void __init init_bsp_APIC(void)
* Don't do the setup now if we have a SMP BIOS as the
* through-I/O-APIC virtual wire mode might be active.
*/
- if (smp_found_config || !cpu_has_apic)
+ if (smp_found_config || !boot_has_apic)
return;

value = apic_read(APIC_LVR);
@@ -398,7 +398,7 @@ int detect_init_APIC (void)
return -1;
}

- if (!cpu_has_apic) {
+ if (!boot_has_apic) {
if (boot_cpu_data.x86 == 5) {
printk("APIC turned off by hardware.\n");
return -1;
@@ -887,13 +887,13 @@ asmlinkage void smp_error_interrupt(void
*/
void __init APIC_init_uniprocessor (void)
{
- if (!smp_found_config && !cpu_has_apic)
+ if (!smp_found_config && !boot_has_apic)
return;

/*
* Complain if the BIOS pretends there is one.
*/
- if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_id])) {
+ if (!boot_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_id])) {
printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
boot_cpu_id);
return;
diff -up --recursive --new-file linux-2.4.0-ac12.macro/arch/i386/kernel/i386_ksyms.c linux-2.4.0-ac12/arch/i386/kernel/i386_ksyms.c
--- linux-2.4.0-ac12.macro/arch/i386/kernel/i386_ksyms.c Sun Jan 28 09:40:31 2001
+++ linux-2.4.0-ac12/arch/i386/kernel/i386_ksyms.c Sun Jan 28 20:53:20 2001
@@ -48,7 +48,9 @@ EXPORT_SYMBOL(drive_info);
extern unsigned long get_cmos_time(void);

/* platform dependent support */
+#if 0
EXPORT_SYMBOL(boot_cpu_data);
+#endif
#ifdef CONFIG_EISA
EXPORT_SYMBOL(EISA_bus);
#endif
diff -up --recursive --new-file linux-2.4.0-ac12.macro/arch/i386/kernel/i387.c linux-2.4.0-ac12/arch/i386/kernel/i387.c
--- linux-2.4.0-ac12.macro/arch/i386/kernel/i387.c Sun Jan 28 09:40:31 2001
+++ linux-2.4.0-ac12/arch/i386/kernel/i387.c Sun Jan 28 21:33:16 2001
@@ -19,7 +19,7 @@
#include <asm/uaccess.h>

#ifdef CONFIG_MATH_EMULATION
-#define HAVE_HWFP (boot_cpu_data.hard_math)
+#define HAVE_HWFP (current_cpu_data.hard_math)
#else
#define HAVE_HWFP 1
#endif
diff -up --recursive --new-file linux-2.4.0-ac12.macro/arch/i386/kernel/i8259.c linux-2.4.0-ac12/arch/i386/kernel/i8259.c
--- linux-2.4.0-ac12.macro/arch/i386/kernel/i8259.c Sun Jan 28 09:40:31 2001
+++ linux-2.4.0-ac12/arch/i386/kernel/i8259.c Sun Jan 28 21:42:20 2001
@@ -504,6 +504,6 @@ void __init init_IRQ(void)
* External FPU? Set up irq13 if so, for
* original braindamaged IBM FERR coupling.
*/
- if (boot_cpu_data.hard_math && !cpu_has_fpu)
+ if (boot_cpu_data.hard_math && !boot_has_fpu)
setup_irq(13, &irq13);
}
diff -up --recursive --new-file linux-2.4.0-ac12.macro/arch/i386/kernel/nmi.c linux-2.4.0-ac12/arch/i386/kernel/nmi.c
--- linux-2.4.0-ac12.macro/arch/i386/kernel/nmi.c Thu Jan 18 07:17:30 2001
+++ linux-2.4.0-ac12/arch/i386/kernel/nmi.c Sun Jan 28 21:43:53 2001
@@ -193,7 +193,7 @@ void nmi_watchdog_tick (struct pt_regs *
if (cpu_has_apic && (nmi_watchdog == NMI_LOCAL_APIC)) {
/* XXX: nmi_watchdog should carry this info */
unsigned msr;
- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
+ if (current_cpu_data.x86_vendor == X86_VENDOR_AMD) {
wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/HZ*1000), -1);
} else {
wrmsr(MSR_IA32_PERFCTR1, -(cpu_khz/HZ*1000), 0);
diff -up --recursive --new-file linux-2.4.0-ac12.macro/arch/i386/kernel/setup.c linux-2.4.0-ac12/arch/i386/kernel/setup.c
--- linux-2.4.0-ac12.macro/arch/i386/kernel/setup.c Sun Jan 28 09:40:31 2001
+++ linux-2.4.0-ac12/arch/i386/kernel/setup.c Fri Feb 2 07:55:35 2001
@@ -104,6 +104,7 @@

char ignore_irq13; /* set if exception 16 works */
struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
+__u32 common_x86_capability[NCAPINTS] = { -1U, -1U, -1U, -1U };

unsigned long mmu_cr4_features;

@@ -2002,7 +2003,7 @@ void __init identify_cpu(struct cpuinfo_
*/

/* TSC disabled? */
-#ifdef CONFIG_TSC
+#ifndef CONFIG_X86_TSC
if ( tsc_disable )
clear_bit(X86_FEATURE_TSC, &c->x86_capability);
#endif
@@ -2037,22 +2038,19 @@ void __init identify_cpu(struct cpuinfo_
c->x86_capability[3]);

/*
- * On SMP, boot_cpu_data holds the common feature set between
- * all CPUs; so make sure that we indicate which features are
- * common between the CPUs. The first time this routine gets
- * executed, c == &boot_cpu_data.
+ * On SMP, common_x86_capability holds the common feature
+ * set between all CPUs; so make sure that we indicate
+ * which features are common between the CPUs.
*/
- if ( c != &boot_cpu_data ) {
- /* AND the already accumulated flags with these */
- for ( i = 0 ; i < NCAPINTS ; i++ )
- boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
- }
+ /* AND the already accumulated flags with these */
+ for (i = 0; i < NCAPINTS; i++)
+ common_x86_capability[i] &= c->x86_capability[i];

printk("CPU: Common caps: %08x %08x %08x %08x\n",
- boot_cpu_data.x86_capability[0],
- boot_cpu_data.x86_capability[1],
- boot_cpu_data.x86_capability[2],
- boot_cpu_data.x86_capability[3]);
+ common_x86_capability[0],
+ common_x86_capability[1],
+ common_x86_capability[2],
+ common_x86_capability[3]);
}
/*
* Perform early boot up checks for a valid TSC. See arch/i386/kernel/time.c
@@ -2139,6 +2137,13 @@ int get_cpuinfo(char * buffer)
struct cpuinfo_x86 *c = cpu_data;
int i, n;

+ p += sprintf(p, "\ncommon flags\t:");
+ for ( i = 0 ; i < 32*NCAPINTS ; i++ )
+ if ( test_bit(i, &common_x86_capability) &&
+ x86_cap_flags[i] != NULL )
+ p += sprintf(p, " %s", x86_cap_flags[i]);
+ p += sprintf(p, "\n\n");
+
for (n = 0; n < NR_CPUS; n++, c++) {
int fpu_exception;
#ifdef CONFIG_SMP
@@ -2171,7 +2176,9 @@ int get_cpuinfo(char * buffer)
p += sprintf(p, "cache size\t: %d KB\n", c->x86_cache_size);

/* We use exception 16 if we have hardware math and we've either seen it or the CPU claims it is internal */
- fpu_exception = c->hard_math && (ignore_irq13 || cpu_has_fpu);
+ fpu_exception = c->hard_math &&
+ (ignore_irq13 ||
+ test_bit(X86_FEATURE_FPU, &c->x86_capability));
p += sprintf(p, "fdiv_bug\t: %s\n"
"hlt_bug\t\t: %s\n"
"f00f_bug\t: %s\n"
@@ -2221,10 +2228,10 @@ void __init cpu_init (void)
}
printk("Initializing CPU#%d\n", nr);

- if (cpu_has_vme || cpu_has_tsc || cpu_has_de)
+ if (boot_has_vme || boot_has_tsc || boot_has_de)
clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
#ifndef CONFIG_X86_TSC
- if (tsc_disable && cpu_has_tsc) {
+ if (tsc_disable && boot_has_tsc) {
printk("Disabling TSC...\n");
/**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/
clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability);
diff -up --recursive --new-file linux-2.4.0-ac12.macro/arch/i386/kernel/smpboot.c linux-2.4.0-ac12/arch/i386/kernel/smpboot.c
--- linux-2.4.0-ac12.macro/arch/i386/kernel/smpboot.c Sun Jan 28 09:40:31 2001
+++ linux-2.4.0-ac12/arch/i386/kernel/smpboot.c Wed Jan 31 22:27:05 2001
@@ -890,8 +890,7 @@ void __init smp_boot_cpus(void)
/*
* If we couldn't find a local APIC, then get out of here now!
*/
- if (APIC_INTEGRATED(apic_version[boot_cpu_id]) &&
- !test_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability)) {
+ if (APIC_INTEGRATED(apic_version[boot_cpu_id]) && !boot_has_apic) {
printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
boot_cpu_id);
printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
diff -up --recursive --new-file linux-2.4.0-ac12.macro/arch/i386/kernel/time.c linux-2.4.0-ac12/arch/i386/kernel/time.c
--- linux-2.4.0-ac12.macro/arch/i386/kernel/time.c Wed Jan 3 07:54:00 2001
+++ linux-2.4.0-ac12/arch/i386/kernel/time.c Sun Jan 28 21:50:37 2001
@@ -657,7 +657,7 @@ void __init time_init(void)

dodgy_tsc();

- if (cpu_has_tsc) {
+ if (boot_has_tsc) {
unsigned long tsc_quotient = calibrate_tsc();
if (tsc_quotient) {
fast_gettimeoffset_quotient = tsc_quotient;
diff -up --recursive --new-file linux-2.4.0-ac12.macro/arch/i386/mm/init.c linux-2.4.0-ac12/arch/i386/mm/init.c
--- linux-2.4.0-ac12.macro/arch/i386/mm/init.c Sun Jan 28 09:40:31 2001
+++ linux-2.4.0-ac12/arch/i386/mm/init.c Wed Jan 31 21:49:59 2001
@@ -351,14 +351,14 @@ static void __init pagetable_init (void)
vaddr = i*PGDIR_SIZE + j*PMD_SIZE;
if (end && (vaddr >= end))
break;
- if (cpu_has_pse) {
+ if (boot_has_pse) {
unsigned long __pe;

set_in_cr4(X86_CR4_PSE);
boot_cpu_data.wp_works_ok = 1;
__pe = _KERNPG_TABLE + _PAGE_PSE + __pa(vaddr);
/* Make it "global" too if supported */
- if (cpu_has_pge) {
+ if (boot_has_pge) {
set_in_cr4(X86_CR4_PGE);
__pe += _PAGE_GLOBAL;
}
@@ -452,7 +452,7 @@ void __init paging_init(void)
* We will bail out later - printk doesnt work right now so
* the user would just see a hanging kernel.
*/
- if (cpu_has_pae)
+ if (boot_has_pae)
set_in_cr4(X86_CR4_PAE);
#endif

@@ -611,7 +611,7 @@ void __init mem_init(void)
);

#if CONFIG_X86_PAE
- if (!cpu_has_pae)
+ if (!boot_has_pae)
panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
#endif
if (boot_cpu_data.wp_works_ok < 0)
diff -up --recursive --new-file linux-2.4.0-ac12.macro/drivers/char/mem.c linux-2.4.0-ac12/drivers/char/mem.c
--- linux-2.4.0-ac12.macro/drivers/char/mem.c Sun Jan 28 09:40:44 2001
+++ linux-2.4.0-ac12/drivers/char/mem.c Wed Jan 31 22:25:13 2001
@@ -179,10 +179,10 @@ static inline int noncached_address(unsi
* caching for the high addresses through the KEN pin, but
* we maintain the tradition of paranoia in this code.
*/
- return !( test_bit(X86_FEATURE_MTRR, &boot_cpu_data.x86_capability) ||
- test_bit(X86_FEATURE_K6_MTRR, &boot_cpu_data.x86_capability) ||
- test_bit(X86_FEATURE_CYRIX_ARR, &boot_cpu_data.x86_capability) ||
- test_bit(X86_FEATURE_CENTAUR_MCR, &boot_cpu_data.x86_capability) )
+ return !( test_bit(X86_FEATURE_MTRR, &common_x86_capability) ||
+ test_bit(X86_FEATURE_K6_MTRR, &common_x86_capability) ||
+ test_bit(X86_FEATURE_CYRIX_ARR, &common_x86_capability) ||
+ test_bit(X86_FEATURE_CENTAUR_MCR, &common_x86_capability) )
&& addr >= __pa(high_memory);
#else
return addr >= __pa(high_memory);
diff -up --recursive --new-file linux-2.4.0-ac12.macro/drivers/char/random.c linux-2.4.0-ac12/drivers/char/random.c
--- linux-2.4.0-ac12.macro/drivers/char/random.c Sun Jan 28 09:40:44 2001
+++ linux-2.4.0-ac12/drivers/char/random.c Wed Jan 31 22:20:58 2001
@@ -710,7 +710,7 @@ static void add_timer_randomness(struct
int entropy = 0;

#if defined (__i386__)
- if ( test_bit(X86_FEATURE_TSC, &boot_cpu_data.x86_capability) ) {
+ if ( cpu_has_tsc ) {
__u32 high;
__asm__(".byte 0x0f,0x31"
:"=a" (time), "=d" (high));
diff -up --recursive --new-file linux-2.4.0-ac12.macro/include/asm-i386/bugs.h linux-2.4.0-ac12/include/asm-i386/bugs.h
--- linux-2.4.0-ac12.macro/include/asm-i386/bugs.h Sun Jan 28 09:41:20 2001
+++ linux-2.4.0-ac12/include/asm-i386/bugs.h Wed Jan 31 22:18:40 2001
@@ -83,12 +83,12 @@ static void __init check_fpu(void)
extern void __buggy_fxsr_alignment(void);
__buggy_fxsr_alignment();
}
- if (cpu_has_fxsr) {
+ if (boot_has_fxsr) {
printk(KERN_INFO "Enabling fast FPU save and restore... ");
set_in_cr4(X86_CR4_OSFXSR);
printk("done.\n");
}
- if (cpu_has_xmm) {
+ if (boot_has_xmm) {
printk(KERN_INFO "Enabling unmasked SIMD FPU exception support... ");
set_in_cr4(X86_CR4_OSXMMEXCPT);
printk("done.\n");
@@ -174,7 +174,7 @@ static void __init check_config(void)
* If we configured ourselves for a TSC, we'd better have one!
*/
#ifdef CONFIG_X86_TSC
- if (!cpu_has_tsc)
+ if (!boot_has_tsc)
panic("Kernel compiled for Pentium+, requires TSC feature!");
#endif

@@ -182,7 +182,7 @@ static void __init check_config(void)
* If we configured ourselves for PGE, we'd better have it.
*/
#ifdef CONFIG_X86_PGE
- if (!cpu_has_pge)
+ if (!boot_has_pge)
panic("Kernel compiled for PPro+, requires PGE feature!");
#endif

@@ -193,8 +193,8 @@ static void __init check_config(void)
* Specification Update").
*/
#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_GOOD_APIC)
- if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL
- && test_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability)
+ if (boot_has_apic
+ && boot_cpu_data.x86_vendor == X86_VENDOR_INTEL
&& boot_cpu_data.x86 == 5
&& boot_cpu_data.x86_model == 2
&& (boot_cpu_data.x86_mask < 6 || boot_cpu_data.x86_mask == 11))
diff -up --recursive --new-file linux-2.4.0-ac12.macro/include/asm-i386/elf.h linux-2.4.0-ac12/include/asm-i386/elf.h
--- linux-2.4.0-ac12.macro/include/asm-i386/elf.h Sun Jan 7 21:42:56 2001
+++ linux-2.4.0-ac12/include/asm-i386/elf.h Wed Jan 31 22:14:50 2001
@@ -86,7 +86,7 @@ typedef struct user_fxsr_struct elf_fpxr
instruction set this CPU supports. This could be done in user space,
but it's not easy, and we've already done it here. */

-#define ELF_HWCAP (boot_cpu_data.x86_capability[0])
+#define ELF_HWCAP (common_x86_capability[0])

/* This yields a string that ld.so will use to load implementation
specific libraries for optimization. This is more specific in
diff -up --recursive --new-file linux-2.4.0-ac12.macro/include/asm-i386/processor.h linux-2.4.0-ac12/include/asm-i386/processor.h
--- linux-2.4.0-ac12.macro/include/asm-i386/processor.h Sun Jan 28 09:41:20 2001
+++ linux-2.4.0-ac12/include/asm-i386/processor.h Wed Jan 31 22:08:09 2001
@@ -68,27 +68,52 @@ struct cpuinfo_x86 {
* capabilities of CPUs
*/

+
extern struct cpuinfo_x86 boot_cpu_data;
extern struct tss_struct init_tss[NR_CPUS];

#ifdef CONFIG_SMP
+extern __u32 common_x86_capability[NCAPINTS];
extern struct cpuinfo_x86 cpu_data[];
#define current_cpu_data cpu_data[smp_processor_id()]
#else
+#define common_x86_capability boot_cpu_data.x86_capability
#define cpu_data &boot_cpu_data
#define current_cpu_data boot_cpu_data
#endif

-#define cpu_has_pge (test_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability))
-#define cpu_has_pse (test_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability))
-#define cpu_has_pae (test_bit(X86_FEATURE_PAE, boot_cpu_data.x86_capability))
-#define cpu_has_tsc (test_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability))
-#define cpu_has_de (test_bit(X86_FEATURE_DE, boot_cpu_data.x86_capability))
-#define cpu_has_vme (test_bit(X86_FEATURE_VME, boot_cpu_data.x86_capability))
-#define cpu_has_fxsr (test_bit(X86_FEATURE_FXSR, boot_cpu_data.x86_capability))
-#define cpu_has_xmm (test_bit(X86_FEATURE_XMM, boot_cpu_data.x86_capability))
-#define cpu_has_fpu (test_bit(X86_FEATURE_FPU, boot_cpu_data.x86_capability))
-#define cpu_has_apic (test_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability))
+#define cpu_has_fpu (test_bit(X86_FEATURE_FPU, common_x86_capability))
+#define cpu_has_vme (test_bit(X86_FEATURE_VME, common_x86_capability))
+#define cpu_has_de (test_bit(X86_FEATURE_DE, common_x86_capability))
+#define cpu_has_pse (test_bit(X86_FEATURE_PSE, common_x86_capability))
+#define cpu_has_tsc (test_bit(X86_FEATURE_TSC, common_x86_capability))
+#define cpu_has_pae (test_bit(X86_FEATURE_PAE, common_x86_capability))
+#define cpu_has_apic (test_bit(X86_FEATURE_APIC, common_x86_capability))
+#define cpu_has_pge (test_bit(X86_FEATURE_PGE, common_x86_capability))
+#define cpu_has_mmx (test_bit(X86_FEATURE_MMX, common_x86_capability))
+#define cpu_has_fxsr (test_bit(X86_FEATURE_FXSR, common_x86_capability))
+#define cpu_has_xmm (test_bit(X86_FEATURE_XMM, common_x86_capability))
+
+#define boot_has_fpu (test_bit(X86_FEATURE_FPU, \
+ boot_cpu_data.x86_capability))
+#define boot_has_vme (test_bit(X86_FEATURE_VME, \
+ boot_cpu_data.x86_capability))
+#define boot_has_de (test_bit(X86_FEATURE_DE, \
+ boot_cpu_data.x86_capability))
+#define boot_has_pse (test_bit(X86_FEATURE_PSE, \
+ boot_cpu_data.x86_capability))
+#define boot_has_tsc (test_bit(X86_FEATURE_TSC, \
+ boot_cpu_data.x86_capability))
+#define boot_has_pae (test_bit(X86_FEATURE_PAE, \
+ boot_cpu_data.x86_capability))
+#define boot_has_apic (test_bit(X86_FEATURE_APIC, \
+ boot_cpu_data.x86_capability))
+#define boot_has_pge (test_bit(X86_FEATURE_PGE, \
+ boot_cpu_data.x86_capability))
+#define boot_has_fxsr (test_bit(X86_FEATURE_FXSR, \
+ boot_cpu_data.x86_capability))
+#define boot_has_xmm (test_bit(X86_FEATURE_XMM, \
+ boot_cpu_data.x86_capability))

extern char ignore_irq13;

diff -up --recursive --new-file linux-2.4.0-ac12.macro/include/asm-i386/xor.h linux-2.4.0-ac12/include/asm-i386/xor.h
--- linux-2.4.0-ac12.macro/include/asm-i386/xor.h Sun Nov 12 19:39:51 2000
+++ linux-2.4.0-ac12/include/asm-i386/xor.h Wed Jan 31 22:00:18 2001
@@ -845,7 +845,7 @@ static struct xor_block_template xor_blo
xor_speed(&xor_block_32regs); \
if (cpu_has_xmm) \
xor_speed(&xor_block_pIII_sse); \
- if (md_cpu_has_mmx()) { \
+ if (cpu_has_mmx) { \
xor_speed(&xor_block_pII_mmx); \
xor_speed(&xor_block_p5_mmx); \
} \
diff -up --recursive --new-file linux-2.4.0-ac12.macro/include/linux/raid/md_compatible.h linux-2.4.0-ac12/include/linux/raid/md_compatible.h
--- linux-2.4.0-ac12.macro/include/linux/raid/md_compatible.h Sat Jan 27 21:56:31 2001
+++ linux-2.4.0-ac12/include/linux/raid/md_compatible.h Wed Jan 31 22:04:09 2001
@@ -27,13 +27,7 @@
/* 000 */
#define md__get_free_pages(x,y) __get_free_pages(x,y)

-#ifdef __i386__
-/* 001 */
-extern __inline__ int md_cpu_has_mmx(void)
-{
- return test_bit(X86_FEATURE_MMX, &boot_cpu_data.x86_capability);
-}
-#endif
+/* 001 - md_cpu_has_mmx - use cpu_has_mmx instead */

/* 002 */
#define md_clear_page(page) clear_page(page)


2001-02-02 20:41:01

by H. Peter Anvin

[permalink] [raw]
Subject: Re: CPU capabilities -- an update proposal

Hi there,

I like what you have done here, but there are a few things...

> diff -up --recursive --new-file linux-2.4.0-ac12.macro/include/asm-i386/bugs.h linux-2.4.0-ac12/include/asm-i386/bugs.h
> --- linux-2.4.0-ac12.macro/include/asm-i386/bugs.h Sun Jan 28 09:41:20 2001
> +++ linux-2.4.0-ac12/include/asm-i386/bugs.h Wed Jan 31 22:18:40 2001
> @@ -83,12 +83,12 @@ static void __init check_fpu(void)
> extern void __buggy_fxsr_alignment(void);
> __buggy_fxsr_alignment();
> }
> - if (cpu_has_fxsr) {
> + if (boot_has_fxsr) {
> printk(KERN_INFO "Enabling fast FPU save and restore... ");
> set_in_cr4(X86_CR4_OSFXSR);
> printk("done.\n");
> }
> - if (cpu_has_xmm) {
> + if (boot_has_xmm) {
> printk(KERN_INFO "Enabling unmasked SIMD FPU exception support... ");
> set_in_cr4(X86_CR4_OSXMMEXCPT);
> printk("done.\n");

Once you enable OSFXSR (therefore allowing user-space code to issue SSE
instructions) you *have* to save using FXSAVE, which you can only do if
*all* CPUs support FXSR. Therefore, I would say this is a buggy
change... it is not save to enable OSFXSR unless *all* the CPUs support
FXSR (they don't have to all support SSE, however, although since you
can't control which CPU you execute on, it's pretty useless if they
don't.)

This may mean the code needs to be restructured; I haven't looked at it
in detail.

-hpa

--
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt

2001-02-03 00:00:19

by Hugh Dickins

[permalink] [raw]
Subject: Re: CPU capabilities -- an update proposal

On Fri, 2 Feb 2001, Maciej W. Rozycki wrote:
>
> Following is the current state of my CPU capabilities rework. It
> introduces a new global variable, common_x86_capability, which holds the
> common set of flags for CPUs. The boot_cpu_data is used appropriately
> again, i.e. it's treated as current_cpu_data before smp_store_cpu_info()
> is called (it doesn't matter for UP). I defined a set of macros named
> boot_has_* for the purpose of accessing boot_cpu_data. I did not create
> current_has_* macros to access current_cpu_data as I think this might
> encourage people to use them instead of cpu_has_* incorrectly.

I like common_x86_capability[], and I like that it's _not_ a struct
cpuinfo_x86 - saves us from wasting time on inventing "common" values
for the other cpuinfo_x86 fields (and'ing, or'ing, min'ing, etc.).
I agree with not defining current_has_ macros (at least until good
reason for them appears). And I'm glad you're doing a patch to fix
these common capabilities, without getting bogged down in the issue
of how to publish them via /proc (I think that's something for later).

But I don't much like those two sets of macros (one of you is welcome
but enough!). Congratulations if you have indeed got them all right
(I found no errors), but I'm afraid someone else will later choose
the wrong one, however well you comment. Which was why my version
kept copying the "and" back into boot_cpu_data (admittedly a hack).

I wonder (you or hpa may very quickly point out why this is stupid
and impossible), could we move the identify_cpu() calls into
cpu_init()? I used to think it was called too early for that, but
now I see it's already using current, smp_processor_id(), printk().
If identify_cpu() went in there, then we'd only need one set of
macros (cpu_has_ testing common_x86_capability), and a
considerable source of potential errors would be gone. Not just
errors from using the wrong macro: it's worried me that so much
of startup is relying on the feature flags before identify_cpu()
comes in to adjust them (e.g. adding PGE for an AMD, removing TSC
from a Cyrix and a Centaur). We could eliminate dodgy_tsc() then,
its work already done.

I've not applied and installed your patch, but the only problem
I noticed was in i386_ksyms.c: you've put #if 0 #endif around the
EXPORT_SYMBOL(boot_cpu_data), but you need to export it for UP;
and you've no EXPORT_SYMBOL(common_x86_capability), which you'll
need for SMP. Actually, I'd prefer EXPORT_SYMBOL(boot_cpu_data)
to be replaced by EXPORT_SYMBOL(common_x86_capability) (of course,
without #ifdef 0 #endif), and the SMP/UP divergence removed from
processor.h - give UP its own separate common_x86_capability[]
(hmm, it's already there in setup.c, does that compile?) and
its own cpu_data[1]. A little space wasted, but more confusion
gone - and if you dare, boot_cpu_data can then be __initdata?

Very minor point: remember mem=nopentium switches off PSE,
should be reflected in cpu_data and common_x86_capability.

Hugh

2001-02-03 00:32:32

by Hugh Dickins

[permalink] [raw]
Subject: Re: CPU capabilities -- an update proposal

On Fri, 2 Feb 2001, H. Peter Anvin wrote:
>
> > diff -up --recursive --new-file linux-2.4.0-ac12.macro/include/asm-i386/bugs.h linux-2.4.0-ac12/include/asm-i386/bugs.h
> > --- linux-2.4.0-ac12.macro/include/asm-i386/bugs.h Sun Jan 28 09:41:20 2001
> > +++ linux-2.4.0-ac12/include/asm-i386/bugs.h Wed Jan 31 22:18:40 2001
> > @@ -83,12 +83,12 @@ static void __init check_fpu(void)
> > extern void __buggy_fxsr_alignment(void);
> > __buggy_fxsr_alignment();
> > }
> > - if (cpu_has_fxsr) {
> > + if (boot_has_fxsr) {
> > printk(KERN_INFO "Enabling fast FPU save and restore... ");
> > set_in_cr4(X86_CR4_OSFXSR);
> > printk("done.\n");
> > }
> > - if (cpu_has_xmm) {
> > + if (boot_has_xmm) {
> > printk(KERN_INFO "Enabling unmasked SIMD FPU exception support... ");
> > set_in_cr4(X86_CR4_OSXMMEXCPT);
> > printk("done.\n");
>
> Once you enable OSFXSR (therefore allowing user-space code to issue SSE
> instructions) you *have* to save using FXSAVE, which you can only do if
> *all* CPUs support FXSR. Therefore, I would say this is a buggy
> change... it is not save to enable OSFXSR unless *all* the CPUs support
> FXSR (they don't have to all support SSE, however, although since you
> can't control which CPU you execute on, it's pretty useless if they
> don't.)

That's nothing new: all Maciej has done there is update the names
of the macros. Of course you are right, it is in principle unsafe,
and it would be nice to know about all the CPUs before making such
decisions; but I think there are many other choices like that (TSC?
PSE? PGE? PAE?) made on the basis of that first CPU, before the
others have even been booted, and it's not been a serious problem
in practice. I seem to recall that Intel only support mixed CPU
steppings if the earliest (presumably least capable) is the first
to boot. It would be quite easy to add a second bugs.h check,
this time on common_x86_capability once all CPUs have booted;
but that may be too late, and I doubt it's worth trying harder.

Hugh

2001-02-03 01:15:54

by H. Peter Anvin

[permalink] [raw]
Subject: Re: CPU capabilities -- an update proposal

Hugh Dickins wrote:
>
> I wonder (you or hpa may very quickly point out why this is stupid
> and impossible), could we move the identify_cpu() calls into
> cpu_init()? I used to think it was called too early for that, but
> now I see it's already using current, smp_processor_id(), printk().
>

I like that idea. I think it would clean up a lot of crud.

-hpa

--
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt

2001-02-05 14:17:07

by Maciej W. Rozycki

[permalink] [raw]
Subject: Re: CPU capabilities -- an update proposal

On Fri, 2 Feb 2001, Hugh Dickins wrote:

> I like common_x86_capability[], and I like that it's _not_ a struct
> cpuinfo_x86 - saves us from wasting time on inventing "common" values
> for the other cpuinfo_x86 fields (and'ing, or'ing, min'ing, etc.).

That was my first idea. I decided to implement it as struct cpuinfo_x86
later, though, to remove post-boot boot_cpu_data references completely.
As to the "common" values, I decided to take the KISS approach --
everything but x86_capability and x86_mask is copied from values obtained
by the BSP. The x86_mask field is computed to be the lowest of all
steppings -- some code may find it useful; for now the only use is a bug
check in mtrr.c. I'm not sure if it's possible to mix models with
multiple P6s in a single system. If it is, we might adjust x86_model
appropriately.

> I agree with not defining current_has_ macros (at least until good
> reason for them appears). And I'm glad you're doing a patch to fix
> these common capabilities, without getting bogged down in the issue
> of how to publish them via /proc (I think that's something for later).

They are already made available in /proc/cpuinfo -- see get_cpuinfo(). I
took the simple approach and I don't think we want to complicate it more.
It's six lines of code anyway, so changing it this way or that way is
trivial, if needed.

> But I don't much like those two sets of macros (one of you is welcome
> but enough!). Congratulations if you have indeed got them all right
> (I found no errors), but I'm afraid someone else will later choose
> the wrong one, however well you comment. Which was why my version
> kept copying the "and" back into boot_cpu_data (admittedly a hack).

The two sets of macros have to remain (well, we might rewrite the code to
use test_bit() directly, but what would we gain). You are right it is
problematic to decide which macro to choose. I've rewritten it thus again
-- with the new version almost no code needs to refer to boot_cpu_data
anymore.

> I wonder (you or hpa may very quickly point out why this is stupid
> and impossible), could we move the identify_cpu() calls into
> cpu_init()? I used to think it was called too early for that, but
> now I see it's already using current, smp_processor_id(), printk().

Of course. I've already thought of this yesterday, but I did not
implement it yet because of other boot_cpu_data members such as
wp_works_ok, etc. They are only initialized by the BSP at the moment and
it's performed after cpu_init() by various code subsystems. I'm not sure
how to propagate them back to cpu_data[], yet.

Also smp_store_cpu_info() should be moved early then, as there is code
that depends on certain capabilities of the current CPU as opposed to
common capabilities, MTRR support being an example.

> If identify_cpu() went in there, then we'd only need one set of
> macros (cpu_has_ testing common_x86_capability), and a
> considerable source of potential errors would be gone. Not just
> errors from using the wrong macro: it's worried me that so much
> of startup is relying on the feature flags before identify_cpu()
> comes in to adjust them (e.g. adding PGE for an AMD, removing TSC
> from a Cyrix and a Centaur). We could eliminate dodgy_tsc() then,
> its work already done.

Yep, there are a few other issues -- the erroneous APIC flag on early AMD
K5s and non-Intel MTRR capabilities.

> I've not applied and installed your patch, but the only problem
> I noticed was in i386_ksyms.c: you've put #if 0 #endif around the
> EXPORT_SYMBOL(boot_cpu_data), but you need to export it for UP;
> and you've no EXPORT_SYMBOL(common_x86_capability), which you'll
> need for SMP. Actually, I'd prefer EXPORT_SYMBOL(boot_cpu_data)
> to be replaced by EXPORT_SYMBOL(common_x86_capability) (of course,
> without #ifdef 0 #endif), and the SMP/UP divergence removed from
> processor.h - give UP its own separate common_x86_capability[]
> (hmm, it's already there in setup.c, does that compile?) and
> its own cpu_data[1]. A little space wasted, but more confusion
> gone - and if you dare, boot_cpu_data can then be __initdata?

Yep, I noticed that. It wasn't run-time tested well -- the code wouldn't
even boot SMP on my P5. The intent was to remove boot_cpu_data form the
list of exports and I've accomplished it now but I had to replace
common_x86_capability with common_cpu_data, as I already mentioned. And
yes, I'm going to mark boot_cpu_data __initdata when I finish the work.

> Very minor point: remember mem=nopentium switches off PSE,
> should be reflected in cpu_data and common_x86_capability.

Yes. This is now done. Now that code may depend on common capabilities
reliably I decided to take the following approach to capabilities that are
to be disabled.

- Capabilities that are automatically disabled due to bugs or other
factors are removed from cpu_data[] and as a result they get deleted from
common capabilities, too.

- Capabilities that get disabled due to a user request are only cleared
from common capabilities. The idea behind it is to disable their usage
for normal code, but let them still be visible for special cases (like CPU
handling and maintenance) with no need for code to revert to cpuid.

Here is a new version of the patch. I decided to copy
boot_cpu_data.x86_capability[0] (as filled by head.S) to
common_cpu_data.x86_capability[0] very early, at the beginning of
setup_arch(). This way even code running early on the BSP may make use
common capabilities (via cpu_has_*, for example), at least these "less
advanced" ones. I believe the patch is cleaner now. It fixes a few other
issues I found (like "no387" disabling the FPU only in the BSP) as well.
I'll work to incorporate all your suggestions in the next version.

The patch applies to 2.4.1-ac1; I haven't checked other versions.

Maciej

--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: [email protected], PGP key available +

patch-2.4.1-ac1-cpu_caps-12
diff -up --recursive --new-file linux-2.4.1-ac1.macro/arch/i386/kernel/apic.c linux-2.4.1-ac1/arch/i386/kernel/apic.c
--- linux-2.4.1-ac1.macro/arch/i386/kernel/apic.c Sat Feb 3 12:16:14 2001
+++ linux-2.4.1-ac1/arch/i386/kernel/apic.c Sun Feb 4 17:43:28 2001
@@ -425,7 +425,13 @@ int detect_init_APIC (void)
printk("Could not enable APIC!\n");
return -1;
}
+ /*
+ * About the only place to explicitly SET a bit in
+ * common_cpu_data.x86_capability. We are allowed to do so
+ * though as we are the BSP.
+ */
set_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability);
+ set_bit(X86_FEATURE_APIC, &common_cpu_data.x86_capability);
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
boot_cpu_id = 0;
if (nmi_watchdog != NMI_NONE)
diff -up --recursive --new-file linux-2.4.1-ac1.macro/arch/i386/kernel/i386_ksyms.c linux-2.4.1-ac1/arch/i386/kernel/i386_ksyms.c
--- linux-2.4.1-ac1.macro/arch/i386/kernel/i386_ksyms.c Sat Feb 3 12:16:14 2001
+++ linux-2.4.1-ac1/arch/i386/kernel/i386_ksyms.c Sun Feb 4 17:43:50 2001
@@ -48,7 +48,8 @@ EXPORT_SYMBOL(drive_info);
extern unsigned long get_cmos_time(void);

/* platform dependent support */
-EXPORT_SYMBOL(boot_cpu_data);
+EXPORT_SYMBOL(common_cpu_data);
+EXPORT_SYMBOL(export_cpu_data);
#ifdef CONFIG_EISA
EXPORT_SYMBOL(EISA_bus);
#endif
@@ -119,7 +120,6 @@ EXPORT_SYMBOL(mmx_copy_page);
#endif

#ifdef CONFIG_SMP
-EXPORT_SYMBOL(cpu_data);
EXPORT_SYMBOL(kernel_flag);
EXPORT_SYMBOL(smp_num_cpus);
EXPORT_SYMBOL(cpu_online_map);
diff -up --recursive --new-file linux-2.4.1-ac1.macro/arch/i386/kernel/i387.c linux-2.4.1-ac1/arch/i386/kernel/i387.c
--- linux-2.4.1-ac1.macro/arch/i386/kernel/i387.c Sat Feb 3 12:16:14 2001
+++ linux-2.4.1-ac1/arch/i386/kernel/i387.c Sun Feb 4 17:31:14 2001
@@ -19,7 +19,7 @@
#include <asm/uaccess.h>

#ifdef CONFIG_MATH_EMULATION
-#define HAVE_HWFP (boot_cpu_data.hard_math)
+#define HAVE_HWFP (common_cpu_data.hard_math)
#else
#define HAVE_HWFP 1
#endif
diff -up --recursive --new-file linux-2.4.1-ac1.macro/arch/i386/kernel/i8259.c linux-2.4.1-ac1/arch/i386/kernel/i8259.c
--- linux-2.4.1-ac1.macro/arch/i386/kernel/i8259.c Sat Feb 3 12:16:14 2001
+++ linux-2.4.1-ac1/arch/i386/kernel/i8259.c Sun Feb 4 17:30:24 2001
@@ -391,7 +391,7 @@ static void math_error_irq(int cpl, void
{
extern void math_error(void *);
outb(0,0xF0);
- if (ignore_irq13 || !boot_cpu_data.hard_math)
+ if (ignore_irq13 || !current_cpu_data.hard_math)
return;
math_error((void *)regs->eip);
}
diff -up --recursive --new-file linux-2.4.1-ac1.macro/arch/i386/kernel/mtrr.c linux-2.4.1-ac1/arch/i386/kernel/mtrr.c
--- linux-2.4.1-ac1.macro/arch/i386/kernel/mtrr.c Wed Dec 13 23:54:27 2000
+++ linux-2.4.1-ac1/arch/i386/kernel/mtrr.c Sun Feb 4 18:21:01 2001
@@ -374,7 +374,7 @@ static void set_mtrr_prepare (struct set
return;

/* Save value of CR4 and clear Page Global Enable (bit 7) */
- if ( test_bit(X86_FEATURE_PGE, &boot_cpu_data.x86_capability) )
+ if ( cpu_has_pge )
asm volatile ("movl %%cr4, %0\n\t"
"movl %0, %1\n\t"
"andb $0x7f, %b1\n\t"
@@ -431,7 +431,7 @@ static void set_mtrr_done (struct set_mt
: "=r" (tmp) : : "memory");

/* Restore value of CR4 */
- if ( test_bit(X86_FEATURE_PGE, &boot_cpu_data.x86_capability) )
+ if ( cpu_has_pge )
asm volatile ("movl %0, %%cr4"
: : "r" (ctxt->cr4val) : "memory");

@@ -1176,10 +1176,10 @@ int mtrr_add_page(unsigned long base, un

case MTRR_IF_INTEL:
/* For Intel PPro stepping <= 7, must be 4 MiB aligned */
- if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
- boot_cpu_data.x86 == 6 &&
- boot_cpu_data.x86_model == 1 &&
- boot_cpu_data.x86_mask <= 7 )
+ if ( common_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
+ common_cpu_data.x86 == 6 &&
+ common_cpu_data.x86_model == 1 &&
+ common_cpu_data.x86_mask <= 7 )
{
if ( base & ((1 << (22-PAGE_SHIFT))-1) )
{
@@ -1932,12 +1932,12 @@ static void __init centaur_mcr_init(void

static int __init mtrr_setup(void)
{
- if ( test_bit(X86_FEATURE_MTRR, &boot_cpu_data.x86_capability) ) {
+ if ( test_bit(X86_FEATURE_MTRR, &common_cpu_data.x86_capability) ) {
/* Intel (P6) standard MTRRs */
mtrr_if = MTRR_IF_INTEL;
get_mtrr = intel_get_mtrr;
set_mtrr_up = intel_set_mtrr_up;
- switch (boot_cpu_data.x86_vendor) {
+ switch (common_cpu_data.x86_vendor) {
case X86_VENDOR_AMD:
/* The original Athlon docs said that
total addressable memory is 44 bits wide.
@@ -1949,7 +1949,7 @@ static int __init mtrr_setup(void)
query the width (in bits) of the physical
addressable memory on the Hammer family.
*/
- if (boot_cpu_data.x86 == 7 && (cpuid_eax(0x80000000) >= 0x80000008)) {
+ if (common_cpu_data.x86 == 7 && (cpuid_eax(0x80000000) >= 0x80000008)) {
u32 phys_addr;
phys_addr = cpuid_eax(0x80000008) & 0xff ;
size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1);
@@ -1962,14 +1962,14 @@ static int __init mtrr_setup(void)
size_and_mask = 0x00f00000;
break;
}
- } else if ( test_bit(X86_FEATURE_K6_MTRR, &boot_cpu_data.x86_capability) ) {
+ } else if ( test_bit(X86_FEATURE_K6_MTRR, &common_cpu_data.x86_capability) ) {
/* Pre-Athlon (K6) AMD CPU MTRRs */
mtrr_if = MTRR_IF_AMD_K6;
get_mtrr = amd_get_mtrr;
set_mtrr_up = amd_set_mtrr_up;
size_or_mask = 0xfff00000; /* 32 bits */
size_and_mask = 0;
- } else if ( test_bit(X86_FEATURE_CYRIX_ARR, &boot_cpu_data.x86_capability) ) {
+ } else if ( test_bit(X86_FEATURE_CYRIX_ARR, &common_cpu_data.x86_capability) ) {
/* Cyrix ARRs */
mtrr_if = MTRR_IF_CYRIX_ARR;
get_mtrr = cyrix_get_arr;
@@ -1978,7 +1978,7 @@ static int __init mtrr_setup(void)
cyrix_arr_init();
size_or_mask = 0xfff00000; /* 32 bits */
size_and_mask = 0;
- } else if ( test_bit(X86_FEATURE_CENTAUR_MCR, &boot_cpu_data.x86_capability) ) {
+ } else if ( test_bit(X86_FEATURE_CENTAUR_MCR, &common_cpu_data.x86_capability) ) {
/* Centaur MCRs */
mtrr_if = MTRR_IF_CENTAUR_MCR;
get_mtrr = centaur_get_mcr;
diff -up --recursive --new-file linux-2.4.1-ac1.macro/arch/i386/kernel/nmi.c linux-2.4.1-ac1/arch/i386/kernel/nmi.c
--- linux-2.4.1-ac1.macro/arch/i386/kernel/nmi.c Wed Jan 31 22:01:50 2001
+++ linux-2.4.1-ac1/arch/i386/kernel/nmi.c Sat Feb 3 18:14:43 2001
@@ -193,7 +193,7 @@ void nmi_watchdog_tick (struct pt_regs *
if (cpu_has_apic && (nmi_watchdog == NMI_LOCAL_APIC)) {
/* XXX: nmi_watchdog should carry this info */
unsigned msr;
- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
+ if (current_cpu_data.x86_vendor == X86_VENDOR_AMD) {
wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/HZ*1000), -1);
} else {
wrmsr(MSR_IA32_PERFCTR1, -(cpu_khz/HZ*1000), 0);
diff -up --recursive --new-file linux-2.4.1-ac1.macro/arch/i386/kernel/setup.c linux-2.4.1-ac1/arch/i386/kernel/setup.c
--- linux-2.4.1-ac1.macro/arch/i386/kernel/setup.c Sat Feb 3 12:16:14 2001
+++ linux-2.4.1-ac1/arch/i386/kernel/setup.c Sun Feb 4 22:03:49 2001
@@ -102,8 +102,10 @@
* Machine setup..
*/

+int hard_math_disable __initdata = 0;
char ignore_irq13; /* set if exception 16 works */
struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
+struct cpuinfo_x86 common_cpu_data;

unsigned long mmu_cr4_features;

@@ -548,7 +550,8 @@ static inline void parse_mem_cmdline (ch
to--;
if (!memcmp(from+4, "nopentium", 9)) {
from += 9+4;
- clear_bit(X86_FEATURE_PSE, &boot_cpu_data.x86_capability);
+ clear_bit(X86_FEATURE_PSE,
+ &common_cpu_data.x86_capability);
} else if (!memcmp(from+4, "exactmap", 8)) {
from += 8+4;
e820.nr_map = 0;
@@ -601,6 +604,8 @@ void __init setup_arch(char **cmdline_p)
unsigned long start_pfn, max_pfn, max_low_pfn;
int i;

+ common_cpu_data.x86_capability[0] = boot_cpu_data.x86_capability[0];
+
#ifdef CONFIG_VISWS
visws_get_board_type_and_rev();
#endif
@@ -1887,6 +1892,19 @@ void __init identify_cpu(struct cpuinfo_
{
int junk, i;
u32 xlvl, tfms;
+ __u32 x86_capability_mask;
+
+ /*
+ * We are about to reinitialize data fetched in head.S.
+ * But some early code might have disabled certain CPU
+ * capabilities. We store disabled bits for the BSP.
+ */
+ if (!smp_processor_id()) {
+ x86_capability_mask = common_cpu_data.x86_capability[0];
+ x86_capability_mask ^= c->x86_capability[0];
+ x86_capability_mask &= c->x86_capability[0];
+ x86_capability_mask = ~x86_capability_mask;
+ }

c->loops_per_jiffy = loops_per_jiffy;
c->x86_cache_size = -1;
@@ -2002,12 +2020,6 @@ void __init identify_cpu(struct cpuinfo_
* we do "generic changes."
*/

- /* TSC disabled? */
-#ifdef CONFIG_TSC
- if ( tsc_disable )
- clear_bit(X86_FEATURE_TSC, &c->x86_capability);
-#endif
-
/* FXSR disabled? */
if (disable_x86_fxsr) {
clear_bit(X86_FEATURE_FXSR, &c->x86_capability);
@@ -2038,22 +2050,33 @@ void __init identify_cpu(struct cpuinfo_
c->x86_capability[3]);

/*
- * On SMP, boot_cpu_data holds the common feature set between
- * all CPUs; so make sure that we indicate which features are
- * common between the CPUs. The first time this routine gets
- * executed, c == &boot_cpu_data.
+ * On SMP, common_cpu_data.x86_capability holds the common
+ * feature set between all CPUs; so make sure that we
+ * indicate which features are common between the CPUs.
*/
- if ( c != &boot_cpu_data ) {
- /* AND the already accumulated flags with these */
- for ( i = 0 ; i < NCAPINTS ; i++ )
- boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
+
+ /*
+ * Vendor-specific init may have set additional flags. We
+ * want to copy them to common flags for the BSP, but we want
+ * to disable whatever was disabled by early code.
+ */
+ if (!smp_processor_id()) {
+ common_cpu_data = *c;
+ common_cpu_data.x86_capability[0] &= x86_capability_mask;
}

+ if (c->x86_mask < common_cpu_data.x86_mask)
+ common_cpu_data.x86_mask = c->x86_mask;
+
+ /* AND the already accumulated flags with these */
+ for (i = 0; i < NCAPINTS; i++)
+ common_cpu_data.x86_capability[i] &= c->x86_capability[i];
+
printk("CPU: Common caps: %08x %08x %08x %08x\n",
- boot_cpu_data.x86_capability[0],
- boot_cpu_data.x86_capability[1],
- boot_cpu_data.x86_capability[2],
- boot_cpu_data.x86_capability[3]);
+ common_cpu_data.x86_capability[0],
+ common_cpu_data.x86_capability[1],
+ common_cpu_data.x86_capability[2],
+ common_cpu_data.x86_capability[3]);
}
/*
* Perform early boot up checks for a valid TSC. See arch/i386/kernel/time.c
@@ -2140,6 +2163,13 @@ int get_cpuinfo(char * buffer)
struct cpuinfo_x86 *c = cpu_data;
int i, n;

+ p += sprintf(p, "\ncommon flags\t:");
+ for ( i = 0 ; i < 32*NCAPINTS ; i++ )
+ if ( test_bit(i, &common_cpu_data.x86_capability) &&
+ x86_cap_flags[i] != NULL )
+ p += sprintf(p, " %s", x86_cap_flags[i]);
+ p += sprintf(p, "\n\n");
+
for (n = 0; n < NR_CPUS; n++, c++) {
int fpu_exception;
#ifdef CONFIG_SMP
@@ -2162,7 +2192,7 @@ int get_cpuinfo(char * buffer)
else
p += sprintf(p, "stepping\t: unknown\n");

- if ( test_bit(X86_FEATURE_TSC, &c->x86_capability) ) {
+ if ( cpu_has_tsc ) {
p += sprintf(p, "cpu MHz\t\t: %lu.%03lu\n",
cpu_khz / 1000, (cpu_khz % 1000));
}
@@ -2172,7 +2202,8 @@ int get_cpuinfo(char * buffer)
p += sprintf(p, "cache size\t: %d KB\n", c->x86_cache_size);

/* We use exception 16 if we have hardware math and we've either seen it or the CPU claims it is internal */
- fpu_exception = c->hard_math && (ignore_irq13 || cpu_has_fpu);
+ fpu_exception = c->hard_math &&
+ (ignore_irq13 || cpu_has_fpu);
p += sprintf(p, "fdiv_bug\t: %s\n"
"hlt_bug\t\t: %s\n"
"f00f_bug\t: %s\n"
@@ -2222,13 +2253,20 @@ void __init cpu_init (void)
}
printk("Initializing CPU#%d\n", nr);

- if (cpu_has_vme || cpu_has_tsc || cpu_has_de)
+ if (hard_math_disable) {
+ boot_cpu_data.hard_math = 0;
+ clear_bit(X86_FEATURE_FPU, common_cpu_data.x86_capability);
+ }
+ if (!boot_cpu_data.hard_math)
+ write_cr0(0xE | read_cr0());
+
+ if (boot_has_vme || boot_has_tsc || boot_has_de)
clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
#ifndef CONFIG_X86_TSC
- if (tsc_disable && cpu_has_tsc) {
+ if (tsc_disable && boot_has_tsc) {
+ /* This has to be done early, before time_init(). */
printk("Disabling TSC...\n");
- /**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/
- clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability);
+ clear_bit(X86_FEATURE_TSC, common_cpu_data.x86_capability);
set_in_cr4(X86_CR4_TSD);
}
#endif
diff -up --recursive --new-file linux-2.4.1-ac1.macro/arch/i386/kernel/smpboot.c linux-2.4.1-ac1/arch/i386/kernel/smpboot.c
--- linux-2.4.1-ac1.macro/arch/i386/kernel/smpboot.c Sat Feb 3 12:16:14 2001
+++ linux-2.4.1-ac1/arch/i386/kernel/smpboot.c Sun Feb 4 18:13:52 2001
@@ -147,7 +147,6 @@ void __init smp_store_cpu_info(int id)
c->pmd_quick = 0;
c->pgd_quick = 0;
c->pgtable_cache_sz = 0;
- identify_cpu(c);
/*
* Mask B, Pentium, but not Pentium MMX
*/
@@ -409,6 +408,10 @@ void __init smp_callin(void)

sti();

+ /*
+ * Must be done before mtrr_init.
+ */
+ identify_cpu(&boot_cpu_data);
#ifdef CONFIG_MTRR
/*
* Must be done before calibration delay is computed
@@ -803,7 +806,7 @@ static void smp_tune_scheduling (void)
cacheflush_time = 0;
return;
} else {
- cachesize = boot_cpu_data.x86_cache_size;
+ cachesize = current_cpu_data.x86_cache_size;
if (cachesize == -1) {
cachesize = 16; /* Pentiums, 2x8kB cache */
bandwidth = 100;
@@ -890,8 +893,7 @@ void __init smp_boot_cpus(void)
/*
* If we couldn't find a local APIC, then get out of here now!
*/
- if (APIC_INTEGRATED(apic_version[boot_cpu_id]) &&
- !test_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability)) {
+ if (APIC_INTEGRATED(apic_version[boot_cpu_id]) && !boot_has_apic) {
printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
boot_cpu_id);
printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
diff -up --recursive --new-file linux-2.4.1-ac1.macro/arch/i386/mm/fault.c linux-2.4.1-ac1/arch/i386/mm/fault.c
--- linux-2.4.1-ac1.macro/arch/i386/mm/fault.c Mon Nov 20 18:01:59 2000
+++ linux-2.4.1-ac1/arch/i386/mm/fault.c Sun Feb 4 17:20:45 2001
@@ -241,7 +241,7 @@ bad_area_nosemaphore:
/*
* Pentium F0 0F C7 C8 bug workaround.
*/
- if (boot_cpu_data.f00f_bug) {
+ if (common_cpu_data.f00f_bug) {
unsigned long nr;

nr = (address - idt) >> 3;
diff -up --recursive --new-file linux-2.4.1-ac1.macro/drivers/char/drm/init.c linux-2.4.1-ac1/drivers/char/drm/init.c
--- linux-2.4.1-ac1.macro/drivers/char/drm/init.c Sun Jul 30 22:09:46 2000
+++ linux-2.4.1-ac1/drivers/char/drm/init.c Sun Feb 4 17:18:20 2001
@@ -103,7 +103,7 @@ void drm_parse_options(char *s)
int drm_cpu_valid(void)
{
#if defined(__i386__)
- if (boot_cpu_data.x86 == 3) return 0; /* No cmpxchg on a 386 */
+ if (common_cpu_data.x86 == 3) return 0; /* No cmpxchg on a 386 */
#endif
#if defined(__sparc__) && !defined(__sparc_v9__)
if (1)
diff -up --recursive --new-file linux-2.4.1-ac1.macro/drivers/char/drm/vm.c linux-2.4.1-ac1/drivers/char/drm/vm.c
--- linux-2.4.1-ac1.macro/drivers/char/drm/vm.c Thu Oct 5 21:08:29 2000
+++ linux-2.4.1-ac1/drivers/char/drm/vm.c Sun Feb 4 17:16:21 2001
@@ -317,7 +317,7 @@ int drm_mmap(struct file *filp, struct v
case _DRM_AGP:
if (VM_OFFSET(vma) >= __pa(high_memory)) {
#if defined(__i386__)
- if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
+ if (common_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
}
diff -up --recursive --new-file linux-2.4.1-ac1.macro/drivers/char/mem.c linux-2.4.1-ac1/drivers/char/mem.c
--- linux-2.4.1-ac1.macro/drivers/char/mem.c Sat Feb 3 12:16:22 2001
+++ linux-2.4.1-ac1/drivers/char/mem.c Sun Feb 4 17:46:14 2001
@@ -140,7 +140,7 @@ static inline pgprot_t pgprot_noncached(
/* On PPro and successors, PCD alone doesn't always mean
uncached because of interactions with the MTRRs. PCD | PWT
means definitely uncached. */
- if (boot_cpu_data.x86 > 3)
+ if (common_cpu_data.x86 > 3)
prot |= _PAGE_PCD | _PAGE_PWT;
#elif defined(__powerpc__)
prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
@@ -179,10 +179,14 @@ static inline int noncached_address(unsi
* caching for the high addresses through the KEN pin, but
* we maintain the tradition of paranoia in this code.
*/
- return !( test_bit(X86_FEATURE_MTRR, &boot_cpu_data.x86_capability) ||
- test_bit(X86_FEATURE_K6_MTRR, &boot_cpu_data.x86_capability) ||
- test_bit(X86_FEATURE_CYRIX_ARR, &boot_cpu_data.x86_capability) ||
- test_bit(X86_FEATURE_CENTAUR_MCR, &boot_cpu_data.x86_capability) )
+ return !( test_bit(X86_FEATURE_MTRR,
+ &common_cpu_data.x86_capability) ||
+ test_bit(X86_FEATURE_K6_MTRR,
+ &common_cpu_data.x86_capability) ||
+ test_bit(X86_FEATURE_CYRIX_ARR,
+ &common_cpu_data.x86_capability) ||
+ test_bit(X86_FEATURE_CENTAUR_MCR,
+ &common_cpu_data.x86_capability) )
&& addr >= __pa(high_memory);
#else
return addr >= __pa(high_memory);
diff -up --recursive --new-file linux-2.4.1-ac1.macro/drivers/char/random.c linux-2.4.1-ac1/drivers/char/random.c
--- linux-2.4.1-ac1.macro/drivers/char/random.c Sat Feb 3 12:16:23 2001
+++ linux-2.4.1-ac1/drivers/char/random.c Sat Feb 3 18:14:43 2001
@@ -710,7 +710,7 @@ static void add_timer_randomness(struct
int entropy = 0;

#if defined (__i386__)
- if ( test_bit(X86_FEATURE_TSC, &boot_cpu_data.x86_capability) ) {
+ if ( cpu_has_tsc ) {
__u32 high;
__asm__(".byte 0x0f,0x31"
:"=a" (time), "=d" (high));
diff -up --recursive --new-file linux-2.4.1-ac1.macro/drivers/net/winbond-840.c linux-2.4.1-ac1/drivers/net/winbond-840.c
--- linux-2.4.1-ac1.macro/drivers/net/winbond-840.c Sat Feb 3 12:16:41 2001
+++ linux-2.4.1-ac1/drivers/net/winbond-840.c Sun Feb 4 17:09:08 2001
@@ -827,7 +827,7 @@ static void init_registers(struct net_de
writel(0xE010, ioaddr + PCIBusCfg);
#else
/* When not a module we can work around broken '486 PCI boards. */
-#define x86 boot_cpu_data.x86
+#define x86 common_cpu_data.x86
writel((x86 <= 4 ? 0x4810 : 0xE010), ioaddr + PCIBusCfg);
if (x86 <= 4)
printk(KERN_INFO "%s: This is a 386/486 PCI system, setting cache "
diff -up --recursive --new-file linux-2.4.1-ac1.macro/drivers/scsi/sym53c8xx.c linux-2.4.1-ac1/drivers/scsi/sym53c8xx.c
--- linux-2.4.1-ac1.macro/drivers/scsi/sym53c8xx.c Sun Jan 7 20:57:00 2001
+++ linux-2.4.1-ac1/drivers/scsi/sym53c8xx.c Sun Feb 4 17:08:41 2001
@@ -13570,7 +13570,7 @@ sym53c8xx_pci_init(Scsi_Host_Template *t
extern char x86;
switch(x86) {
#else
- switch(boot_cpu_data.x86) {
+ switch(common_cpu_data.x86) {
#endif
case 4: suggested_cache_line_size = 4; break;
case 6:
diff -up --recursive --new-file linux-2.4.1-ac1.macro/drivers/scsi/sym53c8xx_comm.h linux-2.4.1-ac1/drivers/scsi/sym53c8xx_comm.h
--- linux-2.4.1-ac1.macro/drivers/scsi/sym53c8xx_comm.h Tue Nov 14 10:25:03 2000
+++ linux-2.4.1-ac1/drivers/scsi/sym53c8xx_comm.h Sun Feb 4 17:07:50 2001
@@ -2510,7 +2510,7 @@ sym53c8xx_pci_init(Scsi_Host_Template *t
extern char x86;
switch(x86) {
#else
- switch(boot_cpu_data.x86) {
+ switch(common_cpu_data.x86) {
#endif
case 4: suggested_cache_line_size = 4; break;
case 6:
diff -up --recursive --new-file linux-2.4.1-ac1.macro/drivers/video/fbmem.c linux-2.4.1-ac1/drivers/video/fbmem.c
--- linux-2.4.1-ac1.macro/drivers/video/fbmem.c Sat Feb 3 12:16:51 2001
+++ linux-2.4.1-ac1/drivers/video/fbmem.c Sun Feb 4 17:06:46 2001
@@ -592,7 +592,7 @@ fb_mmap(struct file *file, struct vm_are
#elif defined(__alpha__)
/* Caching is off in the I/O space quadrant by design. */
#elif defined(__i386__)
- if (boot_cpu_data.x86 > 3)
+ if (common_cpu_data.x86 > 3)
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
#elif defined(__mips__)
pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
diff -up --recursive --new-file linux-2.4.1-ac1.macro/drivers/video/sis/sis_main.c linux-2.4.1-ac1/drivers/video/sis/sis_main.c
--- linux-2.4.1-ac1.macro/drivers/video/sis/sis_main.c Sat Feb 3 12:16:51 2001
+++ linux-2.4.1-ac1/drivers/video/sis/sis_main.c Sun Feb 4 17:07:01 2001
@@ -1657,7 +1657,7 @@ static int sisfb_mmap(struct fb_info *in
vma->vm_pgoff = off >> PAGE_SHIFT;

#if defined(__i386__)
- if (boot_cpu_data.x86 > 3)
+ if (common_cpu_data.x86 > 3)
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
#endif
if (io_remap_page_range(vma->vm_start, off, vma->vm_end - vma->vm_start,
diff -up --recursive --new-file linux-2.4.1-ac1.macro/include/asm-i386/bugs.h linux-2.4.1-ac1/include/asm-i386/bugs.h
--- linux-2.4.1-ac1.macro/include/asm-i386/bugs.h Sat Feb 3 12:06:03 2001
+++ linux-2.4.1-ac1/include/asm-i386/bugs.h Sun Feb 4 21:55:59 2001
@@ -43,8 +43,7 @@ __setup("mca-pentium", mca_pentium);

static int __init no_387(char *s)
{
- boot_cpu_data.hard_math = 0;
- write_cr0(0xE | read_cr0());
+ hard_math_disable = 1;
return 1;
}

@@ -193,8 +192,8 @@ static void __init check_config(void)
* Specification Update").
*/
#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_GOOD_APIC)
- if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL
- && test_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability)
+ if (boot_has_apic
+ && boot_cpu_data.x86_vendor == X86_VENDOR_INTEL
&& boot_cpu_data.x86 == 5
&& boot_cpu_data.x86_model == 2
&& (boot_cpu_data.x86_mask < 6 || boot_cpu_data.x86_mask == 11))
diff -up --recursive --new-file linux-2.4.1-ac1.macro/include/asm-i386/elf.h linux-2.4.1-ac1/include/asm-i386/elf.h
--- linux-2.4.1-ac1.macro/include/asm-i386/elf.h Sat Feb 3 13:18:59 2001
+++ linux-2.4.1-ac1/include/asm-i386/elf.h Sun Feb 4 17:46:44 2001
@@ -86,7 +86,7 @@ typedef struct user_fxsr_struct elf_fpxr
instruction set this CPU supports. This could be done in user space,
but it's not easy, and we've already done it here. */

-#define ELF_HWCAP (boot_cpu_data.x86_capability[0])
+#define ELF_HWCAP (common_cpu_data.x86_capability[0])

/* This yields a string that ld.so will use to load implementation
specific libraries for optimization. This is more specific in
diff -up --recursive --new-file linux-2.4.1-ac1.macro/include/asm-i386/processor.h linux-2.4.1-ac1/include/asm-i386/processor.h
--- linux-2.4.1-ac1.macro/include/asm-i386/processor.h Sat Feb 3 13:12:28 2001
+++ linux-2.4.1-ac1/include/asm-i386/processor.h Sun Feb 4 22:05:49 2001
@@ -71,25 +71,64 @@ struct cpuinfo_x86 {
extern struct cpuinfo_x86 boot_cpu_data;
extern struct tss_struct init_tss[NR_CPUS];

+extern struct cpuinfo_x86 common_cpu_data;
+
#ifdef CONFIG_SMP
extern struct cpuinfo_x86 cpu_data[];
#define current_cpu_data cpu_data[smp_processor_id()]
+#define export_cpu_data cpu_data
#else
#define cpu_data &boot_cpu_data
#define current_cpu_data boot_cpu_data
+#define export_cpu_data boot_cpu_data
#endif

-#define cpu_has_pge (test_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability))
-#define cpu_has_pse (test_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability))
-#define cpu_has_pae (test_bit(X86_FEATURE_PAE, boot_cpu_data.x86_capability))
-#define cpu_has_tsc (test_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability))
-#define cpu_has_de (test_bit(X86_FEATURE_DE, boot_cpu_data.x86_capability))
-#define cpu_has_vme (test_bit(X86_FEATURE_VME, boot_cpu_data.x86_capability))
-#define cpu_has_fxsr (test_bit(X86_FEATURE_FXSR, boot_cpu_data.x86_capability))
-#define cpu_has_xmm (test_bit(X86_FEATURE_XMM, boot_cpu_data.x86_capability))
-#define cpu_has_fpu (test_bit(X86_FEATURE_FPU, boot_cpu_data.x86_capability))
-#define cpu_has_apic (test_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability))
+/*
+ * Generic CPU capability tests.
+ */
+#define cpu_has_fpu (test_bit(X86_FEATURE_FPU, \
+ &common_cpu_data.x86_capability))
+#define cpu_has_vme (test_bit(X86_FEATURE_VME, \
+ &common_cpu_data.x86_capability))
+#define cpu_has_de (test_bit(X86_FEATURE_DE, \
+ &common_cpu_data.x86_capability))
+#define cpu_has_pse (test_bit(X86_FEATURE_PSE, \
+ &common_cpu_data.x86_capability))
+#define cpu_has_tsc (test_bit(X86_FEATURE_TSC, \
+ &common_cpu_data.x86_capability))
+#define cpu_has_pae (test_bit(X86_FEATURE_PAE, \
+ &common_cpu_data.x86_capability))
+#define cpu_has_apic (test_bit(X86_FEATURE_APIC, \
+ &common_cpu_data.x86_capability))
+#define cpu_has_pge (test_bit(X86_FEATURE_PGE, \
+ &common_cpu_data.x86_capability))
+#define cpu_has_mmx (test_bit(X86_FEATURE_MMX, \
+ &common_cpu_data.x86_capability))
+#define cpu_has_fxsr (test_bit(X86_FEATURE_FXSR, \
+ &common_cpu_data.x86_capability))
+#define cpu_has_xmm (test_bit(X86_FEATURE_XMM, \
+ &common_cpu_data.x86_capability))
+
+/*
+ * Boot-time CPU capability tests. These should only be used if
+ * early code specifically needs to test a capability of the current
+ * CPU. Early code is defined as anything before identify_cpu() gets
+ * called. Normal code should test cpu_data[]. Note that these are
+ * really intended for CPU setup and handling functions only -- most
+ * code should use cpu_has_* macros anyway.
+ */
+#define boot_has_fpu (test_bit(X86_FEATURE_FPU, \
+ &boot_cpu_data.x86_capability))
+#define boot_has_vme (test_bit(X86_FEATURE_VME, \
+ &boot_cpu_data.x86_capability))
+#define boot_has_de (test_bit(X86_FEATURE_DE, \
+ &boot_cpu_data.x86_capability))
+#define boot_has_tsc (test_bit(X86_FEATURE_TSC, \
+ &boot_cpu_data.x86_capability))
+#define boot_has_apic (test_bit(X86_FEATURE_APIC, \
+ &boot_cpu_data.x86_capability))

+extern int hard_math_disable;
extern char ignore_irq13;

extern void identify_cpu(struct cpuinfo_x86 *);
diff -up --recursive --new-file linux-2.4.1-ac1.macro/include/asm-i386/uaccess.h linux-2.4.1-ac1/include/asm-i386/uaccess.h
--- linux-2.4.1-ac1.macro/include/asm-i386/uaccess.h Sat Feb 3 13:12:29 2001
+++ linux-2.4.1-ac1/include/asm-i386/uaccess.h Sun Feb 4 18:26:31 2001
@@ -52,9 +52,10 @@ extern int __verify_write(const void *,
#else

#define access_ok(type,addr,size) ( (__range_ok(addr,size) == 0) && \
- ((type) == VERIFY_READ || boot_cpu_data.wp_works_ok || \
- segment_eq(get_fs(),KERNEL_DS) || \
- __verify_write((void *)(addr),(size))))
+ ((type) == VERIFY_READ || \
+ common_cpu_data.wp_works_ok || \
+ segment_eq(get_fs(),KERNEL_DS) || \
+ __verify_write((void *)(addr),(size))))

#endif

diff -up --recursive --new-file linux-2.4.1-ac1.macro/include/asm-i386/xor.h linux-2.4.1-ac1/include/asm-i386/xor.h
--- linux-2.4.1-ac1.macro/include/asm-i386/xor.h Sun Nov 12 19:39:51 2000
+++ linux-2.4.1-ac1/include/asm-i386/xor.h Wed Jan 31 22:00:18 2001
@@ -845,7 +845,7 @@ static struct xor_block_template xor_blo
xor_speed(&xor_block_32regs); \
if (cpu_has_xmm) \
xor_speed(&xor_block_pIII_sse); \
- if (md_cpu_has_mmx()) { \
+ if (cpu_has_mmx) { \
xor_speed(&xor_block_pII_mmx); \
xor_speed(&xor_block_p5_mmx); \
} \
diff -up --recursive --new-file linux-2.4.1-ac1.macro/include/linux/raid/md_compatible.h linux-2.4.1-ac1/include/linux/raid/md_compatible.h
--- linux-2.4.1-ac1.macro/include/linux/raid/md_compatible.h Sat Feb 3 13:13:30 2001
+++ linux-2.4.1-ac1/include/linux/raid/md_compatible.h Sat Feb 3 18:14:43 2001
@@ -27,13 +27,7 @@
/* 000 */
#define md__get_free_pages(x,y) __get_free_pages(x,y)

-#ifdef __i386__
-/* 001 */
-extern __inline__ int md_cpu_has_mmx(void)
-{
- return test_bit(X86_FEATURE_MMX, &boot_cpu_data.x86_capability);
-}
-#endif
+/* 001 - md_cpu_has_mmx - use cpu_has_mmx instead */

/* 002 */
#define md_clear_page(page) clear_page(page)