HV: Add one correct Descriptor_table struct to configure VMCS

Now one uint64_t type is used to obtain the corresponding descriptor_table
for GDT/IDT. This will cause the stack protect corruption under -O2.
So the descriptor_table struct is added to configure the GDT/IDT of VMCS.

V1->V2: Move the descriptor_table into vmx.h header file
And its type is renamed from dt_addr_t to descriptor_table.

Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Zheng Gen <gen.zheng@intel.com>
Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com>
Acked-by: Anthony Xu <anthony.xu@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Zhao Yakui 2018-05-10 11:13:59 +08:00 committed by Jack Ren
parent b2cadfecdf
commit 698b53adc4
2 changed files with 29 additions and 29 deletions

View File

@ -372,18 +372,18 @@ static void init_guest_state(struct vcpu *vcpu)
/* Limit */ /* Limit */
limit = 0xFFFF; limit = 0xFFFF;
} else if (get_vcpu_mode(vcpu) == PAGE_PROTECTED_MODE) { } else if (get_vcpu_mode(vcpu) == PAGE_PROTECTED_MODE) {
uint64_t gdtb = 0; descriptor_table gdtb;
/* Base *//* TODO: Should guest GDTB point to host GDTB ? */ /* Base *//* TODO: Should guest GDTB point to host GDTB ? */
/* Obtain the current global descriptor table base */ /* Obtain the current global descriptor table base */
asm volatile ("sgdt %0" : : "m" (gdtb)); asm volatile ("sgdt %0" : : "m" (gdtb));
value32 = gdtb & 0x0ffff;
gdtb = gdtb >> 16; /* base */
if ((gdtb >> 47 & 0x1)) value32 = gdtb.limit;
gdtb |= 0xffff000000000000ull;
base = gdtb; if ((gdtb.base >> 47) & 0x1)
gdtb.base |= 0xffff000000000000ull;
base = gdtb.base;
/* Limit */ /* Limit */
limit = HOST_GDT_SIZE - 1; limit = HOST_GDT_SIZE - 1;
@ -407,20 +407,18 @@ static void init_guest_state(struct vcpu *vcpu)
/* Limit */ /* Limit */
limit = 0xFFFF; limit = 0xFFFF;
} else if (get_vcpu_mode(vcpu) == PAGE_PROTECTED_MODE) { } else if (get_vcpu_mode(vcpu) == PAGE_PROTECTED_MODE) {
uint64_t idtb = 0; descriptor_table idtb ;
/* TODO: Should guest IDTR point to host IDTR ? */ /* TODO: Should guest IDTR point to host IDTR ? */
asm volatile ("sidt %0"::"m" (idtb)); asm volatile ("sidt %0"::"m" (idtb));
value32 = idtb & 0x0ffff;
/* Limit */ /* Limit */
limit = value32; limit = idtb.limit;
idtb = idtb >> 16; /* base */
if ((idtb >> 47 & 0x1)) if ((idtb.base >> 47) & 0x1)
idtb |= 0xffff000000000000ull; idtb.base |= 0xffff000000000000ull;
/* Base */ /* Base */
base = idtb; base = idtb.base;
} }
/* IDTR Base */ /* IDTR Base */
@ -662,8 +660,8 @@ static void init_host_state(__unused struct vcpu *vcpu)
uint64_t trbase_lo; uint64_t trbase_lo;
uint64_t trbase_hi; uint64_t trbase_hi;
uint64_t realtrbase; uint64_t realtrbase;
uint64_t gdtb = 0; descriptor_table gdtb;
uint64_t idtb = 0; descriptor_table idtb;
uint16_t tr_sel; uint16_t tr_sel;
pr_dbg("*********************"); pr_dbg("*********************");
@ -721,19 +719,18 @@ static void init_host_state(__unused struct vcpu *vcpu)
/* TODO: Should guest GDTB point to host GDTB ? */ /* TODO: Should guest GDTB point to host GDTB ? */
/* Obtain the current global descriptor table base */ /* Obtain the current global descriptor table base */
asm volatile ("sgdt %0"::"m" (gdtb)); asm volatile ("sgdt %0"::"m" (gdtb));
value32 = gdtb & 0x0ffff; value32 = gdtb.limit;
gdtb = gdtb >> 16; /* base */
if ((gdtb >> 47) & 0x1) if ((gdtb.base >> 47) & 0x1)
gdtb |= 0xffff000000000000ull; gdtb.base |= 0xffff000000000000ull;
/* Set up the guest and host GDTB base fields with current GDTB base */ /* Set up the guest and host GDTB base fields with current GDTB base */
field = VMX_HOST_GDTR_BASE; field = VMX_HOST_GDTR_BASE;
exec_vmwrite(field, gdtb); exec_vmwrite(field, gdtb.base);
pr_dbg("VMX_HOST_GDTR_BASE: 0x%x ", gdtb); pr_dbg("VMX_HOST_GDTR_BASE: 0x%x ", gdtb.base);
/* TODO: Should guest TR point to host TR ? */ /* TODO: Should guest TR point to host TR ? */
trbase = gdtb + tr_sel; trbase = gdtb.base + tr_sel;
if ((trbase >> 47) & 0x1) if ((trbase >> 47) & 0x1)
trbase |= 0xffff000000000000ull; trbase |= 0xffff000000000000ull;
@ -759,16 +756,13 @@ static void init_host_state(__unused struct vcpu *vcpu)
/* Obtain the current interrupt descriptor table base */ /* Obtain the current interrupt descriptor table base */
asm volatile ("sidt %0"::"m" (idtb)); asm volatile ("sidt %0"::"m" (idtb));
value32 = idtb & 0x0ffff;
/* base */ /* base */
idtb = idtb >> 16; if ((idtb.base >> 47) & 0x1)
idtb.base |= 0xffff000000000000ull;
if ((idtb >> 47 & 0x1))
idtb |= 0xffff000000000000ull;
field = VMX_HOST_IDTR_BASE; field = VMX_HOST_IDTR_BASE;
exec_vmwrite(field, idtb); exec_vmwrite(field, idtb.base);
pr_dbg("VMX_HOST_IDTR_BASE: 0x%x ", idtb); pr_dbg("VMX_HOST_IDTR_BASE: 0x%x ", idtb.base);
asm volatile ("mov $0x174, %rcx"); asm volatile ("mov $0x174, %rcx");
asm volatile ("rdmsr"); asm volatile ("rdmsr");

View File

@ -472,6 +472,12 @@ static inline uint8_t get_vcpu_mode(struct vcpu *vcpu)
{ {
return vcpu->arch_vcpu.cpu_mode; return vcpu->arch_vcpu.cpu_mode;
} }
typedef struct _descriptor_table_{
uint16_t limit;
uint64_t base;
}__attribute__((packed)) descriptor_table;
#endif /* ASSEMBLER */ #endif /* ASSEMBLER */
#endif /* VMX_H_ */ #endif /* VMX_H_ */