summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2022-10-02 14:26:30 -0700
committerGravatar bunnei2022-10-18 19:13:35 -0700
commitabcc009dff5d98b5a04229f3a82baab23d568244 (patch)
treee51f99cf493425a3cd331ffdaa1b984554e429aa
parentcore: hle: kernel: k_interrupt_manager: HandleInterrupt should not depend on ... (diff)
downloadyuzu-abcc009dff5d98b5a04229f3a82baab23d568244.tar.gz
yuzu-abcc009dff5d98b5a04229f3a82baab23d568244.tar.xz
yuzu-abcc009dff5d98b5a04229f3a82baab23d568244.zip
core: hle: kernel: k_process: Improve management of page table & cleanup.
-rw-r--r--src/core/hle/kernel/k_page_table.cpp23
-rw-r--r--src/core/hle/kernel/k_page_table.h8
-rw-r--r--src/core/hle/kernel/k_process.cpp62
-rw-r--r--src/core/hle/kernel/k_process.h31
-rw-r--r--src/core/hle/kernel/kernel.cpp23
-rw-r--r--src/core/hle/kernel/kernel.h3
-rw-r--r--src/core/hle/kernel/svc.cpp2
7 files changed, 92 insertions, 60 deletions
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
index fcffc0b88..22098c056 100644
--- a/src/core/hle/kernel/k_page_table.cpp
+++ b/src/core/hle/kernel/k_page_table.cpp
@@ -256,16 +256,21 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type
256 m_mapped_physical_memory_size = 0; 256 m_mapped_physical_memory_size = 0;
257 m_memory_pool = pool; 257 m_memory_pool = pool;
258 258
259 m_page_table_impl.Resize(m_address_space_width, PageBits); 259 m_page_table_impl = std::make_unique<Common::PageTable>();
260 m_page_table_impl->Resize(m_address_space_width, PageBits);
260 261
261 return m_memory_block_manager.Initialize(m_address_space_start, m_address_space_end, 262 return m_memory_block_manager.Initialize(m_address_space_start, m_address_space_end,
262 m_memory_block_slab_manager); 263 m_memory_block_slab_manager);
263} 264}
264 265
265void KPageTable::Finalize() { 266void KPageTable::Finalize() {
267 // Finalize memory blocks.
266 m_memory_block_manager.Finalize(m_memory_block_slab_manager, [&](VAddr addr, u64 size) { 268 m_memory_block_manager.Finalize(m_memory_block_slab_manager, [&](VAddr addr, u64 size) {
267 m_system.Memory().UnmapRegion(m_page_table_impl, addr, size); 269 m_system.Memory().UnmapRegion(*m_page_table_impl, addr, size);
268 }); 270 });
271
272 // Close the backing page table, as the destructor is not called for guest objects.
273 m_page_table_impl.reset();
269} 274}
270 275
271Result KPageTable::MapProcessCode(VAddr addr, size_t num_pages, KMemoryState state, 276Result KPageTable::MapProcessCode(VAddr addr, size_t num_pages, KMemoryState state,
@@ -514,7 +519,7 @@ Result KPageTable::MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages) {
514 // Begin traversal. 519 // Begin traversal.
515 Common::PageTable::TraversalContext context; 520 Common::PageTable::TraversalContext context;
516 Common::PageTable::TraversalEntry next_entry; 521 Common::PageTable::TraversalEntry next_entry;
517 R_UNLESS(m_page_table_impl.BeginTraversal(next_entry, context, addr), 522 R_UNLESS(m_page_table_impl->BeginTraversal(next_entry, context, addr),
518 ResultInvalidCurrentMemory); 523 ResultInvalidCurrentMemory);
519 524
520 // Prepare tracking variables. 525 // Prepare tracking variables.
@@ -525,7 +530,7 @@ Result KPageTable::MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages) {
525 // Iterate, adding to group as we go. 530 // Iterate, adding to group as we go.
526 const auto& memory_layout = m_system.Kernel().MemoryLayout(); 531 const auto& memory_layout = m_system.Kernel().MemoryLayout();
527 while (tot_size < size) { 532 while (tot_size < size) {
528 R_UNLESS(m_page_table_impl.ContinueTraversal(next_entry, context), 533 R_UNLESS(m_page_table_impl->ContinueTraversal(next_entry, context),
529 ResultInvalidCurrentMemory); 534 ResultInvalidCurrentMemory);
530 535
531 if (next_entry.phys_addr != (cur_addr + cur_size)) { 536 if (next_entry.phys_addr != (cur_addr + cur_size)) {
@@ -588,7 +593,7 @@ bool KPageTable::IsValidPageGroup(const KPageGroup& pg_ll, VAddr addr, size_t nu
588 // Begin traversal. 593 // Begin traversal.
589 Common::PageTable::TraversalContext context; 594 Common::PageTable::TraversalContext context;
590 Common::PageTable::TraversalEntry next_entry; 595 Common::PageTable::TraversalEntry next_entry;
591 if (!m_page_table_impl.BeginTraversal(next_entry, context, addr)) { 596 if (!m_page_table_impl->BeginTraversal(next_entry, context, addr)) {
592 return false; 597 return false;
593 } 598 }
594 599
@@ -599,7 +604,7 @@ bool KPageTable::IsValidPageGroup(const KPageGroup& pg_ll, VAddr addr, size_t nu
599 604
600 // Iterate, comparing expected to actual. 605 // Iterate, comparing expected to actual.
601 while (tot_size < size) { 606 while (tot_size < size) {
602 if (!m_page_table_impl.ContinueTraversal(next_entry, context)) { 607 if (!m_page_table_impl->ContinueTraversal(next_entry, context)) {
603 return false; 608 return false;
604 } 609 }
605 610
@@ -2042,7 +2047,7 @@ Result KPageTable::Operate(VAddr addr, size_t num_pages, const KPageGroup& page_
2042 2047
2043 switch (operation) { 2048 switch (operation) {
2044 case OperationType::MapGroup: 2049 case OperationType::MapGroup:
2045 m_system.Memory().MapMemoryRegion(m_page_table_impl, addr, size, node.GetAddress()); 2050 m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, size, node.GetAddress());
2046 break; 2051 break;
2047 default: 2052 default:
2048 ASSERT(false); 2053 ASSERT(false);
@@ -2064,12 +2069,12 @@ Result KPageTable::Operate(VAddr addr, size_t num_pages, KMemoryPermission perm,
2064 2069
2065 switch (operation) { 2070 switch (operation) {
2066 case OperationType::Unmap: 2071 case OperationType::Unmap:
2067 m_system.Memory().UnmapRegion(m_page_table_impl, addr, num_pages * PageSize); 2072 m_system.Memory().UnmapRegion(*m_page_table_impl, addr, num_pages * PageSize);
2068 break; 2073 break;
2069 case OperationType::Map: { 2074 case OperationType::Map: {
2070 ASSERT(map_addr); 2075 ASSERT(map_addr);
2071 ASSERT(Common::IsAligned(map_addr, PageSize)); 2076 ASSERT(Common::IsAligned(map_addr, PageSize));
2072 m_system.Memory().MapMemoryRegion(m_page_table_impl, addr, num_pages * PageSize, map_addr); 2077 m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, num_pages * PageSize, map_addr);
2073 break; 2078 break;
2074 } 2079 }
2075 case OperationType::ChangePermissions: 2080 case OperationType::ChangePermissions:
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h
index 225854319..1811d3e2d 100644
--- a/src/core/hle/kernel/k_page_table.h
+++ b/src/core/hle/kernel/k_page_table.h
@@ -88,11 +88,11 @@ public:
88 KMemoryAttribute attr_mask, KMemoryAttribute attr); 88 KMemoryAttribute attr_mask, KMemoryAttribute attr);
89 89
90 Common::PageTable& PageTableImpl() { 90 Common::PageTable& PageTableImpl() {
91 return m_page_table_impl; 91 return *m_page_table_impl;
92 } 92 }
93 93
94 const Common::PageTable& PageTableImpl() const { 94 const Common::PageTable& PageTableImpl() const {
95 return m_page_table_impl; 95 return *m_page_table_impl;
96 } 96 }
97 97
98 bool CanContain(VAddr addr, size_t size, KMemoryState state) const; 98 bool CanContain(VAddr addr, size_t size, KMemoryState state) const;
@@ -303,7 +303,7 @@ public:
303 return IsKernel() ? 1 : 4; 303 return IsKernel() ? 1 : 4;
304 } 304 }
305 PAddr GetPhysicalAddr(VAddr addr) const { 305 PAddr GetPhysicalAddr(VAddr addr) const {
306 const auto backing_addr = m_page_table_impl.backing_addr[addr >> PageBits]; 306 const auto backing_addr = m_page_table_impl->backing_addr[addr >> PageBits];
307 ASSERT(backing_addr); 307 ASSERT(backing_addr);
308 return backing_addr + addr; 308 return backing_addr + addr;
309 } 309 }
@@ -365,7 +365,7 @@ private:
365 KMemoryManager::Pool m_memory_pool{KMemoryManager::Pool::Application}; 365 KMemoryManager::Pool m_memory_pool{KMemoryManager::Pool::Application};
366 KMemoryManager::Direction m_allocation_option{KMemoryManager::Direction::FromFront}; 366 KMemoryManager::Direction m_allocation_option{KMemoryManager::Direction::FromFront};
367 367
368 Common::PageTable m_page_table_impl; 368 std::unique_ptr<Common::PageTable> m_page_table_impl;
369 369
370 Core::System& m_system; 370 Core::System& m_system;
371}; 371};
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index abc2115bd..1a0aec56a 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -72,6 +72,7 @@ Result KProcess::Initialize(KProcess* process, Core::System& system, std::string
72 72
73 process->name = std::move(process_name); 73 process->name = std::move(process_name);
74 process->resource_limit = res_limit; 74 process->resource_limit = res_limit;
75 process->system_resource_address = 0;
75 process->state = State::Created; 76 process->state = State::Created;
76 process->program_id = 0; 77 process->program_id = 0;
77 process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID() 78 process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID()
@@ -92,6 +93,7 @@ Result KProcess::Initialize(KProcess* process, Core::System& system, std::string
92 process->exception_thread = nullptr; 93 process->exception_thread = nullptr;
93 process->is_suspended = false; 94 process->is_suspended = false;
94 process->schedule_count = 0; 95 process->schedule_count = 0;
96 process->is_handle_table_initialized = false;
95 97
96 // Open a reference to the resource limit. 98 // Open a reference to the resource limit.
97 process->resource_limit->Open(); 99 process->resource_limit->Open();
@@ -121,9 +123,9 @@ void KProcess::DecrementRunningThreadCount() {
121 } 123 }
122} 124}
123 125
124u64 KProcess::GetTotalPhysicalMemoryAvailable() const { 126u64 KProcess::GetTotalPhysicalMemoryAvailable() {
125 const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) + 127 const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) +
126 page_table->GetNormalMemorySize() + GetSystemResourceSize() + image_size + 128 page_table.GetNormalMemorySize() + GetSystemResourceSize() + image_size +
127 main_thread_stack_size}; 129 main_thread_stack_size};
128 if (const auto pool_size = kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application); 130 if (const auto pool_size = kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application);
129 capacity != pool_size) { 131 capacity != pool_size) {
@@ -135,16 +137,16 @@ u64 KProcess::GetTotalPhysicalMemoryAvailable() const {
135 return memory_usage_capacity; 137 return memory_usage_capacity;
136} 138}
137 139
138u64 KProcess::GetTotalPhysicalMemoryAvailableWithoutSystemResource() const { 140u64 KProcess::GetTotalPhysicalMemoryAvailableWithoutSystemResource() {
139 return GetTotalPhysicalMemoryAvailable() - GetSystemResourceSize(); 141 return GetTotalPhysicalMemoryAvailable() - GetSystemResourceSize();
140} 142}
141 143
142u64 KProcess::GetTotalPhysicalMemoryUsed() const { 144u64 KProcess::GetTotalPhysicalMemoryUsed() {
143 return image_size + main_thread_stack_size + page_table->GetNormalMemorySize() + 145 return image_size + main_thread_stack_size + page_table.GetNormalMemorySize() +
144 GetSystemResourceSize(); 146 GetSystemResourceSize();
145} 147}
146 148
147u64 KProcess::GetTotalPhysicalMemoryUsedWithoutSystemResource() const { 149u64 KProcess::GetTotalPhysicalMemoryUsedWithoutSystemResource() {
148 return GetTotalPhysicalMemoryUsed() - GetSystemResourceUsage(); 150 return GetTotalPhysicalMemoryUsed() - GetSystemResourceUsage();
149} 151}
150 152
@@ -348,6 +350,9 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
348 system_resource_size = metadata.GetSystemResourceSize(); 350 system_resource_size = metadata.GetSystemResourceSize();
349 image_size = code_size; 351 image_size = code_size;
350 352
353 // We currently do not support process-specific system resource
354 UNIMPLEMENTED_IF(system_resource_size != 0);
355
351 KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory, 356 KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory,
352 code_size + system_resource_size); 357 code_size + system_resource_size);
353 if (!memory_reservation.Succeeded()) { 358 if (!memory_reservation.Succeeded()) {
@@ -356,7 +361,7 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
356 return ResultLimitReached; 361 return ResultLimitReached;
357 } 362 }
358 // Initialize proces address space 363 // Initialize proces address space
359 if (const Result result{page_table->InitializeForProcess( 364 if (const Result result{page_table.InitializeForProcess(
360 metadata.GetAddressSpaceType(), false, 0x8000000, code_size, 365 metadata.GetAddressSpaceType(), false, 0x8000000, code_size,
361 &kernel.GetApplicationMemoryBlockManager(), KMemoryManager::Pool::Application)}; 366 &kernel.GetApplicationMemoryBlockManager(), KMemoryManager::Pool::Application)};
362 result.IsError()) { 367 result.IsError()) {
@@ -364,9 +369,9 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
364 } 369 }
365 370
366 // Map process code region 371 // Map process code region
367 if (const Result result{page_table->MapProcessCode(page_table->GetCodeRegionStart(), 372 if (const Result result{page_table.MapProcessCode(page_table.GetCodeRegionStart(),
368 code_size / PageSize, KMemoryState::Code, 373 code_size / PageSize, KMemoryState::Code,
369 KMemoryPermission::None)}; 374 KMemoryPermission::None)};
370 result.IsError()) { 375 result.IsError()) {
371 return result; 376 return result;
372 } 377 }
@@ -374,7 +379,7 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
374 // Initialize process capabilities 379 // Initialize process capabilities
375 const auto& caps{metadata.GetKernelCapabilities()}; 380 const auto& caps{metadata.GetKernelCapabilities()};
376 if (const Result result{ 381 if (const Result result{
377 capabilities.InitializeForUserProcess(caps.data(), caps.size(), *page_table)}; 382 capabilities.InitializeForUserProcess(caps.data(), caps.size(), page_table)};
378 result.IsError()) { 383 result.IsError()) {
379 return result; 384 return result;
380 } 385 }
@@ -384,12 +389,12 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
384 case FileSys::ProgramAddressSpaceType::Is32Bit: 389 case FileSys::ProgramAddressSpaceType::Is32Bit:
385 case FileSys::ProgramAddressSpaceType::Is36Bit: 390 case FileSys::ProgramAddressSpaceType::Is36Bit:
386 case FileSys::ProgramAddressSpaceType::Is39Bit: 391 case FileSys::ProgramAddressSpaceType::Is39Bit:
387 memory_usage_capacity = page_table->GetHeapRegionEnd() - page_table->GetHeapRegionStart(); 392 memory_usage_capacity = page_table.GetHeapRegionEnd() - page_table.GetHeapRegionStart();
388 break; 393 break;
389 394
390 case FileSys::ProgramAddressSpaceType::Is32BitNoMap: 395 case FileSys::ProgramAddressSpaceType::Is32BitNoMap:
391 memory_usage_capacity = page_table->GetHeapRegionEnd() - page_table->GetHeapRegionStart() + 396 memory_usage_capacity = page_table.GetHeapRegionEnd() - page_table.GetHeapRegionStart() +
392 page_table->GetAliasRegionEnd() - page_table->GetAliasRegionStart(); 397 page_table.GetAliasRegionEnd() - page_table.GetAliasRegionStart();
393 break; 398 break;
394 399
395 default: 400 default:
@@ -397,7 +402,7 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
397 } 402 }
398 403
399 // Create TLS region 404 // Create TLS region
400 R_TRY(this->CreateThreadLocalRegion(std::addressof(tls_region_address))); 405 R_TRY(this->CreateThreadLocalRegion(std::addressof(plr_address)));
401 memory_reservation.Commit(); 406 memory_reservation.Commit();
402 407
403 return handle_table.Initialize(capabilities.GetHandleTableSize()); 408 return handle_table.Initialize(capabilities.GetHandleTableSize());
@@ -409,7 +414,7 @@ void KProcess::Run(s32 main_thread_priority, u64 stack_size) {
409 resource_limit->Reserve(LimitableResource::PhysicalMemory, main_thread_stack_size); 414 resource_limit->Reserve(LimitableResource::PhysicalMemory, main_thread_stack_size);
410 415
411 const std::size_t heap_capacity{memory_usage_capacity - (main_thread_stack_size + image_size)}; 416 const std::size_t heap_capacity{memory_usage_capacity - (main_thread_stack_size + image_size)};
412 ASSERT(!page_table->SetMaxHeapSize(heap_capacity).IsError()); 417 ASSERT(!page_table.SetMaxHeapSize(heap_capacity).IsError());
413 418
414 ChangeState(State::Running); 419 ChangeState(State::Running);
415 420
@@ -437,8 +442,8 @@ void KProcess::PrepareForTermination() {
437 442
438 stop_threads(kernel.System().GlobalSchedulerContext().GetThreadList()); 443 stop_threads(kernel.System().GlobalSchedulerContext().GetThreadList());
439 444
440 this->DeleteThreadLocalRegion(tls_region_address); 445 this->DeleteThreadLocalRegion(plr_address);
441 tls_region_address = 0; 446 plr_address = 0;
442 447
443 if (resource_limit) { 448 if (resource_limit) {
444 resource_limit->Release(LimitableResource::PhysicalMemory, 449 resource_limit->Release(LimitableResource::PhysicalMemory,
@@ -474,7 +479,7 @@ void KProcess::Finalize() {
474 } 479 }
475 480
476 // Finalize the page table. 481 // Finalize the page table.
477 page_table.reset(); 482 page_table.Finalize();
478 483
479 // Perform inherited finalization. 484 // Perform inherited finalization.
480 KAutoObjectWithSlabHeapAndContainer<KProcess, KWorkerTask>::Finalize(); 485 KAutoObjectWithSlabHeapAndContainer<KProcess, KWorkerTask>::Finalize();
@@ -628,7 +633,7 @@ bool KProcess::RemoveWatchpoint(Core::System& system, VAddr addr, u64 size,
628void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) { 633void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) {
629 const auto ReprotectSegment = [&](const CodeSet::Segment& segment, 634 const auto ReprotectSegment = [&](const CodeSet::Segment& segment,
630 Svc::MemoryPermission permission) { 635 Svc::MemoryPermission permission) {
631 page_table->SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission); 636 page_table.SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission);
632 }; 637 };
633 638
634 kernel.System().Memory().WriteBlock(*this, base_addr, code_set.memory.data(), 639 kernel.System().Memory().WriteBlock(*this, base_addr, code_set.memory.data(),
@@ -645,8 +650,7 @@ bool KProcess::IsSignaled() const {
645} 650}
646 651
647KProcess::KProcess(KernelCore& kernel_) 652KProcess::KProcess(KernelCore& kernel_)
648 : KAutoObjectWithSlabHeapAndContainer{kernel_}, page_table{std::make_unique<KPageTable>( 653 : KAutoObjectWithSlabHeapAndContainer{kernel_}, page_table{kernel_.System()},
649 kernel_.System())},
650 handle_table{kernel_}, address_arbiter{kernel_.System()}, condition_var{kernel_.System()}, 654 handle_table{kernel_}, address_arbiter{kernel_.System()}, condition_var{kernel_.System()},
651 state_lock{kernel_}, list_lock{kernel_} {} 655 state_lock{kernel_}, list_lock{kernel_} {}
652 656
@@ -668,11 +672,11 @@ Result KProcess::AllocateMainThreadStack(std::size_t stack_size) {
668 // The kernel always ensures that the given stack size is page aligned. 672 // The kernel always ensures that the given stack size is page aligned.
669 main_thread_stack_size = Common::AlignUp(stack_size, PageSize); 673 main_thread_stack_size = Common::AlignUp(stack_size, PageSize);
670 674
671 const VAddr start{page_table->GetStackRegionStart()}; 675 const VAddr start{page_table.GetStackRegionStart()};
672 const std::size_t size{page_table->GetStackRegionEnd() - start}; 676 const std::size_t size{page_table.GetStackRegionEnd() - start};
673 677
674 CASCADE_RESULT(main_thread_stack_top, 678 CASCADE_RESULT(main_thread_stack_top,
675 page_table->AllocateAndMapMemory( 679 page_table.AllocateAndMapMemory(
676 main_thread_stack_size / PageSize, PageSize, false, start, size / PageSize, 680 main_thread_stack_size / PageSize, PageSize, false, start, size / PageSize,
677 KMemoryState::Stack, KMemoryPermission::UserReadWrite)); 681 KMemoryState::Stack, KMemoryPermission::UserReadWrite));
678 682
@@ -681,4 +685,12 @@ Result KProcess::AllocateMainThreadStack(std::size_t stack_size) {
681 return ResultSuccess; 685 return ResultSuccess;
682} 686}
683 687
688void KProcess::FinalizeHandleTable() {
689 // Finalize the table.
690 handle_table.Finalize();
691
692 // Note that the table is finalized.
693 is_handle_table_initialized = false;
694}
695
684} // namespace Kernel 696} // namespace Kernel
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index b1c7da454..fcc2897f9 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -13,6 +13,7 @@
13#include "core/hle/kernel/k_auto_object.h" 13#include "core/hle/kernel/k_auto_object.h"
14#include "core/hle/kernel/k_condition_variable.h" 14#include "core/hle/kernel/k_condition_variable.h"
15#include "core/hle/kernel/k_handle_table.h" 15#include "core/hle/kernel/k_handle_table.h"
16#include "core/hle/kernel/k_page_table.h"
16#include "core/hle/kernel/k_synchronization_object.h" 17#include "core/hle/kernel/k_synchronization_object.h"
17#include "core/hle/kernel/k_thread_local_page.h" 18#include "core/hle/kernel/k_thread_local_page.h"
18#include "core/hle/kernel/k_worker_task.h" 19#include "core/hle/kernel/k_worker_task.h"
@@ -31,7 +32,6 @@ class ProgramMetadata;
31namespace Kernel { 32namespace Kernel {
32 33
33class KernelCore; 34class KernelCore;
34class KPageTable;
35class KResourceLimit; 35class KResourceLimit;
36class KThread; 36class KThread;
37class KSharedMemoryInfo; 37class KSharedMemoryInfo;
@@ -107,12 +107,12 @@ public:
107 107
108 /// Gets a reference to the process' page table. 108 /// Gets a reference to the process' page table.
109 KPageTable& PageTable() { 109 KPageTable& PageTable() {
110 return *page_table; 110 return page_table;
111 } 111 }
112 112
113 /// Gets const a reference to the process' page table. 113 /// Gets const a reference to the process' page table.
114 const KPageTable& PageTable() const { 114 const KPageTable& PageTable() const {
115 return *page_table; 115 return page_table;
116 } 116 }
117 117
118 /// Gets a reference to the process' handle table. 118 /// Gets a reference to the process' handle table.
@@ -150,9 +150,8 @@ public:
150 return address_arbiter.WaitForAddress(address, arb_type, value, timeout); 150 return address_arbiter.WaitForAddress(address, arb_type, value, timeout);
151 } 151 }
152 152
153 /// Gets the address to the process' dedicated TLS region. 153 VAddr GetProcessLocalRegionAddress() const {
154 VAddr GetTLSRegionAddress() const { 154 return plr_address;
155 return tls_region_address;
156 } 155 }
157 156
158 /// Gets the current status of the process 157 /// Gets the current status of the process
@@ -279,18 +278,18 @@ public:
279 } 278 }
280 279
281 /// Retrieves the total physical memory available to this process in bytes. 280 /// Retrieves the total physical memory available to this process in bytes.
282 u64 GetTotalPhysicalMemoryAvailable() const; 281 u64 GetTotalPhysicalMemoryAvailable();
283 282
284 /// Retrieves the total physical memory available to this process in bytes, 283 /// Retrieves the total physical memory available to this process in bytes,
285 /// without the size of the personal system resource heap added to it. 284 /// without the size of the personal system resource heap added to it.
286 u64 GetTotalPhysicalMemoryAvailableWithoutSystemResource() const; 285 u64 GetTotalPhysicalMemoryAvailableWithoutSystemResource();
287 286
288 /// Retrieves the total physical memory used by this process in bytes. 287 /// Retrieves the total physical memory used by this process in bytes.
289 u64 GetTotalPhysicalMemoryUsed() const; 288 u64 GetTotalPhysicalMemoryUsed();
290 289
291 /// Retrieves the total physical memory used by this process in bytes, 290 /// Retrieves the total physical memory used by this process in bytes,
292 /// without the size of the personal system resource heap added to it. 291 /// without the size of the personal system resource heap added to it.
293 u64 GetTotalPhysicalMemoryUsedWithoutSystemResource() const; 292 u64 GetTotalPhysicalMemoryUsedWithoutSystemResource();
294 293
295 /// Gets the list of all threads created with this process as their owner. 294 /// Gets the list of all threads created with this process as their owner.
296 std::list<KThread*>& GetThreadList() { 295 std::list<KThread*>& GetThreadList() {
@@ -413,8 +412,10 @@ private:
413 /// Allocates the main thread stack for the process, given the stack size in bytes. 412 /// Allocates the main thread stack for the process, given the stack size in bytes.
414 Result AllocateMainThreadStack(std::size_t stack_size); 413 Result AllocateMainThreadStack(std::size_t stack_size);
415 414
415 void FinalizeHandleTable();
416
416 /// Memory manager for this process 417 /// Memory manager for this process
417 std::unique_ptr<KPageTable> page_table; 418 KPageTable page_table;
418 419
419 /// Current status of the process 420 /// Current status of the process
420 State state{}; 421 State state{};
@@ -433,6 +434,8 @@ private:
433 /// Resource limit descriptor for this process 434 /// Resource limit descriptor for this process
434 KResourceLimit* resource_limit{}; 435 KResourceLimit* resource_limit{};
435 436
437 VAddr system_resource_address{};
438
436 /// The ideal CPU core for this process, threads are scheduled on this core by default. 439 /// The ideal CPU core for this process, threads are scheduled on this core by default.
437 u8 ideal_core = 0; 440 u8 ideal_core = 0;
438 441
@@ -459,7 +462,7 @@ private:
459 KConditionVariable condition_var; 462 KConditionVariable condition_var;
460 463
461 /// Address indicating the location of the process' dedicated TLS region. 464 /// Address indicating the location of the process' dedicated TLS region.
462 VAddr tls_region_address = 0; 465 VAddr plr_address = 0;
463 466
464 /// Random values for svcGetInfo RandomEntropy 467 /// Random values for svcGetInfo RandomEntropy
465 std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy{}; 468 std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy{};
@@ -485,8 +488,12 @@ private:
485 /// Schedule count of this process 488 /// Schedule count of this process
486 s64 schedule_count{}; 489 s64 schedule_count{};
487 490
491 size_t memory_release_hint{};
492
488 bool is_signaled{}; 493 bool is_signaled{};
489 bool is_suspended{}; 494 bool is_suspended{};
495 bool is_immortal{};
496 bool is_handle_table_initialized{};
490 bool is_initialized{}; 497 bool is_initialized{};
491 498
492 std::atomic<u16> num_running_threads{}; 499 std::atomic<u16> num_running_threads{};
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index b6bbd4984..6879de9ef 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -95,6 +95,15 @@ struct KernelCore::Impl {
95 } 95 }
96 } 96 }
97 97
98 void CloseCurrentProcess() {
99 (*current_process).Finalize();
100 // current_process->Close();
101 // TODO: The current process should be destroyed based on accurate ref counting after
102 // calling Close(). Adding a manual Destroy() call instead to avoid a memory leak.
103 (*current_process).Destroy();
104 current_process = nullptr;
105 }
106
98 void Shutdown() { 107 void Shutdown() {
99 is_shutting_down.store(true, std::memory_order_relaxed); 108 is_shutting_down.store(true, std::memory_order_relaxed);
100 SCOPE_EXIT({ is_shutting_down.store(false, std::memory_order_relaxed); }); 109 SCOPE_EXIT({ is_shutting_down.store(false, std::memory_order_relaxed); });
@@ -157,15 +166,7 @@ struct KernelCore::Impl {
157 } 166 }
158 } 167 }
159 168
160 // Shutdown all processes. 169 CloseCurrentProcess();
161 if (current_process) {
162 (*current_process).Finalize();
163 // current_process->Close();
164 // TODO: The current process should be destroyed based on accurate ref counting after
165 // calling Close(). Adding a manual Destroy() call instead to avoid a memory leak.
166 (*current_process).Destroy();
167 current_process = nullptr;
168 }
169 170
170 // Track kernel objects that were not freed on shutdown 171 // Track kernel objects that were not freed on shutdown
171 { 172 {
@@ -870,6 +871,10 @@ const KProcess* KernelCore::CurrentProcess() const {
870 return impl->current_process; 871 return impl->current_process;
871} 872}
872 873
874void KernelCore::CloseCurrentProcess() {
875 impl->CloseCurrentProcess();
876}
877
873const std::vector<KProcess*>& KernelCore::GetProcessList() const { 878const std::vector<KProcess*>& KernelCore::GetProcessList() const {
874 return impl->process_list; 879 return impl->process_list;
875} 880}
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 79e66483e..6eded9539 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -131,6 +131,9 @@ public:
131 /// Retrieves a const pointer to the current process. 131 /// Retrieves a const pointer to the current process.
132 const KProcess* CurrentProcess() const; 132 const KProcess* CurrentProcess() const;
133 133
134 /// Closes the current process.
135 void CloseCurrentProcess();
136
134 /// Retrieves the list of processes. 137 /// Retrieves the list of processes.
135 const std::vector<KProcess*>& GetProcessList() const; 138 const std::vector<KProcess*>& GetProcessList() const;
136 139
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index bac61fd09..b07ae3f02 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -933,7 +933,7 @@ static Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle han
933 return ResultSuccess; 933 return ResultSuccess;
934 934
935 case GetInfoType::UserExceptionContextAddr: 935 case GetInfoType::UserExceptionContextAddr:
936 *result = process->GetTLSRegionAddress(); 936 *result = process->GetProcessLocalRegionAddress();
937 return ResultSuccess; 937 return ResultSuccess;
938 938
939 case GetInfoType::TotalPhysicalMemoryAvailableWithoutSystemResource: 939 case GetInfoType::TotalPhysicalMemoryAvailableWithoutSystemResource: