VirtualBox

Changeset 96811 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Sep 21, 2022 1:23:31 PM (2 years ago)
Author:
vboxsync
Message:

VMM,IPRT,VBoxGuest,SUPDrv: Added a more efficient interface for guest logging using the CPUID instruction. This is mainly intended for development use and not enabled by default. Require updating host drivers.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r96745 r96811  
    59335933     * Check the input and figure out which mapping entry to use.
    59345934     */
    5935     Assert(cbMem <= 64 || cbMem == 512 || cbMem == 256 || cbMem == 108 || cbMem == 104 || cbMem == 102 || cbMem == 94); /* 512 is the max! */
     5935    Assert(cbMem <= sizeof(pVCpu->iem.s.aBounceBuffers[0]));
     5936    Assert(   cbMem <= 64 || cbMem == 512 || cbMem == 256 || cbMem == 108 || cbMem == 104 || cbMem == 102 || cbMem == 94
     5937           || (iSegReg == UINT8_MAX && uAlignCtl == 0 && fAccess == IEM_ACCESS_DATA_R /* for the CPUID logging interface */) );
    59365938    Assert(~(fAccess & ~(IEM_ACCESS_TYPE_MASK | IEM_ACCESS_WHAT_MASK)));
    59375939    Assert(pVCpu->iem.s.cActiveMappings < RT_ELEMENTS(pVCpu->iem.s.aMemMappings));
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp

    r96637 r96811  
    4848#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    4949# include <VBox/vmm/hmvmxinline.h>
     50#endif
     51#ifndef VBOX_WITHOUT_CPUID_HOST_CALL
     52# include <VBox/vmm/cpuidcall.h>
    5053#endif
    5154#include <VBox/vmm/tm.h>
     
    77557758
    77567759
     7760#ifndef VBOX_WITHOUT_CPUID_HOST_CALL
     7761/**
     7762 * Handles a CPUID call.
     7763 */
     7764static VBOXSTRICTRC iemCpuIdVBoxCall(PVMCPUCC pVCpu, uint32_t iFunction,
     7765                                     uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
     7766{
     7767    switch (iFunction)
     7768    {
     7769        case VBOX_CPUID_FN_ID:
     7770            LogFlow(("iemCpuIdVBoxCall: VBOX_CPUID_FN_ID\n"));
     7771            *pEax = VBOX_CPUID_RESP_ID_EAX;
     7772            *pEbx = VBOX_CPUID_RESP_ID_EBX;
     7773            *pEcx = VBOX_CPUID_RESP_ID_ECX;
     7774            *pEdx = VBOX_CPUID_RESP_ID_EDX;
     7775            break;
     7776
     7777        case VBOX_CPUID_FN_LOG:
     7778        {
     7779            CPUM_IMPORT_EXTRN_RET(pVCpu, CPUMCTX_EXTRN_RDX | CPUMCTX_EXTRN_RBX | CPUMCTX_EXTRN_RSI
     7780                                       | IEM_CPUMCTX_EXTRN_EXEC_DECODED_MEM_MASK);
     7781
     7782            /* Validate input. */
     7783            uint32_t cchToLog = *pEdx;
     7784            if (cchToLog <= _2M)
     7785            {
     7786                uint32_t const uLogPicker = *pEbx;
     7787                if (uLogPicker <= 1)
     7788                {
     7789                    /* Resolve the logger. */
     7790                    PRTLOGGER const pLogger = !uLogPicker
     7791                                            ? RTLogDefaultInstanceEx(UINT32_MAX) : RTLogRelGetDefaultInstanceEx(UINT32_MAX);
     7792                    if (pLogger)
     7793                    {
     7794                        /* Copy over the data: */
     7795                        RTGCPTR GCPtrSrc = pVCpu->cpum.GstCtx.rsi;
     7796                        while (cchToLog > 0)
     7797                        {
     7798                            uint32_t cbToMap = GUEST_PAGE_SIZE - (GCPtrSrc & GUEST_PAGE_OFFSET_MASK);
     7799                            if (cbToMap > cchToLog)
     7800                                cbToMap = cchToLog;
     7801                            /** @todo Extend iemMemMap to allowing page size accessing and avoid 7
     7802                             *        unnecessary calls & iterations per pages. */
     7803                            if (cbToMap > 512)
     7804                                cbToMap = 512;
     7805                            void        *pvSrc    = NULL;
     7806                            VBOXSTRICTRC rcStrict = iemMemMap(pVCpu, &pvSrc, cbToMap, UINT8_MAX, GCPtrSrc, IEM_ACCESS_DATA_R, 0);
     7807                            if (rcStrict == VINF_SUCCESS)
     7808                            {
     7809                                RTLogBulkNestedWrite(pLogger, (const char *)pvSrc, cbToMap, "Gst:");
     7810                                rcStrict = iemMemCommitAndUnmap(pVCpu, pvSrc, IEM_ACCESS_DATA_R);
     7811                                AssertRCSuccessReturn(VBOXSTRICTRC_VAL(rcStrict), rcStrict);
     7812                            }
     7813                            else
     7814                            {
     7815                                Log(("iemCpuIdVBoxCall: %Rrc at %RGp LB %#x\n", VBOXSTRICTRC_VAL(rcStrict), GCPtrSrc, cbToMap));
     7816                                return rcStrict;
     7817                            }
     7818
     7819                            /* Advance. */
     7820                            pVCpu->cpum.GstCtx.rsi = GCPtrSrc += cbToMap;
     7821                            *pEdx                  = cchToLog -= cbToMap;
     7822                        }
     7823                        *pEax = VINF_SUCCESS;
     7824                    }
     7825                    else
     7826                        *pEax = (uint32_t)VERR_NOT_FOUND;
     7827                }
     7828                else
     7829                    *pEax = (uint32_t)VERR_NOT_FOUND;
     7830            }
     7831            else
     7832                *pEax = (uint32_t)VERR_TOO_MUCH_DATA;
     7833            *pEdx = VBOX_CPUID_RESP_GEN_EDX;
     7834            *pEcx = VBOX_CPUID_RESP_GEN_ECX;
     7835            *pEbx = VBOX_CPUID_RESP_GEN_EBX;
     7836            break;
     7837        }
     7838
     7839        default:
     7840            LogFlow(("iemCpuIdVBoxCall: Invalid function %#x (%#x, %#x)\n", iFunction, *pEbx, *pEdx));
     7841            *pEax = (uint32_t)VERR_INVALID_FUNCTION;
     7842            *pEbx = (uint32_t)VERR_INVALID_FUNCTION;
     7843            *pEcx = (uint32_t)VERR_INVALID_FUNCTION;
     7844            *pEdx = (uint32_t)VERR_INVALID_FUNCTION;
     7845            break;
     7846    }
     7847    return VINF_SUCCESS;
     7848}
     7849#endif /* VBOX_WITHOUT_CPUID_HOST_CALL */
     7850
    77577851/**
    77587852 * Implements 'CPUID'.
     
    77737867    }
    77747868
    7775     CPUMGetGuestCpuId(pVCpu, pVCpu->cpum.GstCtx.eax, pVCpu->cpum.GstCtx.ecx, pVCpu->cpum.GstCtx.cs.Attr.n.u1Long,
    7776                       &pVCpu->cpum.GstCtx.eax, &pVCpu->cpum.GstCtx.ebx, &pVCpu->cpum.GstCtx.ecx, &pVCpu->cpum.GstCtx.edx);
     7869
     7870    uint32_t const uEax = pVCpu->cpum.GstCtx.eax;
     7871    uint32_t const uEcx = pVCpu->cpum.GstCtx.ecx;
     7872
     7873#ifndef VBOX_WITHOUT_CPUID_HOST_CALL
     7874    /*
     7875     * CPUID host call backdoor.
     7876     */
     7877    if (   uEax == VBOX_CPUID_REQ_EAX_FIXED
     7878        && (uEcx & VBOX_CPUID_REQ_ECX_FIXED_MASK) == VBOX_CPUID_REQ_ECX_FIXED
     7879        && pVCpu->CTX_SUFF(pVM)->iem.s.fCpuIdHostCall)
     7880    {
     7881        VBOXSTRICTRC rcStrict = iemCpuIdVBoxCall(pVCpu, uEcx & VBOX_CPUID_REQ_ECX_FN_MASK,
     7882                                                 &pVCpu->cpum.GstCtx.eax, &pVCpu->cpum.GstCtx.ebx,
     7883                                                 &pVCpu->cpum.GstCtx.ecx, &pVCpu->cpum.GstCtx.edx);
     7884        if (rcStrict != VINF_SUCCESS)
     7885            return rcStrict;
     7886    }
     7887    /*
     7888     * Regular CPUID.
     7889     */
     7890    else
     7891#endif
     7892        CPUMGetGuestCpuId(pVCpu, uEax, uEcx, pVCpu->cpum.GstCtx.cs.Attr.n.u1Long,
     7893                          &pVCpu->cpum.GstCtx.eax, &pVCpu->cpum.GstCtx.ebx, &pVCpu->cpum.GstCtx.ecx, &pVCpu->cpum.GstCtx.edx);
     7894
    77777895    pVCpu->cpum.GstCtx.rax &= UINT32_C(0xffffffff);
    77787896    pVCpu->cpum.GstCtx.rbx &= UINT32_C(0xffffffff);
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