aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-12-29 16:59:12 +0100
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-12-29 16:59:12 +0100
commitb33ac9e43315d6e9864e2d324f8f5a620d5ec421 (patch)
tree4cc74f4bf055b004e4bc1b4ef7d11c177d64f86d
parent484a058c48287df3fc9fa0b146dd8c827ffff7be (diff)
downloadxen-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--.hgignore1
-rw-r--r--xen/arch/x86/Makefile13
-rw-r--r--xen/arch/x86/boot/x86_32.S8
-rw-r--r--xen/arch/x86/boot/x86_64.S8
-rw-r--r--xen/arch/x86/domain.c2
-rw-r--r--xen/arch/x86/setup.c176
-rw-r--r--xen/arch/x86/traps.c7
-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.h2
10 files changed, 127 insertions, 110 deletions
diff --git a/.hgignore b/.hgignore
index 766a688126..9a52e9ce12 100644
--- a/.hgignore
+++ b/.hgignore
@@ -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))