diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2005-12-29 16:59:12 +0100 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2005-12-29 16:59:12 +0100 |
commit | b33ac9e43315d6e9864e2d324f8f5a620d5ec421 (patch) | |
tree | 4cc74f4bf055b004e4bc1b4ef7d11c177d64f86d | |
parent | 484a058c48287df3fc9fa0b146dd8c827ffff7be (diff) | |
download | xen-b33ac9e43315d6e9864e2d324f8f5a620d5ec421.tar.gz xen-b33ac9e43315d6e9864e2d324f8f5a620d5ec421.tar.bz2 xen-b33ac9e43315d6e9864e2d324f8f5a620d5ec421.zip |
Various fixes to Xen stack management. Ensure the cpu0_stack
is always sufficiently aligned (requires some linker script
tricks). Small fixes to show_trace() and ensure that Xen
stack pointers are always below the 'struct cpu_info' region.
Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r-- | .hgignore | 1 | ||||
-rw-r--r-- | xen/arch/x86/Makefile | 13 | ||||
-rw-r--r-- | xen/arch/x86/boot/x86_32.S | 8 | ||||
-rw-r--r-- | xen/arch/x86/boot/x86_64.S | 8 | ||||
-rw-r--r-- | xen/arch/x86/domain.c | 2 | ||||
-rw-r--r-- | xen/arch/x86/setup.c | 176 | ||||
-rw-r--r-- | xen/arch/x86/traps.c | 7 | ||||
-rw-r--r-- | xen/arch/x86/x86_32/xen.lds.S (renamed from xen/arch/x86/x86_32/xen.lds) | 10 | ||||
-rw-r--r-- | xen/arch/x86/x86_64/xen.lds.S (renamed from xen/arch/x86/x86_64/xen.lds) | 10 | ||||
-rw-r--r-- | xen/include/asm-x86/current.h | 2 |
10 files changed, 127 insertions, 110 deletions
@@ -181,6 +181,7 @@ ^xen/TAGS$ ^xen/arch/x86/asm-offsets\.s$ ^xen/arch/x86/boot/mkelf32$ +^xen/arch/x86/xen\.lds$ ^xen/ddb/.*$ ^xen/include/asm$ ^xen/include/asm-.*/asm-offsets\.h$ diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 54fcf82dae..9cdbc5798c 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -29,6 +29,7 @@ ifeq ($(TARGET_SUBARCH),x86_32) endif OBJS := $(subst $(TARGET_SUBARCH)/asm-offsets.o,,$(OBJS)) +OBJS := $(subst $(TARGET_SUBARCH)/xen.lds.o,,$(OBJS)) ifneq ($(crash_debug),y) OBJS := $(patsubst cdb%.o,,$(OBJS)) @@ -43,22 +44,25 @@ $(TARGET): $(TARGET)-syms boot/mkelf32 $(CURDIR)/arch.o: $(OBJS) $(LD) $(LDFLAGS) -r -o $@ $(OBJS) -$(TARGET)-syms: boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(TARGET_SUBARCH)/xen.lds - $(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \ +$(TARGET)-syms: boot/$(TARGET_SUBARCH).o $(ALL_OBJS) xen.lds + $(LD) $(LDFLAGS) -T xen.lds -N \ boot/$(TARGET_SUBARCH).o $(ALL_OBJS) -o $@ $(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S $(MAKE) $(BASEDIR)/xen-syms.o - $(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \ + $(LD) $(LDFLAGS) -T xen.lds -N \ boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@ $(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S $(MAKE) $(BASEDIR)/xen-syms.o - $(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \ + $(LD) $(LDFLAGS) -T xen.lds -N \ boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@ rm -f $(BASEDIR)/xen-syms.S $(BASEDIR)/xen-syms.o asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c $(HDRS) $(CC) $(CFLAGS) -S -o $@ $< +xen.lds: $(TARGET_SUBARCH)/xen.lds.S $(HDRS) + $(CC) $(CFLAGS) -P -E -Ui386 -D__ASSEMBLY__ -o $@ $< + boot/mkelf32: boot/mkelf32.c $(HOSTCC) $(HOSTCFLAGS) -o $@ $< @@ -73,5 +77,6 @@ clean: rm -f dm/*.o dm/*~ dm/core rm -f genapic/*.o genapic/*~ genapic/core rm -f cpu/*.o cpu/*~ cpu/core + rm -f xen.lds .PHONY: default clean diff --git a/xen/arch/x86/boot/x86_32.S b/xen/arch/x86/boot/x86_32.S index 59e68ca7ef..d5a85e77fc 100644 --- a/xen/arch/x86/boot/x86_32.S +++ b/xen/arch/x86/boot/x86_32.S @@ -189,7 +189,7 @@ ignore_int: /*** STACK LOCATION ***/ ENTRY(stack_start) - .long cpu0_stack + STACK_SIZE - 200 - __PAGE_OFFSET + .long cpu0_stack + STACK_SIZE - __PAGE_OFFSET .long __HYPERVISOR_DS /*** DESCRIPTOR TABLES ***/ @@ -256,10 +256,6 @@ ENTRY(idle_pg_table_l2) .fill 1*PAGE_SIZE,1,0 #endif -#if (STACK_ORDER == 0) -.section ".bss.page_aligned","w" -#else -.section ".bss.twopage_aligned","w" -#endif +.section ".bss.stack_aligned","w" ENTRY(cpu0_stack) .fill STACK_SIZE,1,0 diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S index 126850a0f8..0d82c2087f 100644 --- a/xen/arch/x86/boot/x86_64.S +++ b/xen/arch/x86/boot/x86_64.S @@ -219,7 +219,7 @@ idt: .quad idt_table ENTRY(stack_start) - .quad cpu0_stack + STACK_SIZE - 200 + .quad cpu0_stack + STACK_SIZE high_start: .quad __high_start @@ -265,10 +265,6 @@ ENTRY(idle_pg_table_l2) .org 0x4000 + PAGE_SIZE .code64 -#if (STACK_ORDER == 0) -.section ".bss.page_aligned","w" -#else -.section ".bss.twopage_aligned","w" -#endif +.section ".bss.stack_aligned","w" ENTRY(cpu0_stack) .fill STACK_SIZE,1,0 diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 4c586226dd..850b88d141 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -98,7 +98,7 @@ void startup_cpu_idle_loop(void) cpu_set(smp_processor_id(), v->domain->cpumask); v->arch.schedule_tail = continue_idle_task; - idle_loop(); + reset_stack_and_jump(idle_loop); } static long no_idt[2]; diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 1259e095e8..1d9b96f72f 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -138,10 +138,18 @@ static void __init do_initcalls(void) (*call)(); } -static void __init start_of_day(void) +/* Variables handed off from __start_xen() to start_of_day(). */ +static unsigned long initial_images_start, initial_images_end; +static multiboot_info_t *mbi; + +void __init start_of_day(void) { int i; unsigned long vgdt, gdt_pfn; + char *cmdline; + unsigned long _initrd_start = 0, _initrd_len = 0; + unsigned int initrdidx = 1; + module_t *mod = (module_t *)__va(mbi->mods_addr); early_cpu_init(); @@ -249,20 +257,93 @@ static void __init start_of_day(void) schedulers_start(); watchdog_enable(); + + shadow_mode_init(); + + /* initialize access control security module */ + acm_init(&initrdidx, mbi, initial_images_start); + + /* Create initial domain 0. */ + dom0 = do_createdomain(0, 0); + if ( dom0 == NULL ) + panic("Error creating domain 0\n"); + + set_bit(_DOMF_privileged, &dom0->domain_flags); + /* post-create hooks sets security label */ + acm_post_domain0_create(dom0->domain_id); + + /* Grab the DOM0 command line. */ + cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL); + if ( cmdline != NULL ) + { + static char dom0_cmdline[MAX_GUEST_CMDLINE]; + + /* Skip past the image name and copy to a local buffer. */ + while ( *cmdline == ' ' ) cmdline++; + if ( (cmdline = strchr(cmdline, ' ')) != NULL ) + { + while ( *cmdline == ' ' ) cmdline++; + strcpy(dom0_cmdline, cmdline); + } + + cmdline = dom0_cmdline; + + /* Append any extra parameters. */ + if ( skip_ioapic_setup && !strstr(cmdline, "noapic") ) + strcat(cmdline, " noapic"); + if ( acpi_skip_timer_override && + !strstr(cmdline, "acpi_skip_timer_override") ) + strcat(cmdline, " acpi_skip_timer_override"); + if ( (strlen(acpi_param) != 0) && !strstr(cmdline, "acpi=") ) + { + strcat(cmdline, " acpi="); + strcat(cmdline, acpi_param); + } + } + + if ( (initrdidx > 0) && (initrdidx < mbi->mods_count) ) + { + _initrd_start = initial_images_start + + (mod[initrdidx].mod_start - mod[0].mod_start); + _initrd_len = mod[initrdidx].mod_end - mod[initrdidx].mod_start; + } + + /* + * We're going to setup domain0 using the module(s) that we stashed safely + * above our heap. The second module, if present, is an initrd ramdisk. + */ + if ( construct_dom0(dom0, + initial_images_start, + mod[0].mod_end-mod[0].mod_start, + _initrd_start, + _initrd_len, + cmdline) != 0) + panic("Could not set up DOM0 guest OS\n"); + + /* Scrub RAM that is still free and so may go to an unprivileged domain. */ + scrub_heap_pages(); + + init_trace_bufs(); + + /* Give up the VGA console if DOM0 is configured to grab it. */ + console_endboot(cmdline && strstr(cmdline, "tty0")); + + /* Hide UART from DOM0 if we're using it */ + serial_endboot(); + + domain_unpause_by_systemcontroller(dom0); + + startup_cpu_idle_loop(); } #define EARLY_FAIL() for ( ; ; ) __asm__ __volatile__ ( "hlt" ) static struct e820entry e820_raw[E820MAX]; -void __init __start_xen(multiboot_info_t *mbi) +void __init __start_xen(multiboot_info_t *__mbi) { - char *cmdline; - module_t *mod = (module_t *)__va(mbi->mods_addr); + module_t *mod = (module_t *)__va(__mbi->mods_addr); unsigned long nr_pages, modules_length; - unsigned long initial_images_start, initial_images_end; - unsigned long _initrd_start = 0, _initrd_len = 0; - unsigned int initrdidx = 1; physaddr_t s, e; int i, e820_warn = 0, e820_raw_nr = 0, bytes = 0; struct ns16550_defaults ns16550 = { @@ -271,6 +352,8 @@ void __init __start_xen(multiboot_info_t *mbi) .stop_bits = 1 }; + mbi = __mbi; + /* Parse the command-line options. */ if ( (mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0) ) cmdline_parse(__va(mbi->cmdline)); @@ -486,84 +569,7 @@ void __init __start_xen(multiboot_info_t *mbi) early_boot = 0; - start_of_day(); - - shadow_mode_init(); - - /* initialize access control security module */ - acm_init(&initrdidx, mbi, initial_images_start); - - /* Create initial domain 0. */ - dom0 = do_createdomain(0, 0); - if ( dom0 == NULL ) - panic("Error creating domain 0\n"); - - set_bit(_DOMF_privileged, &dom0->domain_flags); - /* post-create hooks sets security label */ - acm_post_domain0_create(dom0->domain_id); - - /* Grab the DOM0 command line. */ - cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL); - if ( cmdline != NULL ) - { - static char dom0_cmdline[MAX_GUEST_CMDLINE]; - - /* Skip past the image name and copy to a local buffer. */ - while ( *cmdline == ' ' ) cmdline++; - if ( (cmdline = strchr(cmdline, ' ')) != NULL ) - { - while ( *cmdline == ' ' ) cmdline++; - strcpy(dom0_cmdline, cmdline); - } - - cmdline = dom0_cmdline; - - /* Append any extra parameters. */ - if ( skip_ioapic_setup && !strstr(cmdline, "noapic") ) - strcat(cmdline, " noapic"); - if ( acpi_skip_timer_override && - !strstr(cmdline, "acpi_skip_timer_override") ) - strcat(cmdline, " acpi_skip_timer_override"); - if ( (strlen(acpi_param) != 0) && !strstr(cmdline, "acpi=") ) - { - strcat(cmdline, " acpi="); - strcat(cmdline, acpi_param); - } - } - - if ( (initrdidx > 0) && (initrdidx < mbi->mods_count) ) - { - _initrd_start = initial_images_start + - (mod[initrdidx].mod_start - mod[0].mod_start); - _initrd_len = mod[initrdidx].mod_end - mod[initrdidx].mod_start; - } - - /* - * We're going to setup domain0 using the module(s) that we stashed safely - * above our heap. The second module, if present, is an initrd ramdisk. - */ - if ( construct_dom0(dom0, - initial_images_start, - mod[0].mod_end-mod[0].mod_start, - _initrd_start, - _initrd_len, - cmdline) != 0) - panic("Could not set up DOM0 guest OS\n"); - - /* Scrub RAM that is still free and so may go to an unprivileged domain. */ - scrub_heap_pages(); - - init_trace_bufs(); - - /* Give up the VGA console if DOM0 is configured to grab it. */ - console_endboot(cmdline && strstr(cmdline, "tty0")); - - /* Hide UART from DOM0 if we're using it */ - serial_endboot(); - - domain_unpause_by_systemcontroller(dom0); - - startup_cpu_idle_loop(); + reset_stack_and_jump(start_of_day); } void arch_get_xen_caps(xen_capabilities_info_t info) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 40959e6758..64a6e2a5d7 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -192,7 +192,8 @@ static void show_trace(struct cpu_user_regs *regs) /* Bounds for range of valid frame pointer. */ low = (unsigned long)(ESP_BEFORE_EXCEPTION(regs) - 2); - high = (low & ~(STACK_SIZE - 1)) + (STACK_SIZE - sizeof(struct cpu_info)); + high = (low & ~(STACK_SIZE - 1)) + + (STACK_SIZE - sizeof(struct cpu_info) - 2*sizeof(unsigned long)); /* The initial frame pointer. */ next = regs->ebp; @@ -200,14 +201,14 @@ static void show_trace(struct cpu_user_regs *regs) for ( ; ; ) { /* Valid frame pointer? */ - if ( (next < low) || (next > high) ) + if ( (next < low) || (next >= high) ) { /* * Exception stack frames have a different layout, denoted by an * inverted frame pointer. */ next = ~next; - if ( (next < low) || (next > high) ) + if ( (next < low) || (next >= high) ) break; frame = (unsigned long *)next; next = frame[0]; diff --git a/xen/arch/x86/x86_32/xen.lds b/xen/arch/x86/x86_32/xen.lds.S index f3c168f662..fb76cbc73d 100644 --- a/xen/arch/x86/x86_32/xen.lds +++ b/xen/arch/x86/x86_32/xen.lds.S @@ -2,6 +2,12 @@ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> * Modified for i386 Xen by Keir Fraser */ + +#include <xen/config.h> +#include <asm/page.h> +#undef ENTRY +#undef ALIGN + OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) ENTRY(start) @@ -50,12 +56,12 @@ SECTIONS __initcall_start = .; .initcall.init : { *(.initcall.init) } :text __initcall_end = .; - . = ALIGN(8192); + . = ALIGN(STACK_SIZE); __init_end = .; __bss_start = .; /* BSS */ .bss : { - *(.bss.twopage_aligned) + *(.bss.stack_aligned) *(.bss.page_aligned) *(.bss) } :text diff --git a/xen/arch/x86/x86_64/xen.lds b/xen/arch/x86/x86_64/xen.lds.S index 837d335f0d..d8685201ab 100644 --- a/xen/arch/x86/x86_64/xen.lds +++ b/xen/arch/x86/x86_64/xen.lds.S @@ -1,5 +1,11 @@ /* Excerpts written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> */ /* Modified for x86-64 Xen by Keir Fraser */ + +#include <xen/config.h> +#include <asm/page.h> +#undef ENTRY +#undef ALIGN + OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") OUTPUT_ARCH(i386:x86-64) ENTRY(start) @@ -48,12 +54,12 @@ SECTIONS __initcall_start = .; .initcall.init : { *(.initcall.init) } :text __initcall_end = .; - . = ALIGN(8192); + . = ALIGN(STACK_SIZE); __init_end = .; __bss_start = .; /* BSS */ .bss : { - *(.bss.twopage_aligned) + *(.bss.stack_aligned) *(.bss.page_aligned) *(.bss) } :text diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h index 7916b57ae9..2a63b75002 100644 --- a/xen/include/asm-x86/current.h +++ b/xen/include/asm-x86/current.h @@ -49,7 +49,7 @@ static inline struct cpu_info *get_cpu_info(void) #define reset_stack_and_jump(__fn) \ __asm__ __volatile__ ( \ "mov %0,%%"__OP"sp; jmp "STR(__fn) \ - : : "r" (guest_cpu_user_regs()) ) + : : "r" (guest_cpu_user_regs()) : "memory" ) #define schedule_tail(_ed) (((_ed)->arch.schedule_tail)(_ed)) |