tss_descr was mapped to descriptor table pointer but in fact it should be a gdt entry. Add two helper functions to pick base and limit from gdt 64bit entry and assign to HOST_BASE_TR, GUEST_BASE_TR and GUEST_LIMIT_TR. Signed-off-by: Zhenzhong Duan <zhenzhong.duan@xxxxxxxxx> --- lib/x86/desc.h | 2 ++ lib/x86/desc.c | 12 ++++++++++++ x86/vmx.c | 8 ++++---- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/x86/desc.h b/lib/x86/desc.h index a6ffb38..cb71046 100644 --- a/lib/x86/desc.h +++ b/lib/x86/desc.h @@ -209,6 +209,8 @@ void set_intr_task_gate(int vec, void *fn); void setup_tss32(void); #else extern tss64_t tss; +u64 get_gdt_entry_64_base(struct segment_desc64 *entry); +u64 get_gdt_entry_64_limit(struct segment_desc64 *entry); #endif unsigned exception_vector(void); diff --git a/lib/x86/desc.c b/lib/x86/desc.c index e7378c1..5482366 100644 --- a/lib/x86/desc.c +++ b/lib/x86/desc.c @@ -376,6 +376,18 @@ void setup_alt_stack(void) { tss.ist1 = (u64)intr_alt_stack + 4096; } +u64 get_gdt_entry_64_base(struct segment_desc64 *entry) +{ + return ((uint64_t) entry->base1 | + ((uint64_t) entry->base2 << 16) | + ((uint64_t) entry->base3 << 24) | + ((uint64_t) entry->base4 << 32)); +} +u64 get_gdt_entry_64_limit(struct segment_desc64 *entry) +{ + return ((uint64_t) entry->limit1 | + ((uint64_t) entry->limit << 16)); +} #endif static bool exception; diff --git a/x86/vmx.c b/x86/vmx.c index 20dc677..2d87d88 100644 --- a/x86/vmx.c +++ b/x86/vmx.c @@ -75,7 +75,7 @@ union vmx_ept_vpid ept_vpid; extern struct descriptor_table_ptr gdt64_desc; extern struct descriptor_table_ptr idt_descr; -extern struct descriptor_table_ptr tss_descr; +extern struct segment_desc64 tss_descr; extern void *vmx_return; extern void *entry_sysenter; extern void *guest_entry; @@ -1275,7 +1275,7 @@ static void init_vmcs_host(void) vmcs_write(HOST_SEL_FS, KERNEL_DS); vmcs_write(HOST_SEL_GS, KERNEL_DS); vmcs_write(HOST_SEL_TR, TSS_MAIN); - vmcs_write(HOST_BASE_TR, tss_descr.base); + vmcs_write(HOST_BASE_TR, get_gdt_entry_64_base(&tss_descr)); vmcs_write(HOST_BASE_GDTR, gdt64_desc.base); vmcs_write(HOST_BASE_IDTR, idt_descr.base); vmcs_write(HOST_BASE_FS, 0); @@ -1331,7 +1331,7 @@ static void init_vmcs_guest(void) vmcs_write(GUEST_BASE_DS, 0); vmcs_write(GUEST_BASE_FS, 0); vmcs_write(GUEST_BASE_GS, 0); - vmcs_write(GUEST_BASE_TR, tss_descr.base); + vmcs_write(GUEST_BASE_TR, get_gdt_entry_64_base(&tss_descr)); vmcs_write(GUEST_BASE_LDTR, 0); vmcs_write(GUEST_LIMIT_CS, 0xFFFFFFFF); @@ -1341,7 +1341,7 @@ static void init_vmcs_guest(void) vmcs_write(GUEST_LIMIT_FS, 0xFFFFFFFF); vmcs_write(GUEST_LIMIT_GS, 0xFFFFFFFF); vmcs_write(GUEST_LIMIT_LDTR, 0xffff); - vmcs_write(GUEST_LIMIT_TR, tss_descr.limit); + vmcs_write(GUEST_LIMIT_TR, get_gdt_entry_64_limit(&tss_descr)); vmcs_write(GUEST_AR_CS, 0xa09b); vmcs_write(GUEST_AR_DS, 0xc093); -- 2.25.1