2018-11-28 17:18:09 -05:00
|
|
|
using Ryujinx.Common;
|
2020-07-30 09:16:41 -04:00
|
|
|
using Ryujinx.Common.Logging;
|
2020-05-03 18:54:50 -04:00
|
|
|
using Ryujinx.Cpu;
|
2019-01-24 20:59:53 -05:00
|
|
|
using Ryujinx.HLE.Exceptions;
|
2018-12-18 00:33:36 -05:00
|
|
|
using Ryujinx.HLE.HOS.Kernel.Common;
|
|
|
|
using Ryujinx.HLE.HOS.Kernel.Memory;
|
|
|
|
using Ryujinx.HLE.HOS.Kernel.Threading;
|
2023-01-04 17:15:45 -05:00
|
|
|
using Ryujinx.Horizon.Common;
|
2020-12-01 18:23:43 -05:00
|
|
|
using Ryujinx.Memory;
|
2018-11-28 17:18:09 -05:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Threading;
|
|
|
|
|
2018-12-18 00:33:36 -05:00
|
|
|
namespace Ryujinx.HLE.HOS.Kernel.Process
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
class KProcess : KSynchronizationObject
|
|
|
|
{
|
2020-12-01 18:23:43 -05:00
|
|
|
public const int KernelVersionMajor = 10;
|
|
|
|
public const int KernelVersionMinor = 4;
|
2018-11-28 17:18:09 -05:00
|
|
|
public const int KernelVersionRevision = 0;
|
|
|
|
|
|
|
|
public const int KernelVersionPacked =
|
2020-12-01 18:23:43 -05:00
|
|
|
(KernelVersionMajor << 19) |
|
|
|
|
(KernelVersionMinor << 15) |
|
2018-11-28 17:18:09 -05:00
|
|
|
(KernelVersionRevision << 0);
|
|
|
|
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
public KPageTableBase MemoryManager { get; private set; }
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
private SortedDictionary<ulong, KTlsPageInfo> _fullTlsPages;
|
|
|
|
private SortedDictionary<ulong, KTlsPageInfo> _freeTlsPages;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2019-01-18 17:26:39 -05:00
|
|
|
public int DefaultCpuCore { get; set; }
|
2018-11-28 17:18:09 -05:00
|
|
|
|
|
|
|
public bool Debug { get; private set; }
|
|
|
|
|
|
|
|
public KResourceLimit ResourceLimit { get; private set; }
|
|
|
|
|
|
|
|
public ulong PersonalMmHeapPagesCount { get; private set; }
|
|
|
|
|
2019-12-25 20:50:17 -05:00
|
|
|
public ProcessState State { get; private set; }
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
private object _processLock;
|
|
|
|
private object _threadingLock;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-04 19:52:39 -05:00
|
|
|
public KAddressArbiter AddressArbiter { get; private set; }
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2022-01-29 16:18:03 -05:00
|
|
|
public ulong[] RandomEntropy { get; private set; }
|
2021-12-30 04:55:06 -05:00
|
|
|
public KThread[] PinnedThreads { get; private set; }
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
private bool _signaled;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
|
|
|
public string Name { get; private set; }
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
private int _threadCount;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
public ProcessCreationFlags Flags { get; private set; }
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
private MemoryRegion _memRegion;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-04 19:52:39 -05:00
|
|
|
public KProcessCapabilities Capabilities { get; private set; }
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2022-05-03 17:28:32 -04:00
|
|
|
public bool AllowCodeMemoryForJit { get; private set; }
|
|
|
|
|
2019-09-02 12:03:57 -04:00
|
|
|
public ulong TitleId { get; private set; }
|
2021-12-04 18:23:26 -05:00
|
|
|
public bool IsApplication { get; private set; }
|
2022-02-09 15:18:07 -05:00
|
|
|
public ulong Pid { get; private set; }
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
private long _creationTimestamp;
|
2018-12-06 06:16:24 -05:00
|
|
|
private ulong _entrypoint;
|
2020-12-01 18:23:43 -05:00
|
|
|
private ThreadStart _customThreadStart;
|
2018-12-06 06:16:24 -05:00
|
|
|
private ulong _imageSize;
|
|
|
|
private ulong _mainThreadStackSize;
|
|
|
|
private ulong _memoryUsageCapacity;
|
2020-12-01 18:23:43 -05:00
|
|
|
private int _version;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
|
|
|
public KHandleTable HandleTable { get; private set; }
|
|
|
|
|
|
|
|
public ulong UserExceptionContextAddress { get; private set; }
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
private LinkedList<KThread> _threads;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
|
|
|
public bool IsPaused { get; private set; }
|
|
|
|
|
2020-12-09 17:20:05 -05:00
|
|
|
private long _totalTimeRunning;
|
|
|
|
|
|
|
|
public long TotalTimeRunning => _totalTimeRunning;
|
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
private IProcessContextFactory _contextFactory;
|
|
|
|
public IProcessContext Context { get; private set; }
|
|
|
|
public IVirtualMemoryManager CpuMemory => Context.AddressSpace;
|
2019-02-24 02:24:35 -05:00
|
|
|
|
2018-12-04 19:52:39 -05:00
|
|
|
public HleProcessDebugger Debugger { get; private set; }
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2022-05-03 17:28:32 -04:00
|
|
|
public KProcess(KernelContext context, bool allowCodeMemoryForJit = false) : base(context)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2020-12-01 18:23:43 -05:00
|
|
|
_processLock = new object();
|
2018-12-06 06:16:24 -05:00
|
|
|
_threadingLock = new object();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
AddressArbiter = new KAddressArbiter(context);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
_fullTlsPages = new SortedDictionary<ulong, KTlsPageInfo>();
|
|
|
|
_freeTlsPages = new SortedDictionary<ulong, KTlsPageInfo>();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
|
|
|
Capabilities = new KProcessCapabilities();
|
|
|
|
|
2022-05-03 17:28:32 -04:00
|
|
|
AllowCodeMemoryForJit = allowCodeMemoryForJit;
|
|
|
|
|
2022-01-29 16:18:03 -05:00
|
|
|
RandomEntropy = new ulong[KScheduler.CpuCoresCount];
|
2021-12-30 04:55:06 -05:00
|
|
|
PinnedThreads = new KThread[KScheduler.CpuCoresCount];
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
// TODO: Remove once we no longer need to initialize it externally.
|
|
|
|
HandleTable = new KHandleTable(context);
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
_threads = new LinkedList<KThread>();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
|
|
|
Debugger = new HleProcessDebugger(this);
|
|
|
|
}
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
public Result InitializeKip(
|
2018-12-06 06:16:24 -05:00
|
|
|
ProcessCreationInfo creationInfo,
|
2020-12-01 18:23:43 -05:00
|
|
|
ReadOnlySpan<int> capabilities,
|
|
|
|
KPageList pageList,
|
|
|
|
KResourceLimit resourceLimit,
|
|
|
|
MemoryRegion memRegion,
|
2020-12-09 17:20:05 -05:00
|
|
|
IProcessContextFactory contextFactory,
|
|
|
|
ThreadStart customThreadStart = null)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
ResourceLimit = resourceLimit;
|
2020-12-01 18:23:43 -05:00
|
|
|
_memRegion = memRegion;
|
|
|
|
_contextFactory = contextFactory ?? new ProcessContextFactory();
|
2020-12-09 17:20:05 -05:00
|
|
|
_customThreadStart = customThreadStart;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
AddressSpaceType addrSpaceType = (AddressSpaceType)((int)(creationInfo.Flags & ProcessCreationFlags.AddressSpaceMask) >> (int)ProcessCreationFlags.AddressSpaceShift);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2021-06-29 13:32:02 -04:00
|
|
|
Pid = KernelContext.NewKipId();
|
|
|
|
|
2022-02-09 15:18:07 -05:00
|
|
|
if (Pid == 0 || Pid >= KernelConstants.InitialProcessId)
|
2021-06-29 13:32:02 -04:00
|
|
|
{
|
|
|
|
throw new InvalidOperationException($"Invalid KIP Id {Pid}.");
|
|
|
|
}
|
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
InitializeMemoryManager(creationInfo.Flags);
|
2019-02-24 02:24:35 -05:00
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
bool aslrEnabled = creationInfo.Flags.HasFlag(ProcessCreationFlags.EnableAslr);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
ulong codeAddress = creationInfo.CodeAddress;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
ulong codeSize = (ulong)creationInfo.CodePagesCount * KPageTableBase.PageSize;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
KMemoryBlockSlabManager slabManager = creationInfo.Flags.HasFlag(ProcessCreationFlags.IsApplication)
|
|
|
|
? KernelContext.LargeMemoryBlockSlabManager
|
|
|
|
: KernelContext.SmallMemoryBlockSlabManager;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
Result result = MemoryManager.InitializeForProcess(
|
2018-12-06 06:16:24 -05:00
|
|
|
addrSpaceType,
|
|
|
|
aslrEnabled,
|
|
|
|
!aslrEnabled,
|
|
|
|
memRegion,
|
|
|
|
codeAddress,
|
|
|
|
codeSize,
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
slabManager);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result != Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
if (!MemoryManager.CanContain(codeAddress, codeSize, MemoryState.CodeStatic))
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
return KernelResult.InvalidMemRange;
|
|
|
|
}
|
|
|
|
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
result = MemoryManager.MapPages(codeAddress, pageList, MemoryState.CodeStatic, KMemoryPermission.None);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result != Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
result = Capabilities.InitializeForKernel(capabilities, MemoryManager);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result != Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2020-12-09 17:20:05 -05:00
|
|
|
return ParseProcessInfo(creationInfo);
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
public Result Initialize(
|
2018-12-06 06:16:24 -05:00
|
|
|
ProcessCreationInfo creationInfo,
|
2020-12-01 18:23:43 -05:00
|
|
|
ReadOnlySpan<int> capabilities,
|
|
|
|
KResourceLimit resourceLimit,
|
|
|
|
MemoryRegion memRegion,
|
|
|
|
IProcessContextFactory contextFactory,
|
|
|
|
ThreadStart customThreadStart = null)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
ResourceLimit = resourceLimit;
|
2020-12-01 18:23:43 -05:00
|
|
|
_memRegion = memRegion;
|
|
|
|
_contextFactory = contextFactory ?? new ProcessContextFactory();
|
2020-12-09 17:20:05 -05:00
|
|
|
_customThreadStart = customThreadStart;
|
2021-12-04 18:23:26 -05:00
|
|
|
IsApplication = creationInfo.Flags.HasFlag(ProcessCreationFlags.IsApplication);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
ulong personalMmHeapSize = GetPersonalMmHeapSize((ulong)creationInfo.SystemResourcePagesCount, memRegion);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
ulong codePagesCount = (ulong)creationInfo.CodePagesCount;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
ulong neededSizeForProcess = personalMmHeapSize + codePagesCount * KPageTableBase.PageSize;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
if (neededSizeForProcess != 0 && resourceLimit != null)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
if (!resourceLimit.Reserve(LimitableResource.Memory, neededSizeForProcess))
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
return KernelResult.ResLimitExceeded;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CleanUpForError()
|
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
if (neededSizeForProcess != 0 && resourceLimit != null)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
resourceLimit.Release(LimitableResource.Memory, neededSizeForProcess);
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
PersonalMmHeapPagesCount = (ulong)creationInfo.SystemResourcePagesCount;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
KMemoryBlockSlabManager slabManager;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
|
|
|
if (PersonalMmHeapPagesCount != 0)
|
|
|
|
{
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
slabManager = new KMemoryBlockSlabManager(PersonalMmHeapPagesCount * KPageTableBase.PageSize);
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
slabManager = creationInfo.Flags.HasFlag(ProcessCreationFlags.IsApplication)
|
|
|
|
? KernelContext.LargeMemoryBlockSlabManager
|
|
|
|
: KernelContext.SmallMemoryBlockSlabManager;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
AddressSpaceType addrSpaceType = (AddressSpaceType)((int)(creationInfo.Flags & ProcessCreationFlags.AddressSpaceMask) >> (int)ProcessCreationFlags.AddressSpaceShift);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2021-06-29 13:32:02 -04:00
|
|
|
Pid = KernelContext.NewProcessId();
|
|
|
|
|
2022-02-09 15:18:07 -05:00
|
|
|
if (Pid == ulong.MaxValue || Pid < KernelConstants.InitialProcessId)
|
2021-06-29 13:32:02 -04:00
|
|
|
{
|
|
|
|
throw new InvalidOperationException($"Invalid Process Id {Pid}.");
|
|
|
|
}
|
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
InitializeMemoryManager(creationInfo.Flags);
|
2019-02-24 02:24:35 -05:00
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
bool aslrEnabled = creationInfo.Flags.HasFlag(ProcessCreationFlags.EnableAslr);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
ulong codeAddress = creationInfo.CodeAddress;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
ulong codeSize = codePagesCount * KPageTableBase.PageSize;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
Result result = MemoryManager.InitializeForProcess(
|
2018-12-06 06:16:24 -05:00
|
|
|
addrSpaceType,
|
|
|
|
aslrEnabled,
|
|
|
|
!aslrEnabled,
|
|
|
|
memRegion,
|
|
|
|
codeAddress,
|
|
|
|
codeSize,
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
slabManager);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result != Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
CleanUpForError();
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
if (!MemoryManager.CanContain(codeAddress, codeSize, MemoryState.CodeStatic))
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
CleanUpForError();
|
|
|
|
|
|
|
|
return KernelResult.InvalidMemRange;
|
|
|
|
}
|
|
|
|
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
result = MemoryManager.MapPages(
|
2018-12-06 06:16:24 -05:00
|
|
|
codeAddress,
|
|
|
|
codePagesCount,
|
2018-11-28 17:18:09 -05:00
|
|
|
MemoryState.CodeStatic,
|
2020-12-01 18:23:43 -05:00
|
|
|
KMemoryPermission.None);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result != Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
CleanUpForError();
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
result = Capabilities.InitializeForUser(capabilities, MemoryManager);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result != Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
CleanUpForError();
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
result = ParseProcessInfo(creationInfo);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result != Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
CleanUpForError();
|
|
|
|
}
|
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
private Result ParseProcessInfo(ProcessCreationInfo creationInfo)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2019-07-01 22:39:22 -04:00
|
|
|
// Ensure that the current kernel version is equal or above to the minimum required.
|
2020-12-01 18:23:43 -05:00
|
|
|
uint requiredKernelVersionMajor = (uint)Capabilities.KernelReleaseVersion >> 19;
|
2018-12-06 06:16:24 -05:00
|
|
|
uint requiredKernelVersionMinor = ((uint)Capabilities.KernelReleaseVersion >> 15) & 0xf;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
if (KernelContext.EnableVersionChecks)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
if (requiredKernelVersionMajor > KernelVersionMajor)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
return KernelResult.InvalidCombination;
|
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
if (requiredKernelVersionMajor != KernelVersionMajor && requiredKernelVersionMajor < 3)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
return KernelResult.InvalidCombination;
|
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
if (requiredKernelVersionMinor > KernelVersionMinor)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
return KernelResult.InvalidCombination;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
Result result = AllocateThreadLocalStorage(out ulong userExceptionContextAddress);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result != Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
UserExceptionContextAddress = userExceptionContextAddress;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2021-04-24 06:16:01 -04:00
|
|
|
MemoryHelper.FillWithZeros(CpuMemory, userExceptionContextAddress, KTlsPageInfo.TlsEntrySize);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
Name = creationInfo.Name;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2019-12-25 20:50:17 -05:00
|
|
|
State = ProcessState.Created;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
_creationTimestamp = PerformanceCounter.ElapsedMilliseconds;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
Flags = creationInfo.Flags;
|
|
|
|
_version = creationInfo.Version;
|
|
|
|
TitleId = creationInfo.TitleId;
|
2018-12-06 06:16:24 -05:00
|
|
|
_entrypoint = creationInfo.CodeAddress;
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
_imageSize = (ulong)creationInfo.CodePagesCount * KPageTableBase.PageSize;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
switch (Flags & ProcessCreationFlags.AddressSpaceMask)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2020-12-01 18:23:43 -05:00
|
|
|
case ProcessCreationFlags.AddressSpace32Bit:
|
|
|
|
case ProcessCreationFlags.AddressSpace64BitDeprecated:
|
|
|
|
case ProcessCreationFlags.AddressSpace64Bit:
|
2018-12-06 06:16:24 -05:00
|
|
|
_memoryUsageCapacity = MemoryManager.HeapRegionEnd -
|
2019-02-24 02:24:35 -05:00
|
|
|
MemoryManager.HeapRegionStart;
|
2018-11-28 17:18:09 -05:00
|
|
|
break;
|
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
case ProcessCreationFlags.AddressSpace32BitWithoutAlias:
|
2018-12-06 06:16:24 -05:00
|
|
|
_memoryUsageCapacity = MemoryManager.HeapRegionEnd -
|
|
|
|
MemoryManager.HeapRegionStart +
|
|
|
|
MemoryManager.AliasRegionEnd -
|
|
|
|
MemoryManager.AliasRegionStart;
|
2018-11-28 17:18:09 -05:00
|
|
|
break;
|
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
default: throw new InvalidOperationException($"Invalid MMU flags value 0x{Flags:x2}.");
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
GenerateRandomEntropy();
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
return Result.Success;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
public Result AllocateThreadLocalStorage(out ulong address)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2020-05-03 23:41:29 -04:00
|
|
|
KernelContext.CriticalSection.Enter();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
Result result;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
if (_freeTlsPages.Count > 0)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2019-07-01 22:39:22 -04:00
|
|
|
// If we have free TLS pages available, just use the first one.
|
2018-12-06 06:16:24 -05:00
|
|
|
KTlsPageInfo pageInfo = _freeTlsPages.Values.First();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
if (!pageInfo.TryGetFreePage(out address))
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
throw new InvalidOperationException("Unexpected failure getting free TLS page!");
|
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
if (pageInfo.IsFull())
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
_freeTlsPages.Remove(pageInfo.PageVirtualAddress);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
_fullTlsPages.Add(pageInfo.PageVirtualAddress, pageInfo);
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
result = Result.Success;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-07-01 22:39:22 -04:00
|
|
|
// Otherwise, we need to create a new one.
|
2018-12-06 06:16:24 -05:00
|
|
|
result = AllocateTlsPage(out KTlsPageInfo pageInfo);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result == Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
if (!pageInfo.TryGetFreePage(out address))
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
throw new InvalidOperationException("Unexpected failure getting free TLS page!");
|
|
|
|
}
|
|
|
|
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
_freeTlsPages.Add(pageInfo.PageVirtualAddress, pageInfo);
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
address = 0;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
KernelContext.CriticalSection.Leave();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
private Result AllocateTlsPage(out KTlsPageInfo pageInfo)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2020-05-03 23:41:29 -04:00
|
|
|
pageInfo = default;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
if (!KernelContext.UserSlabHeapPages.TryGetItem(out ulong tlsPagePa))
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
return KernelResult.OutOfMemory;
|
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
ulong regionStart = MemoryManager.TlsIoRegionStart;
|
2020-12-01 18:23:43 -05:00
|
|
|
ulong regionSize = MemoryManager.TlsIoRegionEnd - regionStart;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
ulong regionPagesCount = regionSize / KPageTableBase.PageSize;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
Result result = MemoryManager.MapPages(
|
2018-11-28 17:18:09 -05:00
|
|
|
1,
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
KPageTableBase.PageSize,
|
2018-12-06 06:16:24 -05:00
|
|
|
tlsPagePa,
|
2018-11-28 17:18:09 -05:00
|
|
|
true,
|
2018-12-06 06:16:24 -05:00
|
|
|
regionStart,
|
|
|
|
regionPagesCount,
|
2018-11-28 17:18:09 -05:00
|
|
|
MemoryState.ThreadLocal,
|
2020-12-01 18:23:43 -05:00
|
|
|
KMemoryPermission.ReadAndWrite,
|
2018-12-06 06:16:24 -05:00
|
|
|
out ulong tlsPageVa);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result != Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2020-05-03 23:41:29 -04:00
|
|
|
KernelContext.UserSlabHeapPages.Free(tlsPagePa);
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
pageInfo = new KTlsPageInfo(tlsPageVa, tlsPagePa);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
MemoryHelper.FillWithZeros(CpuMemory, tlsPageVa, KPageTableBase.PageSize);
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
public Result FreeThreadLocalStorage(ulong tlsSlotAddr)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2022-12-26 09:11:05 -05:00
|
|
|
ulong tlsPageAddr = BitUtils.AlignDown<ulong>(tlsSlotAddr, KPageTableBase.PageSize);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
KernelContext.CriticalSection.Enter();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
Result result = Result.Success;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
KTlsPageInfo pageInfo;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
if (_fullTlsPages.TryGetValue(tlsPageAddr, out pageInfo))
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2019-07-01 22:39:22 -04:00
|
|
|
// TLS page was full, free slot and move to free pages tree.
|
2018-12-06 06:16:24 -05:00
|
|
|
_fullTlsPages.Remove(tlsPageAddr);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
_freeTlsPages.Add(tlsPageAddr, pageInfo);
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
2018-12-06 06:16:24 -05:00
|
|
|
else if (!_freeTlsPages.TryGetValue(tlsPageAddr, out pageInfo))
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
result = KernelResult.InvalidAddress;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
if (pageInfo != null)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
pageInfo.FreeTlsSlot(tlsSlotAddr);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
if (pageInfo.IsEmpty())
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2019-07-01 22:39:22 -04:00
|
|
|
// TLS page is now empty, we should ensure it is removed
|
|
|
|
// from all trees, and free the memory it was using.
|
2018-12-06 06:16:24 -05:00
|
|
|
_freeTlsPages.Remove(tlsPageAddr);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
KernelContext.CriticalSection.Leave();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
FreeTlsPage(pageInfo);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
return Result.Success;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
KernelContext.CriticalSection.Leave();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
private Result FreeTlsPage(KTlsPageInfo pageInfo)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2023-01-04 17:15:45 -05:00
|
|
|
Result result = MemoryManager.UnmapForKernel(pageInfo.PageVirtualAddress, 1, MemoryState.ThreadLocal);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result == Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
KernelContext.UserSlabHeapPages.Free(pageInfo.PagePhysicalAddress);
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
private void GenerateRandomEntropy()
|
|
|
|
{
|
2019-07-01 22:39:22 -04:00
|
|
|
// TODO.
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
public Result Start(int mainThreadPriority, ulong stackSize)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
lock (_processLock)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2019-12-25 20:50:17 -05:00
|
|
|
if (State > ProcessState.CreatedAttached)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
return KernelResult.InvalidState;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ResourceLimit != null && !ResourceLimit.Reserve(LimitableResource.Thread, 1))
|
|
|
|
{
|
|
|
|
return KernelResult.ResLimitExceeded;
|
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
KResourceLimit threadResourceLimit = ResourceLimit;
|
|
|
|
KResourceLimit memoryResourceLimit = null;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
if (_mainThreadStackSize != 0)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
throw new InvalidOperationException("Trying to start a process with a invalid state!");
|
|
|
|
}
|
|
|
|
|
2022-12-26 09:11:05 -05:00
|
|
|
ulong stackSizeRounded = BitUtils.AlignUp<ulong>(stackSize, KPageTableBase.PageSize);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
ulong neededSize = stackSizeRounded + _imageSize;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2019-07-01 22:39:22 -04:00
|
|
|
// Check if the needed size for the code and the stack will fit on the
|
|
|
|
// memory usage capacity of this Process. Also check for possible overflow
|
|
|
|
// on the above addition.
|
2020-12-01 18:23:43 -05:00
|
|
|
if (neededSize > _memoryUsageCapacity || neededSize < stackSizeRounded)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
threadResourceLimit?.Release(LimitableResource.Thread, 1);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
|
|
|
return KernelResult.OutOfMemory;
|
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
if (stackSizeRounded != 0 && ResourceLimit != null)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
memoryResourceLimit = ResourceLimit;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
if (!memoryResourceLimit.Reserve(LimitableResource.Memory, stackSizeRounded))
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
threadResourceLimit?.Release(LimitableResource.Thread, 1);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
|
|
|
return KernelResult.ResLimitExceeded;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
Result result;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
KThread mainThread = null;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
ulong stackTop = 0;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
|
|
|
void CleanUpForError()
|
|
|
|
{
|
|
|
|
HandleTable.Destroy();
|
|
|
|
|
2019-01-18 17:26:39 -05:00
|
|
|
mainThread?.DecrementReferenceCount();
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
if (_mainThreadStackSize != 0)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
ulong stackBottom = stackTop - _mainThreadStackSize;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
ulong stackPagesCount = _mainThreadStackSize / KPageTableBase.PageSize;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
MemoryManager.UnmapForKernel(stackBottom, stackPagesCount, MemoryState.Stack);
|
2019-01-18 17:26:39 -05:00
|
|
|
|
|
|
|
_mainThreadStackSize = 0;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
memoryResourceLimit?.Release(LimitableResource.Memory, stackSizeRounded);
|
|
|
|
threadResourceLimit?.Release(LimitableResource.Thread, 1);
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
if (stackSizeRounded != 0)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
ulong stackPagesCount = stackSizeRounded / KPageTableBase.PageSize;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
ulong regionStart = MemoryManager.StackRegionStart;
|
2020-12-01 18:23:43 -05:00
|
|
|
ulong regionSize = MemoryManager.StackRegionEnd - regionStart;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
ulong regionPagesCount = regionSize / KPageTableBase.PageSize;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
result = MemoryManager.MapPages(
|
2018-12-06 06:16:24 -05:00
|
|
|
stackPagesCount,
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
KPageTableBase.PageSize,
|
2018-11-28 17:18:09 -05:00
|
|
|
0,
|
|
|
|
false,
|
2018-12-06 06:16:24 -05:00
|
|
|
regionStart,
|
|
|
|
regionPagesCount,
|
2018-11-28 17:18:09 -05:00
|
|
|
MemoryState.Stack,
|
2020-12-01 18:23:43 -05:00
|
|
|
KMemoryPermission.ReadAndWrite,
|
2018-12-06 06:16:24 -05:00
|
|
|
out ulong stackBottom);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result != Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
CleanUpForError();
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
_mainThreadStackSize += stackSizeRounded;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
stackTop = stackBottom + stackSizeRounded;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
ulong heapCapacity = _memoryUsageCapacity - _mainThreadStackSize - _imageSize;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
result = MemoryManager.SetHeapCapacity(heapCapacity);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result != Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
CleanUpForError();
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
HandleTable = new KHandleTable(KernelContext);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
result = HandleTable.Initialize(Capabilities.HandleTableSize);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result != Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
CleanUpForError();
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
mainThread = new KThread(KernelContext);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
result = mainThread.Initialize(
|
|
|
|
_entrypoint,
|
2018-11-28 17:18:09 -05:00
|
|
|
0,
|
2018-12-06 06:16:24 -05:00
|
|
|
stackTop,
|
|
|
|
mainThreadPriority,
|
2018-11-28 17:18:09 -05:00
|
|
|
DefaultCpuCore,
|
2020-12-01 18:23:43 -05:00
|
|
|
this,
|
|
|
|
ThreadType.User,
|
|
|
|
_customThreadStart);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result != Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
CleanUpForError();
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
result = HandleTable.GenerateHandle(mainThread, out int mainThreadHandle);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result != Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
CleanUpForError();
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
mainThread.SetEntryArguments(0, mainThreadHandle);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2019-12-25 20:50:17 -05:00
|
|
|
ProcessState oldState = State;
|
|
|
|
ProcessState newState = State != ProcessState.Created
|
2018-11-28 17:18:09 -05:00
|
|
|
? ProcessState.Attached
|
|
|
|
: ProcessState.Started;
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
SetState(newState);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
result = mainThread.Start();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result != Result.Success)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2020-12-01 18:23:43 -05:00
|
|
|
SetState(oldState);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
|
|
|
CleanUpForError();
|
2020-12-01 18:23:43 -05:00
|
|
|
}
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
if (result == Result.Success)
|
2019-01-18 17:26:39 -05:00
|
|
|
{
|
|
|
|
mainThread.IncrementReferenceCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
mainThread.DecrementReferenceCount();
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
private void SetState(ProcessState newState)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2019-12-25 20:50:17 -05:00
|
|
|
if (State != newState)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2020-12-01 18:23:43 -05:00
|
|
|
State = newState;
|
2018-12-06 06:16:24 -05:00
|
|
|
_signaled = true;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
|
|
|
Signal();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
public Result InitializeThread(
|
2018-12-06 06:16:24 -05:00
|
|
|
KThread thread,
|
2020-12-01 18:23:43 -05:00
|
|
|
ulong entrypoint,
|
|
|
|
ulong argsPtr,
|
|
|
|
ulong stackTop,
|
|
|
|
int priority,
|
2022-06-11 13:58:30 -04:00
|
|
|
int cpuCore,
|
|
|
|
ThreadStart customThreadStart = null)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
lock (_processLock)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2022-06-11 13:58:30 -04:00
|
|
|
return thread.Initialize(entrypoint, argsPtr, stackTop, priority, cpuCore, this, ThreadType.User, customThreadStart);
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-31 15:29:35 -04:00
|
|
|
public IExecutionContext CreateExecutionContext()
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2022-05-31 15:29:35 -04:00
|
|
|
return Context?.CreateExecutionContext(new ExceptionCallbacks(
|
|
|
|
InterruptHandler,
|
|
|
|
null,
|
|
|
|
KernelContext.SyscallHandler.SvcCall,
|
|
|
|
UndefinedInstructionHandler));
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2022-05-31 15:29:35 -04:00
|
|
|
private void InterruptHandler(IExecutionContext context)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2020-12-09 17:20:05 -05:00
|
|
|
KThread currentThread = KernelStatic.GetCurrentThread();
|
|
|
|
|
2022-03-12 12:12:12 -05:00
|
|
|
if (currentThread.Context.Running &&
|
|
|
|
currentThread.Owner != null &&
|
2021-12-30 04:55:06 -05:00
|
|
|
currentThread.GetUserDisableCount() != 0 &&
|
|
|
|
currentThread.Owner.PinnedThreads[currentThread.CurrentCore] == null)
|
|
|
|
{
|
|
|
|
KernelContext.CriticalSection.Enter();
|
|
|
|
|
|
|
|
currentThread.Owner.PinThread(currentThread);
|
|
|
|
|
|
|
|
currentThread.SetUserInterruptFlag();
|
|
|
|
|
|
|
|
KernelContext.CriticalSection.Leave();
|
|
|
|
}
|
2022-01-16 07:21:44 -05:00
|
|
|
|
|
|
|
if (currentThread.IsSchedulable)
|
2020-12-09 17:20:05 -05:00
|
|
|
{
|
|
|
|
KernelContext.Schedulers[currentThread.CurrentCore].Schedule();
|
|
|
|
}
|
|
|
|
|
|
|
|
currentThread.HandlePostSyscall();
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public void IncrementThreadCount()
|
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
Interlocked.Increment(ref _threadCount);
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public void DecrementThreadCountAndTerminateIfZero()
|
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
if (Interlocked.Decrement(ref _threadCount) == 0)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
Terminate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-25 20:50:17 -05:00
|
|
|
public void DecrementToZeroWhileTerminatingCurrent()
|
|
|
|
{
|
|
|
|
while (Interlocked.Decrement(ref _threadCount) != 0)
|
|
|
|
{
|
|
|
|
Destroy();
|
|
|
|
TerminateCurrentProcess();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Nintendo panic here because if it reaches this point, the current thread should be already dead.
|
|
|
|
// As we handle the death of the thread in the post SVC handler and inside the CPU emulator, we don't panic here.
|
|
|
|
}
|
|
|
|
|
2018-11-28 17:18:09 -05:00
|
|
|
public ulong GetMemoryCapacity()
|
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
ulong totalCapacity = (ulong)ResourceLimit.GetRemainingValue(LimitableResource.Memory);
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
totalCapacity += MemoryManager.GetTotalHeapSize();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
totalCapacity += GetPersonalMmHeapSize();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
totalCapacity += _imageSize + _mainThreadStackSize;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
if (totalCapacity <= _memoryUsageCapacity)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
return totalCapacity;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
return _memoryUsageCapacity;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public ulong GetMemoryUsage()
|
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
return _imageSize + _mainThreadStackSize + MemoryManager.GetTotalHeapSize() + GetPersonalMmHeapSize();
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public ulong GetMemoryCapacityWithoutPersonalMmHeap()
|
|
|
|
{
|
|
|
|
return GetMemoryCapacity() - GetPersonalMmHeapSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
public ulong GetMemoryUsageWithoutPersonalMmHeap()
|
|
|
|
{
|
|
|
|
return GetMemoryUsage() - GetPersonalMmHeapSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
private ulong GetPersonalMmHeapSize()
|
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
return GetPersonalMmHeapSize(PersonalMmHeapPagesCount, _memRegion);
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
private static ulong GetPersonalMmHeapSize(ulong personalMmHeapPagesCount, MemoryRegion memRegion)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
if (memRegion == MemoryRegion.Applet)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
POWER - Performance Optimizations With Extensive Ramifications (#2286)
* Refactoring of KMemoryManager class
* Replace some trivial uses of DRAM address with VA
* Get rid of GetDramAddressFromVa
* Abstracting more operations on derived page table class
* Run auto-format on KPageTableBase
* Managed to make TryConvertVaToPa private, few uses remains now
* Implement guest physical pages ref counting, remove manual freeing
* Make DoMmuOperation private and call new abstract methods only from the base class
* Pass pages count rather than size on Map/UnmapMemory
* Change memory managers to take host pointers
* Fix a guest memory leak and simplify KPageTable
* Expose new methods for host range query and mapping
* Some refactoring of MapPagesFromClientProcess to allow proper page ref counting and mapping without KPageLists
* Remove more uses of AddVaRangeToPageList, now only one remains (shared memory page checking)
* Add a SharedMemoryStorage class, will be useful for host mapping
* Sayonara AddVaRangeToPageList, you served us well
* Start to implement host memory mapping (WIP)
* Support memory tracking through host exception handling
* Fix some access violations from HLE service guest memory access and CPU
* Fix memory tracking
* Fix mapping list bugs, including a race and a error adding mapping ranges
* Simple page table for memory tracking
* Simple "volatile" region handle mode
* Update UBOs directly (experimental, rough)
* Fix the overlap check
* Only set non-modified buffers as volatile
* Fix some memory tracking issues
* Fix possible race in MapBufferFromClientProcess (block list updates were not locked)
* Write uniform update to memory immediately, only defer the buffer set.
* Fix some memory tracking issues
* Pass correct pages count on shared memory unmap
* Armeilleure Signal Handler v1 + Unix changes
Unix currently behaves like windows, rather than remapping physical
* Actually check if the host platform is unix
* Fix decommit on linux.
* Implement windows 10 placeholder shared memory, fix a buffer issue.
* Make PTC version something that will never match with master
* Remove testing variable for block count
* Add reference count for memory manager, fix dispose
Can still deadlock with OpenAL
* Add address validation, use page table for mapped check, add docs
Might clean up the page table traversing routines.
* Implement batched mapping/tracking.
* Move documentation, fix tests.
* Cleanup uniform buffer update stuff.
* Remove unnecessary assignment.
* Add unsafe host mapped memory switch
On by default. Would be good to turn this off for untrusted code (homebrew, exefs mods) and give the user the option to turn it on manually, though that requires some UI work.
* Remove C# exception handlers
They have issues due to current .NET limitations, so the meilleure one fully replaces them for now.
* Fix MapPhysicalMemory on the software MemoryManager.
* Null check for GetHostAddress, docs
* Add configuration for setting memory manager mode (not in UI yet)
* Add config to UI
* Fix type mismatch on Unix signal handler code emit
* Fix 6GB DRAM mode.
The size can be greater than `uint.MaxValue` when the DRAM is >4GB.
* Address some feedback.
* More detailed error if backing memory cannot be mapped.
* SetLastError on all OS functions for consistency
* Force pages dirty with UBO update instead of setting them directly.
Seems to be much faster across a few games. Need retesting.
* Rebase, configuration rework, fix mem tracking regression
* Fix race in FreePages
* Set memory managers null after decrementing ref count
* Remove readonly keyword, as this is now modified.
* Use a local variable for the signal handler rather than a register.
* Fix bug with buffer resize, and index/uniform buffer binding.
Should fix flickering in games.
* Add InvalidAccessHandler to MemoryTracking
Doesn't do anything yet
* Call invalid access handler on unmapped read/write.
Same rules as the regular memory manager.
* Make unsafe mapped memory its own MemoryManagerType
* Move FlushUboDirty into UpdateState.
* Buffer dirty cache, rather than ubo cache
Much cleaner, may be reusable for Inline2Memory updates.
* This doesn't return anything anymore.
* Add sigaction remove methods, correct a few function signatures.
* Return empty list of physical regions for size 0.
* Also on AddressSpaceManager
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2021-05-24 16:52:44 -04:00
|
|
|
return personalMmHeapPagesCount * KPageTableBase.PageSize;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2020-12-09 17:20:05 -05:00
|
|
|
public void AddCpuTime(long ticks)
|
|
|
|
{
|
|
|
|
Interlocked.Add(ref _totalTimeRunning, ticks);
|
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
public void AddThread(KThread thread)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
lock (_threadingLock)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
thread.ProcessListNode = _threads.AddLast(thread);
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
public void RemoveThread(KThread thread)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
lock (_threadingLock)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
_threads.Remove(thread.ProcessListNode);
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
public bool IsCpuCoreAllowed(int core)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2022-01-29 16:18:03 -05:00
|
|
|
return (Capabilities.AllowedCpuCoresMask & (1UL << core)) != 0;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
public bool IsPriorityAllowed(int priority)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2022-01-29 16:18:03 -05:00
|
|
|
return (Capabilities.AllowedThreadPriosMask & (1UL << priority)) != 0;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public override bool IsSignaled()
|
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
return _signaled;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
public Result Terminate()
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2023-01-04 17:15:45 -05:00
|
|
|
Result result;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
bool shallTerminate = false;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
KernelContext.CriticalSection.Enter();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
lock (_processLock)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2019-12-25 20:50:17 -05:00
|
|
|
if (State >= ProcessState.Started)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2020-12-01 18:23:43 -05:00
|
|
|
if (State == ProcessState.Started ||
|
|
|
|
State == ProcessState.Crashed ||
|
2019-12-25 20:50:17 -05:00
|
|
|
State == ProcessState.Attached ||
|
|
|
|
State == ProcessState.DebugSuspended)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
|
|
|
SetState(ProcessState.Exiting);
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
shallTerminate = true;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
result = Result.Success;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
result = KernelResult.InvalidState;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
KernelContext.CriticalSection.Leave();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
if (shallTerminate)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2020-12-09 17:20:05 -05:00
|
|
|
UnpauseAndTerminateAllThreadsExcept(KernelStatic.GetCurrentThread());
|
2018-11-28 17:18:09 -05:00
|
|
|
|
|
|
|
HandleTable.Destroy();
|
|
|
|
|
2019-12-25 20:50:17 -05:00
|
|
|
SignalExitToDebugTerminated();
|
2018-11-28 17:18:09 -05:00
|
|
|
SignalExit();
|
|
|
|
}
|
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2019-12-25 20:50:17 -05:00
|
|
|
public void TerminateCurrentProcess()
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2019-12-25 20:50:17 -05:00
|
|
|
bool shallTerminate = false;
|
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
KernelContext.CriticalSection.Enter();
|
2019-12-25 20:50:17 -05:00
|
|
|
|
|
|
|
lock (_processLock)
|
|
|
|
{
|
|
|
|
if (State >= ProcessState.Started)
|
|
|
|
{
|
|
|
|
if (State == ProcessState.Started ||
|
|
|
|
State == ProcessState.Attached ||
|
|
|
|
State == ProcessState.DebugSuspended)
|
|
|
|
{
|
|
|
|
SetState(ProcessState.Exiting);
|
|
|
|
|
|
|
|
shallTerminate = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
KernelContext.CriticalSection.Leave();
|
2019-12-25 20:50:17 -05:00
|
|
|
|
|
|
|
if (shallTerminate)
|
|
|
|
{
|
2020-12-09 17:20:05 -05:00
|
|
|
UnpauseAndTerminateAllThreadsExcept(KernelStatic.GetCurrentThread());
|
2019-12-25 20:50:17 -05:00
|
|
|
|
|
|
|
HandleTable.Destroy();
|
|
|
|
|
|
|
|
// NOTE: this is supposed to be called in receiving of the mailbox.
|
|
|
|
SignalExitToDebugExited();
|
|
|
|
SignalExit();
|
|
|
|
}
|
2022-06-23 20:53:16 -04:00
|
|
|
|
|
|
|
KernelStatic.GetCurrentThread().Exit();
|
2019-12-25 20:50:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
private void UnpauseAndTerminateAllThreadsExcept(KThread currentThread)
|
|
|
|
{
|
|
|
|
lock (_threadingLock)
|
|
|
|
{
|
2020-05-03 23:41:29 -04:00
|
|
|
KernelContext.CriticalSection.Enter();
|
2019-12-25 20:50:17 -05:00
|
|
|
|
2021-12-30 04:55:06 -05:00
|
|
|
if (currentThread != null && PinnedThreads[currentThread.CurrentCore] == currentThread)
|
|
|
|
{
|
|
|
|
UnpinThread(currentThread);
|
|
|
|
}
|
|
|
|
|
2019-12-25 20:50:17 -05:00
|
|
|
foreach (KThread thread in _threads)
|
|
|
|
{
|
2022-06-23 20:53:16 -04:00
|
|
|
if (thread != currentThread && (thread.SchedFlags & ThreadSchedState.LowMask) != ThreadSchedState.TerminationPending)
|
2019-12-25 20:50:17 -05:00
|
|
|
{
|
|
|
|
thread.PrepareForTermination();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
KernelContext.CriticalSection.Leave();
|
2019-12-25 20:50:17 -05:00
|
|
|
}
|
|
|
|
|
2020-09-22 00:50:40 -04:00
|
|
|
while (true)
|
2019-12-25 20:50:17 -05:00
|
|
|
{
|
2020-09-22 00:50:40 -04:00
|
|
|
KThread blockedThread = null;
|
|
|
|
|
|
|
|
lock (_threadingLock)
|
2019-12-25 20:50:17 -05:00
|
|
|
{
|
2020-09-22 00:50:40 -04:00
|
|
|
foreach (KThread thread in _threads)
|
2019-12-25 20:50:17 -05:00
|
|
|
{
|
2020-09-22 00:50:40 -04:00
|
|
|
if (thread != currentThread && (thread.SchedFlags & ThreadSchedState.LowMask) != ThreadSchedState.TerminationPending)
|
|
|
|
{
|
|
|
|
thread.IncrementReferenceCount();
|
2019-12-25 20:50:17 -05:00
|
|
|
|
2020-09-22 00:50:40 -04:00
|
|
|
blockedThread = thread;
|
|
|
|
break;
|
|
|
|
}
|
2019-12-25 20:50:17 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-22 00:50:40 -04:00
|
|
|
if (blockedThread == null)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-12-25 20:50:17 -05:00
|
|
|
blockedThread.Terminate();
|
|
|
|
blockedThread.DecrementReferenceCount();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void SignalExitToDebugTerminated()
|
|
|
|
{
|
|
|
|
// TODO: Debug events.
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2019-12-25 20:50:17 -05:00
|
|
|
private void SignalExitToDebugExited()
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2019-07-01 22:39:22 -04:00
|
|
|
// TODO: Debug events.
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
private void SignalExit()
|
|
|
|
{
|
|
|
|
if (ResourceLimit != null)
|
|
|
|
{
|
|
|
|
ResourceLimit.Release(LimitableResource.Memory, GetMemoryUsage());
|
|
|
|
}
|
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
KernelContext.CriticalSection.Enter();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
|
|
|
SetState(ProcessState.Exited);
|
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
KernelContext.CriticalSection.Leave();
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
public Result ClearIfNotExited()
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2023-01-04 17:15:45 -05:00
|
|
|
Result result;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
KernelContext.CriticalSection.Enter();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
lock (_processLock)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2019-12-25 20:50:17 -05:00
|
|
|
if (State != ProcessState.Exited && _signaled)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
_signaled = false;
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
result = Result.Success;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-12-06 06:16:24 -05:00
|
|
|
result = KernelResult.InvalidState;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-03 23:41:29 -04:00
|
|
|
KernelContext.CriticalSection.Leave();
|
2018-11-28 17:18:09 -05:00
|
|
|
|
2018-12-06 06:16:24 -05:00
|
|
|
return result;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
private void InitializeMemoryManager(ProcessCreationFlags flags)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2020-12-01 18:23:43 -05:00
|
|
|
int addrSpaceBits = (flags & ProcessCreationFlags.AddressSpaceMask) switch
|
2019-02-24 02:24:35 -05:00
|
|
|
{
|
2020-12-01 18:23:43 -05:00
|
|
|
ProcessCreationFlags.AddressSpace32Bit => 32,
|
|
|
|
ProcessCreationFlags.AddressSpace64BitDeprecated => 36,
|
|
|
|
ProcessCreationFlags.AddressSpace32BitWithoutAlias => 32,
|
|
|
|
ProcessCreationFlags.AddressSpace64Bit => 39,
|
|
|
|
_ => 39
|
2020-05-03 23:41:29 -04:00
|
|
|
};
|
|
|
|
|
Add multi-level function table (#2228)
* Add AddressTable<T>
* Use AddressTable<T> for dispatch
* Remove JumpTable & co.
* Add fallback for out of range addresses
* Add PPTC support
* Add documentation to `AddressTable<T>`
* Make AddressTable<T> configurable
* Fix table walk
* Fix IsMapped check
* Remove CountTableCapacity
* Add PPTC support for fast path
* Rename IsMapped to IsValid
* Remove stale comment
* Change format of address in exception message
* Add TranslatorStubs
* Split DispatchStub
Avoids recompilation of stubs during tests.
* Add hint for 64bit or 32bit
* Add documentation to `Symbol`
* Add documentation to `TranslatorStubs`
Make `TranslatorStubs` disposable as well.
* Add documentation to `SymbolType`
* Add `AddressTableEventSource` to monitor function table size
Add an EventSource which measures the amount of unmanaged bytes
allocated by AddressTable<T> instances.
dotnet-counters monitor -n Ryujinx --counters ARMeilleure
* Add `AllowLcqInFunctionTable` optimization toggle
This is to reduce the impact this change has on the test duration.
Before everytime a test was ran, the FunctionTable would be initialized
and populated so that the newly compiled test would get registered to
it.
* Implement unmanaged dispatcher
Uses the DispatchStub to dispatch into the next translation, which
allows execution to stay in unmanaged for longer and skips a
ConcurrentDictionary look up when the target translation has been
registered to the FunctionTable.
* Remove redundant null check
* Tune levels of FunctionTable
Uses 5 levels instead of 4 and change unit of AddressTableEventSource
from KB to MB.
* Use 64-bit function table
Improves codegen for direct branches:
mov qword [rax+0x408],0x10603560
- mov rcx,sub_10603560_OFFSET
- mov ecx,[rcx]
- mov ecx,ecx
- mov rdx,JIT_CACHE_BASE
- add rdx,rcx
+ mov rcx,sub_10603560
+ mov rdx,[rcx]
mov rcx,rax
Improves codegen for dispatch stub:
and rax,byte +0x1f
- mov eax,[rcx+rax*4]
- mov eax,eax
- mov rcx,JIT_CACHE_BASE
- lea rax,[rcx+rax]
+ mov rax,[rcx+rax*8]
mov rcx,rbx
* Remove `JitCacheSymbol` & `JitCache.Offset`
* Turn `Translator.Translate` into an instance method
We do not have to add more parameter to this method and related ones as
new structures are added & needed for translation.
* Add symbol only when PTC is enabled
Address LDj3SNuD's feedback
* Change `NativeContext.Running` to a 32-bit integer
* Fix PageTable symbol for host mapped
2021-05-29 17:06:28 -04:00
|
|
|
bool for64Bit = flags.HasFlag(ProcessCreationFlags.Is64Bit);
|
|
|
|
|
2021-06-29 13:32:02 -04:00
|
|
|
Context = _contextFactory.Create(KernelContext, Pid, 1UL << addrSpaceBits, InvalidAccessHandler, for64Bit);
|
2019-12-25 18:28:17 -05:00
|
|
|
|
2022-05-02 19:30:02 -04:00
|
|
|
MemoryManager = new KPageTable(KernelContext, CpuMemory);
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2020-07-30 09:16:41 -04:00
|
|
|
private bool InvalidAccessHandler(ulong va)
|
2018-11-28 17:18:09 -05:00
|
|
|
{
|
2020-12-13 02:30:27 -05:00
|
|
|
KernelStatic.GetCurrentThread()?.PrintGuestStackTrace();
|
2021-05-20 19:27:16 -04:00
|
|
|
KernelStatic.GetCurrentThread()?.PrintGuestRegisterPrintout();
|
2020-07-30 09:16:41 -04:00
|
|
|
|
2020-08-03 19:32:53 -04:00
|
|
|
Logger.Error?.Print(LogClass.Cpu, $"Invalid memory access at virtual address 0x{va:X16}.");
|
2020-07-30 09:16:41 -04:00
|
|
|
|
|
|
|
return false;
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
|
2022-05-31 15:29:35 -04:00
|
|
|
private void UndefinedInstructionHandler(IExecutionContext context, ulong address, int opCode)
|
2019-01-24 20:59:53 -05:00
|
|
|
{
|
2020-12-09 17:20:05 -05:00
|
|
|
KernelStatic.GetCurrentThread().PrintGuestStackTrace();
|
2021-05-20 19:27:16 -04:00
|
|
|
KernelStatic.GetCurrentThread()?.PrintGuestRegisterPrintout();
|
2020-07-30 09:16:41 -04:00
|
|
|
|
2022-05-31 15:29:35 -04:00
|
|
|
throw new UndefinedInstructionException(address, opCode);
|
2019-01-24 20:59:53 -05:00
|
|
|
}
|
2020-02-06 06:38:24 -05:00
|
|
|
|
2020-12-01 18:23:43 -05:00
|
|
|
protected override void Destroy() => Context.Dispose();
|
2021-09-11 16:08:25 -04:00
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
public Result SetActivity(bool pause)
|
2021-09-11 16:08:25 -04:00
|
|
|
{
|
|
|
|
KernelContext.CriticalSection.Enter();
|
|
|
|
|
|
|
|
if (State != ProcessState.Exiting && State != ProcessState.Exited)
|
|
|
|
{
|
|
|
|
if (pause)
|
|
|
|
{
|
|
|
|
if (IsPaused)
|
|
|
|
{
|
|
|
|
KernelContext.CriticalSection.Leave();
|
|
|
|
|
|
|
|
return KernelResult.InvalidState;
|
|
|
|
}
|
|
|
|
|
|
|
|
lock (_threadingLock)
|
|
|
|
{
|
|
|
|
foreach (KThread thread in _threads)
|
|
|
|
{
|
|
|
|
thread.Suspend(ThreadSchedState.ProcessPauseFlag);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IsPaused = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!IsPaused)
|
|
|
|
{
|
|
|
|
KernelContext.CriticalSection.Leave();
|
|
|
|
|
|
|
|
return KernelResult.InvalidState;
|
|
|
|
}
|
|
|
|
|
|
|
|
lock (_threadingLock)
|
|
|
|
{
|
|
|
|
foreach (KThread thread in _threads)
|
|
|
|
{
|
|
|
|
thread.Resume(ThreadSchedState.ProcessPauseFlag);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IsPaused = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
KernelContext.CriticalSection.Leave();
|
|
|
|
|
2023-01-04 17:15:45 -05:00
|
|
|
return Result.Success;
|
2021-09-11 16:08:25 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
KernelContext.CriticalSection.Leave();
|
|
|
|
|
|
|
|
return KernelResult.InvalidState;
|
|
|
|
}
|
2021-12-30 04:55:06 -05:00
|
|
|
|
|
|
|
public void PinThread(KThread thread)
|
|
|
|
{
|
|
|
|
if (!thread.TerminationRequested)
|
|
|
|
{
|
|
|
|
PinnedThreads[thread.CurrentCore] = thread;
|
|
|
|
|
|
|
|
thread.Pin();
|
|
|
|
|
|
|
|
KernelContext.ThreadReselectionRequested = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void UnpinThread(KThread thread)
|
|
|
|
{
|
|
|
|
if (!thread.TerminationRequested)
|
|
|
|
{
|
|
|
|
thread.Unpin();
|
|
|
|
|
|
|
|
PinnedThreads[thread.CurrentCore] = null;
|
|
|
|
|
|
|
|
KernelContext.ThreadReselectionRequested = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool IsExceptionUserThread(KThread thread)
|
|
|
|
{
|
|
|
|
// TODO
|
|
|
|
return false;
|
|
|
|
}
|
2018-11-28 17:18:09 -05:00
|
|
|
}
|
|
|
|
}
|