Messages in this thread Patch in this message | | | Date | Fri, 25 Feb 2000 23:29:34 +0100 (CET) | From | Ingo Molnar <> | Subject | [patch] smp-2.3.48-B2, MP config table in high memory |
| |
> Not surprising. We probably have tons of small ordering assumptions > that just never came up..
it just turned out to be a single assumption: init_apic_mappings() must happen after init_smp_config(). (this also explains my crash)
The attached smp-2.3.48-B2 patch (against pre2-2.3.48) boots just fine here. The reserve_bootmem() thing might just be paranoia - is there any conceivable possibility that pagetable_init() overwrites the MP table?
Lyle, could you check out this patch on your 'interesting' system? Thanks.
Ingo
--- linux/init/main.c.orig2 Fri Feb 25 13:19:45 2000 +++ linux/init/main.c Fri Feb 25 13:20:33 2000 @@ -489,7 +489,6 @@ lock_kernel(); printk(linux_banner); setup_arch(&command_line); - paging_init(); trap_init(); init_IRQ(); sched_init(); --- linux/mm/bootmem.c.orig2 Fri Feb 25 13:30:41 2000 +++ linux/mm/bootmem.c Fri Feb 25 13:31:34 2000 @@ -82,7 +82,7 @@ BUG(); for (i = sidx; i < eidx; i++) if (test_and_set_bit(i, bdata->node_bootmem_map)) - BUG(); + printk("hm, page %08x reserved twice.\n", i*PAGE_SIZE); } static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr, unsigned long size) --- linux/include/linux/mm.h.orig2 Fri Feb 25 13:20:48 2000 +++ linux/include/linux/mm.h Fri Feb 25 13:33:26 2000 @@ -393,7 +393,6 @@ extern int pgt_cache_water[2]; extern int check_pgt_cache(void); -extern void paging_init(void); extern void free_area_init(unsigned long * zones_size); extern void free_area_init_node(int nid, pg_data_t *pgdat, unsigned long * zones_size, unsigned long zone_start_paddr); --- linux/include/asm-i386/mpspec.h.orig2 Fri Feb 25 13:16:05 2000 +++ linux/include/asm-i386/mpspec.h Fri Feb 25 13:16:32 2000 @@ -152,7 +152,8 @@ extern unsigned int boot_cpu_id; extern unsigned long phys_cpu_present_map; extern int smp_found_config; -extern void init_smp_config(void); +extern void find_smp_config (void); +extern void get_smp_config (void); extern int nr_ioapics; extern int apic_version [NR_CPUS]; extern int mp_bus_id_to_type [MAX_MP_BUSSES]; --- linux/include/asm-i386/pgtable.h.orig2 Fri Feb 25 13:22:08 2000 +++ linux/include/asm-i386/pgtable.h Fri Feb 25 13:32:49 2000 @@ -18,6 +18,7 @@ #include <linux/threads.h> extern pgd_t swapper_pg_dir[1024]; +extern void paging_init(void); /* Caches aren't brain-dead on the intel. */ #define flush_cache_all() do { } while (0) --- linux/arch/i386/mm/init.c.orig2 Fri Feb 25 14:09:01 2000 +++ linux/arch/i386/mm/init.c Fri Feb 25 14:08:23 2000 @@ -438,10 +438,6 @@ __flush_tlb_all(); -#ifdef CONFIG_X86_LOCAL_APIC - init_apic_mappings(); -#endif - #ifdef CONFIG_HIGHMEM kmap_init(); #endif --- linux/arch/i386/kernel/mpparse.c.orig2 Fri Feb 25 13:12:22 2000 +++ linux/arch/i386/kernel/mpparse.c Fri Feb 25 14:15:06 2000 @@ -316,11 +316,14 @@ return num_processors; } +static struct intel_mp_floating *mpf_found; + /* * Scan the memory blocks for an SMP configuration block. */ -static int __init smp_get_mpf(struct intel_mp_floating *mpf) +void __init get_smp_config (void) { + struct intel_mp_floating *mpf = mpf_found; printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification); if (mpf->mpf_feature2 & (1<<7)) { printk(" IMCR and PIC compatibility mode.\n"); @@ -329,7 +332,6 @@ printk(" Virtual Wire compatibility mode.\n"); pic_mode = 0; } - smp_found_config = 1; /* * default CPU id - if it's different in the mptable * then we change it before first using it. @@ -388,7 +390,7 @@ default: printk("???\nUnknown standard configuration %d\n", mpf->mpf_feature1); - return 1; + return; } if (mpf->mpf_feature1 > 4) { printk("Bus #1 is PCI\n"); @@ -412,10 +414,9 @@ /* * Only use the first configuration found. */ - return 1; } -static int __init smp_scan_config(unsigned long base, unsigned long length) +static int __init smp_scan_config (unsigned long base, unsigned long length) { unsigned long *bp = phys_to_virt(base); struct intel_mp_floating *mpf; @@ -432,9 +433,13 @@ ((mpf->mpf_specification == 1) || (mpf->mpf_specification == 4)) ) { + smp_found_config = 1; printk("found SMP MP-table at %08ld\n", virt_to_phys(mpf)); - smp_get_mpf(mpf); + reserve_bootmem((unsigned long)mpf, PAGE_SIZE); + if (mpf->mpf_physptr) + reserve_bootmem(mpf->mpf_physptr, PAGE_SIZE); + mpf_found = mpf; return 1; } bp += 4; @@ -443,7 +448,7 @@ return 0; } -void __init init_intel_smp (void) +void __init find_intel_smp (void) { unsigned int address; @@ -488,7 +493,7 @@ * sense, but it doesnt have a BIOS(-configuration table). * No problem for Linux. */ -void __init init_visws_smp(void) +void __init find_visws_smp(void) { smp_found_config = 1; @@ -505,13 +510,13 @@ * - Intel MP Configuration Table * - or SGI Visual Workstation configuration */ -void __init init_smp_config (void) +void __init find_smp_config (void) { #ifdef CONFIG_X86_IO_APIC - init_intel_smp(); + find_intel_smp(); #endif #ifdef CONFIG_VISWS - init_visws_smp(); + find_visws_smp(); #endif } --- linux/arch/i386/kernel/setup.c.orig2 Fri Feb 25 13:14:46 2000 +++ linux/arch/i386/kernel/setup.c Fri Feb 25 14:09:39 2000 @@ -709,9 +709,20 @@ #ifdef CONFIG_X86_IO_APIC /* - * Save possible boot-time SMP configuration: + * Find and reserve possible boot-time SMP configuration: */ - init_smp_config(); + find_smp_config(); +#endif + paging_init(); +#ifdef CONFIG_X86_IO_APIC + /* + * get boot-time SMP configuration: + */ + if (smp_found_config) + get_smp_config(); +#endif +#ifdef CONFIG_X86_LOCAL_APIC + init_apic_mappings(); #endif #ifdef CONFIG_BLK_DEV_INITRD
| |