VirtualBox

Changeset 24243 in vbox


Ignore:
Timestamp:
Nov 2, 2009 10:24:15 AM (15 years ago)
Author:
vboxsync
Message:

TPR patching for VT-x without VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC. Untested.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/HWACCM.cpp

    r23794 r24243  
    11051105                    LogRel(("HWACCM: enmFlushContext %d\n", pVM->hwaccm.s.vmx.enmFlushContext));
    11061106                }
     1107
     1108                /* TPR patching status logging. */
     1109                if (pVM->hwaccm.s.fTRPPatchingAllowed)
     1110                {
     1111                    if (    (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
     1112                        &&  (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC))
     1113                    {
     1114                        pVM->hwaccm.s.fTRPPatchingAllowed = false;  /* not necessary as we have a hardware solution. */
     1115                        LogRel(("HWACCM: TPR Patching not required (VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC).\n"));
     1116                    }
     1117                    else
     1118                    {
     1119                        /* TPR patching needs access to the MSR_K8_LSTAR msr. */
     1120                        if (!CPUMGetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_LONG_MODE))
     1121                        {
     1122                            pVM->hwaccm.s.fTRPPatchingAllowed = false;
     1123                            LogRel(("HWACCM: TPR patching disabled (long mode not supported).\n"));
     1124                        }
     1125                    }
     1126                }
     1127                LogRel(("HWACCM: TPR Patching %s.\n", (pVM->hwaccm.s.fTRPPatchingAllowed) ? "enabled" : "disabled"));
    11071128            }
    11081129            else
     
    14551476    pVM->hwaccm.s.pFreeGuestPatchMem     = 0;
    14561477    pVM->hwaccm.s.cbGuestPatchMem        = 0;
    1457     pVM->hwaccm.s.svm.cPatches           = 0;
    1458     pVM->hwaccm.s.svm.PatchTree          = 0;
    1459     pVM->hwaccm.s.svm.fTPRPatchingActive = false;
    1460     ASMMemZero32(pVM->hwaccm.s.svm.aPatches, sizeof(pVM->hwaccm.s.svm.aPatches));
     1478    pVM->hwaccm.s.cPatches           = 0;
     1479    pVM->hwaccm.s.PatchTree          = 0;
     1480    pVM->hwaccm.s.fTPRPatchingActive = false;
     1481    ASMMemZero32(pVM->hwaccm.s.aPatches, sizeof(pVM->hwaccm.s.aPatches));
    14611482}
    14621483
     
    14791500
    14801501    Log(("hwaccmR3RemovePatches\n"));
    1481     for (unsigned i = 0; i < pVM->hwaccm.s.svm.cPatches; i++)
     1502    for (unsigned i = 0; i < pVM->hwaccm.s.cPatches; i++)
    14821503    {
    14831504        uint8_t         szInstr[15];
    1484         PHWACCMTPRPATCH pPatch = &pVM->hwaccm.s.svm.aPatches[i];
     1505        PHWACCMTPRPATCH pPatch = &pVM->hwaccm.s.aPatches[i];
    14851506        RTGCPTR         pInstrGC = (RTGCPTR)pPatch->Core.Key;
    14861507        int             rc;
     
    15171538#endif
    15181539    }
    1519     pVM->hwaccm.s.svm.cPatches        = 0;
    1520     pVM->hwaccm.s.svm.PatchTree       = 0;
    1521     pVM->hwaccm.s.pFreeGuestPatchMem  = pVM->hwaccm.s.pGuestPatchMem;
    1522     pVM->hwaccm.s.svm.fTPRPatchingActive = false;
     1540    pVM->hwaccm.s.cPatches           = 0;
     1541    pVM->hwaccm.s.PatchTree          = 0;
     1542    pVM->hwaccm.s.pFreeGuestPatchMem = pVM->hwaccm.s.pGuestPatchMem;
     1543    pVM->hwaccm.s.fTPRPatchingActive = false;
    15231544    return VINF_SUCCESS;
    15241545}
     
    15551576{
    15561577    Log(("HWACMMR3EnablePatching %RGv size %x\n", pPatchMem, cbPatchMem));
    1557 
    1558     /* Current TPR patching only applies to AMD cpus.
    1559      * Needs to be extended to Intel CPUs without the APIC TPR hardware optimization.
    1560      */
    1561     if (CPUMGetHostCpuVendor(pVM) != CPUMCPUVENDOR_AMD)
    1562         return VERR_NOT_SUPPORTED;
    1563 
    15641578    if (pVM->cCpus > 1)
    15651579    {
     
    15951609    pVM->hwaccm.s.pFreeGuestPatchMem  = 0;
    15961610    pVM->hwaccm.s.cbGuestPatchMem     = 0;
    1597     pVM->hwaccm.s.svm.fTPRPatchingActive = false;
     1611    pVM->hwaccm.s.fTPRPatchingActive = false;
    15981612    return VINF_SUCCESS;
    15991613}
     
    16241638
    16251639    /* Two or more VCPUs were racing to patch this instruction. */
    1626     PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.svm.PatchTree, (AVLOU32KEY)pCtx->eip);
     1640    PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
    16271641    if (pPatch)
    16281642        return VINF_SUCCESS;
    16291643
    1630     Assert(pVM->hwaccm.s.svm.cPatches < RT_ELEMENTS(pVM->hwaccm.s.svm.aPatches));
     1644    Assert(pVM->hwaccm.s.cPatches < RT_ELEMENTS(pVM->hwaccm.s.aPatches));
    16311645
    16321646    int rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, &cbOp);
     
    16371651    {
    16381652        uint8_t         aVMMCall[3] = { 0xf, 0x1, 0xd9};
    1639         uint32_t        idx = pVM->hwaccm.s.svm.cPatches;
    1640         PHWACCMTPRPATCH pPatch = &pVM->hwaccm.s.svm.aPatches[idx];
     1653        uint32_t        idx = pVM->hwaccm.s.cPatches;
     1654        PHWACCMTPRPATCH pPatch = &pVM->hwaccm.s.aPatches[idx];
    16411655
    16421656        rc = PGMPhysSimpleReadGCPtr(pVCpu, pPatch->aOpcode, pCtx->rip, cbOp);
     
    16881702                &&  pDis->param2.flags == USE_IMMEDIATE8
    16891703                &&  pDis->param2.parval == 4
    1690                 &&  oldcbOp + cbOp < sizeof(pVM->hwaccm.s.svm.aPatches[idx].aOpcode))
     1704                &&  oldcbOp + cbOp < sizeof(pVM->hwaccm.s.aPatches[idx].aOpcode))
    16911705            {
    16921706                uint8_t szInstr[15];
     
    17291743
    17301744        pPatch->Core.Key = pCtx->eip;
    1731         rc = RTAvloU32Insert(&pVM->hwaccm.s.svm.PatchTree, &pPatch->Core);
     1745        rc = RTAvloU32Insert(&pVM->hwaccm.s.PatchTree, &pPatch->Core);
    17321746        AssertRC(rc);
    17331747
    1734         pVM->hwaccm.s.svm.cPatches++;
     1748        pVM->hwaccm.s.cPatches++;
    17351749        STAM_COUNTER_INC(&pVM->hwaccm.s.StatTPRReplaceSuccess);
    17361750        return VINF_SUCCESS;
     
    17381752
    17391753    /* Save invalid patch, so we will not try again. */
    1740     uint32_t  idx = pVM->hwaccm.s.svm.cPatches;
     1754    uint32_t  idx = pVM->hwaccm.s.cPatches;
    17411755
    17421756#ifdef LOG_ENABLED
     
    17471761#endif
    17481762
    1749     pPatch = &pVM->hwaccm.s.svm.aPatches[idx];
     1763    pPatch = &pVM->hwaccm.s.aPatches[idx];
    17501764    pPatch->Core.Key = pCtx->eip;
    17511765    pPatch->enmType  = HWACCMTPRINSTR_INVALID;
    1752     rc = RTAvloU32Insert(&pVM->hwaccm.s.svm.PatchTree, &pPatch->Core);
     1766    rc = RTAvloU32Insert(&pVM->hwaccm.s.PatchTree, &pPatch->Core);
    17531767    AssertRC(rc);
    1754     pVM->hwaccm.s.svm.cPatches++;
     1768    pVM->hwaccm.s.cPatches++;
    17551769    STAM_COUNTER_INC(&pVM->hwaccm.s.StatTPRReplaceFailure);
    17561770    return VINF_SUCCESS;
     
    17821796        return VINF_SUCCESS;
    17831797
    1784     Assert(pVM->hwaccm.s.svm.cPatches < RT_ELEMENTS(pVM->hwaccm.s.svm.aPatches));
     1798    Assert(pVM->hwaccm.s.cPatches < RT_ELEMENTS(pVM->hwaccm.s.aPatches));
    17851799
    17861800    /* Two or more VCPUs were racing to patch this instruction. */
    1787     PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.svm.PatchTree, (AVLOU32KEY)pCtx->eip);
     1801    PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
    17881802    if (pPatch)
    17891803    {
     
    18001814        &&  cbOp >= 5)
    18011815    {
    1802         uint32_t        idx = pVM->hwaccm.s.svm.cPatches;
    1803         PHWACCMTPRPATCH pPatch = &pVM->hwaccm.s.svm.aPatches[idx];
     1816        uint32_t        idx = pVM->hwaccm.s.cPatches;
     1817        PHWACCMTPRPATCH pPatch = &pVM->hwaccm.s.aPatches[idx];
    18041818        uint8_t         aPatch[64];
    18051819        uint32_t        off = 0;
     
    19631977
    19641978            pPatch->Core.Key = pCtx->eip;
    1965             rc = RTAvloU32Insert(&pVM->hwaccm.s.svm.PatchTree, &pPatch->Core);
     1979            rc = RTAvloU32Insert(&pVM->hwaccm.s.PatchTree, &pPatch->Core);
    19661980            AssertRC(rc);
    19671981
    1968             pVM->hwaccm.s.svm.cPatches++;
    1969             pVM->hwaccm.s.svm.fTPRPatchingActive = true;
     1982            pVM->hwaccm.s.cPatches++;
     1983            pVM->hwaccm.s.fTPRPatchingActive = true;
    19701984            STAM_COUNTER_INC(&pVM->hwaccm.s.StatTPRPatchSuccess);
    19711985            return VINF_SUCCESS;
     
    19761990
    19771991    /* Save invalid patch, so we will not try again. */
    1978     uint32_t  idx = pVM->hwaccm.s.svm.cPatches;
     1992    uint32_t  idx = pVM->hwaccm.s.cPatches;
    19791993
    19801994#ifdef LOG_ENABLED
     
    19841998#endif
    19851999
    1986     pPatch = &pVM->hwaccm.s.svm.aPatches[idx];
     2000    pPatch = &pVM->hwaccm.s.aPatches[idx];
    19872001    pPatch->Core.Key = pCtx->eip;
    19882002    pPatch->enmType  = HWACCMTPRINSTR_INVALID;
    1989     rc = RTAvloU32Insert(&pVM->hwaccm.s.svm.PatchTree, &pPatch->Core);
     2003    rc = RTAvloU32Insert(&pVM->hwaccm.s.PatchTree, &pPatch->Core);
    19902004    AssertRC(rc);
    1991     pVM->hwaccm.s.svm.cPatches++;
     2005    pVM->hwaccm.s.cPatches++;
    19922006    STAM_COUNTER_INC(&pVM->hwaccm.s.StatTPRPatchFailure);
    19932007    return VINF_SUCCESS;
     
    24202434
    24212435    /* Store all the guest patch records too. */
    2422     rc = SSMR3PutU32(pSSM, pVM->hwaccm.s.svm.cPatches);
     2436    rc = SSMR3PutU32(pSSM, pVM->hwaccm.s.cPatches);
    24232437    AssertRCReturn(rc, rc);
    24242438
    2425     for (unsigned i = 0; i < pVM->hwaccm.s.svm.cPatches; i++)
    2426     {
    2427         PHWACCMTPRPATCH pPatch = &pVM->hwaccm.s.svm.aPatches[i];
     2439    for (unsigned i = 0; i < pVM->hwaccm.s.cPatches; i++)
     2440    {
     2441        PHWACCMTPRPATCH pPatch = &pVM->hwaccm.s.aPatches[i];
    24282442
    24292443        rc = SSMR3PutU32(pSSM, pPatch->Core.Key);
     
    25252539
    25262540        /* Fetch all TPR patch records. */
    2527         rc = SSMR3GetU32(pSSM, &pVM->hwaccm.s.svm.cPatches);
     2541        rc = SSMR3GetU32(pSSM, &pVM->hwaccm.s.cPatches);
    25282542        AssertRCReturn(rc, rc);
    25292543
    2530         for (unsigned i = 0; i < pVM->hwaccm.s.svm.cPatches; i++)
    2531         {
    2532             PHWACCMTPRPATCH pPatch = &pVM->hwaccm.s.svm.aPatches[i];
     2544        for (unsigned i = 0; i < pVM->hwaccm.s.cPatches; i++)
     2545        {
     2546            PHWACCMTPRPATCH pPatch = &pVM->hwaccm.s.aPatches[i];
    25332547
    25342548            rc = SSMR3GetU32(pSSM, &pPatch->Core.Key);
     
    25512565
    25522566            if (pPatch->enmType == HWACCMTPRINSTR_JUMP_REPLACEMENT)
    2553                 pVM->hwaccm.s.svm.fTPRPatchingActive = true;
    2554 
    2555             Assert(pPatch->enmType == HWACCMTPRINSTR_JUMP_REPLACEMENT || pVM->hwaccm.s.svm.fTPRPatchingActive == false);
     2567                pVM->hwaccm.s.fTPRPatchingActive = true;
     2568
     2569            Assert(pPatch->enmType == HWACCMTPRINSTR_JUMP_REPLACEMENT || pVM->hwaccm.s.fTPRPatchingActive == false);
    25562570
    25572571            rc = SSMR3GetU32(pSSM, &pPatch->uSrcOperand);
     
    25762590            Log(("cFaults   = %d\n", pPatch->cFaults));
    25772591            Log(("target    = %x\n", pPatch->pJumpTarget));
    2578             rc = RTAvloU32Insert(&pVM->hwaccm.s.svm.PatchTree, &pPatch->Core);
     2592            rc = RTAvloU32Insert(&pVM->hwaccm.s.PatchTree, &pPatch->Core);
    25792593            AssertRC(rc);
    25802594        }
  • trunk/src/VBox/VMM/HWACCMInternal.h

    r23699 r24243  
    269269    bool                        fGlobalInit;
    270270
     271    /** Set when TPR patching is active. */
     272    bool                        fTPRPatchingActive;
     273    bool                        u8Alignment[7];
     274
    271275    /** And mask for copying register contents. */
    272276    uint64_t                    u64RegisterMask;
     
    402406        /** Set if erratum 170 affects the AMD cpu. */
    403407        bool                        fAlwaysFlushTLB;
    404         /** Set when TPR patching is active. */
    405         bool                        fTPRPatchingActive;
     408        bool                        u8Alignment;
    406409
    407410        /** R0 memory object for the IO bitmap (12kb). */
     
    417420        /** SVM feature bits from cpuid 0x8000000a */
    418421        uint32_t                    u32Features;
    419 
    420         /**
    421          * AVL tree with all patches (active or disabled) sorted by guest instruction address
    422          */
    423         AVLOU32TREE                 PatchTree;
    424         uint32_t                    cPatches;
    425         HWACCMTPRPATCH              aPatches[64];
    426422    } svm;
     423
     424    /**
     425     * AVL tree with all patches (active or disabled) sorted by guest instruction address
     426     */
     427    AVLOU32TREE                     PatchTree;
     428    uint32_t                        cPatches;
     429    HWACCMTPRPATCH                  aPatches[64];
    427430
    428431    struct
     
    437440    /** HWACCMR0Init was run */
    438441    bool                    fHWACCMR0Init;
    439     bool                    u8Alignment[7];
     442    bool                    u8Alignment1[7];
    440443
    441444    STAMCOUNTER             StatTPRPatchSuccess;
  • trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp

    r24216 r24243  
    10951095        AssertRC(rc);
    10961096
    1097         if (pVM->hwaccm.s.svm.fTPRPatchingActive)
     1097        if (pVM->hwaccm.s.fTPRPatchingActive)
    10981098        {
    10991099            /* Our patch code uses LSTAR for TPR caching. */
     
    15191519    if (fSyncTPR)
    15201520    {
    1521         if (pVM->hwaccm.s.svm.fTPRPatchingActive)
     1521        if (pVM->hwaccm.s.fTPRPatchingActive)
    15221522        {
    15231523            if ((pCtx->msrLSTAR & 0xff) != u8LastTPR)
     
    16551655                &&  CPUMGetGuestCPL(pVCpu, CPUMCTX2CORE(pCtx)) == 0
    16561656                &&  !CPUMIsGuestInLongModeEx(pCtx)
    1657                 &&  pVM->hwaccm.s.svm.cPatches < RT_ELEMENTS(pVM->hwaccm.s.svm.aPatches))
     1657                &&  pVM->hwaccm.s.cPatches < RT_ELEMENTS(pVM->hwaccm.s.aPatches))
    16581658            {
    16591659                RTGCPHYS GCPhysApicBase, GCPhys;
     
    16661666                {
    16671667                    /* Only attempt to patch the instruction once. */
    1668                     PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.svm.PatchTree, (AVLOU32KEY)pCtx->eip);
     1668                    PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
    16691669                    if (!pPatch)
    16701670                    {
     
    18231823            &&  CPUMGetGuestCPL(pVCpu, CPUMCTX2CORE(pCtx)) == 0
    18241824            &&  !CPUMIsGuestInLongModeEx(pCtx)
    1825             &&  pVM->hwaccm.s.svm.cPatches < RT_ELEMENTS(pVM->hwaccm.s.svm.aPatches))
     1825            &&  pVM->hwaccm.s.cPatches < RT_ELEMENTS(pVM->hwaccm.s.aPatches))
    18261826        {
    18271827            RTGCPHYS GCPhysApicBase;
     
    18321832            {
    18331833                /* Only attempt to patch the instruction once. */
    1834                 PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.svm.PatchTree, (AVLOU32KEY)pCtx->eip);
     1834                PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
    18351835                if (!pPatch)
    18361836                {
     
    23802380
    23812381        /* When an interrupt is pending, we'll let MSR_K8_LSTAR writes fault in our TPR patch code. */
    2382         if (    pVM->hwaccm.s.svm.fTPRPatchingActive
     2382        if (    pVM->hwaccm.s.fTPRPatchingActive
    23832383            &&  pCtx->ecx == MSR_K8_LSTAR
    23842384            &&  pVMCB->ctrl.u64ExitInfo1 == 1 /* wrmsr */)
     
    25292529        uint8_t u8Tpr;
    25302530
    2531         PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.svm.PatchTree, (AVLOU32KEY)pCtx->eip);
     2531        PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
    25322532        if (!pPatch)
    25332533            break;
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r24216 r24243  
    22782278    /* Check if we need to use TPR shadowing. */
    22792279    if (    CPUMIsGuestInLongModeEx(pCtx)
    2280         || (   (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC)
     2280        || (   ((pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC) || pVM->hwaccm.s.fTRPPatchingAllowed)
    22812281            &&  pVM->hwaccm.s.fHasIoApic)
    22822282       )
     
    24902490        rc  = VMXWriteVMCS(VMX_VMCS_CTRL_TPR_THRESHOLD, (fPending) ? (u8LastTPR >> 4) : 0);     /* cr8 bits 3-0 correspond to bits 7-4 of the task priority mmio register. */
    24912491        AssertRC(rc);
     2492
     2493        if (pVM->hwaccm.s.fTPRPatchingActive)
     2494        {
     2495            Assert(!CPUMIsGuestInLongModeEx(pCtx));
     2496            /* Our patch code uses LSTAR for TPR caching. */
     2497            pCtx->msrLSTAR = u8LastTPR;
     2498
     2499            if (fPending)
     2500                /* A TPR change could activate a pending interrupt, so catch lstar writes. */
     2501                vmxR0SetMSRPermission(pVCpu, MSR_K8_LSTAR, true, false);
     2502            else
     2503                /* No interrupts are pending, so we don't need to be explicitely notified.
     2504                 * There are enough world switches for detecting pending interrupts.
     2505                 */
     2506                vmxR0SetMSRPermission(pVCpu, MSR_K8_LSTAR, true, true);
     2507        }
    24922508    }
    24932509
     
    26982714
    26992715    /* Sync back the TPR if it was changed. */
    2700     if (    fSetupTPRCaching
    2701         &&  u8LastTPR != pVCpu->hwaccm.s.vmx.pVAPIC[0x80])
    2702     {
    2703         rc = PDMApicSetTPR(pVCpu, pVCpu->hwaccm.s.vmx.pVAPIC[0x80]);
    2704         AssertRC(rc);
     2716    if (fSetupTPRCaching)
     2717    {
     2718        if (pVM->hwaccm.s.fTPRPatchingActive)
     2719        {
     2720            if ((pCtx->msrLSTAR & 0xff) != u8LastTPR)
     2721            {
     2722                /* Our patch code uses LSTAR for TPR caching. */
     2723                rc = PDMApicSetTPR(pVCpu, pCtx->msrLSTAR & 0xff);
     2724                AssertRC(rc);
     2725            }
     2726        }
     2727        else
     2728        if (u8LastTPR != pVCpu->hwaccm.s.vmx.pVAPIC[0x80])
     2729        {
     2730            rc = PDMApicSetTPR(pVCpu, pVCpu->hwaccm.s.vmx.pVAPIC[0x80]);
     2731            AssertRC(rc);
     2732        }
    27052733    }
    27062734
     
    27942822#endif
    27952823                Assert(!pVM->hwaccm.s.fNestedPaging);
     2824
     2825#ifdef VBOX_HWACCM_WITH_GUEST_PATCHING
     2826                /* Shortcut for APIC TPR reads and writes; 32 bits guests only */
     2827                if (    pVM->hwaccm.s.fTRPPatchingAllowed
     2828                    &&  pVM->hwaccm.s.pGuestPatchMem
     2829                    &&  (exitQualification & 0xfff) == 0x080
     2830                    &&  !(errCode & X86_TRAP_PF_P)  /* not present */
     2831                    &&  CPUMGetGuestCPL(pVCpu, CPUMCTX2CORE(pCtx)) == 0
     2832                    &&  !CPUMIsGuestInLongModeEx(pCtx)
     2833                    &&  pVM->hwaccm.s.cPatches < RT_ELEMENTS(pVM->hwaccm.s.aPatches))
     2834                {
     2835                    RTGCPHYS GCPhysApicBase, GCPhys;
     2836                    PDMApicGetBase(pVM, &GCPhysApicBase);   /* @todo cache this */
     2837                    GCPhysApicBase &= PAGE_BASE_GC_MASK;
     2838
     2839                    rc = PGMGstGetPage(pVCpu, (RTGCPTR)exitQualification, NULL, &GCPhys);
     2840                    if (    rc == VINF_SUCCESS
     2841                        &&  GCPhys == GCPhysApicBase)
     2842                    {
     2843                        /* Only attempt to patch the instruction once. */
     2844                        PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
     2845                        if (!pPatch)
     2846                        {
     2847                            rc = VINF_EM_HWACCM_PATCH_TPR_INSTR;
     2848                            break;
     2849                        }
     2850                    }
     2851                }
     2852#endif
    27962853
    27972854                Log2(("Page fault at %RGv error code %x\n", exitQualification, errCode));
     
    34273484    }
    34283485
     3486    case VMX_EXIT_WRMSR:                /* 32 WRMSR. Guest software attempted to execute WRMSR. */
     3487        /* When an interrupt is pending, we'll let MSR_K8_LSTAR writes fault in our TPR patch code. */
     3488        if (    pVM->hwaccm.s.fTPRPatchingActive
     3489            &&  pCtx->ecx == MSR_K8_LSTAR)
     3490        {
     3491            Assert(!CPUMIsGuestInLongModeEx(pCtx));
     3492            if ((pCtx->eax & 0xff) != u8LastTPR)
     3493            {
     3494                Log(("VMX: Faulting MSR_K8_LSTAR write with new TPR value %x\n", pCtx->eax & 0xff));
     3495
     3496                /* Our patch code uses LSTAR for TPR caching. */
     3497                rc = PDMApicSetTPR(pVCpu, pCtx->eax & 0xff);
     3498                AssertRC(rc);
     3499            }
     3500
     3501            /* Skip the instruction and continue. */
     3502            pCtx->rip += cbInstr;     /* wrmsr = [0F 30] */
     3503
     3504            /* Only resume if successful. */
     3505            STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit1, x);
     3506            goto ResumeExecution;
     3507        }
     3508        /* no break */
    34293509    case VMX_EXIT_RDMSR:                /* 31 RDMSR. Guest software attempted to execute RDMSR. */
    3430     case VMX_EXIT_WRMSR:                /* 32 WRMSR. Guest software attempted to execute WRMSR. */
    34313510    {
    34323511        uint32_t cbSize;
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