diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 1027c0e12..9256d9421 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -300,14 +300,15 @@ ResultCode Process::HeapFree(VAddr target, u32 size) {
 
     // Free heaps block by block
     CASCADE_RESULT(auto backing_blocks, vm_manager.GetBackingBlocksForRange(target, size));
-    for (const auto& backing_block : backing_blocks) {
-        memory_region->Free(backing_block.lower(), backing_block.upper() - backing_block.lower());
+    for (const auto& [backing_memory, block_size] : backing_blocks) {
+        const auto backing_offset = kernel.memory.GetFCRAMOffset(backing_memory.GetPtr());
+        memory_region->Free(backing_offset, block_size);
+        holding_memory -= MemoryRegionInfo::Interval(backing_offset, backing_offset + block_size);
     }
 
     ResultCode result = vm_manager.UnmapRange(target, size);
     ASSERT(result.IsSuccess());
 
-    holding_memory -= backing_blocks;
     memory_used -= size;
     resource_limit->current_commit -= size;
 
@@ -504,9 +505,7 @@ ResultCode Process::Map(VAddr target, VAddr source, u32 size, VMAPermission perm
 
     CASCADE_RESULT(auto backing_blocks, vm_manager.GetBackingBlocksForRange(source, size));
     VAddr interval_target = target;
-    for (const auto& backing_block : backing_blocks) {
-        auto backing_memory = kernel.memory.GetFCRAMRef(backing_block.lower());
-        auto block_size = backing_block.upper() - backing_block.lower();
+    for (const auto& [backing_memory, block_size] : backing_blocks) {
         auto target_vma =
             vm_manager.MapBackingMemory(interval_target, backing_memory, block_size, target_state);
         ASSERT(target_vma.Succeeded());
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index a28590ad5..b86fd2ae5 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -70,10 +70,7 @@ ResultVal<std::shared_ptr<SharedMemory>> KernelSystem::CreateSharedMemory(
 
         auto backing_blocks = vm_manager.GetBackingBlocksForRange(address, size);
         ASSERT(backing_blocks.Succeeded()); // should success after verifying memory state above
-        for (const auto& interval : backing_blocks.Unwrap()) {
-            shared_memory->backing_blocks.emplace_back(memory.GetFCRAMRef(interval.lower()),
-                                                       interval.upper() - interval.lower());
-        }
+        shared_memory->backing_blocks = std::move(backing_blocks).Unwrap();
     }
 
     shared_memory->base_address = address;
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp
index f187b92bf..f2c798750 100644
--- a/src/core/hle/kernel/vm_manager.cpp
+++ b/src/core/hle/kernel/vm_manager.cpp
@@ -391,9 +391,9 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
         plgldr->OnMemoryChanged(process, Core::System::GetInstance().Kernel());
 }
 
-ResultVal<MemoryRegionInfo::IntervalSet> VMManager::GetBackingBlocksForRange(VAddr address,
-                                                                             u32 size) {
-    MemoryRegionInfo::IntervalSet backing_blocks;
+ResultVal<std::vector<std::pair<MemoryRef, u32>>> VMManager::GetBackingBlocksForRange(VAddr address,
+                                                                                      u32 size) {
+    std::vector<std::pair<MemoryRef, u32>> backing_blocks;
     VAddr interval_target = address;
     while (interval_target != address + size) {
         auto vma = FindVMA(interval_target);
@@ -404,10 +404,8 @@ ResultVal<MemoryRegionInfo::IntervalSet> VMManager::GetBackingBlocksForRange(VAd
 
         VAddr interval_end = std::min(address + size, vma->second.base + vma->second.size);
         u32 interval_size = interval_end - interval_target;
-        auto backing_memory = memory.GetFCRAMOffset(vma->second.backing_memory +
-                                                    (interval_target - vma->second.base));
-        backing_blocks +=
-            MemoryRegionInfo::Interval(backing_memory, backing_memory + interval_size);
+        auto backing_memory = vma->second.backing_memory + (interval_target - vma->second.base);
+        backing_blocks.push_back({backing_memory, interval_size});
 
         interval_target += interval_size;
     }
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h
index d520eeccb..615d5d1ce 100644
--- a/src/core/hle/kernel/vm_manager.h
+++ b/src/core/hle/kernel/vm_manager.h
@@ -206,7 +206,8 @@ public:
     void LogLayout(Common::Log::Level log_level) const;
 
     /// Gets a list of backing memory blocks for the specified range
-    ResultVal<MemoryRegionInfo::IntervalSet> GetBackingBlocksForRange(VAddr address, u32 size);
+    ResultVal<std::vector<std::pair<MemoryRef, u32>>> GetBackingBlocksForRange(VAddr address,
+                                                                               u32 size);
 
     /// Each VMManager has its own page table, which is set as the main one when the owning process
     /// is scheduled.