Sfoglia il codice sorgente

Merge pull request #2687 from lioncash/tls-process

kernel/process: Allocate the process' TLS region during initialization
bunnei 7 anni fa
parent
commit
5d369112d9

+ 18 - 11
src/core/hle/kernel/process.cpp

@@ -184,19 +184,11 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) {
 }
 
 void Process::Run(s32 main_thread_priority, u64 stack_size) {
-    // The kernel always ensures that the given stack size is page aligned.
-    main_thread_stack_size = Common::AlignUp(stack_size, Memory::PAGE_SIZE);
-
-    // Allocate and map the main thread stack
-    // TODO(bunnei): This is heap area that should be allocated by the kernel and not mapped as part
-    // of the user address space.
-    const VAddr mapping_address = vm_manager.GetTLSIORegionEndAddress() - main_thread_stack_size;
-    vm_manager
-        .MapMemoryBlock(mapping_address, std::make_shared<std::vector<u8>>(main_thread_stack_size),
-                        0, main_thread_stack_size, MemoryState::Stack)
-        .Unwrap();
+    AllocateMainThreadStack(stack_size);
+    tls_region_address = CreateTLSRegion();
 
     vm_manager.LogLayout();
+
     ChangeStatus(ProcessStatus::Running);
 
     SetupMainThread(*this, kernel, main_thread_priority);
@@ -226,6 +218,9 @@ void Process::PrepareForTermination() {
     stop_threads(system.Scheduler(2).GetThreadList());
     stop_threads(system.Scheduler(3).GetThreadList());
 
+    FreeTLSRegion(tls_region_address);
+    tls_region_address = 0;
+
     ChangeStatus(ProcessStatus::Exited);
 }
 
@@ -325,4 +320,16 @@ void Process::ChangeStatus(ProcessStatus new_status) {
     WakeupAllWaitingThreads();
 }
 
+void Process::AllocateMainThreadStack(u64 stack_size) {
+    // The kernel always ensures that the given stack size is page aligned.
+    main_thread_stack_size = Common::AlignUp(stack_size, Memory::PAGE_SIZE);
+
+    // Allocate and map the main thread stack
+    const VAddr mapping_address = vm_manager.GetTLSIORegionEndAddress() - main_thread_stack_size;
+    vm_manager
+        .MapMemoryBlock(mapping_address, std::make_shared<std::vector<u8>>(main_thread_stack_size),
+                        0, main_thread_stack_size, MemoryState::Stack)
+        .Unwrap();
+}
+
 } // namespace Kernel

+ 11 - 0
src/core/hle/kernel/process.h

@@ -135,6 +135,11 @@ public:
         return mutex;
     }
 
+    /// Gets the address to the process' dedicated TLS region.
+    VAddr GetTLSRegionAddress() const {
+        return tls_region_address;
+    }
+
     /// Gets the current status of the process
     ProcessStatus GetStatus() const {
         return status;
@@ -296,6 +301,9 @@ private:
     /// a process signal.
     void ChangeStatus(ProcessStatus new_status);
 
+    /// Allocates the main thread stack for the process, given the stack size in bytes.
+    void AllocateMainThreadStack(u64 stack_size);
+
     /// Memory manager for this process.
     Kernel::VMManager vm_manager;
 
@@ -358,6 +366,9 @@ private:
     /// variable related facilities.
     Mutex mutex;
 
+    /// Address indicating the location of the process' dedicated TLS region.
+    VAddr tls_region_address = 0;
+
     /// Random values for svcGetInfo RandomEntropy
     std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy{};
 

+ 1 - 3
src/core/hle/kernel/svc.cpp

@@ -843,9 +843,7 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
             return RESULT_SUCCESS;
 
         case GetInfoType::UserExceptionContextAddr:
-            LOG_WARNING(Kernel_SVC,
-                        "(STUBBED) Attempted to query user exception context address, returned 0");
-            *result = 0;
+            *result = process->GetTLSRegionAddress();
             return RESULT_SUCCESS;
 
         case GetInfoType::TotalPhysicalMemoryAvailableWithoutSystemResource: