[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Fix SMP booting: x86/64 startup initialisation fixes and so on.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 8d31f9a9c4232b8f9d0200d0a3d312170c197f63 # Parent e26f574eac9afa1196b1721a30f551e9fe745a3e Fix SMP booting: x86/64 startup initialisation fixes and so on. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r e26f574eac9a -r 8d31f9a9c423 linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c Thu Aug 25 13:26:37 2005 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c Thu Aug 25 13:27:10 2005 @@ -19,11 +19,13 @@ #include "cpu.h" +#ifndef CONFIG_XEN DEFINE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]); EXPORT_PER_CPU_SYMBOL(cpu_gdt_table); DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); +#endif static int cachesize_override __initdata = -1; static int disable_x86_fxsr __initdata = 0; diff -r e26f574eac9a -r 8d31f9a9c423 linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Thu Aug 25 13:26:37 2005 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Thu Aug 25 13:27:10 2005 @@ -131,15 +131,7 @@ */ void __init smp_alloc_memory(void) { -#if 1 - int cpu; - - for (cpu = 1; cpu < NR_CPUS; cpu++) { - cpu_gdt_descr[cpu].address = (unsigned long) - alloc_bootmem_low_pages(PAGE_SIZE); - /* XXX free unused pages later */ - } -#else +#if 0 trampoline_base = (void *) alloc_bootmem_low_pages(PAGE_SIZE); /* * Has to be in very low memory so we can execute @@ -861,8 +853,8 @@ atomic_set(&init_deasserted, 0); #if 1 - if (cpu_gdt_descr[0].size > PAGE_SIZE) - BUG(); + cpu_gdt_descr[cpu].address = __get_free_page(GFP_KERNEL); + BUG_ON(cpu_gdt_descr[0].size > PAGE_SIZE); cpu_gdt_descr[cpu].size = cpu_gdt_descr[0].size; printk("GDT: copying %d bytes from %lx to %lx\n", cpu_gdt_descr[0].size, cpu_gdt_descr[0].address, diff -r e26f574eac9a -r 8d31f9a9c423 linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Thu Aug 25 13:26:37 2005 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Thu Aug 25 13:27:10 2005 @@ -871,6 +871,7 @@ } } +#ifndef CONFIG_XEN fastcall void setup_x86_bogus_stack(unsigned char * stk) { unsigned long *switch16_ptr, *switch32_ptr; @@ -915,6 +916,7 @@ memcpy(stack32, stack16, len); return stack32; } +#endif /* * 'math_state_restore()' saves the current math information in the diff -r e26f574eac9a -r 8d31f9a9c423 linux-2.6-xen-sparse/arch/xen/x86_64/kernel/early_printk.c --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/early_printk.c Thu Aug 25 13:26:37 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/early_printk.c Thu Aug 25 13:27:10 2005 @@ -5,6 +5,8 @@ #include <linux/string.h> #include <asm/io.h> #include <asm/processor.h> + +#ifndef CONFIG_XEN /* Simple VGA output */ @@ -59,7 +61,6 @@ .index = -1, }; -#ifndef CONFIG_XEN /* Serial functions loosely based on a similar package from Klaus P. Gerlicher */ static int early_serial_base = 0x3f8; /* ttyS0 */ @@ -148,7 +149,8 @@ outb((divisor >> 8) & 0xff, early_serial_base + DLH); outb(c & ~DLAB, early_serial_base + LCR); } -#else + +#else /* CONFIG_XEN */ static void early_serial_write(struct console *con, const char *s, unsigned count) @@ -167,6 +169,13 @@ static __init void early_serial_init(char *s) { } + +/* + * No early VGA console on Xen, as we do not have convenient ISA-space + * mappings. Someone should fix this for domain 0. For now, use fake serial. + */ +#define early_vga_console early_serial_console + #endif static struct console early_serial_console = { diff -r e26f574eac9a -r 8d31f9a9c423 linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S Thu Aug 25 13:26:37 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S Thu Aug 25 13:27:10 2005 @@ -206,11 +206,13 @@ .quad 0,0,0 /* three TLS descriptors */ .quad 0 /* unused now? __KERNEL16_CS - 16bit PM for S3 wakeup. */ -gdt_end: +gdt_end: +#if 0 /* asm/segment.h:GDT_ENTRIES must match this */ /* This should be a multiple of the cache line size */ /* GDTs of other CPUs: */ .fill (GDT_SIZE * NR_CPUS) - (gdt_end - cpu_gdt_table) +#endif .org 0x8000 ENTRY(empty_zero_page) diff -r e26f574eac9a -r 8d31f9a9c423 linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c Thu Aug 25 13:26:37 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c Thu Aug 25 13:27:10 2005 @@ -536,48 +536,7 @@ } #endif -#ifdef CONFIG_XEN -#define reserve_ebda_region() void(0) - -static void __init print_memory_map(char *who) -{ - int i; - - for (i = 0; i < e820.nr_map; i++) { - early_printk(" %s: %016Lx - %016Lx ", who, - e820.map[i].addr, - e820.map[i].addr + e820.map[i].size); - switch (e820.map[i].type) { - case E820_RAM: early_printk("(usable)\n"); - break; - case E820_RESERVED: - early_printk("(reserved)\n"); - break; - case E820_ACPI: - early_printk("(ACPI data)\n"); - break; - case E820_NVS: - early_printk("(ACPI NVS)\n"); - break; - default: early_printk("type %u\n", e820.map[i].type); - break; - } - } -} - -void __init smp_alloc_memory(void) -{ - int cpu; - - for (cpu = 1; cpu < NR_CPUS; cpu++) { - cpu_gdt_descr[cpu].address = (unsigned long) - alloc_bootmem_low_pages(PAGE_SIZE); - /* XXX free unused pages later */ - } -} - - -#else +#ifndef CONFIG_XEN #define EBDA_ADDR_POINTER 0x40E static void __init reserve_ebda_region(void) { @@ -628,7 +587,6 @@ VMASST_TYPE_writable_pagetables); ARCH_SETUP - print_memory_map(machine_specific_memory_setup()); #else ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); drive_info = DRIVE_INFO; @@ -743,9 +701,6 @@ initrd_start = 0; } } -#endif -#ifdef CONFIG_SMP - smp_alloc_memory(); #endif #else /* CONFIG_XEN */ #ifdef CONFIG_BLK_DEV_INITRD diff -r e26f574eac9a -r 8d31f9a9c423 linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c Thu Aug 25 13:26:37 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c Thu Aug 25 13:27:10 2005 @@ -286,10 +286,10 @@ memcpy(me->thread.tls_array, cpu_gdt_table[cpu], GDT_ENTRY_TLS_ENTRIES * 8); #else - memcpy(me->thread.tls_array, &get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN], + memcpy(me->thread.tls_array, &get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN], GDT_ENTRY_TLS_ENTRIES * 8); - cpu_gdt_init(&cpu_gdt_descr[cpu]); + cpu_gdt_init(&cpu_gdt_descr[cpu]); #endif /* diff -r e26f574eac9a -r 8d31f9a9c423 linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c Thu Aug 25 13:26:37 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c Thu Aug 25 13:27:10 2005 @@ -739,8 +739,8 @@ atomic_set(&init_deasserted, 0); #ifdef CONFIG_XEN - if (cpu_gdt_descr[0].size > PAGE_SIZE) - BUG(); + cpu_gdt_descr[cpu].address = __get_free_page(GFP_KERNEL); + BUG_ON(cpu_gdt_descr[0].size > PAGE_SIZE); cpu_gdt_descr[cpu].size = cpu_gdt_descr[0].size; memcpy((void *)cpu_gdt_descr[cpu].address, (void *)cpu_gdt_descr[0].address, cpu_gdt_descr[0].size); @@ -798,6 +798,8 @@ ctxt.ctrlreg[3] = virt_to_mfn(init_level4_pgt) << PAGE_SHIFT; boot_error = HYPERVISOR_boot_vcpu(cpu, &ctxt); + if (boot_error) + printk("boot error: %ld\n", boot_error); if (!boot_error) { /* diff -r e26f574eac9a -r 8d31f9a9c423 linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c Thu Aug 25 13:26:37 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c Thu Aug 25 13:27:10 2005 @@ -536,70 +536,38 @@ round_up(ptes * 8, PAGE_SIZE); } -static void xen_copy_pt(void) -{ - unsigned long va = __START_KERNEL_map; - unsigned long addr, *pte_page; +void __init xen_init_pt(void) +{ + unsigned long addr, *page; int i; - pud_t *pud; pmd_t *pmd; pte_t *pte; - unsigned long *page = (unsigned long *) init_level4_pgt; - - addr = (unsigned long) page[pgd_index(va)]; + + for (i = 0; i < NR_CPUS; i++) + per_cpu(cur_pgd, i) = init_mm.pgd; + + memset((void *)init_level4_pgt, 0, PAGE_SIZE); + memset((void *)level3_kernel_pgt, 0, PAGE_SIZE); + memset((void *)level2_kernel_pgt, 0, PAGE_SIZE); + + /* Find the initial pte page that was built for us. */ + page = (unsigned long *)xen_start_info.pt_base; + addr = page[pgd_index(__START_KERNEL_map)]; addr_to_page(addr, page); - - pud = (pud_t *) &page[pud_index(va)]; - addr = page[pud_index(va)]; + addr = page[pud_index(__START_KERNEL_map)]; addr_to_page(addr, page); - level3_kernel_pgt[pud_index(va)] = - __pud(__pa_symbol(level2_kernel_pgt) | _KERNPG_TABLE | _PAGE_USER); - - for (;;) { - pmd = (pmd_t *) &page[pmd_index(va)]; - if (pmd_present(*pmd)) { - level2_kernel_pgt[pmd_index(va)] = *pmd; - /* - * if pmd is valid, check pte. - */ - addr = page[pmd_index(va)]; - addr_to_page(addr, pte_page); - - for (i = 0; i < PTRS_PER_PTE; i++) { - pte = (pte_t *) &pte_page[pte_index(va)]; - if (pte_present(*pte)) - va += PAGE_SIZE; - else - break; - } - - } else - break; - } - + /* Construct mapping of initial pte page in our own directories. */ init_level4_pgt[pgd_index(__START_KERNEL_map)] = mk_kernel_pgd(__pa_symbol(level3_kernel_pgt)); -} - -void __init xen_init_pt(void) -{ - int i; - - for (i = 0; i < NR_CPUS; i++) - per_cpu(cur_pgd, i) = init_mm.pgd; - - memcpy((void *)init_level4_pgt, - (void *)xen_start_info.pt_base, PAGE_SIZE); - - memset((void *)level3_kernel_pgt, 0, PAGE_SIZE); - memset((void *)level2_kernel_pgt, 0, PAGE_SIZE); - - xen_copy_pt(); + level3_kernel_pgt[pud_index(__START_KERNEL_map)] = + __pud(__pa_symbol(level2_kernel_pgt) | + _KERNPG_TABLE | _PAGE_USER); + memcpy((void *)level2_kernel_pgt, page, PAGE_SIZE); make_page_readonly(init_level4_pgt); + make_page_readonly(init_level4_user_pgt); make_page_readonly(level3_kernel_pgt); + make_page_readonly(level3_user_pgt); make_page_readonly(level2_kernel_pgt); - make_page_readonly(init_level4_user_pgt); - make_page_readonly(level3_user_pgt); /* for vsyscall stuff */ xen_pgd_pin(__pa_symbol(init_level4_pgt)); xen_pgd_pin(__pa_symbol(init_level4_user_pgt)); @@ -609,7 +577,6 @@ set_pgd((pgd_t *)(init_level4_user_pgt + 511), mk_kernel_pgd(__pa_symbol(level3_user_pgt))); - } /* @@ -617,69 +584,58 @@ * mapping done by Xen is minimal (e.g. 8MB) and we need to extend the * mapping for early initialization. */ - -#define MIN_INIT_SIZE 0x800000 static unsigned long current_size, extended_size; void __init extend_init_mapping(void) { unsigned long va = __START_KERNEL_map; - unsigned long addr, *pte_page; - - unsigned long phys; + unsigned long phys, addr, *pte_page; pmd_t *pmd; pte_t *pte, new_pte; unsigned long *page = (unsigned long *) init_level4_pgt; int i; - addr = (unsigned long) page[pgd_index(va)]; + addr = page[pgd_index(va)]; addr_to_page(addr, page); - addr = page[pud_index(va)]; addr_to_page(addr, page); for (;;) { + pmd = (pmd_t *)&page[pmd_index(va)]; + if (!pmd_present(*pmd)) + break; + addr = page[pmd_index(va)]; + addr_to_page(addr, pte_page); + for (i = 0; i < PTRS_PER_PTE; i++) { + pte = (pte_t *) &pte_page[pte_index(va)]; + if (!pte_present(*pte)) + break; + va += PAGE_SIZE; + current_size += PAGE_SIZE; + } + } + + while (va < __START_KERNEL_map + current_size + tables_space) { pmd = (pmd_t *) &page[pmd_index(va)]; - if (pmd_present(*pmd)) { - /* - * if pmd is valid, check pte. - */ - addr = page[pmd_index(va)]; - addr_to_page(addr, pte_page); - - for (i = 0; i < PTRS_PER_PTE; i++) { - pte = (pte_t *) &pte_page[pte_index(va)]; - - if (pte_present(*pte)) { - va += PAGE_SIZE; - current_size += PAGE_SIZE; - } else - break; - } - - } else - break; - } - - for (; va < __START_KERNEL_map + current_size + tables_space; ) { - pmd = (pmd_t *) &page[pmd_index(va)]; - - if (pmd_none(*pmd)) { - pte_page = (unsigned long *) alloc_static_page(&phys); - make_page_readonly(pte_page); - xen_pte_pin(phys); - set_pmd(pmd, __pmd(phys | _KERNPG_TABLE | _PAGE_USER)); - - for (i = 0; i < PTRS_PER_PTE; i++, va += PAGE_SIZE) { - new_pte = pfn_pte((va - __START_KERNEL_map) >> PAGE_SHIFT, - __pgprot(_KERNPG_TABLE | _PAGE_USER)); - - pte = (pte_t *) &pte_page[pte_index(va)]; - xen_l1_entry_update(pte, new_pte); - extended_size += PAGE_SIZE; - } - } - } + if (!pmd_none(*pmd)) + continue; + pte_page = (unsigned long *) alloc_static_page(&phys); + make_page_readonly(pte_page); + xen_pte_pin(phys); + set_pmd(pmd, __pmd(phys | _KERNPG_TABLE | _PAGE_USER)); + for (i = 0; i < PTRS_PER_PTE; i++, va += PAGE_SIZE) { + new_pte = pfn_pte( + (va - __START_KERNEL_map) >> PAGE_SHIFT, + __pgprot(_KERNPG_TABLE | _PAGE_USER)); + pte = (pte_t *)&pte_page[pte_index(va)]; + xen_l1_entry_update(pte, new_pte); + extended_size += PAGE_SIZE; + } + } + + /* Kill mapping of low 1MB. */ + for (va = __START_KERNEL_map; va < (unsigned long)&_text; va += PAGE_SIZE) + HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0); } @@ -719,10 +675,6 @@ table_end<<PAGE_SHIFT); start_pfn = ((current_size + extended_size) >> PAGE_SHIFT); - - /* - * TBD: Need to calculate at runtime - */ __flush_tlb_all(); init_mapping_done = 1; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |