From: Andrew Cooper Date: Thu, 1 Jun 2017 11:15:22 +0000 (+0100) Subject: Split existing Gate Descriptor infrastructure out into x86-gate.h X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=7c9cc539cacc6bbeba0e2cc58aa841a6736281e2;p=people%2Fandrewcoop%2Fxen-test-framework.git Split existing Gate Descriptor infrastructure out into x86-gate.h Following in the style of the TSS work: * Rename gate_desc to env_gate * Rename seg_gate{32,64} to x86_gate{32,64} In addition, * Expose call gate parameter counts for completeness. * Introduce pack_gate() which works on the appropriate type of gate, which allows for removal of #ifdef'ary during HVM setup. * Introduce pack_task_gate() which wraps pack_gate(), and allows for further #ifdef'ary removal in setup_doublefault(). Signed-off-by: Andrew Cooper --- diff --git a/arch/x86/desc.c b/arch/x86/desc.c index e695d49..fad8355 100644 --- a/arch/x86/desc.c +++ b/arch/x86/desc.c @@ -26,7 +26,7 @@ desc_ptr gdt_ptr = #if defined(CONFIG_HVM) -gate_desc idt[256] = { }; +env_gate idt[256]; desc_ptr idt_ptr = { diff --git a/arch/x86/hvm/traps.c b/arch/x86/hvm/traps.c index 042afe0..2a466df 100644 --- a/arch/x86/hvm/traps.c +++ b/arch/x86/hvm/traps.c @@ -48,9 +48,9 @@ env_tss tss __aligned(16) = .iopb = X86_TSS_INVALID_IO_BITMAP, }; -#if defined(__i386__) static env_tss tss_DF __aligned(16) = { +#if defined(__i386__) .esp = _u(&boot_stack[3 * PAGE_SIZE]), .ss = __KERN_DS, .ds = __KERN_DS, @@ -62,67 +62,31 @@ static env_tss tss_DF __aligned(16) = .cs = __KERN_CS, .cr3 = _u(cr3_target), +#endif .iopb = X86_TSS_INVALID_IO_BITMAP, }; -#endif - -void pack_gate32(struct seg_gate32 *gate, unsigned int type, uint32_t func, - unsigned int dpl, unsigned int seg) -{ - gate->offset0 = func & 0xffff; - gate->selector = seg; - gate->_r0 = 0; - gate->type = type; - gate->s = 0; - gate->dpl = dpl; - gate->p = 1; - gate->offset1 = (func >> 16) & 0xffff; -} - -void pack_gate64(struct seg_gate64 *gate, unsigned int type, uint64_t func, - unsigned int dpl, unsigned int ist, unsigned int seg) -{ - gate->offset0 = func & 0xffff; - gate->selector = seg; - gate->ist = ist; - gate->_r0 = 0; - gate->type = type; - gate->s = 0; - gate->dpl = dpl; - gate->p = 1; - gate->offset1 = (func >> 16) & 0xffff; - gate->offset2 = (func >> 32) & 0xffffffffu; - gate->_r1 = 0; -} static void setup_gate(unsigned int entry, void *addr, unsigned int dpl) { -#if defined(__i386__) - pack_gate32(&idt[entry], 14, _u(addr), dpl, __KERN_CS); -#elif defined(__x86_64__) - pack_gate64(&idt[entry], 14, _u(addr), dpl, 0, __KERN_CS); -#endif + pack_gate(&idt[entry], 14, __KERN_CS, _u(addr), dpl, 0); } static void setup_doublefault(void) { -#if defined(__i386__) - gdt[GDTE_TSS_DF] = (typeof(*gdt))INIT_GDTE(_u(&tss_DF), 0x67, 0x89); + if ( IS_DEFINED(CONFIG_32BIT) ) + { + gdt[GDTE_TSS_DF] = (typeof(*gdt))INIT_GDTE(_u(&tss_DF), 0x67, 0x89); - pack_gate32(&idt[X86_EXC_DF], 5, 0, 0, GDTE_TSS_DF * 8); -#elif defined(__x86_64__) - pack_gate64(&idt[X86_EXC_DF], 14, _u(entry_DF), 0, 1, __KERN_CS); -#endif + pack_task_gate(&idt[X86_EXC_DF], GDTE_TSS_DF * 8); + } + else + pack_gate(&idt[X86_EXC_DF], 14, __KERN_CS, _u(entry_DF), 0, 1); } int xtf_set_idte(unsigned int vector, struct xtf_idte *idte) { -#if defined(__i386__) - pack_gate32(&idt[vector], 14, idte->addr, idte->dpl, idte->cs); -#elif defined(__x86_64__) - pack_gate64(&idt[vector], 14, idte->addr, idte->dpl, 0, idte->cs); -#endif + pack_gate(&idt[vector], 14, idte->cs, idte->addr, idte->dpl, 0); return 0; } diff --git a/arch/x86/include/arch/desc.h b/arch/x86/include/arch/desc.h index 6991a68..5613450 100644 --- a/arch/x86/include/arch/desc.h +++ b/arch/x86/include/arch/desc.h @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -56,39 +57,6 @@ struct __packed seg_desc32 { }; }; -/** 8-byte gate - Protected mode IDT entry, GDT task/call gate. */ -struct __packed seg_gate32 { - union { - struct { - uint32_t lo, hi; - }; - struct { - uint16_t offset0; - uint16_t selector; - uint8_t _r0; - unsigned int type: 4, s: 1, dpl: 2, p: 1; - uint16_t offset1; - }; - }; -}; - -/** 16-byte gate - Long mode IDT entry. */ -struct __packed seg_gate64 { - union { - struct { - uint64_t lo, hi; - }; - struct { - uint16_t offset0; - uint16_t selector; - unsigned int ist: 3, _r0: 5, type: 4, s: 1, dpl: 2, p: 1; - uint16_t offset1; - uint32_t offset2; - uint32_t _r1; - }; - }; -}; - /* GDT/LDT attribute flags for user segments */ /* Common */ @@ -165,7 +133,7 @@ extern user_desc gdt[NR_GDT_ENTRIES]; extern desc_ptr gdt_ptr; #if defined(CONFIG_HVM) -extern gate_desc idt[256]; +extern env_gate idt[256]; extern desc_ptr idt_ptr; extern env_tss tss; diff --git a/arch/x86/include/arch/x86-gate.h b/arch/x86/include/arch/x86-gate.h new file mode 100644 index 0000000..98de219 --- /dev/null +++ b/arch/x86/include/arch/x86-gate.h @@ -0,0 +1,120 @@ +/** + * @file arch/x86/include/arch/x86-gate.h + * + * %x86 Gate Descriptor infrastructure. + */ + +#ifndef XTF_X86_GATE_H +#define XTF_X86_GATE_H + +#include + +/** 8-byte gate - Protected mode IDT entry, GDT task/call gate. */ +struct __packed x86_gate32 { + union { + struct { + uint32_t lo, hi; + }; + struct { + uint16_t offset0; + uint16_t selector; + unsigned int param_count:5, _r0:3; + unsigned int type:4, s:1, dpl:2, p:1; + uint16_t offset1; + }; + }; +}; + +static inline void pack_x86_gate32( + struct x86_gate32 *g, + unsigned int type, unsigned int sel, uint32_t offset, + unsigned int dpl, unsigned int count) +{ + g->offset0 = offset & 0xffff; + g->selector = sel; + g->param_count = count; + g->_r0 = 0; + g->type = type; + g->s = 0; + g->dpl = dpl; + g->p = 1; + g->offset1 = (offset >> 16) & 0xffff; +} + +/** 16-byte gate - Long mode IDT entry, GDT call gate. */ +struct __packed x86_gate64 { + union { + struct { + uint64_t lo, hi; + }; + struct { + uint16_t offset0; + uint16_t selector; + unsigned int ist:3, _r0:5; + unsigned int type:4, s:1, dpl:2, p:1; + uint16_t offset1; + uint32_t offset2; + uint32_t _r1; + }; + }; +}; + +static inline void pack_x86_gate64( + struct x86_gate64 *g, + unsigned int type, unsigned int sel, uint64_t offset, + unsigned int dpl, unsigned int ist) +{ + g->offset0 = offset & 0xffff; + g->selector = sel; + g->ist = ist; + g->_r0 = 0; + g->type = type; + g->s = 0; + g->dpl = dpl; + g->p = 1; + g->offset1 = (offset >> 16) & 0xffff; + g->offset2 = (offset >> 32) & 0xffffffffu; + g->_r1 = 0; +} + +#if defined(__x86_64__) + +typedef struct x86_gate64 env_gate; + +#elif defined(__i386__) + +typedef struct x86_gate32 env_gate; + +#else +# error Bad architecture for Gate infrastructure +#endif + +static inline void pack_gate( + env_gate *g, + unsigned int type, unsigned int sel, unsigned long offset, + unsigned int dpl, unsigned int other) +{ +#if defined(__x86_64__) + pack_x86_gate64 +#else + pack_x86_gate32 +#endif + (g, type, sel, offset, dpl, other); +} + +static inline void pack_task_gate(env_gate *g, unsigned int selector) +{ + pack_gate(g, 5, selector, 0, 0, 0); +} + +#endif /* XTF_X86_TSS_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */