private static int UnmapBuffer(ServiceCtx Context) { long InputPosition = Context.Request.GetBufferType0x21().Position; long OutputPosition = Context.Request.GetBufferType0x22().Position; NvGpuASUnmapBuffer Args = AMemoryHelper.Read <NvGpuASUnmapBuffer>(Context.Memory, InputPosition); NvGpuASCtx ASCtx = GetASCtx(Context); lock (ASCtx) { if (ASCtx.RemoveMap(Args.Offset, out long Size)) { if (Size != 0) { ASCtx.Vmm.Free(Args.Offset, Size); } } else { Context.Device.Log.PrintWarning(LogClass.ServiceNv, $"Invalid buffer offset {Args.Offset:x16}!"); } } return(NvResult.Success); }
private static int FreeSpace(ServiceCtx Context) { long InputPosition = Context.Request.GetBufferType0x21().Position; long OutputPosition = Context.Request.GetBufferType0x22().Position; NvGpuASAllocSpace Args = AMemoryHelper.Read <NvGpuASAllocSpace>(Context.Memory, InputPosition); NvGpuASCtx ASCtx = GetASCtx(Context); int Result = NvResult.Success; lock (ASCtx) { ulong Size = (ulong)Args.Pages * (ulong)Args.PageSize; if (ASCtx.RemoveReservation(Args.Offset)) { ASCtx.Vmm.Free(Args.Offset, (long)Size); } else { Context.Device.Log.PrintWarning(LogClass.ServiceNv, $"Failed to free offset 0x{Args.Offset:x16} size 0x{Size:x16}!"); Result = NvResult.InvalidInput; } } return(Result); }
private static int UnmapBuffer(ServiceCtx context) { long inputPosition = context.Request.GetBufferType0x21().Position; long outputPosition = context.Request.GetBufferType0x22().Position; NvGpuASUnmapBuffer args = MemoryHelper.Read <NvGpuASUnmapBuffer>(context.Memory, inputPosition); NvGpuASCtx asCtx = GetASCtx(context); lock (asCtx) { if (asCtx.RemoveMap(args.Offset, out long size)) { if (size != 0) { asCtx.Vmm.Free(args.Offset, size); } } else { Logger.PrintWarning(LogClass.ServiceNv, $"Invalid buffer offset {args.Offset:x16}!"); } } return(NvResult.Success); }
private static int FreeSpace(ServiceCtx context) { long inputPosition = context.Request.GetBufferType0x21().Position; long outputPosition = context.Request.GetBufferType0x22().Position; NvGpuASAllocSpace args = MemoryHelper.Read <NvGpuASAllocSpace>(context.Memory, inputPosition); NvGpuASCtx asCtx = GetASCtx(context); int result = NvResult.Success; lock (asCtx) { ulong size = (ulong)args.Pages * (ulong)args.PageSize; if (asCtx.RemoveReservation(args.Offset)) { asCtx.Vmm.Free(args.Offset, (long)size); } else { Logger.PrintWarning(LogClass.ServiceNv, $"Failed to free offset 0x{args.Offset:x16} size 0x{size:x16}!"); result = NvResult.InvalidInput; } } return(result); }
private static int AllocSpace(ServiceCtx Context) { long InputPosition = Context.Request.GetBufferType0x21().Position; long OutputPosition = Context.Request.GetBufferType0x22().Position; NvGpuASAllocSpace Args = AMemoryHelper.Read <NvGpuASAllocSpace>(Context.Memory, InputPosition); NvGpuASCtx ASCtx = GetASCtx(Context); ulong Size = (ulong)Args.Pages * (ulong)Args.PageSize; int Result = NvResult.Success; lock (ASCtx) { //Note: When the fixed offset flag is not set, //the Offset field holds the alignment size instead. if ((Args.Flags & FlagFixedOffset) != 0) { Args.Offset = ASCtx.Vmm.ReserveFixed(Args.Offset, (long)Size); } else { Args.Offset = ASCtx.Vmm.Reserve((long)Size, Args.Offset); } if (Args.Offset < 0) { Args.Offset = 0; Context.Device.Log.PrintWarning(LogClass.ServiceNv, $"Failed to allocate size {Size:x16}!"); Result = NvResult.OutOfMemory; } else { ASCtx.AddReservation(Args.Offset, (long)Size); } } AMemoryHelper.Write(Context.Memory, OutputPosition, Args); return(Result); }
private static int AllocSpace(ServiceCtx context) { long inputPosition = context.Request.GetBufferType0x21().Position; long outputPosition = context.Request.GetBufferType0x22().Position; NvGpuASAllocSpace args = MemoryHelper.Read <NvGpuASAllocSpace>(context.Memory, inputPosition); NvGpuASCtx asCtx = GetASCtx(context); ulong size = (ulong)args.Pages * (ulong)args.PageSize; int result = NvResult.Success; lock (asCtx) { // Note: When the fixed offset flag is not set, // the Offset field holds the alignment size instead. if ((args.Flags & FlagFixedOffset) != 0) { args.Offset = asCtx.Vmm.ReserveFixed(args.Offset, (long)size); } else { args.Offset = asCtx.Vmm.Reserve((long)size, args.Offset); } if (args.Offset < 0) { args.Offset = 0; Logger.PrintWarning(LogClass.ServiceNv, $"Failed to allocate size {size:x16}!"); result = NvResult.OutOfMemory; } else { asCtx.AddReservation(args.Offset, (long)size); } } MemoryHelper.Write(context.Memory, outputPosition, args); return(result); }
private static int MapBufferEx(ServiceCtx Context) { const string MapErrorMsg = "Failed to map fixed buffer with offset 0x{0:x16} and size 0x{1:x16}!"; long InputPosition = Context.Request.GetBufferType0x21().Position; long OutputPosition = Context.Request.GetBufferType0x22().Position; NvGpuASMapBufferEx Args = AMemoryHelper.Read <NvGpuASMapBufferEx>(Context.Memory, InputPosition); NvGpuASCtx ASCtx = GetASCtx(Context); NvMapHandle Map = NvMapIoctl.GetNvMapWithFb(Context, Args.NvMapHandle); if (Map == null) { Context.Device.Log.PrintWarning(LogClass.ServiceNv, $"Invalid NvMap handle 0x{Args.NvMapHandle:x8}!"); return(NvResult.InvalidInput); } long PA; if ((Args.Flags & FlagRemapSubRange) != 0) { lock (ASCtx) { if (ASCtx.TryGetMapPhysicalAddress(Args.Offset, out PA)) { long VA = Args.Offset + Args.BufferOffset; PA += Args.BufferOffset; if (ASCtx.Vmm.Map(PA, VA, Args.MappingSize) < 0) { string Msg = string.Format(MapErrorMsg, VA, Args.MappingSize); Context.Device.Log.PrintWarning(LogClass.ServiceNv, Msg); return(NvResult.InvalidInput); } return(NvResult.Success); } else { Context.Device.Log.PrintWarning(LogClass.ServiceNv, $"Address 0x{Args.Offset:x16} not mapped!"); return(NvResult.InvalidInput); } } } PA = Map.Address + Args.BufferOffset; long Size = Args.MappingSize; if (Size == 0) { Size = (uint)Map.Size; } int Result = NvResult.Success; lock (ASCtx) { //Note: When the fixed offset flag is not set, //the Offset field holds the alignment size instead. bool VaAllocated = (Args.Flags & FlagFixedOffset) == 0; if (!VaAllocated) { if (ASCtx.ValidateFixedBuffer(Args.Offset, Size)) { Args.Offset = ASCtx.Vmm.Map(PA, Args.Offset, Size); } else { string Msg = string.Format(MapErrorMsg, Args.Offset, Size); Context.Device.Log.PrintWarning(LogClass.ServiceNv, Msg); Result = NvResult.InvalidInput; } } else { Args.Offset = ASCtx.Vmm.Map(PA, Size); } if (Args.Offset < 0) { Args.Offset = 0; Context.Device.Log.PrintWarning(LogClass.ServiceNv, $"Failed to map size 0x{Size:x16}!"); Result = NvResult.InvalidInput; } else { ASCtx.AddMap(Args.Offset, Size, PA, VaAllocated); } } AMemoryHelper.Write(Context.Memory, OutputPosition, Args); return(Result); }
private static int MapBufferEx(ServiceCtx context) { const string mapErrorMsg = "Failed to map fixed buffer with offset 0x{0:x16} and size 0x{1:x16}!"; long inputPosition = context.Request.GetBufferType0x21().Position; long outputPosition = context.Request.GetBufferType0x22().Position; NvGpuASMapBufferEx args = MemoryHelper.Read <NvGpuASMapBufferEx>(context.Memory, inputPosition); NvGpuASCtx asCtx = GetASCtx(context); NvMapHandle map = NvMapIoctl.GetNvMapWithFb(context, args.NvMapHandle); if (map == null) { Logger.PrintWarning(LogClass.ServiceNv, $"Invalid NvMap handle 0x{args.NvMapHandle:x8}!"); return(NvResult.InvalidInput); } long pa; if ((args.Flags & FlagRemapSubRange) != 0) { lock (asCtx) { if (asCtx.TryGetMapPhysicalAddress(args.Offset, out pa)) { long va = args.Offset + args.BufferOffset; pa += args.BufferOffset; if (asCtx.Vmm.Map(pa, va, args.MappingSize) < 0) { string msg = string.Format(mapErrorMsg, va, args.MappingSize); Logger.PrintWarning(LogClass.ServiceNv, msg); return(NvResult.InvalidInput); } return(NvResult.Success); } else { Logger.PrintWarning(LogClass.ServiceNv, $"Address 0x{args.Offset:x16} not mapped!"); return(NvResult.InvalidInput); } } } pa = map.Address + args.BufferOffset; long size = args.MappingSize; if (size == 0) { size = (uint)map.Size; } int result = NvResult.Success; lock (asCtx) { // Note: When the fixed offset flag is not set, // the Offset field holds the alignment size instead. bool vaAllocated = (args.Flags & FlagFixedOffset) == 0; if (!vaAllocated) { if (asCtx.ValidateFixedBuffer(args.Offset, size)) { args.Offset = asCtx.Vmm.Map(pa, args.Offset, size); } else { string msg = string.Format(mapErrorMsg, args.Offset, size); Logger.PrintWarning(LogClass.ServiceNv, msg); result = NvResult.InvalidInput; } } else { args.Offset = asCtx.Vmm.Map(pa, size); } if (args.Offset < 0) { args.Offset = 0; Logger.PrintWarning(LogClass.ServiceNv, $"Failed to map size 0x{size:x16}!"); result = NvResult.InvalidInput; } else { asCtx.AddMap(args.Offset, size, pa, vaAllocated); } } MemoryHelper.Write(context.Memory, outputPosition, args); return(result); }