int hax_alloc_page_frame(uint8 flags, hax_memdesc_phys *memdesc) { PHYSICAL_ADDRESS low_addr, high_addr, skip_bytes; ULONG options; PMDL pmdl; // TODO: Support HAX_PAGE_ALLOC_BELOW_4G if (flags & HAX_PAGE_ALLOC_BELOW_4G) { hax_warning("%s: HAX_PAGE_ALLOC_BELOW_4G is ignored\n", __func__); } if (!memdesc) { hax_error("%s: memdesc == NULL\n", __func__); return -EINVAL; } low_addr.QuadPart = 0; high_addr.QuadPart = (int64)-1; skip_bytes.QuadPart = 0; // TODO: MM_ALLOCATE_NO_WAIT? options = MM_ALLOCATE_FULLY_REQUIRED; if (!(flags & HAX_PAGE_ALLOC_ZEROED)) { options |= MM_DONT_ZERO_ALLOCATION; } // This call may block pmdl = MmAllocatePagesForMdlEx(low_addr, high_addr, skip_bytes, PAGE_SIZE_4K, MmCached, options); if (!pmdl) { hax_error("%s: Failed to allocate 4KB of nonpaged memory\n", __func__); return -ENOMEM; } memdesc->pmdl = pmdl; return 0; }
PMDL Ext_AllocateInnerMdl(PMDL pSourceMdl) { PHYSICAL_ADDRESS LowAddress, HighAddress, SkipBytes; LowAddress.QuadPart = 0; HighAddress.QuadPart = 0xFFFFFFFFFFFFFFFF; SkipBytes.QuadPart = 0; PMDL pNewMdl = MmAllocatePagesForMdlEx(LowAddress, HighAddress, SkipBytes, pSourceMdl->ByteCount, MmCached, MM_DONT_ZERO_ALLOCATION); pNewMdl->Next = pSourceMdl; return pNewMdl; }
VOID BalloonFill( IN WDFOBJECT WdfDevice, IN size_t num) { PDEVICE_CONTEXT ctx = GetDeviceContext(WdfDevice); PHYSICAL_ADDRESS LowAddress; PHYSICAL_ADDRESS HighAddress; PHYSICAL_ADDRESS SkipBytes; PPAGE_LIST_ENTRY pNewPageListEntry; PMDL pPageMdl; TraceEvents(TRACE_LEVEL_VERBOSE, DBG_HW_ACCESS, "--> %s\n", __FUNCTION__); ctx->num_pfns = 0; if (IsLowMemory(WdfDevice)) { TraceEvents(TRACE_LEVEL_WARNING, DBG_HW_ACCESS, "Low memory. Allocated pages: %d\n", ctx->num_pages); return; } num = min(num, PAGE_SIZE / sizeof(PFN_NUMBER)); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "Inflate balloon with %d pages.\n", num); LowAddress.QuadPart = 0; HighAddress.QuadPart = (ULONGLONG)-1; SkipBytes.QuadPart = 0; #if (NTDDI_VERSION < NTDDI_WS03SP1) pPageMdl = MmAllocatePagesForMdl(LowAddress, HighAddress, SkipBytes, num * PAGE_SIZE); #else pPageMdl = MmAllocatePagesForMdlEx(LowAddress, HighAddress, SkipBytes, num * PAGE_SIZE, MmNonCached, MM_DONT_ZERO_ALLOCATION); #endif if (pPageMdl == NULL) { TraceEvents(TRACE_LEVEL_WARNING, DBG_HW_ACCESS, "Failed to allocate pages.\n"); return; } if (MmGetMdlByteCount(pPageMdl) != (num * PAGE_SIZE)) { TraceEvents(TRACE_LEVEL_WARNING, DBG_HW_ACCESS, "Not all requested memory was allocated (%d/%d).\n", MmGetMdlByteCount(pPageMdl), num * PAGE_SIZE); MmFreePagesFromMdl(pPageMdl); ExFreePool(pPageMdl); return; } pNewPageListEntry = (PPAGE_LIST_ENTRY)ExAllocateFromNPagedLookasideList( &ctx->LookAsideList); if (pNewPageListEntry == NULL) { TraceEvents(TRACE_LEVEL_ERROR, DBG_HW_ACCESS, "Failed to allocate list entry.\n"); MmFreePagesFromMdl(pPageMdl); ExFreePool(pPageMdl); return; } pNewPageListEntry->PageMdl = pPageMdl; PushEntryList(&ctx->PageListHead, &(pNewPageListEntry->SingleListEntry)); ctx->num_pfns = num; ctx->num_pages += ctx->num_pfns; RtlCopyMemory(ctx->pfns_table, MmGetMdlPfnArray(pPageMdl), ctx->num_pfns * sizeof(PFN_NUMBER)); BalloonTellHost(WdfDevice, ctx->InfVirtQueue); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_HW_ACCESS, "<-- %s\n", __FUNCTION__); }