Ensure segment bases are consistent with their selectors for VMX guests in VM86 mode. Signed-off-by: David Lively diff -r 880433ba7487 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Mon May 1 17:08:02 2006 -0400 +++ b/xen/arch/x86/hvm/vmx/vmx.c Tue May 2 10:31:03 2006 -0400 @@ -487,6 +487,33 @@ static void vmx_store_cpu_guest_regs( __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs)); } +/* Ensure segment bases are consistent with their + * selectors for guests in VM86 mode. + */ +static void fixup_vm86_seg_bases(struct cpu_user_regs *regs) +{ + unsigned long base; + + BUG_ON(__vmread(GUEST_ES_BASE, &base)); + if (regs->es << 4 != base) + BUG_ON(__vmwrite(GUEST_ES_BASE, regs->es << 4)); + BUG_ON(__vmread(GUEST_CS_BASE, &base)); + if (regs->cs << 4 != base) + BUG_ON(__vmwrite(GUEST_CS_BASE, regs->cs << 4)); + BUG_ON(__vmread(GUEST_SS_BASE, &base)); + if (regs->ss << 4 != base) + BUG_ON(__vmwrite(GUEST_SS_BASE, regs->ss << 4)); + BUG_ON(__vmread(GUEST_DS_BASE, &base)); + if (regs->ds << 4 != base) + BUG_ON(__vmwrite(GUEST_DS_BASE, regs->ds << 4)); + BUG_ON(__vmread(GUEST_FS_BASE, &base)); + if (regs->fs << 4 != base) + BUG_ON(__vmwrite(GUEST_FS_BASE, regs->fs << 4)); + BUG_ON(__vmread(GUEST_GS_BASE, &base)); + if (regs->gs << 4 != base) + BUG_ON(__vmwrite(GUEST_GS_BASE, regs->gs << 4)); +} + void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs) { if ( v != current ) @@ -523,6 +550,8 @@ void vmx_load_cpu_guest_regs(struct vcpu __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB); else __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB); + if (regs->rflags & EF_VM) + fixup_vm86_seg_bases(regs); __vmwrite(GUEST_CS_SELECTOR, regs->cs); __vmwrite(GUEST_RIP, regs->rip); @@ -540,6 +569,8 @@ void vmx_load_cpu_guest_regs(struct vcpu __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB); else __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB); + if (regs->eflags & EF_VM) + fixup_vm86_seg_bases(regs); __vmwrite(GUEST_CS_SELECTOR, regs->cs); __vmwrite(GUEST_RIP, regs->eip);