Changeset 47687 in vbox for trunk/src/VBox
- Timestamp:
- Aug 13, 2013 12:10:19 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r47683 r47687 7479 7479 HMVMX_CHECK_BREAK(!(u32Val & ~uZapCR0), VMX_IGS_CR0_FIXED0); 7480 7480 if ( !fUnrestrictedGuest 7481 && CPUMIsGuestPagingEnabledEx(pCtx)7482 && ! CPUMIsGuestInProtectedMode(pVCpu))7481 && (u32Val & X86_CR0_PG) 7482 && !(u32Val & X86_CR0_PE)) 7483 7483 { 7484 7484 HMVMX_ERROR_BREAK(VMX_IGS_CR0_PG_PE_COMBO); … … 7507 7507 uint64_t u64DebugCtlMsr = u64Val; 7508 7508 7509 #ifdef VBOX_STRICT 7510 rc = VMXReadVmcs32(VMX_VMCS32_CTRL_PROC_EXEC, &u32Val); 7511 AssertRCBreak(rc); 7512 Assert(u32Val == pVCpu->hm.s.vmx.u32ProcCtls); 7513 #endif 7514 const bool fLongModeGuest = !!(pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_ENTRY_IA32E_MODE_GUEST); 7515 7516 /* 7517 * RIP and RFLAGS. 7518 */ 7519 uint32_t u32EFlags; 7520 #if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) 7521 if (HMVMX_IS_64BIT_HOST_MODE()) 7522 { 7523 rc = VMXReadVmcs64(VMX_VMCS_GUEST_RIP, &u64Val); 7524 AssertRCBreak(rc); 7525 /* pCtx->rip can be different than the one in the VMCS (e.g. run guest code and VM-exits that don't update it). */ 7526 if ( !fLongModeGuest 7527 || !pCtx->cs.Attr.n.u1Long) 7528 { 7529 HMVMX_CHECK_BREAK(!(u64Val & UINT64_C(0xffffffff00000000)), VMX_IGS_LONGMODE_RIP_INVALID); 7530 } 7531 /** @todo If the processor supports N < 64 linear-address bits, bits 63:N 7532 * must be identical if the "IA32e mode guest" VM-entry control is 1 7533 * and CS.L is 1. No check applies if the CPU supports 64 7534 * linear-address bits. */ 7535 7536 /* Flags in pCtx can be different (real-on-v86 for instance). We are only concerned about the VMCS contents here. */ 7537 rc = VMXReadVmcs64(VMX_VMCS_GUEST_RFLAGS, &u64Val); 7538 AssertRCBreak(rc); 7539 HMVMX_CHECK_BREAK(!(u64Val & UINT64_C(0xffffffffffc08028)), /* Bit 63:22, Bit 15, 5, 3 MBZ. */ 7540 VMX_IGS_RFLAGS_RESERVED); 7541 HMVMX_CHECK_BREAK((u64Val & X86_EFL_RA1_MASK), VMX_IGS_RFLAGS_RESERVED1); /* Bit 1 MB1. */ 7542 u32EFlags = u64Val; 7543 } 7544 else 7545 #endif 7546 { 7547 rc = VMXReadVmcs32(VMX_VMCS_GUEST_RFLAGS, &u32EFlags); 7548 AssertRCBreak(rc); 7549 HMVMX_CHECK_BREAK(!(u32EFlags & 0xffc08028), VMX_IGS_RFLAGS_RESERVED); /* Bit 31:22, Bit 15, 5, 3 MBZ. */ 7550 HMVMX_CHECK_BREAK((u32EFlags & X86_EFL_RA1_MASK), VMX_IGS_RFLAGS_RESERVED1); /* Bit 1 MB1. */ 7551 } 7552 7553 if ( fLongModeGuest 7554 || !(pCtx->cr0 & X86_CR0_PE)) 7555 { 7556 HMVMX_CHECK_BREAK(!(u32EFlags & X86_EFL_VM), VMX_IGS_RFLAGS_VM_INVALID); 7557 } 7558 7559 uint32_t u32EntryInfo; 7560 rc = VMXReadVmcs32(VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO, &u32EntryInfo); 7561 AssertRCBreak(rc); 7562 if ( VMX_ENTRY_INTERRUPTION_INFO_VALID(u32EntryInfo) 7563 && VMX_ENTRY_INTERRUPTION_INFO_TYPE(u32EntryInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_EXT_INT) 7564 { 7565 HMVMX_CHECK_BREAK(u32Val & X86_EFL_IF, VMX_IGS_RFLAGS_IF_INVALID); 7566 } 7567 7509 7568 /* 7510 7569 * 64-bit checks. … … 7513 7572 if (HMVMX_IS_64BIT_HOST_MODE()) 7514 7573 { 7515 if ( (pVCpu->hm.s.vmx.u32EntryCtls & VMX_VMCS_CTRL_ENTRY_IA32E_MODE_GUEST)7574 if ( fLongModeGuest 7516 7575 && !fUnrestrictedGuest) 7517 7576 { … … 7520 7579 } 7521 7580 7522 if ( ! (pVCpu->hm.s.vmx.u32EntryCtls & VMX_VMCS_CTRL_ENTRY_IA32E_MODE_GUEST)7581 if ( !fLongModeGuest 7523 7582 && (pCtx->cr4 & X86_CR4_PCIDE)) 7524 7583 { … … 7600 7659 HMVMX_CHECK_BREAK( (pCtx->ldtr.Attr.u & X86DESCATTR_UNUSABLE) 7601 7660 || !(pCtx->ldtr.Sel & X86_SEL_LDT), VMX_IGS_LDTR_TI_INVALID); 7602 if ( !pVM->hm.s.vmx.fUnrestrictedGuest 7603 && ( !CPUMIsGuestInRealModeEx(pCtx) 7604 && !CPUMIsGuestInV86ModeEx(pCtx))) 7605 { 7606 /* Protected mode checks */ 7661 if (!(u32EFlags & X86_EFL_VM)) 7662 { 7607 7663 /* CS */ 7608 7664 HMVMX_CHECK_BREAK(pCtx->cs.Attr.n.u1Present, VMX_IGS_CS_ATTR_P_INVALID); … … 7615 7671 /* CS cannot be loaded with NULL in protected mode. */ 7616 7672 HMVMX_CHECK_BREAK(pCtx->cs.Attr.u && !(pCtx->cs.Attr.u & X86DESCATTR_UNUSABLE), VMX_IGS_CS_ATTR_UNUSABLE); 7673 HMVMX_CHECK_BREAK(pCtx->cs.Attr.n.u1DescType, VMX_IGS_CS_ATTR_S_INVALID); 7617 7674 if (pCtx->cs.Attr.n.u4Type == 9 || pCtx->cs.Attr.n.u4Type == 11) 7618 7675 HMVMX_CHECK_BREAK(pCtx->cs.Attr.n.u2Dpl == pCtx->ss.Attr.n.u2Dpl, VMX_IGS_CS_SS_ATTR_DPL_UNEQUAL); 7619 7676 else if (pCtx->cs.Attr.n.u4Type == 13 || pCtx->cs.Attr.n.u4Type == 15) 7620 7677 HMVMX_CHECK_BREAK(pCtx->cs.Attr.n.u2Dpl <= pCtx->ss.Attr.n.u2Dpl, VMX_IGS_CS_SS_ATTR_DPL_MISMATCH); 7678 else if (pVM->hm.s.vmx.fUnrestrictedGuest && pCtx->cs.Attr.n.u4Type == 3) 7679 HMVMX_CHECK_BREAK(pCtx->cs.Attr.n.u2Dpl == 0, VMX_IGS_CS_ATTR_DPL_INVALID); 7621 7680 else 7622 7681 HMVMX_ERROR_BREAK(VMX_IGS_CS_ATTR_TYPE_INVALID); 7682 7623 7683 /* SS */ 7624 HMVMX_CHECK_BREAK((pCtx->ss.Sel & X86_SEL_RPL) == (pCtx->cs.Sel & X86_SEL_RPL), VMX_IGS_SS_CS_RPL_UNEQUAL); 7684 HMVMX_CHECK_BREAK( pVM->hm.s.vmx.fUnrestrictedGuest 7685 || (pCtx->ss.Sel & X86_SEL_RPL) == (pCtx->cs.Sel & X86_SEL_RPL), VMX_IGS_SS_CS_RPL_UNEQUAL); 7625 7686 HMVMX_CHECK_BREAK(pCtx->ss.Attr.n.u2Dpl == (pCtx->ss.Sel & X86_SEL_RPL), VMX_IGS_SS_ATTR_DPL_RPL_UNEQUAL); 7626 7687 if ( !(pCtx->cr0 & X86_CR0_PE) … … 7640 7701 || (pCtx->ss.Attr.n.u1Granularity), VMX_IGS_SS_ATTR_G_INVALID); 7641 7702 } 7703 7642 7704 /* DS, ES, FS, GS - only check for usable selectors, see hmR0VmxWriteSegmentReg(). */ 7643 7705 if (!(pCtx->ds.Attr.u & X86DESCATTR_UNUSABLE)) … … 7645 7707 HMVMX_CHECK_BREAK(pCtx->ds.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED, VMX_IGS_DS_ATTR_A_INVALID); 7646 7708 HMVMX_CHECK_BREAK(pCtx->ds.Attr.n.u1Present, VMX_IGS_DS_ATTR_P_INVALID); 7647 HMVMX_CHECK_BREAK(pCtx->ds.Attr.n.u4Type > 11 || pCtx->ds.Attr.n.u2Dpl >= (pCtx->ds.Sel & X86_SEL_RPL), 7648 VMX_IGS_DS_ATTR_DPL_RPL_UNEQUAL); 7709 HMVMX_CHECK_BREAK( pVM->hm.s.vmx.fUnrestrictedGuest 7710 || pCtx->ds.Attr.n.u4Type > 11 7711 || pCtx->ds.Attr.n.u2Dpl >= (pCtx->ds.Sel & X86_SEL_RPL), VMX_IGS_DS_ATTR_DPL_RPL_UNEQUAL); 7649 7712 HMVMX_CHECK_BREAK(!(pCtx->ds.Attr.u & 0xf00), VMX_IGS_DS_ATTR_RESERVED); 7650 7713 HMVMX_CHECK_BREAK(!(pCtx->ds.Attr.u & 0xfffe0000), VMX_IGS_DS_ATTR_RESERVED); … … 7660 7723 HMVMX_CHECK_BREAK(pCtx->es.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED, VMX_IGS_ES_ATTR_A_INVALID); 7661 7724 HMVMX_CHECK_BREAK(pCtx->es.Attr.n.u1Present, VMX_IGS_ES_ATTR_P_INVALID); 7662 HMVMX_CHECK_BREAK(pCtx->es.Attr.n.u4Type > 11 || pCtx->es.Attr.n.u2Dpl >= (pCtx->es.Sel & X86_SEL_RPL), 7663 VMX_IGS_ES_ATTR_DPL_RPL_UNEQUAL); 7725 HMVMX_CHECK_BREAK( pVM->hm.s.vmx.fUnrestrictedGuest 7726 || pCtx->es.Attr.n.u4Type > 11 7727 || pCtx->es.Attr.n.u2Dpl >= (pCtx->es.Sel & X86_SEL_RPL), VMX_IGS_DS_ATTR_DPL_RPL_UNEQUAL); 7664 7728 HMVMX_CHECK_BREAK(!(pCtx->es.Attr.u & 0xf00), VMX_IGS_ES_ATTR_RESERVED); 7665 7729 HMVMX_CHECK_BREAK(!(pCtx->es.Attr.u & 0xfffe0000), VMX_IGS_ES_ATTR_RESERVED); … … 7675 7739 HMVMX_CHECK_BREAK(pCtx->fs.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED, VMX_IGS_FS_ATTR_A_INVALID); 7676 7740 HMVMX_CHECK_BREAK(pCtx->fs.Attr.n.u1Present, VMX_IGS_FS_ATTR_P_INVALID); 7677 HMVMX_CHECK_BREAK(pCtx->fs.Attr.n.u4Type > 11 || pCtx->fs.Attr.n.u2Dpl >= (pCtx->fs.Sel & X86_SEL_RPL), 7678 VMX_IGS_FS_ATTR_DPL_RPL_UNEQUAL); 7741 HMVMX_CHECK_BREAK( pVM->hm.s.vmx.fUnrestrictedGuest 7742 || pCtx->fs.Attr.n.u4Type > 11 7743 || pCtx->fs.Attr.n.u2Dpl >= (pCtx->fs.Sel & X86_SEL_RPL), VMX_IGS_FS_ATTR_DPL_RPL_UNEQUAL); 7679 7744 HMVMX_CHECK_BREAK(!(pCtx->fs.Attr.u & 0xf00), VMX_IGS_FS_ATTR_RESERVED); 7680 7745 HMVMX_CHECK_BREAK(!(pCtx->fs.Attr.u & 0xfffe0000), VMX_IGS_FS_ATTR_RESERVED); … … 7690 7755 HMVMX_CHECK_BREAK(pCtx->gs.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED, VMX_IGS_GS_ATTR_A_INVALID); 7691 7756 HMVMX_CHECK_BREAK(pCtx->gs.Attr.n.u1Present, VMX_IGS_GS_ATTR_P_INVALID); 7692 HMVMX_CHECK_BREAK(pCtx->gs.Attr.n.u4Type > 11 || pCtx->gs.Attr.n.u2Dpl >= (pCtx->gs.Sel & X86_SEL_RPL), 7693 VMX_IGS_GS_ATTR_DPL_RPL_UNEQUAL); 7757 HMVMX_CHECK_BREAK( pVM->hm.s.vmx.fUnrestrictedGuest 7758 || pCtx->gs.Attr.n.u4Type > 11 7759 || pCtx->gs.Attr.n.u2Dpl >= (pCtx->gs.Sel & X86_SEL_RPL), VMX_IGS_GS_ATTR_DPL_RPL_UNEQUAL); 7694 7760 HMVMX_CHECK_BREAK(!(pCtx->gs.Attr.u & 0xf00), VMX_IGS_GS_ATTR_RESERVED); 7695 7761 HMVMX_CHECK_BREAK(!(pCtx->gs.Attr.u & 0xfffe0000), VMX_IGS_GS_ATTR_RESERVED); … … 7719 7785 #endif 7720 7786 } 7721 else if ( CPUMIsGuestInV86ModeEx(pCtx) 7722 || ( CPUMIsGuestInRealModeEx(pCtx) 7723 && !pVM->hm.s.vmx.fUnrestrictedGuest)) 7724 { 7725 /* Real and v86 mode checks. */ 7787 else 7788 { 7789 /* V86 mode checks. */ 7726 7790 uint32_t u32CSAttr, u32SSAttr, u32DSAttr, u32ESAttr, u32FSAttr, u32GSAttr; 7727 7791 if (pVCpu->hm.s.vmx.RealMode.fRealOnV86Active) … … 7792 7856 } 7793 7857 #endif 7794 if ( pVCpu->hm.s.vmx.u32EntryCtls & VMX_VMCS_CTRL_ENTRY_IA32E_MODE_GUEST)7858 if (fLongModeGuest) 7795 7859 { 7796 7860 HMVMX_CHECK_BREAK(pCtx->tr.Attr.n.u4Type == 11, /* 64-bit busy TSS. */ … … 7835 7899 AssertRCBreak(rc); 7836 7900 HMVMX_CHECK_BREAK(!(u32Val & 0xffff0000), VMX_IGS_IDTR_LIMIT_INVALID); /* Bits 31:16 MBZ. */ 7837 7838 /*7839 * RIP and RFLAGS.7840 */7841 uint32_t u32EFlags;7842 #if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)7843 if (HMVMX_IS_64BIT_HOST_MODE())7844 {7845 rc = VMXReadVmcs64(VMX_VMCS_GUEST_RIP, &u64Val);7846 AssertRCBreak(rc);7847 /* pCtx->rip can be different than the one in the VMCS (e.g. run guest code and VM-exits that don't update it). */7848 if ( !(pVCpu->hm.s.vmx.u32EntryCtls & VMX_VMCS_CTRL_ENTRY_IA32E_MODE_GUEST)7849 || !pCtx->cs.Attr.n.u1Long)7850 {7851 HMVMX_CHECK_BREAK(!(u64Val & UINT64_C(0xffffffff00000000)), VMX_IGS_LONGMODE_RIP_INVALID);7852 }7853 /** @todo If the processor supports N < 64 linear-address bits, bits 63:N7854 * must be identical if the "IA32e mode guest" VM-entry control is 17855 * and CS.L is 1. No check applies if the CPU supports 647856 * linear-address bits. */7857 7858 /* Flags in pCtx can be different (real-on-v86 for instance). We are only concerned about the VMCS contents here. */7859 rc = VMXReadVmcs64(VMX_VMCS_GUEST_RFLAGS, &u64Val);7860 AssertRCBreak(rc);7861 HMVMX_CHECK_BREAK(!(u64Val & UINT64_C(0xffffffffffc08028)), /* Bit 63:22, Bit 15, 5, 3 MBZ. */7862 VMX_IGS_RFLAGS_RESERVED);7863 HMVMX_CHECK_BREAK((u64Val & X86_EFL_RA1_MASK), VMX_IGS_RFLAGS_RESERVED1); /* Bit 1 MB1. */7864 u32EFlags = u64Val;7865 }7866 else7867 #endif7868 {7869 rc = VMXReadVmcs32(VMX_VMCS_GUEST_RFLAGS, &u32EFlags);7870 AssertRCBreak(rc);7871 HMVMX_CHECK_BREAK(!(u32EFlags & 0xffc08028), VMX_IGS_RFLAGS_RESERVED); /* Bit 31:22, Bit 15, 5, 3 MBZ. */7872 HMVMX_CHECK_BREAK((u32EFlags & X86_EFL_RA1_MASK), VMX_IGS_RFLAGS_RESERVED1); /* Bit 1 MB1. */7873 }7874 7875 if ( (pVCpu->hm.s.vmx.u32EntryCtls & VMX_VMCS_CTRL_ENTRY_IA32E_MODE_GUEST)7876 || !(pCtx->cr0 & X86_CR0_PE))7877 {7878 HMVMX_CHECK_BREAK(!(u32EFlags & X86_EFL_VM), VMX_IGS_RFLAGS_VM_INVALID);7879 }7880 7881 uint32_t u32EntryInfo;7882 rc = VMXReadVmcs32(VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO, &u32EntryInfo);7883 AssertRCBreak(rc);7884 if ( VMX_ENTRY_INTERRUPTION_INFO_VALID(u32EntryInfo)7885 && VMX_ENTRY_INTERRUPTION_INFO_TYPE(u32EntryInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_EXT_INT)7886 {7887 HMVMX_CHECK_BREAK(u32Val & X86_EFL_IF, VMX_IGS_RFLAGS_IF_INVALID);7888 }7889 7901 7890 7902 /*
Note:
See TracChangeset
for help on using the changeset viewer.