Fix Linux aligned mapping retention (#247)

* Fix Linux aligned mapping retention

* Cover Linux aligned mapping retention
This commit is contained in:
Spooks
2026-07-15 19:34:35 -06:00
committed by GitHub
parent 864cbb0fa0
commit 9bacb883f1
2 changed files with 85 additions and 4 deletions
@@ -95,6 +95,32 @@ public sealed class GuestMemoryAllocatorTests
Assert.Equal(0UL, (ulong)memory.GetPointer(address));
}
[Fact]
public void AlignedAllocationDoesNotRetainOverallocatedMappingsOutsideMacOS()
{
if (OperatingSystem.IsMacOS())
{
return;
}
const ulong desiredAddress = 0x00005000_0000_0123;
const ulong alignment = 0x10000;
const ulong alignedAddress = 0x00005000_0001_0000;
const ulong allocationSize = 0x2000;
using var host = new RelocatingHostMemory(alignedAddress);
using var memory = new PhysicalVirtualMemory(host);
Assert.True(memory.TryAllocateAtOrAbove(desiredAddress, 0x1234, false, alignment, out var actualAddress));
Assert.Equal(alignedAddress + alignment, actualAddress);
Assert.Equal(
[
(alignedAddress, allocationSize),
(alignedAddress + alignment, allocationSize),
],
host.AllocationCalls);
Assert.Equal([alignedAddress + 0x1000], host.FreedAddresses);
}
private sealed class FakeHostMemory : IHostMemory
{
public ulong Allocate(ulong desiredAddress, ulong size, HostPageProtection protection) =>
@@ -197,6 +223,63 @@ public sealed class GuestMemoryAllocatorTests
}
}
private sealed class RelocatingHostMemory(ulong firstAddress) : IHostMemory, IDisposable
{
private bool _relocatedFirstAllocation;
public List<(ulong Address, ulong Size)> AllocationCalls { get; } = [];
public List<ulong> FreedAddresses { get; } = [];
public ulong Allocate(ulong desiredAddress, ulong size, HostPageProtection protection)
{
AllocationCalls.Add((desiredAddress, size));
if (!_relocatedFirstAllocation)
{
_relocatedFirstAllocation = true;
return firstAddress + 0x1000;
}
return desiredAddress;
}
public ulong Reserve(ulong desiredAddress, ulong size, HostPageProtection protection) => 0;
public bool Commit(ulong address, ulong size, HostPageProtection protection) => true;
public bool Free(ulong address)
{
FreedAddresses.Add(address);
return true;
}
public bool Protect(ulong address, ulong size, HostPageProtection protection, out uint rawOldProtection)
{
rawOldProtection = 0;
return true;
}
public bool ProtectRaw(ulong address, ulong size, uint rawProtection, out uint rawOldProtection)
{
rawOldProtection = 0;
return true;
}
public bool Query(ulong address, out HostRegionInfo info)
{
info = default;
return false;
}
public void FlushInstructionCache(ulong address, ulong size)
{
}
public void Dispose()
{
}
}
private sealed class LazyHostMemory(ulong address) : IHostMemory, IDisposable
{
public bool CommitSucceeds { get; set; } = true;