diff --git a/hypervisor/arch/x86/guest/guest.c b/hypervisor/arch/x86/guest/guest.c index 974392a2e..438cd3967 100644 --- a/hypervisor/arch/x86/guest/guest.c +++ b/hypervisor/arch/x86/guest/guest.c @@ -680,3 +680,36 @@ uint64_t create_guest_initial_paging(struct vm *vm) return GUEST_INIT_PAGE_TABLE_START; } + +/******************************************************************* + * GUEST initial GDT table + * + * If guest starts with protected mode, HV needs to prepare Guest GDT. + ******************************************************************/ + +#define GUEST_INIT_GDT_SKIP_SIZE 0x8000UL +#define GUEST_INIT_GDT_START (CONFIG_LOW_RAM_START + \ + GUEST_INIT_GDT_SKIP_SIZE) + +/* The GDT defined below compatible with linux kernel */ +#define GUEST_INIT_GDT_DESC_0 (0x0) +#define GUEST_INIT_GDT_DESC_1 (0x0) +#define GUEST_INIT_GDT_DESC_2 (0x00CF9B000000FFFFULL) /* Linear Code */ +#define GUEST_INIT_GDT_DESC_3 (0x00CF93000000FFFFULL) /* Linear Data */ + +static const uint64_t guest_init_gdt[] = { + GUEST_INIT_GDT_DESC_0, + GUEST_INIT_GDT_DESC_1, + GUEST_INIT_GDT_DESC_2, + GUEST_INIT_GDT_DESC_3, +}; + +uint32_t create_guest_init_gdt(struct vm *vm, uint32_t *limit) +{ + void *gtd_addr = GPA2HVA(vm, GUEST_INIT_GDT_START); + + *limit = sizeof(guest_init_gdt) - 1; + memcpy_s(gtd_addr, 64, guest_init_gdt, sizeof(guest_init_gdt)); + + return GUEST_INIT_GDT_START; +}; diff --git a/hypervisor/include/arch/x86/guest/guest.h b/hypervisor/include/arch/x86/guest/guest.h index 7cc41418b..4329f8107 100644 --- a/hypervisor/include/arch/x86/guest/guest.h +++ b/hypervisor/include/arch/x86/guest/guest.h @@ -123,6 +123,8 @@ extern vm_sw_loader_t vm_sw_loader; int copy_from_vm(struct vm *vm, void *h_ptr, uint64_t gpa, uint32_t size); int copy_to_vm(struct vm *vm, void *h_ptr, uint64_t gpa, uint32_t size); + +uint32_t create_guest_init_gdt(struct vm *vm, uint32_t *limit); #endif /* !ASSEMBLER */ #endif /* GUEST_H*/