VirtualBox

Changeset 72306 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
May 23, 2018 5:42:46 PM (7 years ago)
Author:
vboxsync
Message:

NEM/win: Intercept and handle MSR accesses. bugref:9044

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/NEMAllNativeTemplate-win.cpp.h

    r72263 r72306  
    16061606
    16071607
     1608/**
     1609 * Deals with MSR intercept message.
     1610 *
     1611 * @returns Strict VBox status code.
     1612 * @param   pVCpu           The cross context per CPU structure.
     1613 * @param   pMsg            The message.
     1614 * @param   pCtx            The register context.
     1615 * @param   pGVCpu          The global (ring-0) per CPU structure (NULL in r3).
     1616 */
     1617NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinHandleMessageMsr(PVMCPU pVCpu, HV_X64_MSR_INTERCEPT_MESSAGE const *pMsg,
     1618                                                      PCPUMCTX pCtx, PGVMCPU pGVCpu)
     1619{
     1620    /*
     1621     * A wee bit of sanity first.
     1622     */
     1623    AssertMsg(pMsg->Header.InstructionLength < 0x10, ("%#x\n", pMsg->Header.InstructionLength));
     1624    Assert(   pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_READ
     1625           || pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE);
     1626
     1627    /*
     1628     * Check CPL as that's common to both RDMSR and WRMSR.
     1629     */
     1630    VBOXSTRICTRC rcStrict;
     1631    if (pMsg->Header.CsSegment.DescriptorPrivilegeLevel == 0)
     1632    {
     1633        /*
     1634         * Handle writes.
     1635         */
     1636        if (pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE)
     1637        {
     1638            rcStrict = CPUMSetGuestMsr(pVCpu, pMsg->MsrNummber, RT_MAKE_U64((uint32_t)pMsg->Rax, (uint32_t)pMsg->Rdx));
     1639            Log4(("MsrExit/%u: %04x:%08RX64: WRMSR %08x, %08x:%08x -> %Rrc\n",
     1640                  pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip,
     1641                  pMsg->MsrNummber, (uint32_t)pMsg->Rax, (uint32_t)pMsg->Rdx, VBOXSTRICTRC_VAL(rcStrict) ));
     1642            if (rcStrict == VINF_SUCCESS)
     1643            {
     1644                nemHCWinCopyStateFromX64Header(pVCpu, pCtx, &pMsg->Header);
     1645                nemHCWinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pMsg->Header);
     1646                return VINF_SUCCESS;
     1647            }
     1648#ifndef IN_RING3
     1649            /* move to ring-3 and handle the trap/whatever there, as we want to LogRel this. */
     1650            if (rcStrict == VERR_CPUM_RAISE_GP_0)
     1651                rcStrict = VINF_CPUM_R3_MSR_WRITE;
     1652            return rcStrict;
     1653#else
     1654            LogRel(("MsrExit/%u: %04x:%08RX64: WRMSR %08x, %08x:%08x -> %Rrc!\n",
     1655                    pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip,
     1656                    pMsg->MsrNummber, (uint32_t)pMsg->Rax, (uint32_t)pMsg->Rdx, VBOXSTRICTRC_VAL(rcStrict) ));
     1657#endif
     1658        }
     1659        /*
     1660         * Handle reads.
     1661         */
     1662        else
     1663        {
     1664            uint64_t uValue = 0;
     1665            rcStrict = CPUMQueryGuestMsr(pVCpu, pMsg->MsrNummber, &uValue);
     1666            Log4(("MsrExit/%u: %04x:%08RX64: RDMSR %08x -> %08RX64 / %Rrc\n", pVCpu->idCpu, pMsg->Header.CsSegment.Selector,
     1667                  pMsg->Header.Rip, pMsg->MsrNummber, uValue, VBOXSTRICTRC_VAL(rcStrict) ));
     1668            if (rcStrict == VINF_SUCCESS)
     1669            {
     1670                nemHCWinCopyStateFromX64Header(pVCpu, pCtx, &pMsg->Header);
     1671                nemHCWinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pMsg->Header);
     1672                return VINF_SUCCESS;
     1673            }
     1674#ifndef IN_RING3
     1675            /* move to ring-3 and handle the trap/whatever there, as we want to LogRel this. */
     1676            if (rcStrict == VERR_CPUM_RAISE_GP_0)
     1677                rcStrict = VINF_CPUM_R3_MSR_READ;
     1678            return rcStrict;
     1679#else
     1680            LogRel(("MsrExit/%u: %04x:%08RX64: RDMSR %08x -> %08RX64 / %Rrc\n", pVCpu->idCpu, pMsg->Header.CsSegment.Selector,
     1681                    pMsg->Header.Rip, pMsg->MsrNummber, uValue, VBOXSTRICTRC_VAL(rcStrict) ));
     1682#endif
     1683        }
     1684    }
     1685    else if (pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE)
     1686        Log4(("MsrExit/%u: CPL %u -> #GP(0); WRMSR %08x, %08x:%08x\n", pVCpu->idCpu,
     1687              pMsg->Header.CsSegment.DescriptorPrivilegeLevel, pMsg->MsrNummber, (uint32_t)pMsg->Rax, (uint32_t)pMsg->Rdx ));
     1688    else
     1689        Log4(("MsrExit/%u: CPL %u -> #GP(0); RDMSR %08x\n",
     1690              pVCpu->idCpu, pMsg->Header.CsSegment.DescriptorPrivilegeLevel, pMsg->MsrNummber));
     1691
     1692    /*
     1693     * If we get down here, we're supposed to #GP(0).
     1694     */
     1695    rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, pGVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "NMI");
     1696    if (rcStrict == VINF_SUCCESS)
     1697    {
     1698        rcStrict = IEMInjectTrap(pVCpu, X86_XCPT_GP, TRPM_TRAP, 0, 0, 0);
     1699        if (rcStrict == VINF_IEM_RAISED_XCPT)
     1700            rcStrict = VINF_SUCCESS;
     1701        else if (rcStrict != VINF_SUCCESS)
     1702            Log4(("MsrExit/%u: Injecting #GP(0) failed: %Rrc\n", VBOXSTRICTRC_VAL(rcStrict) ));
     1703    }
     1704    return rcStrict;
     1705}
    16081706
    16091707
     
    16861784                return nemHCWinHandleMessageCpuId(pVCpu, &pMsg->X64CpuIdIntercept, pCtx);
    16871785
     1786            case HvMessageTypeX64MsrIntercept:
     1787                Assert(pMsg->Header.PayloadSize == sizeof(pMsg->X64MsrIntercept));
     1788                return nemHCWinHandleMessageMsr(pVCpu, &pMsg->X64MsrIntercept, pCtx, pGVCpu);
     1789
    16881790            case HvMessageTypeUnrecoverableException:
    16891791                Assert(pMsg->Header.PayloadSize == sizeof(pMsg->X64InterceptHeader));
     
    16971799                                            VERR_INTERNAL_ERROR_2);
    16981800
    1699             case HvMessageTypeX64MsrIntercept:
    17001801            case HvMessageTypeX64ExceptionIntercept:
    17011802            case HvMessageTypeX64ApicEoi:
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r72300 r72306  
    746746    if (!pVM->nem.s.fExtendedCpuIdExit)
    747747        return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "Missing required extended CPUID exit support");
     748    if (!pVM->nem.s.fExtendedMsrExit)
     749        return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "Missing required extended MSR exit support");
    748750
    749751#undef NEM_LOG_REL_CAP_EX
     
    10491051        RT_ZERO(Property);
    10501052        Property.ExtendedVmExits.X64CpuidExit  = pVM->nem.s.fExtendedCpuIdExit; /** @todo Register fixed results and restrict cpuid exits */
     1053        Property.ExtendedVmExits.X64MsrExit    = pVM->nem.s.fExtendedMsrExit;
    10511054#if 0 /** @todo handle some MSRs too. */
    1052         Property.ExtendedVmExits.X64MsrExit    = pVM->nem.s.fExtendedMsrExit;
    10531055        Property.ExtendedVmExits.ExceptionExit = pVM->nem.s.fExtendedXcptExit;
    10541056#endif
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