]> xenbits.xensource.com Git - people/andrewcoop/xen-test-framework.git/commitdiff
Introduce pack_{tss,ldt}_desc() to work around latent 64bit issues
authorAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 13 May 2019 10:26:25 +0000 (10:26 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 13 May 2019 11:49:17 +0000 (12:49 +0100)
LDT and TSS descriptors use two slots in 64bit.  While no published tests are
affected, some in-development ones are.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
arch/x86/hvm/traps.c
arch/x86/include/arch/desc.h
tests/nmi-taskswitch-priv/main.c
tests/xsa-191/main.c
tests/xsa-192/main.c

index bb5b720e7128ea14d62aa53c3dc0d363b4128fb0..1e3df526dc80b797f8bdda1bcd8af3013bec4595 100644 (file)
@@ -107,7 +107,7 @@ void arch_init_traps(void)
     /* Handle #DF with a task gate in 32bit, and IST 1 in 64bit. */
     if ( IS_DEFINED(CONFIG_32BIT) )
     {
-        gdt[GDTE_TSS_DF] = GDTE(_u(&tss_DF), 0x67, 0x89);
+        pack_tss_desc(&gdt[GDTE_TSS_DF], &tss_DF);
         pack_task_gate(&idt[X86_EXC_DF], GDTE_TSS_DF * 8);
     }
     else
@@ -118,8 +118,7 @@ void arch_init_traps(void)
 
     lidt(&idt_ptr);
 
-    gdt[GDTE_TSS] = GDTE(_u(&tss), 0x67, 0x89);
-    barrier();
+    pack_tss_desc(&gdt[GDTE_TSS], &tss);
     ltr(GDTE_TSS * 8);
 
     /*
index 89198ecabe2578749c9030bebde15a4fe2b4e918..bc39e6ce154bf339bf7b300155462d1088ac1fbd 100644 (file)
@@ -170,6 +170,29 @@ static inline unsigned int user_desc_limit(const user_desc *d)
     return limit;
 }
 
+static inline void pack_tss_desc(user_desc *d, const env_tss *t)
+{
+    unsigned long base = (unsigned long)t;
+
+    d[0] = GDTE(base, sizeof(*t) - 1, 0x89);
+#ifdef __x86_64__
+    d[1] = (user_desc){{{ .lo = base >> 32, .hi = 0 }}};
+#endif
+    barrier(); /* Force desc update before ltr. */
+}
+
+static inline void pack_ldt_desc(user_desc *d, const user_desc *ldt,
+                                 unsigned int limit)
+{
+    unsigned long base = (unsigned long)ldt;
+
+    d[0] = GDTE(base, limit, 0x82);
+#ifdef __x86_64__
+    d[1] = (user_desc){{{ .lo = base >> 32, .hi = 0 }}};
+#endif
+    barrier(); /* Force desc update before lldt. */
+}
+
 #endif /* XTF_X86_DESC_H */
 
 /*
index ec5508959ba0318e2fda9f8c5647292dc1c1ccc8..f3149e05c22cdc89125bdf8436d2986bfdf2c598 100644 (file)
@@ -146,7 +146,7 @@ void test_main(void)
      * Set up NMI handling to be a task gate.
      */
     xtf_unhandled_exception_hook = unhandled_exception;
-    update_desc(&gdt[GDTE_AVAIL0], GDTE(_u(&nmi_tss), 0x67, 0x89));
+    pack_tss_desc(&gdt[GDTE_AVAIL0], &nmi_tss);
     pack_task_gate(&idt[X86_EXC_NMI], GDTE_AVAIL0 * 8);
 
     /*
index 438c151fa968bff9395e846e6a9da87e78f70354..d3b2c02375b9469d6808e362f66f30b010ce5c3d 100644 (file)
@@ -64,7 +64,7 @@ void test_main(void)
 
     user_desc ldt[1] = { gdt[__KERN_DS >> 3] };
 
-    update_desc(&gdt[GDTE_AVAIL0], GDTE(_u(ldt), sizeof(ldt) - 1, 0x82));
+    pack_ldt_desc(&gdt[GDTE_AVAIL0], ldt, sizeof(ldt) - 1);
 
     lldt(GDTE_AVAIL0 << 3);
     lldt(0);
index de42903210e46273c7a57a0c674218ea3a2e4188..0fee916fded2e6f1370f124c378157a20bbf9988 100644 (file)
@@ -86,7 +86,7 @@ void test_main(void)
     xtf_set_idte(X86_VEC_AVAIL, &idte);
 
     /* Create the vm86 TSS descriptor. */
-    update_desc(&gdt[GDTE_AVAIL0], GDTE(_u(&vm86_tss), 0x67, 0x89));
+    pack_tss_desc(&gdt[GDTE_AVAIL0], &vm86_tss);
 
     /* Copy a stub to somewhere vm86 can actually reach. */
     uint8_t insn_buf[] = { 0xcd, X86_VEC_AVAIL }; /* `int $X86_VEC_AVAIL` */
@@ -98,7 +98,7 @@ void test_main(void)
      */
     if ( vendor_is_amd )
     {
-        update_desc(&gdt[GDTE_AVAIL1], GDTE(0, 0, 0x82));
+        pack_ldt_desc(&gdt[GDTE_AVAIL1], 0, 0);
         lldt(GDTE_AVAIL1 << 3);
     }
     lldt(0);