diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_memory.cc index 9373269ec..31061a697 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_memory.cc @@ -330,9 +330,20 @@ dword_result_t MmAllocatePhysicalMemoryEx(dword_t flags, dword_t region_size, uint32_t allocation_type = kMemoryAllocationReserve | kMemoryAllocationCommit; uint32_t protect = FromXdkProtectFlags(protect_bits); bool top_down = true; - auto heap = kernel_memory()->LookupHeapByType(true, page_size); + auto heap = static_cast( + kernel_memory()->LookupHeapByType(true, page_size)); + // min_addr_range/max_addr_range are bounds in physical memory, not virtual. + uint32_t heap_base = heap->heap_base(); + uint32_t heap_physical_address_offset = heap->GetPhysicalAddress(heap_base); + uint32_t heap_min_addr = + xe::sat_sub(min_addr_range.value(), heap_physical_address_offset); + uint32_t heap_max_addr = + xe::sat_sub(max_addr_range.value(), heap_physical_address_offset); + uint32_t heap_size = heap->heap_size(); + heap_min_addr = heap_base + std::min(heap_min_addr, heap_size); + heap_max_addr = heap_base + std::min(heap_max_addr, heap_size); uint32_t base_address; - if (!heap->AllocRange(min_addr_range, max_addr_range, adjusted_size, + if (!heap->AllocRange(heap_min_addr, heap_max_addr, adjusted_size, adjusted_alignment, allocation_type, protect, top_down, &base_address)) { // Failed - assume no memory available.