ia64/xen-unstable

changeset 8459:fe039c5fd127

Reset the stack pointer on every cpu early during bootstrap.
Ensures we do not overlap with the cpu_info structure.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Dec 29 17:53:22 2005 +0100 (2005-12-29)
parents 4dbca1428acd
children 4937d9f496ab
files xen/arch/x86/boot/x86_32.S xen/arch/x86/boot/x86_64.S xen/arch/x86/setup.c xen/arch/x86/smpboot.c
line diff
     1.1 --- a/xen/arch/x86/boot/x86_32.S	Thu Dec 29 17:37:08 2005 +0100
     1.2 +++ b/xen/arch/x86/boot/x86_32.S	Thu Dec 29 17:53:22 2005 +0100
     1.3 @@ -167,7 +167,7 @@ 1:      /* Paging enabled, so we can now
     1.4          lidt    idt_descr
     1.5                  
     1.6          cmp     $(SECONDARY_CPU_FLAG),%ebx
     1.7 -        je      start_secondary
     1.8 +        je      init_secondary
     1.9  
    1.10          /* Call into main C routine. This should never return.*/
    1.11         	call	__start_xen
     2.1 --- a/xen/arch/x86/boot/x86_64.S	Thu Dec 29 17:37:08 2005 +0100
     2.2 +++ b/xen/arch/x86/boot/x86_64.S	Thu Dec 29 17:53:22 2005 +0100
     2.3 @@ -142,7 +142,7 @@ 1:      /* Now in compatibility mode. Lo
     2.4          lidt    idt_descr(%rip)
     2.5                  
     2.6          cmp     $(SECONDARY_CPU_FLAG),%ebx
     2.7 -        je      start_secondary
     2.8 +        je      init_secondary
     2.9  
    2.10          /* Initialize BSS (no nasty surprises!) */
    2.11          lea     __bss_start(%rip),%rdi
     3.1 --- a/xen/arch/x86/setup.c	Thu Dec 29 17:37:08 2005 +0100
     3.2 +++ b/xen/arch/x86/setup.c	Thu Dec 29 17:53:22 2005 +0100
     3.3 @@ -138,212 +138,21 @@ static void __init do_initcalls(void)
     3.4          (*call)();
     3.5  }
     3.6  
     3.7 -/* Variables handed off from __start_xen() to start_of_day(). */
     3.8 -static unsigned long initial_images_start, initial_images_end;
     3.9 +#define EARLY_FAIL() for ( ; ; ) __asm__ __volatile__ ( "hlt" )
    3.10 +
    3.11 +static struct e820entry e820_raw[E820MAX];
    3.12 +
    3.13  static multiboot_info_t *mbi;
    3.14  
    3.15  void __init start_of_day(void)
    3.16  {
    3.17 -    int i;
    3.18      unsigned long vgdt, gdt_pfn;
    3.19      char *cmdline;
    3.20      unsigned long _initrd_start = 0, _initrd_len = 0;
    3.21      unsigned int initrdidx = 1;
    3.22      module_t *mod = (module_t *)__va(mbi->mods_addr);
    3.23 -
    3.24 -    early_cpu_init();
    3.25 -
    3.26 -    paging_init();
    3.27 -
    3.28 -    /* Unmap the first page of CPU0's stack. */
    3.29 -    memguard_guard_stack(cpu0_stack);
    3.30 -
    3.31 -    open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);
    3.32 -
    3.33 -    if ( opt_watchdog ) 
    3.34 -        nmi_watchdog = NMI_LOCAL_APIC;
    3.35 -
    3.36 -    sort_exception_tables();
    3.37 -
    3.38 -    arch_do_createdomain(current);
    3.39 -    
    3.40 -    /*
    3.41 -     * Map default GDT into its final positions in the idle page table. As
    3.42 -     * noted in arch_do_createdomain(), we must map for every possible VCPU#.
    3.43 -     */
    3.44 -    vgdt = GDT_VIRT_START(current) + FIRST_RESERVED_GDT_BYTE;
    3.45 -    gdt_pfn = virt_to_phys(gdt_table) >> PAGE_SHIFT;
    3.46 -    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
    3.47 -    {
    3.48 -        map_pages_to_xen(vgdt, gdt_pfn, 1, PAGE_HYPERVISOR);
    3.49 -        vgdt += 1 << PDPT_VCPU_VA_SHIFT;
    3.50 -    }
    3.51 -
    3.52 -    find_smp_config();
    3.53 -
    3.54 -    smp_alloc_memory();
    3.55 -
    3.56 -    dmi_scan_machine();
    3.57 -
    3.58 -    generic_apic_probe();
    3.59 -
    3.60 -    acpi_boot_table_init();
    3.61 -    acpi_boot_init();
    3.62 -
    3.63 -    if ( smp_found_config ) 
    3.64 -        get_smp_config();
    3.65 -
    3.66 -    init_apic_mappings();
    3.67 -
    3.68 -    init_IRQ();
    3.69 -
    3.70 -    trap_init();
    3.71 -
    3.72 -    ac_timer_init();
    3.73 -
    3.74 -    early_time_init();
    3.75 -
    3.76 -    arch_init_memory();
    3.77 -
    3.78 -    scheduler_init();
    3.79 -
    3.80 -    identify_cpu(&boot_cpu_data);
    3.81 -    if ( cpu_has_fxsr )
    3.82 -        set_in_cr4(X86_CR4_OSFXSR);
    3.83 -    if ( cpu_has_xmm )
    3.84 -        set_in_cr4(X86_CR4_OSXMMEXCPT);
    3.85 -
    3.86 -    if ( opt_nosmp )
    3.87 -    {
    3.88 -        max_cpus = 0;
    3.89 -        smp_num_siblings = 1;
    3.90 -        boot_cpu_data.x86_num_cores = 1;
    3.91 -    }
    3.92 -
    3.93 -    smp_prepare_cpus(max_cpus);
    3.94 -
    3.95 -    /* We aren't hotplug-capable yet. */
    3.96 -    BUG_ON(!cpus_empty(cpu_present_map));
    3.97 -    for_each_cpu ( i )
    3.98 -        cpu_set(i, cpu_present_map);
    3.99 -
   3.100 -    /*
   3.101 -     * Initialise higher-level timer functions. We do this fairly late
   3.102 -     * (post-SMP) because the time bases and scale factors need to be updated 
   3.103 -     * regularly, and SMP initialisation can cause a long delay with 
   3.104 -     * interrupts not yet enabled.
   3.105 -     */
   3.106 -    init_xen_time();
   3.107 -
   3.108 -    initialize_keytable();
   3.109 -
   3.110 -    serial_init_postirq();
   3.111 -
   3.112 -    BUG_ON(!local_irq_is_enabled());
   3.113 -
   3.114 -    for_each_present_cpu ( i )
   3.115 -    {
   3.116 -        if ( num_online_cpus() >= max_cpus )
   3.117 -            break;
   3.118 -        if ( !cpu_online(i) )
   3.119 -            __cpu_up(i);
   3.120 -    }
   3.121 -
   3.122 -    printk("Brought up %ld CPUs\n", (long)num_online_cpus());
   3.123 -    smp_cpus_done(max_cpus);
   3.124 -
   3.125 -    do_initcalls();
   3.126 -
   3.127 -    schedulers_start();
   3.128 -
   3.129 -    watchdog_enable();
   3.130 -
   3.131 -    shadow_mode_init();
   3.132 -
   3.133 -    /* initialize access control security module */
   3.134 -    acm_init(&initrdidx, mbi, initial_images_start);
   3.135 -
   3.136 -    /* Create initial domain 0. */
   3.137 -    dom0 = do_createdomain(0, 0);
   3.138 -    if ( dom0 == NULL )
   3.139 -        panic("Error creating domain 0\n");
   3.140 -
   3.141 -    set_bit(_DOMF_privileged, &dom0->domain_flags);
   3.142 -    /* post-create hooks sets security label */
   3.143 -    acm_post_domain0_create(dom0->domain_id);
   3.144 -
   3.145 -    /* Grab the DOM0 command line. */
   3.146 -    cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
   3.147 -    if ( cmdline != NULL )
   3.148 -    {
   3.149 -        static char dom0_cmdline[MAX_GUEST_CMDLINE];
   3.150 -
   3.151 -        /* Skip past the image name and copy to a local buffer. */
   3.152 -        while ( *cmdline == ' ' ) cmdline++;
   3.153 -        if ( (cmdline = strchr(cmdline, ' ')) != NULL )
   3.154 -        {
   3.155 -            while ( *cmdline == ' ' ) cmdline++;
   3.156 -            strcpy(dom0_cmdline, cmdline);
   3.157 -        }
   3.158 -
   3.159 -        cmdline = dom0_cmdline;
   3.160 -
   3.161 -        /* Append any extra parameters. */
   3.162 -        if ( skip_ioapic_setup && !strstr(cmdline, "noapic") )
   3.163 -            strcat(cmdline, " noapic");
   3.164 -        if ( acpi_skip_timer_override &&
   3.165 -             !strstr(cmdline, "acpi_skip_timer_override") )
   3.166 -            strcat(cmdline, " acpi_skip_timer_override");
   3.167 -        if ( (strlen(acpi_param) != 0) && !strstr(cmdline, "acpi=") )
   3.168 -        {
   3.169 -            strcat(cmdline, " acpi=");
   3.170 -            strcat(cmdline, acpi_param);
   3.171 -        }
   3.172 -    }
   3.173 -
   3.174 -    if ( (initrdidx > 0) && (initrdidx < mbi->mods_count) )
   3.175 -    {
   3.176 -        _initrd_start = initial_images_start +
   3.177 -            (mod[initrdidx].mod_start - mod[0].mod_start);
   3.178 -        _initrd_len   = mod[initrdidx].mod_end - mod[initrdidx].mod_start;
   3.179 -    }
   3.180 -
   3.181 -    /*
   3.182 -     * We're going to setup domain0 using the module(s) that we stashed safely
   3.183 -     * above our heap. The second module, if present, is an initrd ramdisk.
   3.184 -     */
   3.185 -    if ( construct_dom0(dom0,
   3.186 -                        initial_images_start, 
   3.187 -                        mod[0].mod_end-mod[0].mod_start,
   3.188 -                        _initrd_start,
   3.189 -                        _initrd_len,
   3.190 -                        cmdline) != 0)
   3.191 -        panic("Could not set up DOM0 guest OS\n");
   3.192 -
   3.193 -    /* Scrub RAM that is still free and so may go to an unprivileged domain. */
   3.194 -    scrub_heap_pages();
   3.195 -
   3.196 -    init_trace_bufs();
   3.197 -
   3.198 -    /* Give up the VGA console if DOM0 is configured to grab it. */
   3.199 -    console_endboot(cmdline && strstr(cmdline, "tty0"));
   3.200 -
   3.201 -    /* Hide UART from DOM0 if we're using it */
   3.202 -    serial_endboot();
   3.203 -
   3.204 -    domain_unpause_by_systemcontroller(dom0);
   3.205 -
   3.206 -    startup_cpu_idle_loop();
   3.207 -}
   3.208 -
   3.209 -#define EARLY_FAIL() for ( ; ; ) __asm__ __volatile__ ( "hlt" )
   3.210 -
   3.211 -static struct e820entry e820_raw[E820MAX];
   3.212 -
   3.213 -void __init __start_xen(multiboot_info_t *__mbi)
   3.214 -{
   3.215 -    module_t *mod = (module_t *)__va(__mbi->mods_addr);
   3.216      unsigned long nr_pages, modules_length;
   3.217 +    unsigned long initial_images_start, initial_images_end;
   3.218      physaddr_t s, e;
   3.219      int i, e820_warn = 0, e820_raw_nr = 0, bytes = 0;
   3.220      struct ns16550_defaults ns16550 = {
   3.221 @@ -352,8 +161,6 @@ void __init __start_xen(multiboot_info_t
   3.222          .stop_bits = 1
   3.223      };
   3.224  
   3.225 -    mbi = __mbi;
   3.226 -
   3.227      /* Parse the command-line options. */
   3.228      if ( (mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0) )
   3.229          cmdline_parse(__va(mbi->cmdline));
   3.230 @@ -569,6 +376,194 @@ void __init __start_xen(multiboot_info_t
   3.231  
   3.232      early_boot = 0;
   3.233  
   3.234 +    early_cpu_init();
   3.235 +
   3.236 +    paging_init();
   3.237 +
   3.238 +    /* Unmap the first page of CPU0's stack. */
   3.239 +    memguard_guard_stack(cpu0_stack);
   3.240 +
   3.241 +    open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);
   3.242 +
   3.243 +    if ( opt_watchdog ) 
   3.244 +        nmi_watchdog = NMI_LOCAL_APIC;
   3.245 +
   3.246 +    sort_exception_tables();
   3.247 +
   3.248 +    arch_do_createdomain(current);
   3.249 +    
   3.250 +    /*
   3.251 +     * Map default GDT into its final positions in the idle page table. As
   3.252 +     * noted in arch_do_createdomain(), we must map for every possible VCPU#.
   3.253 +     */
   3.254 +    vgdt = GDT_VIRT_START(current) + FIRST_RESERVED_GDT_BYTE;
   3.255 +    gdt_pfn = virt_to_phys(gdt_table) >> PAGE_SHIFT;
   3.256 +    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
   3.257 +    {
   3.258 +        map_pages_to_xen(vgdt, gdt_pfn, 1, PAGE_HYPERVISOR);
   3.259 +        vgdt += 1 << PDPT_VCPU_VA_SHIFT;
   3.260 +    }
   3.261 +
   3.262 +    find_smp_config();
   3.263 +
   3.264 +    smp_alloc_memory();
   3.265 +
   3.266 +    dmi_scan_machine();
   3.267 +
   3.268 +    generic_apic_probe();
   3.269 +
   3.270 +    acpi_boot_table_init();
   3.271 +    acpi_boot_init();
   3.272 +
   3.273 +    if ( smp_found_config ) 
   3.274 +        get_smp_config();
   3.275 +
   3.276 +    init_apic_mappings();
   3.277 +
   3.278 +    init_IRQ();
   3.279 +
   3.280 +    trap_init();
   3.281 +
   3.282 +    ac_timer_init();
   3.283 +
   3.284 +    early_time_init();
   3.285 +
   3.286 +    arch_init_memory();
   3.287 +
   3.288 +    scheduler_init();
   3.289 +
   3.290 +    identify_cpu(&boot_cpu_data);
   3.291 +    if ( cpu_has_fxsr )
   3.292 +        set_in_cr4(X86_CR4_OSFXSR);
   3.293 +    if ( cpu_has_xmm )
   3.294 +        set_in_cr4(X86_CR4_OSXMMEXCPT);
   3.295 +
   3.296 +    if ( opt_nosmp )
   3.297 +    {
   3.298 +        max_cpus = 0;
   3.299 +        smp_num_siblings = 1;
   3.300 +        boot_cpu_data.x86_num_cores = 1;
   3.301 +    }
   3.302 +
   3.303 +    smp_prepare_cpus(max_cpus);
   3.304 +
   3.305 +    /* We aren't hotplug-capable yet. */
   3.306 +    BUG_ON(!cpus_empty(cpu_present_map));
   3.307 +    for_each_cpu ( i )
   3.308 +        cpu_set(i, cpu_present_map);
   3.309 +
   3.310 +    /*
   3.311 +     * Initialise higher-level timer functions. We do this fairly late
   3.312 +     * (post-SMP) because the time bases and scale factors need to be updated 
   3.313 +     * regularly, and SMP initialisation can cause a long delay with 
   3.314 +     * interrupts not yet enabled.
   3.315 +     */
   3.316 +    init_xen_time();
   3.317 +
   3.318 +    initialize_keytable();
   3.319 +
   3.320 +    serial_init_postirq();
   3.321 +
   3.322 +    BUG_ON(!local_irq_is_enabled());
   3.323 +
   3.324 +    for_each_present_cpu ( i )
   3.325 +    {
   3.326 +        if ( num_online_cpus() >= max_cpus )
   3.327 +            break;
   3.328 +        if ( !cpu_online(i) )
   3.329 +            __cpu_up(i);
   3.330 +    }
   3.331 +
   3.332 +    printk("Brought up %ld CPUs\n", (long)num_online_cpus());
   3.333 +    smp_cpus_done(max_cpus);
   3.334 +
   3.335 +    do_initcalls();
   3.336 +
   3.337 +    schedulers_start();
   3.338 +
   3.339 +    watchdog_enable();
   3.340 +
   3.341 +    shadow_mode_init();
   3.342 +
   3.343 +    /* initialize access control security module */
   3.344 +    acm_init(&initrdidx, mbi, initial_images_start);
   3.345 +
   3.346 +    /* Create initial domain 0. */
   3.347 +    dom0 = do_createdomain(0, 0);
   3.348 +    if ( dom0 == NULL )
   3.349 +        panic("Error creating domain 0\n");
   3.350 +
   3.351 +    set_bit(_DOMF_privileged, &dom0->domain_flags);
   3.352 +    /* post-create hooks sets security label */
   3.353 +    acm_post_domain0_create(dom0->domain_id);
   3.354 +
   3.355 +    /* Grab the DOM0 command line. */
   3.356 +    cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
   3.357 +    if ( cmdline != NULL )
   3.358 +    {
   3.359 +        static char dom0_cmdline[MAX_GUEST_CMDLINE];
   3.360 +
   3.361 +        /* Skip past the image name and copy to a local buffer. */
   3.362 +        while ( *cmdline == ' ' ) cmdline++;
   3.363 +        if ( (cmdline = strchr(cmdline, ' ')) != NULL )
   3.364 +        {
   3.365 +            while ( *cmdline == ' ' ) cmdline++;
   3.366 +            strcpy(dom0_cmdline, cmdline);
   3.367 +        }
   3.368 +
   3.369 +        cmdline = dom0_cmdline;
   3.370 +
   3.371 +        /* Append any extra parameters. */
   3.372 +        if ( skip_ioapic_setup && !strstr(cmdline, "noapic") )
   3.373 +            strcat(cmdline, " noapic");
   3.374 +        if ( acpi_skip_timer_override &&
   3.375 +             !strstr(cmdline, "acpi_skip_timer_override") )
   3.376 +            strcat(cmdline, " acpi_skip_timer_override");
   3.377 +        if ( (strlen(acpi_param) != 0) && !strstr(cmdline, "acpi=") )
   3.378 +        {
   3.379 +            strcat(cmdline, " acpi=");
   3.380 +            strcat(cmdline, acpi_param);
   3.381 +        }
   3.382 +    }
   3.383 +
   3.384 +    if ( (initrdidx > 0) && (initrdidx < mbi->mods_count) )
   3.385 +    {
   3.386 +        _initrd_start = initial_images_start +
   3.387 +            (mod[initrdidx].mod_start - mod[0].mod_start);
   3.388 +        _initrd_len   = mod[initrdidx].mod_end - mod[initrdidx].mod_start;
   3.389 +    }
   3.390 +
   3.391 +    /*
   3.392 +     * We're going to setup domain0 using the module(s) that we stashed safely
   3.393 +     * above our heap. The second module, if present, is an initrd ramdisk.
   3.394 +     */
   3.395 +    if ( construct_dom0(dom0,
   3.396 +                        initial_images_start, 
   3.397 +                        mod[0].mod_end-mod[0].mod_start,
   3.398 +                        _initrd_start,
   3.399 +                        _initrd_len,
   3.400 +                        cmdline) != 0)
   3.401 +        panic("Could not set up DOM0 guest OS\n");
   3.402 +
   3.403 +    /* Scrub RAM that is still free and so may go to an unprivileged domain. */
   3.404 +    scrub_heap_pages();
   3.405 +
   3.406 +    init_trace_bufs();
   3.407 +
   3.408 +    /* Give up the VGA console if DOM0 is configured to grab it. */
   3.409 +    console_endboot(cmdline && strstr(cmdline, "tty0"));
   3.410 +
   3.411 +    /* Hide UART from DOM0 if we're using it */
   3.412 +    serial_endboot();
   3.413 +
   3.414 +    domain_unpause_by_systemcontroller(dom0);
   3.415 +
   3.416 +    startup_cpu_idle_loop();
   3.417 +}
   3.418 +
   3.419 +void __init __start_xen(multiboot_info_t *__mbi)
   3.420 +{
   3.421 +    mbi = __mbi;
   3.422      reset_stack_and_jump(start_of_day);
   3.423  }
   3.424  
     4.1 --- a/xen/arch/x86/smpboot.c	Thu Dec 29 17:37:08 2005 +0100
     4.2 +++ b/xen/arch/x86/smpboot.c	Thu Dec 29 17:53:22 2005 +0100
     4.3 @@ -429,7 +429,7 @@ static void construct_percpu_idt(unsigne
     4.4  /*
     4.5   * Activate a secondary processor.
     4.6   */
     4.7 -void __init start_secondary(void *unused)
     4.8 +void __init start_secondary(void)
     4.9  {
    4.10  	unsigned int cpu = cpucount;
    4.11  
    4.12 @@ -472,6 +472,11 @@ void __init start_secondary(void *unused
    4.13  	startup_cpu_idle_loop();
    4.14  }
    4.15  
    4.16 +void __init init_secondary(void)
    4.17 +{
    4.18 +    reset_stack_and_jump(start_secondary);
    4.19 +}
    4.20 +
    4.21  extern struct {
    4.22  	void * esp;
    4.23  	unsigned short ss;
    4.24 @@ -788,11 +793,10 @@ static int __init do_boot_cpu(int apicid
    4.25  
    4.26  	stack = alloc_xenheap_pages(STACK_ORDER);
    4.27  #if defined(__i386__)
    4.28 -	stack_start.esp = (void *)__pa(stack);
    4.29 +	stack_start.esp = (void *)__pa(stack) + STACK_SIZE;
    4.30  #elif defined(__x86_64__)
    4.31 -	stack_start.esp = stack;
    4.32 +	stack_start.esp = stack + STACK_SIZE;
    4.33  #endif
    4.34 -	stack_start.esp += STACK_SIZE - sizeof(struct cpu_info);
    4.35  
    4.36  	/* Debug build: detect stack overflow by setting up a guard page. */
    4.37  	memguard_guard_stack(stack);