ia64/xen-unstable

changeset 18524:6d3b932cbeca

i386: make double fault TSS per-CPU

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>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Sep 22 14:00:24 2008 +0100 (2008-09-22)
parents 7f1a36b834e1
children ae24b533dc9d
files xen/arch/x86/boot/x86_32.S xen/arch/x86/smpboot.c xen/arch/x86/x86_32/traps.c xen/include/asm-x86/desc.h
line diff
     1.1 --- a/xen/arch/x86/boot/x86_32.S	Mon Sep 22 13:46:57 2008 +0100
     1.2 +++ b/xen/arch/x86/boot/x86_32.S	Mon Sep 22 14:00:24 2008 +0100
     1.3 @@ -95,7 +95,7 @@ ENTRY(idle_pg_table)
     1.4          .long ((MACH2PHYS_VIRT_END - 1) >> 12) & 0xffff,                \
     1.5                ((MACH2PHYS_VIRT_END - 1) >> 12) & (0xf << 16) | (d)
     1.6  ENTRY(boot_cpu_gdt_table)
     1.7 -        .quad 0x0000000000000000     /* unused */
     1.8 +        .quad 0x0000000000000000     /* double fault TSS */
     1.9          .quad 0x00cf9a000000ffff     /* 0xe008 ring 0 4.00GB code at 0x0 */
    1.10          .quad 0x00cf92000000ffff     /* 0xe010 ring 0 4.00GB data at 0x0 */
    1.11          GUEST_DESC(0x00c0ba00)       /* 0xe019 ring 1 3.xxGB code at 0x0 */
     2.1 --- a/xen/arch/x86/smpboot.c	Mon Sep 22 13:46:57 2008 +0100
     2.2 +++ b/xen/arch/x86/smpboot.c	Mon Sep 22 14:00:24 2008 +0100
     2.3 @@ -901,6 +901,13 @@ static int __devinit do_boot_cpu(int api
     2.4  			= l1e_from_page(virt_to_page(gdt) + i,
     2.5  					__PAGE_HYPERVISOR);
     2.6  
     2.7 +#ifdef __i386__
     2.8 +	if (!per_cpu(doublefault_tss, cpu)) {
     2.9 +		per_cpu(doublefault_tss, cpu) = alloc_xenheap_page();
    2.10 +		memset(per_cpu(doublefault_tss, cpu), 0, PAGE_SIZE);
    2.11 +	}
    2.12 +#endif
    2.13 +
    2.14  	/*
    2.15  	 * This grunge runs the startup process for
    2.16  	 * the targeted processor.
     3.1 --- a/xen/arch/x86/x86_32/traps.c	Mon Sep 22 13:46:57 2008 +0100
     3.2 +++ b/xen/arch/x86/x86_32/traps.c	Mon Sep 22 14:00:24 2008 +0100
     3.3 @@ -188,9 +188,9 @@ void show_page_walk(unsigned long addr)
     3.4      unmap_domain_page(l1t);
     3.5  }
     3.6  
     3.7 -#define DOUBLEFAULT_STACK_SIZE 2048
     3.8 -static struct tss_struct doublefault_tss;
     3.9 -static unsigned char doublefault_stack[DOUBLEFAULT_STACK_SIZE];
    3.10 +DEFINE_PER_CPU(struct tss_struct *, doublefault_tss);
    3.11 +static unsigned char __attribute__ ((__section__ (".bss.page_aligned")))
    3.12 +    boot_cpu_doublefault_space[PAGE_SIZE];
    3.13  
    3.14  asmlinkage void do_double_fault(void)
    3.15  {
    3.16 @@ -303,34 +303,36 @@ static void set_task_gate(unsigned int n
    3.17  
    3.18  void __devinit subarch_percpu_traps_init(void)
    3.19  {
    3.20 -    struct tss_struct *tss = &doublefault_tss;
    3.21 +    struct tss_struct *tss = this_cpu(doublefault_tss);
    3.22      asmlinkage int hypercall(void);
    3.23  
    3.24 -    if ( smp_processor_id() != 0 )
    3.25 -        return;
    3.26 +    if ( !tss )
    3.27 +    {
    3.28 +        /* The hypercall entry vector is only accessible from ring 1. */
    3.29 +        _set_gate(idt_table+HYPERCALL_VECTOR, 14, 1, &hypercall);
    3.30  
    3.31 -    /* The hypercall entry vector is only accessible from ring 1. */
    3.32 -    _set_gate(idt_table+HYPERCALL_VECTOR, 14, 1, &hypercall);
    3.33 +        tss = (void *)boot_cpu_doublefault_space;
    3.34 +        this_cpu(doublefault_tss) = tss;
    3.35 +    }
    3.36  
    3.37      /*
    3.38       * Make a separate task for double faults. This will get us debug output if
    3.39       * we blow the kernel stack.
    3.40       */
    3.41 -    memset(tss, 0, sizeof(*tss));
    3.42      tss->ds     = __HYPERVISOR_DS;
    3.43      tss->es     = __HYPERVISOR_DS;
    3.44      tss->ss     = __HYPERVISOR_DS;
    3.45 -    tss->esp    = (unsigned long)&doublefault_stack[DOUBLEFAULT_STACK_SIZE];
    3.46 +    tss->esp    = (unsigned long)tss + PAGE_SIZE;
    3.47      tss->__cr3  = __pa(idle_pg_table);
    3.48      tss->cs     = __HYPERVISOR_CS;
    3.49      tss->eip    = (unsigned long)do_double_fault;
    3.50      tss->eflags = 2;
    3.51      tss->bitmap = IOBMP_INVALID_OFFSET;
    3.52      _set_tssldt_desc(
    3.53 -        boot_cpu_gdt_table + __DOUBLEFAULT_TSS_ENTRY - FIRST_RESERVED_GDT_ENTRY,
    3.54 +        this_cpu(gdt_table) + DOUBLEFAULT_TSS_ENTRY - FIRST_RESERVED_GDT_ENTRY,
    3.55          (unsigned long)tss, 235, 9);
    3.56  
    3.57 -    set_task_gate(TRAP_double_fault, __DOUBLEFAULT_TSS_ENTRY<<3);
    3.58 +    set_task_gate(TRAP_double_fault, DOUBLEFAULT_TSS_ENTRY << 3);
    3.59  }
    3.60  
    3.61  void init_int80_direct_trap(struct vcpu *v)
     4.1 --- a/xen/include/asm-x86/desc.h	Mon Sep 22 13:46:57 2008 +0100
     4.2 +++ b/xen/include/asm-x86/desc.h	Mon Sep 22 14:00:24 2008 +0100
     4.3 @@ -47,7 +47,7 @@
     4.4  #define FLAT_COMPAT_USER_DS   FLAT_USER_DS
     4.5  #define FLAT_COMPAT_USER_SS   FLAT_USER_SS
     4.6  
     4.7 -#define __DOUBLEFAULT_TSS_ENTRY FIRST_RESERVED_GDT_ENTRY
     4.8 +#define DOUBLEFAULT_TSS_ENTRY FIRST_RESERVED_GDT_ENTRY
     4.9  
    4.10  #define TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8)
    4.11  #define LDT_ENTRY (TSS_ENTRY + 1)
    4.12 @@ -199,6 +199,8 @@ do {                                    
    4.13          (((u32)(addr) & 0x00FF0000U) >> 16);             \
    4.14  } while (0)
    4.15  
    4.16 +DECLARE_PER_CPU(struct tss_struct *, doublefault_tss);
    4.17 +
    4.18  #endif
    4.19  
    4.20  struct desc_ptr {