@@ -1846,7 +1846,22 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu,
vmx->rmode.tr.ar = vmx_segment_access_rights(var);
return;
}
- vmcs_writel(sf->base, var->base);
+
+ /* Intel 64 and IA-32 Architecture Software Developer's Manual Vol. 3b,
+ * section 22.3.1.2 states that VMENTRY will fail if bits 63:32 of the
+ * base address for CS, SS, DS, ES are not 0 and the register is usable.
+ *
+ * If var->base happens to have bit 31 set, then it will get sign
+ * extended on the vmcs_writel(), causing this check to fail. Make
+ * sure to use the 32-bit version where appropriate.
+ */
+ if (sf->base == GUEST_CS_BASE ||
+ ((~sf->ar_bytes & 0x00010000) && (sf->base == GUEST_SS_BASE ||
+ sf->base == GUEST_DS_BASE ||
+ sf->base == GUEST_ES_BASE)))
+ vmcs_write32(sf->base, var->base);
+ else
+ vmcs_writel(sf->base, var->base);
vmcs_write32(sf->limit, var->limit);
vmcs_write16(sf->selector, var->selector);
if (vmx->rmode.vm86_active && var->s) {