VirtualBox

Changeset 47687 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 13, 2013 12:10:19 PM (11 years ago)
Author:
vboxsync
Message:

VMM/HMVMXR0: Added segment checks to hmR0VmxCheckGuestState() while using unrestricted execution.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r47683 r47687  
    74797479        HMVMX_CHECK_BREAK(!(u32Val & ~uZapCR0), VMX_IGS_CR0_FIXED0);
    74807480        if (   !fUnrestrictedGuest
    7481             && CPUMIsGuestPagingEnabledEx(pCtx)
    7482             && !CPUMIsGuestInProtectedMode(pVCpu))
     7481            && (u32Val & X86_CR0_PG)
     7482            && !(u32Val & X86_CR0_PE))
    74837483        {
    74847484            HMVMX_ERROR_BREAK(VMX_IGS_CR0_PG_PE_COMBO);
     
    75077507        uint64_t u64DebugCtlMsr = u64Val;
    75087508
     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
    75097568        /*
    75107569         * 64-bit checks.
     
    75137572        if (HMVMX_IS_64BIT_HOST_MODE())
    75147573        {
    7515             if (   (pVCpu->hm.s.vmx.u32EntryCtls & VMX_VMCS_CTRL_ENTRY_IA32E_MODE_GUEST)
     7574            if (   fLongModeGuest
    75167575                && !fUnrestrictedGuest)
    75177576            {
     
    75207579            }
    75217580
    7522             if (   !(pVCpu->hm.s.vmx.u32EntryCtls & VMX_VMCS_CTRL_ENTRY_IA32E_MODE_GUEST)
     7581            if (   !fLongModeGuest
    75237582                && (pCtx->cr4 & X86_CR4_PCIDE))
    75247583            {
     
    76007659        HMVMX_CHECK_BREAK(   (pCtx->ldtr.Attr.u & X86DESCATTR_UNUSABLE)
    76017660                          || !(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        {
    76077663            /* CS */
    76087664            HMVMX_CHECK_BREAK(pCtx->cs.Attr.n.u1Present, VMX_IGS_CS_ATTR_P_INVALID);
     
    76157671            /* CS cannot be loaded with NULL in protected mode. */
    76167672            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);
    76177674            if (pCtx->cs.Attr.n.u4Type == 9 || pCtx->cs.Attr.n.u4Type == 11)
    76187675                HMVMX_CHECK_BREAK(pCtx->cs.Attr.n.u2Dpl == pCtx->ss.Attr.n.u2Dpl, VMX_IGS_CS_SS_ATTR_DPL_UNEQUAL);
    76197676            else if (pCtx->cs.Attr.n.u4Type == 13 || pCtx->cs.Attr.n.u4Type == 15)
    76207677                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);
    76217680            else
    76227681                HMVMX_ERROR_BREAK(VMX_IGS_CS_ATTR_TYPE_INVALID);
     7682
    76237683            /* 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);
    76257686            HMVMX_CHECK_BREAK(pCtx->ss.Attr.n.u2Dpl == (pCtx->ss.Sel & X86_SEL_RPL), VMX_IGS_SS_ATTR_DPL_RPL_UNEQUAL);
    76267687            if (   !(pCtx->cr0 & X86_CR0_PE)
     
    76407701                                  || (pCtx->ss.Attr.n.u1Granularity), VMX_IGS_SS_ATTR_G_INVALID);
    76417702            }
     7703
    76427704            /* DS, ES, FS, GS - only check for usable selectors, see hmR0VmxWriteSegmentReg(). */
    76437705            if (!(pCtx->ds.Attr.u & X86DESCATTR_UNUSABLE))
     
    76457707                HMVMX_CHECK_BREAK(pCtx->ds.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED, VMX_IGS_DS_ATTR_A_INVALID);
    76467708                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);
    76497712                HMVMX_CHECK_BREAK(!(pCtx->ds.Attr.u & 0xf00), VMX_IGS_DS_ATTR_RESERVED);
    76507713                HMVMX_CHECK_BREAK(!(pCtx->ds.Attr.u & 0xfffe0000), VMX_IGS_DS_ATTR_RESERVED);
     
    76607723                HMVMX_CHECK_BREAK(pCtx->es.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED, VMX_IGS_ES_ATTR_A_INVALID);
    76617724                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);
    76647728                HMVMX_CHECK_BREAK(!(pCtx->es.Attr.u & 0xf00), VMX_IGS_ES_ATTR_RESERVED);
    76657729                HMVMX_CHECK_BREAK(!(pCtx->es.Attr.u & 0xfffe0000), VMX_IGS_ES_ATTR_RESERVED);
     
    76757739                HMVMX_CHECK_BREAK(pCtx->fs.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED, VMX_IGS_FS_ATTR_A_INVALID);
    76767740                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);
    76797744                HMVMX_CHECK_BREAK(!(pCtx->fs.Attr.u & 0xf00), VMX_IGS_FS_ATTR_RESERVED);
    76807745                HMVMX_CHECK_BREAK(!(pCtx->fs.Attr.u & 0xfffe0000), VMX_IGS_FS_ATTR_RESERVED);
     
    76907755                HMVMX_CHECK_BREAK(pCtx->gs.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED, VMX_IGS_GS_ATTR_A_INVALID);
    76917756                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);
    76947760                HMVMX_CHECK_BREAK(!(pCtx->gs.Attr.u & 0xf00), VMX_IGS_GS_ATTR_RESERVED);
    76957761                HMVMX_CHECK_BREAK(!(pCtx->gs.Attr.u & 0xfffe0000), VMX_IGS_GS_ATTR_RESERVED);
     
    77197785#endif
    77207786        }
    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. */
    77267790            uint32_t u32CSAttr, u32SSAttr, u32DSAttr, u32ESAttr, u32FSAttr, u32GSAttr;
    77277791            if (pVCpu->hm.s.vmx.RealMode.fRealOnV86Active)
     
    77927856        }
    77937857#endif
    7794         if (pVCpu->hm.s.vmx.u32EntryCtls & VMX_VMCS_CTRL_ENTRY_IA32E_MODE_GUEST)
     7858        if (fLongModeGuest)
    77957859        {
    77967860            HMVMX_CHECK_BREAK(pCtx->tr.Attr.n.u4Type == 11,           /* 64-bit busy TSS. */
     
    78357899        AssertRCBreak(rc);
    78367900        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:N
    7854              *        must be identical if the "IA32e mode guest" VM-entry control is 1
    7855              *        and CS.L is 1. No check applies if the CPU supports 64
    7856              *        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         else
    7867 #endif
    7868         {
    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         }
    78897901
    78907902        /*
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette