diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 992d24ec7e..29d71087a7 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -149,7 +149,7 @@ unsigned long __read_mostly xen_phys_start; unsigned long __read_mostly xen_virt_end; -char __section(".bss.stack_aligned") __aligned(STACK_SIZE) +char __section(".init.bss.stack_aligned") __aligned(STACK_SIZE) cpu0_stack[STACK_SIZE]; struct cpuinfo_x86 __read_mostly boot_cpu_data = { 0, 0, 0, 0, -1 }; @@ -696,7 +696,6 @@ static void __init noreturn reinit_bsp_stack(void) percpu_traps_init(); stack_base[0] = stack; - memguard_guard_stack(stack); rc = setup_cpu_root_pgt(0); if ( rc ) @@ -850,6 +849,8 @@ void __init noreturn __start_xen(unsigned long mbi_p) { char *memmap_type = NULL; char *cmdline, *kextra, *loader; + void *bsp_stack; + struct cpu_info *info = get_cpu_info(), *bsp_info; unsigned int initrdidx, num_parked = 0; multiboot_info_t *mbi; module_t *mod; @@ -881,7 +882,7 @@ void __init noreturn __start_xen(unsigned long mbi_p) /* Full exception support from here on in. */ rdmsrl(MSR_EFER, this_cpu(efer)); - asm volatile ( "mov %%cr4,%0" : "=r" (get_cpu_info()->cr4) ); + asm volatile ( "mov %%cr4,%0" : "=r" (info->cr4) ); /* Enable NMIs. Our loader (e.g. Tboot) may have left them disabled. */ enable_nmis(); @@ -1720,6 +1721,10 @@ void __init noreturn __start_xen(unsigned long mbi_p) */ vm_init(); + bsp_stack = cpu_alloc_stack(0); + if ( !bsp_stack ) + panic("No memory for BSP stack\n"); + console_init_ring(); vesa_init(); @@ -1975,17 +1980,18 @@ void __init noreturn __start_xen(unsigned long mbi_p) if ( bsp_delay_spec_ctrl ) { - struct cpu_info *info = get_cpu_info(); - info->spec_ctrl_flags &= ~SCF_use_shadow; barrier(); wrmsrl(MSR_SPEC_CTRL, default_xen_spec_ctrl); info->last_spec_ctrl = default_xen_spec_ctrl; } - /* Jump to the 1:1 virtual mappings of cpu0_stack. */ + /* Copy the cpu info block, and move onto the BSP stack. */ + bsp_info = get_cpu_info_from_stack((unsigned long)bsp_stack); + *bsp_info = *info; + asm volatile ("mov %[stk], %%rsp; jmp %c[fn]" :: - [stk] "g" (__va(__pa(get_stack_bottom()))), + [stk] "g" (&bsp_info->guest_cpu_user_regs), [fn] "i" (reinit_bsp_stack) : "memory"); unreachable(); } diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index 5abfae4c72..d968504539 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -988,6 +988,23 @@ static void cpu_smpboot_free(unsigned int cpu, bool remove) } } +void *cpu_alloc_stack(unsigned int cpu) +{ + nodeid_t node = cpu_to_node(cpu); + unsigned int memflags = 0; + void *stack; + + if ( node != NUMA_NO_NODE ) + memflags = MEMF_node(node); + + stack = alloc_xenheap_pages(STACK_ORDER, memflags); + + if ( stack ) + memguard_guard_stack(stack); + + return stack; +} + static int cpu_smpboot_alloc(unsigned int cpu) { struct cpu_info *info; @@ -1000,15 +1017,10 @@ static int cpu_smpboot_alloc(unsigned int cpu) if ( node != NUMA_NO_NODE ) memflags = MEMF_node(node); - if ( stack_base[cpu] == NULL ) - { - stack_base[cpu] = alloc_xenheap_pages(STACK_ORDER, memflags); - if ( !stack_base[cpu] ) + if ( stack_base[cpu] == NULL && + (stack_base[cpu] = cpu_alloc_stack(cpu)) == NULL ) goto out; - memguard_guard_stack(stack_base[cpu]); - } - info = get_cpu_info_from_stack((unsigned long)stack_base[cpu]); info->processor_id = cpu; info->per_cpu_offset = __per_cpu_offset[cpu]; diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S index fcc6646487..7c9758c8cc 100644 --- a/xen/arch/x86/xen.lds.S +++ b/xen/arch/x86/xen.lds.S @@ -205,6 +205,7 @@ SECTIONS } :text DECL_SECTION(.init.data) { #endif + *(.init.bss.stack_aligned) *(.init.rodata) *(.init.rodata.*) @@ -293,7 +294,6 @@ SECTIONS DECL_SECTION(.bss) { __bss_start = .; - *(.bss.stack_aligned) *(.bss.page_aligned*) . = ALIGN(PAGE_SIZE); __per_cpu_start = .; diff --git a/xen/include/asm-x86/smp.h b/xen/include/asm-x86/smp.h index f7485f602e..9628d7842d 100644 --- a/xen/include/asm-x86/smp.h +++ b/xen/include/asm-x86/smp.h @@ -85,6 +85,8 @@ extern cpumask_t **socket_cpumask; extern unsigned int disabled_cpus; extern bool unaccounted_cpus; +void *cpu_alloc_stack(unsigned int cpu); + #endif /* !__ASSEMBLY__ */ #endif