Fix remap when handle is 0 (#1882)

* Nvservices cleanup and attempt to fix remap

* Unmap if remap handle is 0

* Remove mapped pool add from Remap
This commit is contained in:
gdkchan 2021-01-09 20:11:31 -03:00 committed by GitHub
parent 71e2a00221
commit 8e0a421264
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 88 additions and 117 deletions

View file

@ -1,5 +1,4 @@
using Ryujinx.Common.Collections;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.HLE.HOS.Kernel.Process;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types;
@ -16,8 +15,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
private NvMemoryAllocator _memoryAllocator;
public NvHostAsGpuDeviceFile(ServiceCtx context, IVirtualMemoryManager memory, long owner) : base(context, owner)
{
_memoryAllocator = context.Device.MemoryAllocator;
{
_memoryAllocator = context.Device.MemoryAllocator;
}
public override NvInternalResult Ioctl(NvIoctl command, Span<byte> arguments)
@ -123,7 +122,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
arguments.Offset = address;
}
if (arguments.Offset < 0)
if (arguments.Offset == NvMemoryAllocator.PteUnmapped)
{
arguments.Offset = 0;
@ -153,7 +152,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
if (addressSpaceContext.RemoveReservation(arguments.Offset))
{
_memoryAllocator.DeallocateRange(arguments.Offset, size);
addressSpaceContext.Gmm.Free(arguments.Offset, size);
addressSpaceContext.Gmm.Unmap(arguments.Offset, size);
}
else
{
@ -178,7 +177,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
if (size != 0)
{
_memoryAllocator.DeallocateRange(arguments.Offset, size);
addressSpaceContext.Gmm.Free(arguments.Offset, size);
addressSpaceContext.Gmm.Unmap(arguments.Offset, size);
}
}
else
@ -196,22 +195,6 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Context);
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, arguments.NvMapHandle, true);
if (map == null)
{
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid NvMap handle 0x{arguments.NvMapHandle:x8}!");
return NvInternalResult.InvalidInput;
}
ulong pageSize = (ulong)arguments.PageSize;
if (pageSize == 0)
{
pageSize = (ulong)map.Align;
}
ulong physicalAddress;
if ((arguments.Flags & AddressSpaceFlags.RemapSubRange) != 0)
@ -225,15 +208,6 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
physicalAddress += arguments.BufferOffset;
addressSpaceContext.Gmm.Map(physicalAddress, virtualAddress, arguments.MappingSize);
if (virtualAddress < 0)
{
string message = string.Format(mapErrorMsg, virtualAddress, arguments.MappingSize, pageSize);
Logger.Warning?.Print(LogClass.ServiceNv, message);
return NvInternalResult.InvalidInput;
}
return NvInternalResult.Success;
}
else
@ -245,6 +219,22 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
}
}
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, arguments.NvMapHandle);
if (map == null)
{
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid NvMap handle 0x{arguments.NvMapHandle:x8}!");
return NvInternalResult.InvalidInput;
}
ulong pageSize = (ulong)arguments.PageSize;
if (pageSize == 0)
{
pageSize = (ulong)map.Align;
}
physicalAddress = map.Address + arguments.BufferOffset;
ulong size = arguments.MappingSize;
@ -284,12 +274,12 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
{
_memoryAllocator.AllocateRange(va, size, freeAddressStartPosition);
}
addressSpaceContext.Gmm.Map(physicalAddress, va, size);
arguments.Offset = va;
}
if (arguments.Offset < 0)
if (arguments.Offset == NvMemoryAllocator.PteUnmapped)
{
arguments.Offset = 0;
@ -322,32 +312,32 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
private NvInternalResult Remap(Span<RemapArguments> arguments)
{
AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Context);
for (int index = 0; index < arguments.Length; index++)
{
MemoryManager gmm = GetAddressSpaceContext(Context).Gmm;
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, arguments[index].NvMapHandle, true);
ulong mapOffs = (ulong)arguments[index].MapOffset << 16;
ulong gpuVa = (ulong)arguments[index].GpuOffset << 16;
ulong size = (ulong)arguments[index].Pages << 16;
if (map == null)
if (arguments[index].NvMapHandle == 0)
{
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid NvMap handle 0x{arguments[index].NvMapHandle:x8}!");
return NvInternalResult.InvalidInput;
gmm.Unmap(gpuVa, size);
}
ulong shiftedGpuOffset = ((ulong)arguments[index].GpuOffset << 16);
gmm.Map(
((ulong)arguments[index].MapOffset << 16) + map.Address,
shiftedGpuOffset,
(ulong)arguments[index].Pages << 16);
if (shiftedGpuOffset < 0)
else
{
Logger.Warning?.Print(LogClass.ServiceNv,
$"Page 0x{arguments[index].GpuOffset:x16} size 0x{arguments[index].Pages:x16} not allocated!");
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, arguments[index].NvMapHandle);
return NvInternalResult.InvalidInput;
if (map == null)
{
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid NvMap handle 0x{arguments[index].NvMapHandle:x8}!");
return NvInternalResult.InvalidInput;
}
gmm.Map(mapOffs + map.Address, gpuVa, size);
}
}