As a follow-up to the per-CPU-GDT patch, this also makes the double fault TSS (and the associated stack) per-CPU. Signed-off-by: Jan Beulich <jbeulich@novell.com> Index: 2008-09-19/xen/arch/x86/boot/x86_32.S ==================================================================--- 2008-09-19.orig/xen/arch/x86/boot/x86_32.S 2008-09-19 13:58:31.000000000 +0200 +++ 2008-09-19/xen/arch/x86/boot/x86_32.S 2008-09-19 13:58:46.000000000 +0200 @@ -95,7 +95,7 @@ ENTRY(idle_pg_table) .long ((MACH2PHYS_VIRT_END - 1) >> 12) & 0xffff, \ ((MACH2PHYS_VIRT_END - 1) >> 12) & (0xf << 16) | (d) ENTRY(boot_cpu_gdt_table) - .quad 0x0000000000000000 /* unused */ + .quad 0x0000000000000000 /* double fault TSS */ .quad 0x00cf9a000000ffff /* 0xe008 ring 0 4.00GB code at 0x0 */ .quad 0x00cf92000000ffff /* 0xe010 ring 0 4.00GB data at 0x0 */ GUEST_DESC(0x00c0ba00) /* 0xe019 ring 1 3.xxGB code at 0x0 */ Index: 2008-09-19/xen/arch/x86/smpboot.c ==================================================================--- 2008-09-19.orig/xen/arch/x86/smpboot.c 2008-09-19 13:58:31.000000000 +0200 +++ 2008-09-19/xen/arch/x86/smpboot.c 2008-09-19 13:59:11.000000000 +0200 @@ -901,6 +901,13 @@ static int __devinit do_boot_cpu(int api = l1e_from_page(virt_to_page(gdt) + i, __PAGE_HYPERVISOR); +#ifdef __i386__ + if (!per_cpu(doublefault_tss, cpu)) { + per_cpu(doublefault_tss, cpu) = alloc_xenheap_page(); + memset(per_cpu(doublefault_tss, cpu), 0, PAGE_SIZE); + } +#endif + /* * This grunge runs the startup process for * the targeted processor. Index: 2008-09-19/xen/arch/x86/x86_32/traps.c ==================================================================--- 2008-09-19.orig/xen/arch/x86/x86_32/traps.c 2008-09-19 13:58:31.000000000 +0200 +++ 2008-09-19/xen/arch/x86/x86_32/traps.c 2008-09-19 13:58:46.000000000 +0200 @@ -188,9 +188,9 @@ void show_page_walk(unsigned long addr) unmap_domain_page(l1t); } -#define DOUBLEFAULT_STACK_SIZE 2048 -static struct tss_struct doublefault_tss; -static unsigned char doublefault_stack[DOUBLEFAULT_STACK_SIZE]; +DEFINE_PER_CPU(struct tss_struct *, doublefault_tss); +static unsigned char __attribute__ ((__section__ (".bss.page_aligned"))) + boot_cpu_doublefault_space[PAGE_SIZE]; asmlinkage void do_double_fault(void) { @@ -303,34 +303,36 @@ static void set_task_gate(unsigned int n void __devinit subarch_percpu_traps_init(void) { - struct tss_struct *tss = &doublefault_tss; + struct tss_struct *tss = this_cpu(doublefault_tss); asmlinkage int hypercall(void); - if ( smp_processor_id() != 0 ) - return; + if ( !tss ) + { + /* The hypercall entry vector is only accessible from ring 1. */ + _set_gate(idt_table+HYPERCALL_VECTOR, 14, 1, &hypercall); - /* The hypercall entry vector is only accessible from ring 1. */ - _set_gate(idt_table+HYPERCALL_VECTOR, 14, 1, &hypercall); + tss = (void *)boot_cpu_doublefault_space; + this_cpu(doublefault_tss) = tss; + } /* * Make a separate task for double faults. This will get us debug output if * we blow the kernel stack. */ - memset(tss, 0, sizeof(*tss)); tss->ds = __HYPERVISOR_DS; tss->es = __HYPERVISOR_DS; tss->ss = __HYPERVISOR_DS; - tss->esp = (unsigned long)&doublefault_stack[DOUBLEFAULT_STACK_SIZE]; + tss->esp = (unsigned long)tss + PAGE_SIZE; tss->__cr3 = __pa(idle_pg_table); tss->cs = __HYPERVISOR_CS; tss->eip = (unsigned long)do_double_fault; tss->eflags = 2; tss->bitmap = IOBMP_INVALID_OFFSET; _set_tssldt_desc( - boot_cpu_gdt_table + __DOUBLEFAULT_TSS_ENTRY - FIRST_RESERVED_GDT_ENTRY, + this_cpu(gdt_table) + DOUBLEFAULT_TSS_ENTRY - FIRST_RESERVED_GDT_ENTRY, (unsigned long)tss, 235, 9); - set_task_gate(TRAP_double_fault, __DOUBLEFAULT_TSS_ENTRY<<3); + set_task_gate(TRAP_double_fault, DOUBLEFAULT_TSS_ENTRY << 3); } void init_int80_direct_trap(struct vcpu *v) Index: 2008-09-19/xen/include/asm-x86/desc.h ==================================================================--- 2008-09-19.orig/xen/include/asm-x86/desc.h 2008-09-19 13:58:31.000000000 +0200 +++ 2008-09-19/xen/include/asm-x86/desc.h 2008-09-19 13:58:46.000000000 +0200 @@ -47,7 +47,7 @@ #define FLAT_COMPAT_USER_DS FLAT_USER_DS #define FLAT_COMPAT_USER_SS FLAT_USER_SS -#define __DOUBLEFAULT_TSS_ENTRY FIRST_RESERVED_GDT_ENTRY +#define DOUBLEFAULT_TSS_ENTRY FIRST_RESERVED_GDT_ENTRY #define TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8) #define LDT_ENTRY (TSS_ENTRY + 1) @@ -199,6 +199,8 @@ do { (((u32)(addr) & 0x00FF0000U) >> 16); \ } while (0) +DECLARE_PER_CPU(struct tss_struct *, doublefault_tss); + #endif struct desc_ptr { _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel