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@xxxxxxxxxx>
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@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|