diff --git a/libraries/libmesosphere/include/mesosphere/init/kern_init_slab_setup.hpp b/libraries/libmesosphere/include/mesosphere/init/kern_init_slab_setup.hpp index 5cb58d86e..209b8d732 100644 --- a/libraries/libmesosphere/include/mesosphere/init/kern_init_slab_setup.hpp +++ b/libraries/libmesosphere/include/mesosphere/init/kern_init_slab_setup.hpp @@ -36,6 +36,7 @@ namespace ams::kern::init { size_t num_KDebug; size_t num_KIoPool; size_t num_KIoRegion; + size_t num_KSessionRequestMappings; }; NOINLINE void InitializeSlabResourceCounts(); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_session_request.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_session_request.hpp index 3ca4c1cfa..752cc9178 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_session_request.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_session_request.hpp @@ -29,7 +29,10 @@ namespace ams::kern { public: class SessionMappings { private: - static constexpr size_t NumStaticMappings = 8; + /* At most 15 buffers of each type (4-bit descriptor counts), for 45 total. */ + static constexpr size_t NumMappings = ((1ul << 4) - 1) * 3; + static constexpr size_t NumStaticMappings = 8; + static constexpr size_t NumDynamicMappings = NumMappings - NumStaticMappings; class Mapping { private: @@ -50,16 +53,27 @@ namespace ams::kern { constexpr ALWAYS_INLINE size_t GetSize() const { return m_size; } constexpr ALWAYS_INLINE KMemoryState GetMemoryState() const { return m_state; } }; + public: + class DynamicMappings : public KSlabAllocated { + private: + Mapping m_mappings[NumDynamicMappings]; + public: + constexpr explicit DynamicMappings() : m_mappings() { /* ... */ } + + constexpr ALWAYS_INLINE Mapping &Get(size_t idx) { return m_mappings[idx]; } + constexpr ALWAYS_INLINE const Mapping &Get(size_t idx) const { return m_mappings[idx]; } + }; + static_assert(sizeof(DynamicMappings) == sizeof(Mapping) * NumDynamicMappings); private: Mapping m_static_mappings[NumStaticMappings]; - Mapping *m_mappings; + DynamicMappings *m_dynamic_mappings; u8 m_num_send; u8 m_num_recv; u8 m_num_exch; public: - constexpr explicit SessionMappings(util::ConstantInitializeTag) : m_static_mappings(), m_mappings(), m_num_send(), m_num_recv(), m_num_exch() { /* ... */ } + constexpr explicit SessionMappings(util::ConstantInitializeTag) : m_static_mappings(), m_dynamic_mappings(), m_num_send(), m_num_recv(), m_num_exch() { /* ... */ } - explicit SessionMappings() : m_mappings(nullptr), m_num_send(), m_num_recv(), m_num_exch() { /* ... */ } + explicit SessionMappings() : m_dynamic_mappings(nullptr), m_num_send(), m_num_recv(), m_num_exch() { /* ... */ } void Initialize() { /* ... */ } void Finalize(); @@ -96,7 +110,7 @@ namespace ams::kern { if (index < NumStaticMappings) { return m_static_mappings[index]; } else { - return m_mappings[index - NumStaticMappings]; + return m_dynamic_mappings->Get(index - NumStaticMappings); } } @@ -107,7 +121,7 @@ namespace ams::kern { if (index < NumStaticMappings) { return m_static_mappings[index]; } else { - return m_mappings[index - NumStaticMappings]; + return m_dynamic_mappings->Get(index - NumStaticMappings); } } @@ -118,7 +132,7 @@ namespace ams::kern { if (index < NumStaticMappings) { return m_static_mappings[index]; } else { - return m_mappings[index - NumStaticMappings]; + return m_dynamic_mappings->Get(index - NumStaticMappings); } } }; diff --git a/libraries/libmesosphere/source/init/kern_init_slab_setup.cpp b/libraries/libmesosphere/source/init/kern_init_slab_setup.cpp index f7117077b..fea9eb38b 100644 --- a/libraries/libmesosphere/source/init/kern_init_slab_setup.cpp +++ b/libraries/libmesosphere/source/init/kern_init_slab_setup.cpp @@ -17,30 +17,34 @@ namespace ams::kern::init { + /* For macro convenience. */ + using KSessionRequestMappings = KSessionRequest::SessionMappings::DynamicMappings; + #define SLAB_COUNT(CLASS) g_slab_resource_counts.num_##CLASS #define FOREACH_SLAB_TYPE(HANDLER, ...) \ - HANDLER(KProcess, (SLAB_COUNT(KProcess)), ## __VA_ARGS__) \ - HANDLER(KThread, (SLAB_COUNT(KThread)), ## __VA_ARGS__) \ - HANDLER(KEvent, (SLAB_COUNT(KEvent)), ## __VA_ARGS__) \ - HANDLER(KInterruptEvent, (SLAB_COUNT(KInterruptEvent)), ## __VA_ARGS__) \ - HANDLER(KPort, (SLAB_COUNT(KPort)), ## __VA_ARGS__) \ - HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ## __VA_ARGS__) \ - HANDLER(KSharedMemoryInfo, (SLAB_COUNT(KSharedMemory) * 8), ## __VA_ARGS__) \ - HANDLER(KTransferMemory, (SLAB_COUNT(KTransferMemory)), ## __VA_ARGS__) \ - HANDLER(KCodeMemory, (SLAB_COUNT(KCodeMemory)), ## __VA_ARGS__) \ - HANDLER(KDeviceAddressSpace, (SLAB_COUNT(KDeviceAddressSpace)), ## __VA_ARGS__) \ - HANDLER(KSession, (SLAB_COUNT(KSession)), ## __VA_ARGS__) \ - HANDLER(KSessionRequest, (SLAB_COUNT(KSession) * 2), ## __VA_ARGS__) \ - HANDLER(KLightSession, (SLAB_COUNT(KLightSession)), ## __VA_ARGS__) \ - HANDLER(KThreadLocalPage, (SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8), ## __VA_ARGS__) \ - HANDLER(KObjectName, (SLAB_COUNT(KObjectName)), ## __VA_ARGS__) \ - HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ## __VA_ARGS__) \ - HANDLER(KEventInfo, (SLAB_COUNT(KThread) + SLAB_COUNT(KDebug)), ## __VA_ARGS__) \ - HANDLER(KDebug, (SLAB_COUNT(KDebug)), ## __VA_ARGS__) \ - HANDLER(KIoPool, (SLAB_COUNT(KIoPool)), ## __VA_ARGS__) \ - HANDLER(KIoRegion, (SLAB_COUNT(KIoRegion)), ## __VA_ARGS__) \ - HANDLER(KSecureSystemResource, (SLAB_COUNT(KProcess)), ## __VA_ARGS__) + HANDLER(KProcess, (SLAB_COUNT(KProcess)), ## __VA_ARGS__) \ + HANDLER(KThread, (SLAB_COUNT(KThread)), ## __VA_ARGS__) \ + HANDLER(KEvent, (SLAB_COUNT(KEvent)), ## __VA_ARGS__) \ + HANDLER(KInterruptEvent, (SLAB_COUNT(KInterruptEvent)), ## __VA_ARGS__) \ + HANDLER(KPort, (SLAB_COUNT(KPort)), ## __VA_ARGS__) \ + HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ## __VA_ARGS__) \ + HANDLER(KSharedMemoryInfo, (SLAB_COUNT(KSharedMemory) * 8), ## __VA_ARGS__) \ + HANDLER(KTransferMemory, (SLAB_COUNT(KTransferMemory)), ## __VA_ARGS__) \ + HANDLER(KCodeMemory, (SLAB_COUNT(KCodeMemory)), ## __VA_ARGS__) \ + HANDLER(KDeviceAddressSpace, (SLAB_COUNT(KDeviceAddressSpace)), ## __VA_ARGS__) \ + HANDLER(KSession, (SLAB_COUNT(KSession)), ## __VA_ARGS__) \ + HANDLER(KSessionRequest, (SLAB_COUNT(KSession) * 2), ## __VA_ARGS__) \ + HANDLER(KLightSession, (SLAB_COUNT(KLightSession)), ## __VA_ARGS__) \ + HANDLER(KThreadLocalPage, (SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8), ## __VA_ARGS__) \ + HANDLER(KObjectName, (SLAB_COUNT(KObjectName)), ## __VA_ARGS__) \ + HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ## __VA_ARGS__) \ + HANDLER(KEventInfo, (SLAB_COUNT(KThread) + SLAB_COUNT(KDebug)), ## __VA_ARGS__) \ + HANDLER(KDebug, (SLAB_COUNT(KDebug)), ## __VA_ARGS__) \ + HANDLER(KIoPool, (SLAB_COUNT(KIoPool)), ## __VA_ARGS__) \ + HANDLER(KIoRegion, (SLAB_COUNT(KIoRegion)), ## __VA_ARGS__) \ + HANDLER(KSecureSystemResource, (SLAB_COUNT(KProcess)), ## __VA_ARGS__) \ + HANDLER(KSessionRequestMappings, (SLAB_COUNT(KSessionRequestMappings)), ## __VA_ARGS__) namespace { @@ -55,24 +59,25 @@ namespace ams::kern::init { #undef DEFINE_SLAB_TYPE_ENUM_MEMBER /* Constexpr counts. */ - constexpr size_t SlabCountKProcess = 80; - constexpr size_t SlabCountKThread = 800; - constexpr size_t SlabCountKEvent = 900; - constexpr size_t SlabCountKInterruptEvent = 100; - constexpr size_t SlabCountKPort = 384; - constexpr size_t SlabCountKSharedMemory = 80; - constexpr size_t SlabCountKTransferMemory = 200; - constexpr size_t SlabCountKCodeMemory = 10; - constexpr size_t SlabCountKDeviceAddressSpace = 300; - constexpr size_t SlabCountKSession = 1133; - constexpr size_t SlabCountKLightSession = 100; - constexpr size_t SlabCountKObjectName = 7; - constexpr size_t SlabCountKResourceLimit = 5; - constexpr size_t SlabCountKDebug = cpu::NumCores; - constexpr size_t SlabCountKIoPool = 1; - constexpr size_t SlabCountKIoRegion = 6; + constexpr size_t SlabCountKProcess = 80; + constexpr size_t SlabCountKThread = 800; + constexpr size_t SlabCountKEvent = 900; + constexpr size_t SlabCountKInterruptEvent = 100; + constexpr size_t SlabCountKPort = 384; + constexpr size_t SlabCountKSharedMemory = 80; + constexpr size_t SlabCountKTransferMemory = 200; + constexpr size_t SlabCountKCodeMemory = 10; + constexpr size_t SlabCountKDeviceAddressSpace = 300; + constexpr size_t SlabCountKSession = 1133; + constexpr size_t SlabCountKLightSession = 100; + constexpr size_t SlabCountKObjectName = 7; + constexpr size_t SlabCountKResourceLimit = 5; + constexpr size_t SlabCountKDebug = cpu::NumCores; + constexpr size_t SlabCountKIoPool = 1; + constexpr size_t SlabCountKIoRegion = 6; + constexpr size_t SlabcountKSessionRequestMappings = 40; - constexpr size_t SlabCountExtraKThread = (1024 + 256 + 256) - SlabCountKThread; + constexpr size_t SlabCountExtraKThread = (1024 + 256 + 256) - SlabCountKThread; namespace test { @@ -86,22 +91,23 @@ namespace ams::kern::init { /* Global to hold our resource counts. */ constinit KSlabResourceCounts g_slab_resource_counts = { - .num_KProcess = SlabCountKProcess, - .num_KThread = SlabCountKThread, - .num_KEvent = SlabCountKEvent, - .num_KInterruptEvent = SlabCountKInterruptEvent, - .num_KPort = SlabCountKPort, - .num_KSharedMemory = SlabCountKSharedMemory, - .num_KTransferMemory = SlabCountKTransferMemory, - .num_KCodeMemory = SlabCountKCodeMemory, - .num_KDeviceAddressSpace = SlabCountKDeviceAddressSpace, - .num_KSession = SlabCountKSession, - .num_KLightSession = SlabCountKLightSession, - .num_KObjectName = SlabCountKObjectName, - .num_KResourceLimit = SlabCountKResourceLimit, - .num_KDebug = SlabCountKDebug, - .num_KIoPool = SlabCountKIoPool, - .num_KIoRegion = SlabCountKIoRegion, + .num_KProcess = SlabCountKProcess, + .num_KThread = SlabCountKThread, + .num_KEvent = SlabCountKEvent, + .num_KInterruptEvent = SlabCountKInterruptEvent, + .num_KPort = SlabCountKPort, + .num_KSharedMemory = SlabCountKSharedMemory, + .num_KTransferMemory = SlabCountKTransferMemory, + .num_KCodeMemory = SlabCountKCodeMemory, + .num_KDeviceAddressSpace = SlabCountKDeviceAddressSpace, + .num_KSession = SlabCountKSession, + .num_KLightSession = SlabCountKLightSession, + .num_KObjectName = SlabCountKObjectName, + .num_KResourceLimit = SlabCountKResourceLimit, + .num_KDebug = SlabCountKDebug, + .num_KIoPool = SlabCountKIoPool, + .num_KIoRegion = SlabCountKIoRegion, + .num_KSessionRequestMappings = SlabcountKSessionRequestMappings, }; template diff --git a/libraries/libmesosphere/source/kern_k_session_request.cpp b/libraries/libmesosphere/source/kern_k_session_request.cpp index c14368c83..deb1619d5 100644 --- a/libraries/libmesosphere/source/kern_k_session_request.cpp +++ b/libraries/libmesosphere/source/kern_k_session_request.cpp @@ -19,22 +19,20 @@ namespace ams::kern { Result KSessionRequest::SessionMappings::PushMap(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state, size_t index) { /* At most 15 buffers of each type (4-bit descriptor counts). */ - MESOSPHERE_ASSERT(index < ((1ul << 4) - 1) * 3); + MESOSPHERE_ASSERT(index < NumMappings); /* Get the mapping. */ Mapping *mapping; if (index < NumStaticMappings) { mapping = std::addressof(m_static_mappings[index]); } else { - /* Allocate a page for the extra mappings. */ - if (m_mappings == nullptr) { - KPageBuffer *page_buffer = KPageBuffer::Allocate(); - R_UNLESS(page_buffer != nullptr, svc::ResultOutOfMemory()); - - m_mappings = reinterpret_cast(page_buffer); + /* Allocate dynamic mappings as necessary. */ + if (m_dynamic_mappings == nullptr) { + m_dynamic_mappings = DynamicMappings::Allocate(); + R_UNLESS(m_dynamic_mappings != nullptr, svc::ResultOutOfMemory()); } - mapping = std::addressof(m_mappings[index - NumStaticMappings]); + mapping = std::addressof(m_dynamic_mappings->Get(index - NumStaticMappings)); } /* Set the mapping. */ @@ -59,9 +57,9 @@ namespace ams::kern { } void KSessionRequest::SessionMappings::Finalize() { - if (m_mappings) { - KPageBuffer::Free(reinterpret_cast(m_mappings)); - m_mappings = nullptr; + if (m_dynamic_mappings) { + DynamicMappings::Free(m_dynamic_mappings); + m_dynamic_mappings = nullptr; } }