diff options
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r-- | src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp | 37 | ||||
-rw-r--r-- | src/core/hle/kernel/hle_ipc.cpp | 3 | ||||
-rw-r--r-- | src/core/hle/kernel/k_address_space_info.cpp | 35 | ||||
-rw-r--r-- | src/core/hle/kernel/k_auto_object.cpp | 9 | ||||
-rw-r--r-- | src/core/hle/kernel/k_auto_object.h | 12 | ||||
-rw-r--r-- | src/core/hle/kernel/k_memory_layout.board.nintendo_nx.cpp | 5 | ||||
-rw-r--r-- | src/core/hle/kernel/k_memory_layout.h | 27 | ||||
-rw-r--r-- | src/core/hle/kernel/k_page_table.cpp | 5 | ||||
-rw-r--r-- | src/core/hle/kernel/k_process.cpp | 8 | ||||
-rw-r--r-- | src/core/hle/kernel/k_resource_limit.cpp | 1 | ||||
-rw-r--r-- | src/core/hle/kernel/k_server_session.cpp | 5 | ||||
-rw-r--r-- | src/core/hle/kernel/k_trace.h | 6 | ||||
-rw-r--r-- | src/core/hle/kernel/kernel.cpp | 114 | ||||
-rw-r--r-- | src/core/hle/kernel/kernel.h | 17 | ||||
-rw-r--r-- | src/core/hle/kernel/svc.cpp | 6 |
15 files changed, 211 insertions, 79 deletions
diff --git a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp index 86472b5ce..6f335c251 100644 --- a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp +++ b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp @@ -4,7 +4,8 @@ #include <random> -#include "common/common_sizes.h" +#include "common/literals.h" + #include "core/hle/kernel/board/nintendo/nx/k_system_control.h" #include "core/hle/kernel/board/nintendo/nx/secure_monitor.h" #include "core/hle/kernel/k_trace.h" @@ -25,6 +26,8 @@ constexpr const std::size_t RequiredNonSecureSystemMemorySize = namespace { +using namespace Common::Literals; + u32 GetMemoryModeForInit() { return 0x01; } @@ -57,11 +60,11 @@ size_t KSystemControl::Init::GetIntendedMemorySize() { switch (GetMemorySizeForInit()) { case Smc::MemorySize_4GB: default: // All invalid modes should go to 4GB. - return Common::Size_4_GB; + return 4_GiB; case Smc::MemorySize_6GB: - return Common::Size_6_GB; + return 6_GiB; case Smc::MemorySize_8GB: - return Common::Size_8_GB; + return 8_GiB; } } @@ -79,17 +82,17 @@ std::size_t KSystemControl::Init::GetApplicationPoolSize() { switch (GetMemoryArrangeForInit()) { case Smc::MemoryArrangement_4GB: default: - return Common::Size_3285_MB; + return 3285_MiB; case Smc::MemoryArrangement_4GBForAppletDev: - return Common::Size_2048_MB; + return 2048_MiB; case Smc::MemoryArrangement_4GBForSystemDev: - return Common::Size_3285_MB; + return 3285_MiB; case Smc::MemoryArrangement_6GB: - return Common::Size_4916_MB; + return 4916_MiB; case Smc::MemoryArrangement_6GBForAppletDev: - return Common::Size_3285_MB; + return 3285_MiB; case Smc::MemoryArrangement_8GB: - return Common::Size_4916_MB; + return 4916_MiB; } }(); @@ -103,22 +106,22 @@ size_t KSystemControl::Init::GetAppletPoolSize() { switch (GetMemoryArrangeForInit()) { case Smc::MemoryArrangement_4GB: default: - return Common::Size_507_MB; + return 507_MiB; case Smc::MemoryArrangement_4GBForAppletDev: - return Common::Size_1554_MB; + return 1554_MiB; case Smc::MemoryArrangement_4GBForSystemDev: - return Common::Size_448_MB; + return 448_MiB; case Smc::MemoryArrangement_6GB: - return Common::Size_562_MB; + return 562_MiB; case Smc::MemoryArrangement_6GBForAppletDev: - return Common::Size_2193_MB; + return 2193_MiB; case Smc::MemoryArrangement_8GB: - return Common::Size_2193_MB; + return 2193_MiB; } }(); // Return (possibly) adjusted size. - constexpr size_t ExtraSystemMemoryForAtmosphere = Common::Size_33_MB; + constexpr size_t ExtraSystemMemoryForAtmosphere = 33_MiB; return base_pool_size - ExtraSystemMemoryForAtmosphere - KTraceBufferSize; } diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 28ed6265a..ca68fc325 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -58,6 +58,9 @@ bool SessionRequestManager::HasSessionRequestHandler(const HLERequestContext& co void SessionRequestHandler::ClientConnected(KServerSession* session) { session->ClientConnected(shared_from_this()); + + // Ensure our server session is tracked globally. + kernel.RegisterServerSession(session); } void SessionRequestHandler::ClientDisconnected(KServerSession* session) { diff --git a/src/core/hle/kernel/k_address_space_info.cpp b/src/core/hle/kernel/k_address_space_info.cpp index c7549f7a2..ca29edc88 100644 --- a/src/core/hle/kernel/k_address_space_info.cpp +++ b/src/core/hle/kernel/k_address_space_info.cpp @@ -5,34 +5,37 @@ #include <array> #include "common/assert.h" -#include "common/common_sizes.h" +#include "common/literals.h" #include "core/hle/kernel/k_address_space_info.h" namespace Kernel { namespace { +using namespace Common::Literals; + +constexpr u64 Size_Invalid = UINT64_MAX; + // clang-format off constexpr std::array<KAddressSpaceInfo, 13> AddressSpaceInfos{{ - { .bit_width = 32, .address = Common::Size_2_MB , .size = Common::Size_1_GB - Common::Size_2_MB , .type = KAddressSpaceInfo::Type::MapSmall, }, - { .bit_width = 32, .address = Common::Size_1_GB , .size = Common::Size_4_GB - Common::Size_1_GB , .type = KAddressSpaceInfo::Type::MapLarge, }, - { .bit_width = 32, .address = Common::Size_Invalid, .size = Common::Size_1_GB , .type = KAddressSpaceInfo::Type::Alias, }, - { .bit_width = 32, .address = Common::Size_Invalid, .size = Common::Size_1_GB , .type = KAddressSpaceInfo::Type::Heap, }, - { .bit_width = 36, .address = Common::Size_128_MB , .size = Common::Size_2_GB - Common::Size_128_MB, .type = KAddressSpaceInfo::Type::MapSmall, }, - { .bit_width = 36, .address = Common::Size_2_GB , .size = Common::Size_64_GB - Common::Size_2_GB , .type = KAddressSpaceInfo::Type::MapLarge, }, - { .bit_width = 36, .address = Common::Size_Invalid, .size = Common::Size_6_GB , .type = KAddressSpaceInfo::Type::Heap, }, - { .bit_width = 36, .address = Common::Size_Invalid, .size = Common::Size_6_GB , .type = KAddressSpaceInfo::Type::Alias, }, - { .bit_width = 39, .address = Common::Size_128_MB , .size = Common::Size_512_GB - Common::Size_128_MB, .type = KAddressSpaceInfo::Type::Map39Bit, }, - { .bit_width = 39, .address = Common::Size_Invalid, .size = Common::Size_64_GB , .type = KAddressSpaceInfo::Type::MapSmall }, - { .bit_width = 39, .address = Common::Size_Invalid, .size = Common::Size_6_GB , .type = KAddressSpaceInfo::Type::Heap, }, - { .bit_width = 39, .address = Common::Size_Invalid, .size = Common::Size_64_GB , .type = KAddressSpaceInfo::Type::Alias, }, - { .bit_width = 39, .address = Common::Size_Invalid, .size = Common::Size_2_GB , .type = KAddressSpaceInfo::Type::Stack, }, + { .bit_width = 32, .address = 2_MiB , .size = 1_GiB - 2_MiB , .type = KAddressSpaceInfo::Type::MapSmall, }, + { .bit_width = 32, .address = 1_GiB , .size = 4_GiB - 1_GiB , .type = KAddressSpaceInfo::Type::MapLarge, }, + { .bit_width = 32, .address = Size_Invalid, .size = 1_GiB , .type = KAddressSpaceInfo::Type::Alias, }, + { .bit_width = 32, .address = Size_Invalid, .size = 1_GiB , .type = KAddressSpaceInfo::Type::Heap, }, + { .bit_width = 36, .address = 128_MiB , .size = 2_GiB - 128_MiB, .type = KAddressSpaceInfo::Type::MapSmall, }, + { .bit_width = 36, .address = 2_GiB , .size = 64_GiB - 2_GiB , .type = KAddressSpaceInfo::Type::MapLarge, }, + { .bit_width = 36, .address = Size_Invalid, .size = 6_GiB , .type = KAddressSpaceInfo::Type::Heap, }, + { .bit_width = 36, .address = Size_Invalid, .size = 6_GiB , .type = KAddressSpaceInfo::Type::Alias, }, + { .bit_width = 39, .address = 128_MiB , .size = 512_GiB - 128_MiB, .type = KAddressSpaceInfo::Type::Map39Bit, }, + { .bit_width = 39, .address = Size_Invalid, .size = 64_GiB , .type = KAddressSpaceInfo::Type::MapSmall }, + { .bit_width = 39, .address = Size_Invalid, .size = 6_GiB , .type = KAddressSpaceInfo::Type::Heap, }, + { .bit_width = 39, .address = Size_Invalid, .size = 64_GiB , .type = KAddressSpaceInfo::Type::Alias, }, + { .bit_width = 39, .address = Size_Invalid, .size = 2_GiB , .type = KAddressSpaceInfo::Type::Stack, }, }}; // clang-format on constexpr bool IsAllowedIndexForAddress(std::size_t index) { - return index < AddressSpaceInfos.size() && - AddressSpaceInfos[index].address != Common::Size_Invalid; + return index < AddressSpaceInfos.size() && AddressSpaceInfos[index].address != Size_Invalid; } using IndexArray = diff --git a/src/core/hle/kernel/k_auto_object.cpp b/src/core/hle/kernel/k_auto_object.cpp index dbe237f09..c99a9ebb7 100644 --- a/src/core/hle/kernel/k_auto_object.cpp +++ b/src/core/hle/kernel/k_auto_object.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/kernel/k_auto_object.h" +#include "core/hle/kernel/kernel.h" namespace Kernel { @@ -11,4 +12,12 @@ KAutoObject* KAutoObject::Create(KAutoObject* obj) { return obj; } +void KAutoObject::RegisterWithKernel() { + kernel.RegisterKernelObject(this); +} + +void KAutoObject::UnregisterWithKernel() { + kernel.UnregisterKernelObject(this); +} + } // namespace Kernel diff --git a/src/core/hle/kernel/k_auto_object.h b/src/core/hle/kernel/k_auto_object.h index 88a052f65..e4fcdbc67 100644 --- a/src/core/hle/kernel/k_auto_object.h +++ b/src/core/hle/kernel/k_auto_object.h @@ -85,8 +85,12 @@ private: KERNEL_AUTOOBJECT_TRAITS(KAutoObject, KAutoObject); public: - explicit KAutoObject(KernelCore& kernel_) : kernel(kernel_) {} - virtual ~KAutoObject() = default; + explicit KAutoObject(KernelCore& kernel_) : kernel(kernel_) { + RegisterWithKernel(); + } + virtual ~KAutoObject() { + UnregisterWithKernel(); + } static KAutoObject* Create(KAutoObject* ptr); @@ -166,6 +170,10 @@ public: } } +private: + void RegisterWithKernel(); + void UnregisterWithKernel(); + protected: KernelCore& kernel; std::string name; diff --git a/src/core/hle/kernel/k_memory_layout.board.nintendo_nx.cpp b/src/core/hle/kernel/k_memory_layout.board.nintendo_nx.cpp index a78551291..af652af58 100644 --- a/src/core/hle/kernel/k_memory_layout.board.nintendo_nx.cpp +++ b/src/core/hle/kernel/k_memory_layout.board.nintendo_nx.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "common/alignment.h" +#include "common/literals.h" #include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_memory_manager.h" #include "core/hle/kernel/k_system_control.h" @@ -12,8 +13,10 @@ namespace Kernel { namespace { +using namespace Common::Literals; + constexpr size_t CarveoutAlignment = 0x20000; -constexpr size_t CarveoutSizeMax = (512ULL * 1024 * 1024) - CarveoutAlignment; +constexpr size_t CarveoutSizeMax = (512_MiB) - CarveoutAlignment; bool SetupPowerManagementControllerMemoryRegion(KMemoryLayout& memory_layout) { // Above firmware 2.0.0, the PMC is not mappable. diff --git a/src/core/hle/kernel/k_memory_layout.h b/src/core/hle/kernel/k_memory_layout.h index 288642d9a..57ff538cc 100644 --- a/src/core/hle/kernel/k_memory_layout.h +++ b/src/core/hle/kernel/k_memory_layout.h @@ -7,8 +7,7 @@ #include <utility> #include "common/alignment.h" -#include "common/common_sizes.h" -#include "common/common_types.h" +#include "common/literals.h" #include "core/device_memory.h" #include "core/hle/kernel/k_memory_region.h" #include "core/hle/kernel/k_memory_region_type.h" @@ -16,20 +15,22 @@ namespace Kernel { -constexpr std::size_t L1BlockSize = Common::Size_1_GB; -constexpr std::size_t L2BlockSize = Common::Size_2_MB; +using namespace Common::Literals; + +constexpr std::size_t L1BlockSize = 1_GiB; +constexpr std::size_t L2BlockSize = 2_MiB; constexpr std::size_t GetMaximumOverheadSize(std::size_t size) { return (Common::DivideUp(size, L1BlockSize) + Common::DivideUp(size, L2BlockSize)) * PageSize; } -constexpr std::size_t MainMemorySize = Common::Size_4_GB; -constexpr std::size_t MainMemorySizeMax = Common::Size_8_GB; +constexpr std::size_t MainMemorySize = 4_GiB; +constexpr std::size_t MainMemorySizeMax = 8_GiB; -constexpr std::size_t ReservedEarlyDramSize = 0x60000; +constexpr std::size_t ReservedEarlyDramSize = 384_KiB; constexpr std::size_t DramPhysicalAddress = 0x80000000; -constexpr std::size_t KernelAslrAlignment = Common::Size_2_MB; +constexpr std::size_t KernelAslrAlignment = 2_MiB; constexpr std::size_t KernelVirtualAddressSpaceWidth = 1ULL << 39; constexpr std::size_t KernelPhysicalAddressSpaceWidth = 1ULL << 48; @@ -40,7 +41,7 @@ constexpr std::size_t KernelVirtualAddressSpaceLast = KernelVirtualAddressSpaceE constexpr std::size_t KernelVirtualAddressSpaceSize = KernelVirtualAddressSpaceEnd - KernelVirtualAddressSpaceBase; constexpr std::size_t KernelVirtualAddressCodeBase = KernelVirtualAddressSpaceBase; -constexpr std::size_t KernelVirtualAddressCodeSize = 0x62000; +constexpr std::size_t KernelVirtualAddressCodeSize = 392_KiB; constexpr std::size_t KernelVirtualAddressCodeEnd = KernelVirtualAddressCodeBase + KernelVirtualAddressCodeSize; @@ -53,14 +54,14 @@ constexpr std::size_t KernelPhysicalAddressSpaceSize = constexpr std::size_t KernelPhysicalAddressCodeBase = DramPhysicalAddress + ReservedEarlyDramSize; constexpr std::size_t KernelPageTableHeapSize = GetMaximumOverheadSize(MainMemorySizeMax); -constexpr std::size_t KernelInitialPageHeapSize = Common::Size_128_KB; +constexpr std::size_t KernelInitialPageHeapSize = 128_KiB; -constexpr std::size_t KernelSlabHeapDataSize = Common::Size_5_MB; -constexpr std::size_t KernelSlabHeapGapsSize = Common::Size_2_MB - Common::Size_64_KB; +constexpr std::size_t KernelSlabHeapDataSize = 5_MiB; +constexpr std::size_t KernelSlabHeapGapsSize = 2_MiB - 64_KiB; constexpr std::size_t KernelSlabHeapSize = KernelSlabHeapDataSize + KernelSlabHeapGapsSize; // NOTE: This is calculated from KThread slab counts, assuming KThread size <= 0x860. -constexpr std::size_t KernelSlabHeapAdditionalSize = 0x68000ULL; +constexpr std::size_t KernelSlabHeapAdditionalSize = 416_KiB; constexpr std::size_t KernelResourceSize = KernelPageTableHeapSize + KernelInitialPageHeapSize + KernelSlabHeapSize; diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index 66d260635..701268545 100644 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp @@ -4,6 +4,7 @@ #include "common/alignment.h" #include "common/assert.h" +#include "common/literals.h" #include "common/scope_exit.h" #include "core/core.h" #include "core/hle/kernel/k_address_space_info.h" @@ -23,6 +24,8 @@ namespace Kernel { namespace { +using namespace Common::Literals; + constexpr std::size_t GetAddressSpaceWidthFromType(FileSys::ProgramAddressSpaceType as_type) { switch (as_type) { case FileSys::ProgramAddressSpaceType::Is32Bit: @@ -89,7 +92,7 @@ ResultCode KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_ } // Set code regions and determine remaining - constexpr std::size_t RegionAlignment{2 * 1024 * 1024}; + constexpr std::size_t RegionAlignment{2_MiB}; VAddr process_code_start{}; VAddr process_code_end{}; std::size_t stack_region_size{}; diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index d1bd98051..8ead1a769 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -10,6 +10,7 @@ #include "common/alignment.h" #include "common/assert.h" #include "common/logging/log.h" +#include "common/scope_exit.h" #include "common/settings.h" #include "core/core.h" #include "core/device_memory.h" @@ -43,6 +44,8 @@ void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::Threads, 1)); KThread* thread = KThread::Create(system.Kernel()); + SCOPE_EXIT({ thread->Close(); }); + ASSERT(KThread::InitializeUserThread(system, thread, entry_point, 0, stack_top, priority, owner_process.GetIdealCoreId(), &owner_process) .IsSuccess()); @@ -162,7 +165,7 @@ void KProcess::DecrementThreadCount() { ASSERT(num_threads > 0); if (const auto count = --num_threads; count == 0) { - UNIMPLEMENTED_MSG("Process termination is not implemented!"); + LOG_WARNING(Kernel, "Process termination is not fully implemented."); } } @@ -406,6 +409,9 @@ void KProcess::Finalize() { resource_limit->Close(); } + // Finalize the handle table and close any open handles. + handle_table.Finalize(); + // Perform inherited finalization. KAutoObjectWithSlabHeapAndContainer<KProcess, KSynchronizationObject>::Finalize(); } diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp index da88f35bc..0c4bba66b 100644 --- a/src/core/hle/kernel/k_resource_limit.cpp +++ b/src/core/hle/kernel/k_resource_limit.cpp @@ -79,6 +79,7 @@ ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) { R_UNLESS(current_values[index] <= value, ResultInvalidState); limit_values[index] = value; + peak_values[index] = current_values[index]; return ResultSuccess; } diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index 5c3c13ce6..b9f24475c 100644 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp @@ -28,7 +28,10 @@ namespace Kernel { KServerSession::KServerSession(KernelCore& kernel_) : KSynchronizationObject{kernel_} {} -KServerSession::~KServerSession() {} +KServerSession::~KServerSession() { + // Ensure that the global list tracking server sessions does not hold on to a reference. + kernel.UnregisterServerSession(this); +} void KServerSession::Initialize(KSession* parent_session_, std::string&& name_, std::shared_ptr<SessionRequestManager> manager_) { diff --git a/src/core/hle/kernel/k_trace.h b/src/core/hle/kernel/k_trace.h index 91ebf9ab2..79391bccb 100644 --- a/src/core/hle/kernel/k_trace.h +++ b/src/core/hle/kernel/k_trace.h @@ -4,9 +4,13 @@ #pragma once +#include "common/common_funcs.h" + namespace Kernel { +using namespace Common::Literals; + constexpr bool IsKTraceEnabled = false; -constexpr std::size_t KTraceBufferSize = IsKTraceEnabled ? 16 * 1024 * 1024 : 0; +constexpr std::size_t KTraceBufferSize = IsKTraceEnabled ? 16_MiB : 0; } // namespace Kernel diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 2ceeaeb5f..92fbc5532 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -12,7 +12,6 @@ #include <utility> #include "common/assert.h" -#include "common/common_sizes.h" #include "common/logging/log.h" #include "common/microprofile.h" #include "common/thread.h" @@ -62,6 +61,7 @@ struct KernelCore::Impl { void Initialize(KernelCore& kernel) { global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel); + global_handle_table->Initialize(KHandleTable::MaxTableSize); is_phantom_mode_for_singlecore = false; @@ -91,9 +91,39 @@ struct KernelCore::Impl { } void Shutdown() { + // Shutdown all processes. + if (current_process) { + current_process->Finalize(); + current_process->Close(); + current_process = nullptr; + } process_list.clear(); - // Ensures all service threads gracefully shutdown + // Close all open server ports. + std::unordered_set<KServerPort*> server_ports_; + { + std::lock_guard lk(server_ports_lock); + server_ports_ = server_ports; + server_ports.clear(); + } + for (auto* server_port : server_ports_) { + server_port->Close(); + } + // Close all open server sessions. + std::unordered_set<KServerSession*> server_sessions_; + { + std::lock_guard lk(server_sessions_lock); + server_sessions_ = server_sessions; + server_sessions.clear(); + } + for (auto* server_session : server_sessions_) { + server_session->Close(); + } + + // Ensure that the object list container is finalized and properly shutdown. + object_list_container.Finalize(); + + // Ensures all service threads gracefully shutdown. service_threads.clear(); next_object_id = 0; @@ -112,11 +142,7 @@ struct KernelCore::Impl { cores.clear(); - if (current_process) { - current_process->Close(); - current_process = nullptr; - } - + global_handle_table->Finalize(); global_handle_table.reset(); preemption_event = nullptr; @@ -143,6 +169,16 @@ struct KernelCore::Impl { // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others next_host_thread_id = Core::Hardware::NUM_CPU_CORES; + + // Track kernel objects that were not freed on shutdown + { + std::lock_guard lk(registered_objects_lock); + if (registered_objects.size()) { + LOG_WARNING(Kernel, "{} kernel objects were dangling on shutdown!", + registered_objects.size()); + registered_objects.clear(); + } + } } void InitializePhysicalCores() { @@ -180,7 +216,7 @@ struct KernelCore::Impl { system_resource_limit->Reserve(LimitableResource::PhysicalMemory, kernel_size); // Reserve secure applet memory, introduced in firmware 5.0.0 - constexpr u64 secure_applet_memory_size{Common::Size_4_MB}; + constexpr u64 secure_applet_memory_size{4_MiB}; ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory, secure_applet_memory_size)); @@ -320,8 +356,8 @@ struct KernelCore::Impl { const VAddr code_end_virt_addr = KernelVirtualAddressCodeEnd; // Setup the containing kernel region. - constexpr size_t KernelRegionSize = Common::Size_1_GB; - constexpr size_t KernelRegionAlign = Common::Size_1_GB; + constexpr size_t KernelRegionSize = 1_GiB; + constexpr size_t KernelRegionAlign = 1_GiB; constexpr VAddr kernel_region_start = Common::AlignDown(code_start_virt_addr, KernelRegionAlign); size_t kernel_region_size = KernelRegionSize; @@ -368,7 +404,7 @@ struct KernelCore::Impl { // Decide on the actual size for the misc region. constexpr size_t MiscRegionAlign = KernelAslrAlignment; - constexpr size_t MiscRegionMinimumSize = Common::Size_32_MB; + constexpr size_t MiscRegionMinimumSize = 32_MiB; const size_t misc_region_size = Common::AlignUp( std::max(misc_region_needed_size, MiscRegionMinimumSize), MiscRegionAlign); ASSERT(misc_region_size > 0); @@ -381,7 +417,7 @@ struct KernelCore::Impl { misc_region_start, misc_region_size, KMemoryRegionType_KernelMisc)); // Setup the stack region. - constexpr size_t StackRegionSize = Common::Size_14_MB; + constexpr size_t StackRegionSize = 14_MiB; constexpr size_t StackRegionAlign = KernelAslrAlignment; const VAddr stack_region_start = memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion( @@ -414,7 +450,7 @@ struct KernelCore::Impl { slab_region_start, slab_region_size, KMemoryRegionType_KernelSlab)); // Setup the temp region. - constexpr size_t TempRegionSize = Common::Size_128_MB; + constexpr size_t TempRegionSize = 128_MiB; constexpr size_t TempRegionAlign = KernelAslrAlignment; const VAddr temp_region_start = memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion( @@ -470,7 +506,7 @@ struct KernelCore::Impl { // Determine size available for kernel page table heaps, requiring > 8 MB. const PAddr resource_end_phys_addr = slab_start_phys_addr + resource_region_size; const size_t page_table_heap_size = resource_end_phys_addr - slab_end_phys_addr; - ASSERT(page_table_heap_size / Common::Size_4_MB > 2); + ASSERT(page_table_heap_size / 4_MiB > 2); // Insert a physical region for the kernel page table heap region ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( @@ -495,7 +531,7 @@ struct KernelCore::Impl { ASSERT(linear_extents.GetEndAddress() != 0); // Setup the linear mapping region. - constexpr size_t LinearRegionAlign = Common::Size_1_GB; + constexpr size_t LinearRegionAlign = 1_GiB; const PAddr aligned_linear_phys_start = Common::AlignDown(linear_extents.GetAddress(), LinearRegionAlign); const size_t linear_region_size = @@ -631,6 +667,21 @@ struct KernelCore::Impl { user_slab_heap_size); } + KClientPort* CreateNamedServicePort(std::string name) { + auto search = service_interface_factory.find(name); + if (search == service_interface_factory.end()) { + UNIMPLEMENTED(); + return {}; + } + + KClientPort* port = &search->second(system.ServiceManager(), system); + { + std::lock_guard lk(server_ports_lock); + server_ports.insert(&port->GetParent()->GetServerPort()); + } + return port; + } + std::atomic<u32> next_object_id{0}; std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin}; std::atomic<u64> next_user_process_id{KProcess::ProcessIDMin}; @@ -657,6 +708,12 @@ struct KernelCore::Impl { /// the ConnectToPort SVC. std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory; NamedPortTable named_ports; + std::unordered_set<KServerPort*> server_ports; + std::unordered_set<KServerSession*> server_sessions; + std::unordered_set<KAutoObject*> registered_objects; + std::mutex server_ports_lock; + std::mutex server_sessions_lock; + std::mutex registered_objects_lock; std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; std::vector<Kernel::PhysicalCore> cores; @@ -845,12 +902,27 @@ void KernelCore::RegisterNamedService(std::string name, ServiceInterfaceFactory& } KClientPort* KernelCore::CreateNamedServicePort(std::string name) { - auto search = impl->service_interface_factory.find(name); - if (search == impl->service_interface_factory.end()) { - UNIMPLEMENTED(); - return {}; - } - return &search->second(impl->system.ServiceManager(), impl->system); + return impl->CreateNamedServicePort(std::move(name)); +} + +void KernelCore::RegisterServerSession(KServerSession* server_session) { + std::lock_guard lk(impl->server_sessions_lock); + impl->server_sessions.insert(server_session); +} + +void KernelCore::UnregisterServerSession(KServerSession* server_session) { + std::lock_guard lk(impl->server_sessions_lock); + impl->server_sessions.erase(server_session); +} + +void KernelCore::RegisterKernelObject(KAutoObject* object) { + std::lock_guard lk(impl->registered_objects_lock); + impl->registered_objects.insert(object); +} + +void KernelCore::UnregisterKernelObject(KAutoObject* object) { + std::lock_guard lk(impl->registered_objects_lock); + impl->registered_objects.erase(object); } bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const { diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 2d01e1ae0..3a6db0b1c 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -45,6 +45,7 @@ class KPort; class KProcess; class KResourceLimit; class KScheduler; +class KServerSession; class KSession; class KSharedMemory; class KThread; @@ -185,6 +186,22 @@ public: /// Opens a port to a service previously registered with RegisterNamedService. KClientPort* CreateNamedServicePort(std::string name); + /// Registers a server session with the gobal emulation state, to be freed on shutdown. This is + /// necessary because we do not emulate processes for HLE sessions. + void RegisterServerSession(KServerSession* server_session); + + /// Unregisters a server session previously registered with RegisterServerSession when it was + /// destroyed during the current emulation session. + void UnregisterServerSession(KServerSession* server_session); + + /// Registers all kernel objects with the global emulation state, this is purely for tracking + /// leaks after emulation has been shutdown. + void RegisterKernelObject(KAutoObject* object); + + /// Unregisters a kernel object previously registered with RegisterKernelObject when it was + /// destroyed during the current emulation session. + void UnregisterKernelObject(KAutoObject* object); + /// Determines whether or not the given port is a valid named port. bool IsValidNamedPort(NamedPortTable::const_iterator port) const; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 8339e11a0..2eb532472 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -298,6 +298,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out, VAddr po // Create a session. KClientSession* session{}; R_TRY(port->CreateSession(std::addressof(session))); + port->Close(); // Register the session in the table, close the extra reference. handle_table.Register(*out, session); @@ -1439,11 +1440,6 @@ static void ExitProcess(Core::System& system) { LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID()); ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running, "Process has already exited"); - - current_process->PrepareForTermination(); - - // Kill the current thread - system.Kernel().CurrentScheduler()->GetCurrentThread()->Exit(); } static void ExitProcess32(Core::System& system) { |