ia64/xen-unstable
changeset 9922:e1409c2ace46
Ensure segment bases are consistent with their
selectors for VMX guests in VM86 mode.
Signed-off-by: David Lively <dlively@virtualiron.com>
selectors for VMX guests in VM86 mode.
Signed-off-by: David Lively <dlively@virtualiron.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Wed May 03 10:56:19 2006 +0100 (2006-05-03) |
parents | 3f69d30f697d |
children | 47442d409d8e |
files | xen/arch/x86/hvm/vmx/vmx.c |
line diff
1.1 --- a/xen/arch/x86/hvm/vmx/vmx.c Wed May 03 07:44:20 2006 +0100 1.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c Wed May 03 10:56:19 2006 +0100 1.3 @@ -475,6 +475,45 @@ static void vmx_store_cpu_guest_regs( 1.4 __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs)); 1.5 } 1.6 1.7 +/* 1.8 + * The VMX spec (section 4.3.1.2, Checks on Guest Segment 1.9 + * Registers) says that virtual-8086 mode guests' segment 1.10 + * base-address fields in the VMCS must be equal to their 1.11 + * corresponding segment selector field shifted right by 1.12 + * four bits upon vmentry. 1.13 + * 1.14 + * This function (called only for VM86-mode guests) fixes 1.15 + * the bases to be consistent with the selectors in regs 1.16 + * if they're not already. Without this, we can fail the 1.17 + * vmentry check mentioned above. 1.18 + */ 1.19 +static void fixup_vm86_seg_bases(struct cpu_user_regs *regs) 1.20 +{ 1.21 + int err = 0; 1.22 + unsigned long base; 1.23 + 1.24 + err |= __vmread(GUEST_ES_BASE, &base); 1.25 + if (regs->es << 4 != base) 1.26 + err |= __vmwrite(GUEST_ES_BASE, regs->es << 4); 1.27 + err |= __vmread(GUEST_CS_BASE, &base); 1.28 + if (regs->cs << 4 != base) 1.29 + err |= __vmwrite(GUEST_CS_BASE, regs->cs << 4); 1.30 + err |= __vmread(GUEST_SS_BASE, &base); 1.31 + if (regs->ss << 4 != base) 1.32 + err |= __vmwrite(GUEST_SS_BASE, regs->ss << 4); 1.33 + err |= __vmread(GUEST_DS_BASE, &base); 1.34 + if (regs->ds << 4 != base) 1.35 + err |= __vmwrite(GUEST_DS_BASE, regs->ds << 4); 1.36 + err |= __vmread(GUEST_FS_BASE, &base); 1.37 + if (regs->fs << 4 != base) 1.38 + err |= __vmwrite(GUEST_FS_BASE, regs->fs << 4); 1.39 + err |= __vmread(GUEST_GS_BASE, &base); 1.40 + if (regs->gs << 4 != base) 1.41 + err |= __vmwrite(GUEST_GS_BASE, regs->gs << 4); 1.42 + 1.43 + BUG_ON(err); 1.44 +} 1.45 + 1.46 void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs) 1.47 { 1.48 if ( v != current ) 1.49 @@ -511,6 +550,8 @@ void vmx_load_cpu_guest_regs(struct vcpu 1.50 __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB); 1.51 else 1.52 __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB); 1.53 + if (regs->rflags & EF_VM) 1.54 + fixup_vm86_seg_bases(regs); 1.55 1.56 __vmwrite(GUEST_CS_SELECTOR, regs->cs); 1.57 __vmwrite(GUEST_RIP, regs->eip);