]> xenbits.xen.org Git - xenclient/xen.git/commitdiff
Backport xen-unstable changeset - 19400 for 64/32 bit S3 resume issue.
authorKamala Narasimhan <kamala.narasimhan@citrix.com>
Thu, 19 Mar 2009 19:17:22 +0000 (15:17 -0400)
committerKamala Narasimhan <kamala.narasimhan@citrix.com>
Thu, 19 Mar 2009 19:17:22 +0000 (15:17 -0400)
Also, remove previous stopgap patch to get around the same issue.

xen/arch/x86/acpi/suspend.c
xen/arch/x86/cpu/common.c
xen/arch/x86/traps.c
xen/include/asm-x86/desc.h

index 3068590f70d20b365d8b5bafeb8ce3d57f9ccba6..edd94b2e64ddce2d7291358de86b2f3fb6e66c63 100644 (file)
@@ -31,13 +31,9 @@ void save_rest_processor_state(void)
 
 void restore_rest_processor_state(void)
 {
-    int cpu = smp_processor_id();
-    struct tss_struct *t = &init_tss[cpu];
     struct vcpu *v = current;
 
-    /* Rewriting the TSS desc is necessary to clear the Busy flag. */
-    set_tss_desc(cpu, t);
-    load_TR(cpu);
+    load_TR();
 
 #if defined(CONFIG_X86_64)
     /* Recover syscall MSRs */
index 42c6dc12107e260f0d4623f8905ff0d82a2a6250..55d13fa81719597c97e521f5fe0a455e6dc83ac7 100644 (file)
@@ -600,8 +600,7 @@ void __cpuinit cpu_init(void)
        BUG_ON((get_stack_bottom() & 15) != 0);
        t->rsp0 = get_stack_bottom();
 #endif
-       set_tss_desc(cpu,t);
-       load_TR(cpu);
+       load_TR();
        asm volatile ( "lldt %%ax" : : "a" (0) );
 
        /* Clear all 6 debug registers: */
index 3cc884b380263dec4f6901a04486e8c0f417b865..2798fc766988a72a63f3ea791c53f9832fbc5029 100644 (file)
@@ -2978,20 +2978,31 @@ void set_intr_gate(unsigned int n, void *addr)
     __set_intr_gate(n, 0, addr);
 }
 
-void set_tss_desc(unsigned int n, void *addr)
+void load_TR(void)
 {
+    struct tss_struct *tss = &init_tss[smp_processor_id()];
+    struct desc_ptr old_gdt, tss_gdt = {
+        .base = (long)(this_cpu(gdt_table) - FIRST_RESERVED_GDT_ENTRY),
+        .limit = LAST_RESERVED_GDT_BYTE
+    };
+
     _set_tssldt_desc(
-        per_cpu(gdt_table, n) + TSS_ENTRY - FIRST_RESERVED_GDT_ENTRY,
-        (unsigned long)addr,
+        this_cpu(gdt_table) + TSS_ENTRY - FIRST_RESERVED_GDT_ENTRY,
+        (unsigned long)tss,
         offsetof(struct tss_struct, __cacheline_filler) - 1,
         9);
 #ifdef CONFIG_COMPAT
     _set_tssldt_desc(
-        per_cpu(compat_gdt_table, n) + TSS_ENTRY - FIRST_RESERVED_GDT_ENTRY,
-        (unsigned long)addr,
+        this_cpu(compat_gdt_table) + TSS_ENTRY - FIRST_RESERVED_GDT_ENTRY,
+        (unsigned long)tss,
         offsetof(struct tss_struct, __cacheline_filler) - 1,
-        9);
+        11);
 #endif
+
+    /* Switch to non-compat GDT (which has B bit clear) to execute LTR. */
+    asm volatile (
+        "sgdt %1; lgdt %2; ltr %%ax; lgdt %1"
+        : : "a" (TSS_ENTRY << 3), "m" (old_gdt), "m" (tss_gdt) : "memory" );
 }
 
 void __devinit percpu_traps_init(void)
index f59f372092d79293231677eb2cac107e9b1e841e..20eb8dbe5fffa1e3b0bfdfa49c59b49c9e11a01b 100644 (file)
@@ -57,8 +57,6 @@
 
 #ifndef __ASSEMBLY__
 
-#define load_TR(n)  __asm__ __volatile__ ("ltr  %%ax" : : "a" (TSS_ENTRY<<3) )
-
 #if defined(__x86_64__)
 #define GUEST_KERNEL_RPL(d) (is_pv_32bit_domain(d) ? 1 : 3)
 #elif defined(__i386__)
@@ -219,7 +217,7 @@ DECLARE_PER_CPU(struct desc_struct *, compat_gdt_table);
 #endif
 
 extern void set_intr_gate(unsigned int irq, void * addr);
-extern void set_tss_desc(unsigned int n, void *addr);
+extern void load_TR(void);
 
 #endif /* !__ASSEMBLY__ */