Implement support for page sizes > 4KB (#4252)

* Implement support for page sizes > 4KB

* Check and work around more alignment issues

* Was not meant to change this

* Use MemoryBlock.GetPageSize() value for signal handler code

* Do not take the path for private allocations if host supports 4KB pages

* Add Flags attribute on MemoryMapFlags

* Fix dirty region size with 16kb pages

Would accidentally report a size that was too high (generally 16k instead of 4k, uploading 4x as much data)

Co-authored-by: riperiperi <rhy3756547@hotmail.com>
This commit is contained in:
gdkchan 2023-01-17 01:13:24 -03:00 committed by GitHub
parent 43a83a401e
commit 86fd0643c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 1294 additions and 146 deletions

View file

@ -1,6 +1,8 @@
using Ryujinx.Horizon.Common;
using Ryujinx.Memory;
using Ryujinx.Memory.Range;
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace Ryujinx.HLE.HOS.Kernel.Memory
@ -9,11 +11,19 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
{
private readonly IVirtualMemoryManager _cpuMemory;
protected override bool Supports4KBPages => _cpuMemory.Supports4KBPages;
public KPageTable(KernelContext context, IVirtualMemoryManager cpuMemory) : base(context)
{
_cpuMemory = cpuMemory;
}
/// <inheritdoc/>
protected override IEnumerable<HostMemoryRange> GetHostRegions(ulong va, ulong size)
{
return _cpuMemory.GetHostRegions(va, size);
}
/// <inheritdoc/>
protected override void GetPhysicalRegions(ulong va, ulong size, KPageList pageList)
{
@ -43,7 +53,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
return result;
}
result = MapPages(dst, pageList, newDstPermission, false, 0);
result = MapPages(dst, pageList, newDstPermission, MemoryMapFlags.Private, false, 0);
if (result != Result.Success)
{
@ -81,7 +91,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
if (result != Result.Success)
{
Result mapResult = MapPages(dst, dstPageList, oldDstPermission, false, 0);
Result mapResult = MapPages(dst, dstPageList, oldDstPermission, MemoryMapFlags.Private, false, 0);
Debug.Assert(mapResult == Result.Success);
}
@ -89,13 +99,20 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
}
/// <inheritdoc/>
protected override Result MapPages(ulong dstVa, ulong pagesCount, ulong srcPa, KMemoryPermission permission, bool shouldFillPages, byte fillValue)
protected override Result MapPages(
ulong dstVa,
ulong pagesCount,
ulong srcPa,
KMemoryPermission permission,
MemoryMapFlags flags,
bool shouldFillPages,
byte fillValue)
{
ulong size = pagesCount * PageSize;
Context.Memory.Commit(srcPa - DramMemoryMap.DramBase, size);
Context.CommitMemory(srcPa - DramMemoryMap.DramBase, size);
_cpuMemory.Map(dstVa, srcPa - DramMemoryMap.DramBase, size);
_cpuMemory.Map(dstVa, srcPa - DramMemoryMap.DramBase, size, flags);
if (DramMemoryMap.IsHeapPhysicalAddress(srcPa))
{
@ -111,7 +128,13 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
}
/// <inheritdoc/>
protected override Result MapPages(ulong address, KPageList pageList, KMemoryPermission permission, bool shouldFillPages, byte fillValue)
protected override Result MapPages(
ulong address,
KPageList pageList,
KMemoryPermission permission,
MemoryMapFlags flags,
bool shouldFillPages,
byte fillValue)
{
using var scopedPageList = new KScopedPageList(Context.MemoryManager, pageList);
@ -122,9 +145,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
ulong addr = pageNode.Address - DramMemoryMap.DramBase;
ulong size = pageNode.PagesCount * PageSize;
Context.Memory.Commit(addr, size);
Context.CommitMemory(addr, size);
_cpuMemory.Map(currentVa, addr, size);
_cpuMemory.Map(currentVa, addr, size, flags);
if (shouldFillPages)
{
@ -139,6 +162,21 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
return Result.Success;
}
/// <inheritdoc/>
protected override Result MapForeign(IEnumerable<HostMemoryRange> regions, ulong va, ulong size)
{
ulong offset = 0;
foreach (var region in regions)
{
_cpuMemory.MapForeign(va + offset, region.Address, region.Size);
offset += region.Size;
}
return Result.Success;
}
/// <inheritdoc/>
protected override Result Unmap(ulong address, ulong pagesCount)
{
@ -188,4 +226,4 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
_cpuMemory.Write(va, data);
}
}
}
}