ia64/xen-unstable

changeset 19405:e1562a36094e

x86: Ensure we execute LTR when running on non-compat GDT which has
busy bit clear in TSS descriptor.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Mar 19 17:04:06 2009 +0000 (2009-03-19)
parents 633e08774dab
children f87b2374cdf0
files xen/arch/x86/acpi/suspend.c xen/arch/x86/cpu/common.c xen/arch/x86/traps.c xen/include/asm-x86/desc.h
line diff
     1.1 --- a/xen/arch/x86/acpi/suspend.c	Thu Mar 19 14:01:56 2009 +0000
     1.2 +++ b/xen/arch/x86/acpi/suspend.c	Thu Mar 19 17:04:06 2009 +0000
     1.3 @@ -31,13 +31,9 @@ void save_rest_processor_state(void)
     1.4  
     1.5  void restore_rest_processor_state(void)
     1.6  {
     1.7 -    int cpu = smp_processor_id();
     1.8 -    struct tss_struct *t = &init_tss[cpu];
     1.9      struct vcpu *v = current;
    1.10  
    1.11 -    /* Rewriting the TSS desc is necessary to clear the Busy flag. */
    1.12 -    set_tss_desc(cpu, t);
    1.13 -    load_TR(cpu);
    1.14 +    load_TR();
    1.15  
    1.16  #if defined(CONFIG_X86_64)
    1.17      /* Recover syscall MSRs */
     2.1 --- a/xen/arch/x86/cpu/common.c	Thu Mar 19 14:01:56 2009 +0000
     2.2 +++ b/xen/arch/x86/cpu/common.c	Thu Mar 19 17:04:06 2009 +0000
     2.3 @@ -614,8 +614,7 @@ void __cpuinit cpu_init(void)
     2.4  	BUG_ON((get_stack_bottom() & 15) != 0);
     2.5  	t->rsp0 = get_stack_bottom();
     2.6  #endif
     2.7 -	set_tss_desc(cpu,t);
     2.8 -	load_TR(cpu);
     2.9 +	load_TR();
    2.10  	asm volatile ( "lldt %%ax" : : "a" (0) );
    2.11  
    2.12  	/* Clear all 6 debug registers: */
     3.1 --- a/xen/arch/x86/traps.c	Thu Mar 19 14:01:56 2009 +0000
     3.2 +++ b/xen/arch/x86/traps.c	Thu Mar 19 17:04:06 2009 +0000
     3.3 @@ -3004,20 +3004,31 @@ void set_intr_gate(unsigned int n, void 
     3.4      __set_intr_gate(n, 0, addr);
     3.5  }
     3.6  
     3.7 -void set_tss_desc(unsigned int n, void *addr)
     3.8 +void load_TR(void)
     3.9  {
    3.10 +    struct tss_struct *tss = &init_tss[smp_processor_id()];
    3.11 +    struct desc_ptr old_gdt, tss_gdt = {
    3.12 +        .base = (long)(this_cpu(gdt_table) - FIRST_RESERVED_GDT_ENTRY),
    3.13 +        .limit = LAST_RESERVED_GDT_BYTE
    3.14 +    };
    3.15 +
    3.16      _set_tssldt_desc(
    3.17 -        per_cpu(gdt_table, n) + TSS_ENTRY - FIRST_RESERVED_GDT_ENTRY,
    3.18 -        (unsigned long)addr,
    3.19 +        this_cpu(gdt_table) + TSS_ENTRY - FIRST_RESERVED_GDT_ENTRY,
    3.20 +        (unsigned long)tss,
    3.21          offsetof(struct tss_struct, __cacheline_filler) - 1,
    3.22          9);
    3.23  #ifdef CONFIG_COMPAT
    3.24      _set_tssldt_desc(
    3.25 -        per_cpu(compat_gdt_table, n) + TSS_ENTRY - FIRST_RESERVED_GDT_ENTRY,
    3.26 -        (unsigned long)addr,
    3.27 +        this_cpu(compat_gdt_table) + TSS_ENTRY - FIRST_RESERVED_GDT_ENTRY,
    3.28 +        (unsigned long)tss,
    3.29          offsetof(struct tss_struct, __cacheline_filler) - 1,
    3.30          11);
    3.31  #endif
    3.32 +
    3.33 +    /* Switch to non-compat GDT (which has B bit clear) to execute LTR. */
    3.34 +    asm volatile (
    3.35 +        "sgdt %1; lgdt %2; ltr %%ax; lgdt %1"
    3.36 +        : : "a" (TSS_ENTRY << 3), "m" (old_gdt), "m" (tss_gdt) : "memory" );
    3.37  }
    3.38  
    3.39  void __devinit percpu_traps_init(void)
     4.1 --- a/xen/include/asm-x86/desc.h	Thu Mar 19 14:01:56 2009 +0000
     4.2 +++ b/xen/include/asm-x86/desc.h	Thu Mar 19 17:04:06 2009 +0000
     4.3 @@ -57,8 +57,6 @@
     4.4  
     4.5  #ifndef __ASSEMBLY__
     4.6  
     4.7 -#define load_TR(n)  __asm__ __volatile__ ("ltr  %%ax" : : "a" (TSS_ENTRY<<3) )
     4.8 -
     4.9  #if defined(__x86_64__)
    4.10  #define GUEST_KERNEL_RPL(d) (is_pv_32bit_domain(d) ? 1 : 3)
    4.11  #elif defined(__i386__)
    4.12 @@ -219,7 +217,7 @@ DECLARE_PER_CPU(struct desc_struct *, co
    4.13  #endif
    4.14  
    4.15  extern void set_intr_gate(unsigned int irq, void * addr);
    4.16 -extern void set_tss_desc(unsigned int n, void *addr);
    4.17 +extern void load_TR(void);
    4.18  
    4.19  #endif /* !__ASSEMBLY__ */
    4.20