Skip to content

Commit 8925eb5

Browse files
ZideChen0lijinxia
authored andcommitted
hv: set guest segment base to zero if VCPU does not start in real mode
In non real mode, for segment registers other than CS, the guest segment base should be zero, otherwise the guest's segmentation results in wrong effective addresses. Linux boots with the wrong segment registers (base address in hidden part), because it happens that it assigns the segment registers before using any of them, which effectively reloads the segment base addresses from GDT.
1 parent b831120 commit 8925eb5

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

hypervisor/arch/x86/vmx.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -872,21 +872,26 @@ static void init_guest_state(struct vcpu *vcpu)
872872
pr_dbg("VMX_GUEST_GS_ATTR: 0x%x ", value32);
873873

874874
/* Base */
875-
value = 0UL;
875+
if (vcpu_mode == CPU_MODE_REAL) {
876+
value = es << 4;
877+
} else {
878+
value = 0UL;
879+
}
880+
876881
field = VMX_GUEST_ES_BASE;
877-
exec_vmwrite(field, es << 4);
882+
exec_vmwrite(field, value);
878883
pr_dbg("VMX_GUEST_ES_BASE: 0x%016llx ", value);
879884
field = VMX_GUEST_SS_BASE;
880-
exec_vmwrite(field, ss << 4);
885+
exec_vmwrite(field, value);
881886
pr_dbg("VMX_GUEST_SS_BASE: 0x%016llx ", value);
882887
field = VMX_GUEST_DS_BASE;
883-
exec_vmwrite(field, ds << 4);
888+
exec_vmwrite(field, value);
884889
pr_dbg("VMX_GUEST_DS_BASE: 0x%016llx ", value);
885890
field = VMX_GUEST_FS_BASE;
886-
exec_vmwrite(field, fs << 4);
891+
exec_vmwrite(field, value);
887892
pr_dbg("VMX_GUEST_FS_BASE: 0x%016llx ", value);
888893
field = VMX_GUEST_GS_BASE;
889-
exec_vmwrite(field, gs << 4);
894+
exec_vmwrite(field, value);
890895
pr_dbg("VMX_GUEST_GS_BASE: 0x%016llx ", value);
891896

892897
/***************************************************/

0 commit comments

Comments
 (0)