VirtualBox

Changeset 72304 in vbox for trunk/src


Ignore:
Timestamp:
May 23, 2018 3:37:02 PM (7 years ago)
Author:
vboxsync
Message:

NEMR0/win: Handle HV_STATUS_INSUFFICIENT_MEMORY during page mapping. bugref:9044

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp

    r72300 r72304  
    417417     * Ring-3 is not allowed to fill in the host physical addresses of the call.
    418418     */
    419     HV_INPUT_MAP_GPA_PAGES *pMapPages = (HV_INPUT_MAP_GPA_PAGES *)pGVCpu->nem.s.HypercallData.pbPage;
    420     AssertPtrReturn(pMapPages, VERR_INTERNAL_ERROR_3);
    421     pMapPages->TargetPartitionId    = pGVM->nem.s.idHvPartition;
    422     pMapPages->TargetGpaBase        = GCPhysDst >> X86_PAGE_SHIFT;
    423     pMapPages->MapFlags             = fFlags;
    424     pMapPages->u32ExplicitPadding   = 0;
    425     for (uint32_t iPage = 0; iPage < cPages; iPage++, GCPhysSrc += X86_PAGE_SIZE)
    426     {
    427         RTHCPHYS HCPhys = NIL_RTGCPHYS;
    428         int rc = PGMPhysGCPhys2HCPhys(pVM, GCPhysSrc, &HCPhys);
    429         AssertRCReturn(rc, rc);
    430         pMapPages->PageList[iPage] = HCPhys >> X86_PAGE_SHIFT;
    431     }
    432 
    433     uint64_t uResult = g_pfnHvlInvokeHypercall(HvCallMapGpaPages | ((uint64_t)cPages << 32),
    434                                                pGVCpu->nem.s.HypercallData.HCPhysPage, 0);
    435     Log6(("NEMR0MapPages: %RGp/%RGp L %u prot %#x -> %#RX64\n",
    436           GCPhysDst, GCPhysSrc - cPages * X86_PAGE_SIZE, cPages, fFlags, uResult));
    437     if (uResult == ((uint64_t)cPages << 32))
    438         return VINF_SUCCESS;
    439 
    440     LogRel(("g_pfnHvlInvokeHypercall/MapGpaPages -> %#RX64\n", uResult));
    441     return VERR_NEM_MAP_PAGES_FAILED;
     419    for (uint32_t iTries = 0;; iTries++)
     420    {
     421        HV_INPUT_MAP_GPA_PAGES *pMapPages = (HV_INPUT_MAP_GPA_PAGES *)pGVCpu->nem.s.HypercallData.pbPage;
     422        AssertPtrReturn(pMapPages, VERR_INTERNAL_ERROR_3);
     423        pMapPages->TargetPartitionId    = pGVM->nem.s.idHvPartition;
     424        pMapPages->TargetGpaBase        = GCPhysDst >> X86_PAGE_SHIFT;
     425        pMapPages->MapFlags             = fFlags;
     426        pMapPages->u32ExplicitPadding   = 0;
     427        for (uint32_t iPage = 0; iPage < cPages; iPage++, GCPhysSrc += X86_PAGE_SIZE)
     428        {
     429            RTHCPHYS HCPhys = NIL_RTGCPHYS;
     430            int rc = PGMPhysGCPhys2HCPhys(pVM, GCPhysSrc, &HCPhys);
     431            AssertRCReturn(rc, rc);
     432            pMapPages->PageList[iPage] = HCPhys >> X86_PAGE_SHIFT;
     433        }
     434
     435        uint64_t uResult = g_pfnHvlInvokeHypercall(HvCallMapGpaPages | ((uint64_t)cPages << 32),
     436                                                   pGVCpu->nem.s.HypercallData.HCPhysPage, 0);
     437        Log6(("NEMR0MapPages: %RGp/%RGp L %u prot %#x -> %#RX64\n",
     438              GCPhysDst, GCPhysSrc - cPages * X86_PAGE_SIZE, cPages, fFlags, uResult));
     439        if (uResult == ((uint64_t)cPages << 32))
     440            return VINF_SUCCESS;
     441
     442        /*
     443         * If the partition is out of memory, try donate another 512 pages to
     444         * it (2MB).  VID.SYS does multiples of 512 pages, nothing smaller.
     445         */
     446        if (   uResult != HV_STATUS_INSUFFICIENT_MEMORY
     447            || iTries > 16
     448            || g_pfnWinHvDepositMemory == NULL)
     449        {
     450            LogRel(("g_pfnHvlInvokeHypercall/MapGpaPages -> %#RX64\n", uResult));
     451            return VERR_NEM_MAP_PAGES_FAILED;
     452        }
     453
     454        size_t cPagesAdded = 0;
     455        NTSTATUS rcNt = g_pfnWinHvDepositMemory(pGVM->nem.s.idHvPartition, 512, 0, &cPagesAdded);
     456        if (!cPagesAdded)
     457        {
     458            LogRel(("g_pfnWinHvDepositMemory -> %#x / %#RX64\n", rcNt, uResult));
     459            return VERR_NEM_MAP_PAGES_FAILED;
     460        }
     461    }
    442462}
    443463
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