mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
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>
This commit is contained in:
1 parent
484a058c48
commit
b33ac9e433
10 files changed
+127
-110
No files matched your search
@@ -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$
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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];
|
||||
|
||||
+91
-85
@@ -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)
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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))
|
||||
|
||||
|
||||