From: Andrew Cooper Date: Mon, 13 May 2019 10:26:25 +0000 (+0000) Subject: Introduce pack_{tss,ldt}_desc() to work around latent 64bit issues X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=d617dbd3d189e7be468cabff4d5079132731eccf;p=people%2Fandrewcoop%2Fxen-test-framework.git Introduce pack_{tss,ldt}_desc() to work around latent 64bit issues 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 --- diff --git a/arch/x86/hvm/traps.c b/arch/x86/hvm/traps.c index bb5b720..1e3df52 100644 --- a/arch/x86/hvm/traps.c +++ b/arch/x86/hvm/traps.c @@ -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); /* diff --git a/arch/x86/include/arch/desc.h b/arch/x86/include/arch/desc.h index 89198ec..bc39e6c 100644 --- a/arch/x86/include/arch/desc.h +++ b/arch/x86/include/arch/desc.h @@ -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 */ /* diff --git a/tests/nmi-taskswitch-priv/main.c b/tests/nmi-taskswitch-priv/main.c index ec55089..f3149e0 100644 --- a/tests/nmi-taskswitch-priv/main.c +++ b/tests/nmi-taskswitch-priv/main.c @@ -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); /* diff --git a/tests/xsa-191/main.c b/tests/xsa-191/main.c index 438c151..d3b2c02 100644 --- a/tests/xsa-191/main.c +++ b/tests/xsa-191/main.c @@ -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); diff --git a/tests/xsa-192/main.c b/tests/xsa-192/main.c index de42903..0fee916 100644 --- a/tests/xsa-192/main.c +++ b/tests/xsa-192/main.c @@ -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);