VirtualBox

Changeset 72262 in vbox


Ignore:
Timestamp:
May 18, 2018 2:10:08 PM (7 years ago)
Author:
vboxsync
Message:

NEM/win: Intercept all (for now) CPUIDs. bugref:9044

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/nt/hyperv.h

    r72253 r72262  
    13551355
    13561356
     1357/**
     1358 * The payload format for HvMessageTypeX64CpuidIntercept,
     1359 *
     1360 * @note This message does not include HV_X64_INTERCEPT_MESSAGE_HEADER!
     1361 */
     1362typedef struct
     1363{
     1364    HV_X64_INTERCEPT_MESSAGE_HEADER     Header;                 /**< 0x00: The usual intercept header. */
     1365    uint64_t                            Rax;                    /**< 0x28: Input RAX. */
     1366    uint64_t                            Rcx;                    /**< 0x30: Input RCX. */
     1367    uint64_t                            Rdx;                    /**< 0x38: Input RDX. */
     1368    uint64_t                            Rbx;                    /**< 0x40: Input RBX. */
     1369    uint64_t                            DefaultResultRax;       /**< 0x48: Default result RAX. */
     1370    uint64_t                            DefaultResultRcx;       /**< 0x50: Default result RCX. */
     1371    uint64_t                            DefaultResultRdx;       /**< 0x58: Default result RDX. */
     1372    uint64_t                            DefaultResultRbx;       /**< 0x60: Default result RBX. */
     1373} HV_X64_CPUID_INTERCEPT_MESSAGE;
     1374AssertCompileSize(HV_X64_CPUID_INTERCEPT_MESSAGE, 0x68);
     1375/** Pointer to a HvMessageTypeX64CpuidIntercept payload. */
     1376typedef HV_X64_CPUID_INTERCEPT_MESSAGE *PHV_X64_CPUID_INTERCEPT_MESSAGE;
     1377/** Pointer to a const HvMessageTypeX64CpuidIntercept payload. */
     1378typedef HV_X64_CPUID_INTERCEPT_MESSAGE const *PCHV_X64_CPUID_INTERCEPT_MESSAGE;
     1379
     1380/** Full HvMessageTypeX64CpuidIntercept message. */
     1381typedef struct
     1382{
     1383    HV_MESSAGE_HEADER                   MsgHdr;
     1384    HV_X64_CPUID_INTERCEPT_MESSAGE      Payload;
     1385} HV_X64_CPUID_INTERCEPT_MESSAGE_FULL;
     1386
     1387
    13571388/** X64 exception information (HvMessageTypeX64ExceptionIntercept).
    13581389 * @sa WHV_VP_EXCEPTION_INFO */
     
    14771508        /** HvMessageTypeX64IoPortIntercept */
    14781509        HV_X64_IO_PORT_INTERCEPT_MESSAGE    X64IoPortIntercept;
     1510        /** HvMessageTypeX64CpuidIntercept */
     1511        HV_X64_CPUID_INTERCEPT_MESSAGE      X64CpuIdIntercept;
    14791512        /** HvMessageTypeX64ExceptionIntercept */
    14801513        HV_X64_EXCEPTION_INTERCEPT_MESSAGE  X64ExceptionIntercept;
  • trunk/src/VBox/VMM/VMMAll/NEMAllNativeTemplate-win.cpp.h

    r72255 r72262  
    14221422
    14231423    /*
    1424      * Whatever we do, we must clear pending event ejection upon resume.
     1424     * Whatever we do, we must clear pending event injection upon resume.
    14251425     */
    14261426    if (pMsg->Header.ExecutionState.InterruptionPending)
     
    15621562
    15631563/**
     1564 * Deals with CPUID intercept message.
     1565 *
     1566 * @returns Strict VBox status code.
     1567 * @param   pVCpu           The cross context per CPU structure.
     1568 * @param   pMsg            The message.
     1569 * @param   pCtx            The register context.
     1570 */
     1571NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinHandleMessageCpuId(PVMCPU pVCpu, HV_X64_CPUID_INTERCEPT_MESSAGE const *pMsg, PCPUMCTX pCtx)
     1572{
     1573    //Assert(   pMsg->AccessInfo.AccessSize == 1
     1574    //       || pMsg->AccessInfo.AccessSize == 2
     1575    //       || pMsg->AccessInfo.AccessSize == 4);
     1576    //Assert(   pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_READ
     1577    //       || pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE);
     1578    AssertMsg(pMsg->Header.InstructionLength < 0x10, ("%#x\n", pMsg->Header.InstructionLength));
     1579
     1580    /*
     1581     * Soak up state and execute the instruction.
     1582     *
     1583     * Note! If this grows slightly more complicated, combine into an IEMExecDecodedCpuId
     1584     *       function and make everyone use it.
     1585     */
     1586    /** @todo Combine implementations into IEMExecDecodedCpuId as this will
     1587     *        only get weirder with nested VT-x and AMD-V support. */
     1588    nemHCWinCopyStateFromX64Header(pVCpu, pCtx, &pMsg->Header);
     1589
     1590    /* Copy in the low register values (top is always cleared). */
     1591    pCtx->rax = (uint32_t)pMsg->Rax;
     1592    pCtx->rcx = (uint32_t)pMsg->Rcx;
     1593    pCtx->rdx = (uint32_t)pMsg->Rdx;
     1594    pCtx->rbx = (uint32_t)pMsg->Rbx;
     1595    pCtx->fExtrn &= ~(CPUMCTX_EXTRN_RAX | CPUMCTX_EXTRN_RCX | CPUMCTX_EXTRN_RDX | CPUMCTX_EXTRN_RBX);
     1596
     1597    /* Get the correct values. */
     1598    CPUMGetGuestCpuId(pVCpu, pCtx->eax, pCtx->ecx, &pCtx->eax, &pCtx->ebx, &pCtx->ecx, &pCtx->edx);
     1599
     1600    Log4(("CpuIdExit/%u: %04x:%08RX64: rax=%08RX64 / rcx=%08RX64 / rdx=%08RX64 / rbx=%08RX64 -> %08RX32 / %08RX32 / %08RX32 / %08RX32 (hv: %08RX64 / %08RX64 / %08RX64 / %08RX64)\n",
     1601          pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip,
     1602          pMsg->Rax,                           pMsg->Rcx,              pMsg->Rdx,              pMsg->Rbx,
     1603          pCtx->eax,                           pCtx->ecx,              pCtx->edx,              pCtx->ebx,
     1604          pMsg->DefaultResultRax, pMsg->DefaultResultRcx, pMsg->DefaultResultRdx, pMsg->DefaultResultRbx));
     1605
     1606    /* Move RIP and we're done. */
     1607    nemHCWinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pMsg->Header);
     1608
     1609    return VINF_SUCCESS;
     1610}
     1611
     1612
     1613
     1614
     1615/**
    15641616 * Deals with unrecoverable exception (triple fault).
    15651617 *
     
    16351687                return nemHCWinHandleMessageInterruptWindow(pVM, pVCpu, &pMsg->X64InterruptWindow, pCtx, pGVCpu);
    16361688
     1689            case HvMessageTypeX64CpuidIntercept:
     1690                Assert(pMsg->Header.PayloadSize == sizeof(pMsg->X64CpuIdIntercept));
     1691                return nemHCWinHandleMessageCpuId(pVCpu, &pMsg->X64CpuIdIntercept, pCtx);
     1692
    16371693            case HvMessageTypeUnrecoverableException:
    16381694                Assert(pMsg->Header.PayloadSize == sizeof(pMsg->X64InterceptHeader));
     
    16471703
    16481704            case HvMessageTypeX64MsrIntercept:
    1649             case HvMessageTypeX64CpuidIntercept:
    16501705            case HvMessageTypeX64ExceptionIntercept:
    16511706            case HvMessageTypeX64ApicEoi:
     
    16571712            case HvMessageTimerExpired:
    16581713                LogRel(("Unexpected msg:\n%.*Rhxd\n", (int)sizeof(*pMsg), pMsg));
    1659                 AssertLogRelMsgFailedReturn(("Unexpected message on CPU #%u: #x\n", pVCpu->idCpu, pMsg->Header.MessageType),
     1714                AssertLogRelMsgFailedReturn(("Unexpected message on CPU #%u: %#x\n", pVCpu->idCpu, pMsg->Header.MessageType),
    16601715                                            VERR_INTERNAL_ERROR_2);
    16611716
    16621717            default:
    16631718                LogRel(("Unknown msg:\n%.*Rhxd\n", (int)sizeof(*pMsg), pMsg));
    1664                 AssertLogRelMsgFailedReturn(("Unknown message on CPU #%u: #x\n", pVCpu->idCpu, pMsg->Header.MessageType),
     1719                AssertLogRelMsgFailedReturn(("Unknown message on CPU #%u: %#x\n", pVCpu->idCpu, pMsg->Header.MessageType),
    16651720                                            VERR_INTERNAL_ERROR_2);
    16661721        }
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r72252 r72262  
    8181typedef HRESULT (WINAPI *PFNWHVGETCAPABILITY_17110)(WHV_CAPABILITY_CODE, void *, uint32_t, uint32_t *);
    8282typedef HRESULT (WINAPI *PFNWHVSETPARTITIONPROPERTY_17110)(WHV_PARTITION_HANDLE, WHV_PARTITION_PROPERTY_CODE, void *, uint32_t);
     83# define WHvCapabilityCodeExceptionExitBitmap ((WHV_CAPABILITY_CODE)0x00000003)
    8384#endif
    8485
     
    622623        LogRel(("NEM: Warning! Unknown feature definitions: %#RX64\n", Caps.Features.AsUINT64));
    623624    /** @todo RECHECK: WHV_CAPABILITY_FEATURES typedef. */
     625
     626    /*
     627     * Check supported exception exit bitmap bits.
     628     * We don't currently require this, so we just log failure.
     629     */
     630    RT_ZERO(Caps);
     631    hrc = WHvGetCapabilityWrapper(WHvCapabilityCodeExceptionExitBitmap, &Caps, sizeof(Caps));
     632    if (SUCCEEDED(hrc))
     633        LogRel(("NEM: Warning! Supported exception exit bitmap: %#RX64\n", Caps.Features.AsUINT64));
     634    else
     635        LogRel(("NEM: Warning! WHvGetCapability/WHvCapabilityCodeExceptionExitBitmap failed: %Rhrc (Last=%#x/%u)",
     636                hrc, RTNtLastStatusValue(), RTNtLastErrorValue()));
    624637
    625638    /*
     
    747760    }
    748761
     762    /*
     763     * For proper operation, we require CPUID exits.
     764     */
     765    if (!pVM->nem.s.fExtendedCpuIdExit)
     766        return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "Missing required extended CPUID exit support");
     767
    749768#undef NEM_LOG_REL_CAP_EX
    750769#undef NEM_LOG_REL_CAP_SUB_EX
     
    10691088    {
    10701089        RT_ZERO(Property);
    1071 #if 0
    1072         Property.ExtendedVmExits.X64CpuidExit  = pVM->nem.s.fExtendedCpuIdExit;
     1090        Property.ExtendedVmExits.X64CpuidExit  = pVM->nem.s.fExtendedCpuIdExit; /** @todo Register fixed results and restrict cpuid exits */
     1091#if 0 /** @todo handle some MSRs too. */
    10731092        Property.ExtendedVmExits.X64MsrExit    = pVM->nem.s.fExtendedMsrExit;
    10741093        Property.ExtendedVmExits.ExceptionExit = pVM->nem.s.fExtendedXcptExit;
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