From 71d266f867aa9f7c531dc3ef19c9e2cc17bd9351 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 26 Apr 2020 02:49:59 -0700 Subject: [PATCH] kern: implement SvcSetUnsafeLimit --- .../mesosphere/kern_k_memory_manager.hpp | 20 +++++++++++++++++++ .../source/svc/kern_svc_physical_memory.cpp | 13 ++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp index 94fcf208a..8c17c54e0 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp @@ -35,6 +35,9 @@ namespace ams::kern { Pool_Shift = 4, Pool_Mask = (0xF << Pool_Shift), + + /* Aliases. */ + Pool_Unsafe = Pool_Application, }; enum Direction { @@ -184,6 +187,23 @@ namespace ams::kern { address += cur_pages * PageSize; } } + + size_t GetSize() { + size_t total = 0; + for (size_t i = 0; i < this->num_managers; i++) { + total += this->managers[i].GetSize(); + } + return total; + } + + size_t GetSize(Pool pool) { + constexpr Direction GetSizeDirection = Direction_FromFront; + size_t total = 0; + for (auto *manager = this->GetFirstManager(pool, GetSizeDirection); manager != nullptr; manager = this->GetNextManager(manager, GetSizeDirection)) { + total += manager->GetSize(); + } + return total; + } public: static size_t CalculateMetadataOverheadSize(size_t region_size) { return Impl::CalculateMetadataOverheadSize(region_size); diff --git a/libraries/libmesosphere/source/svc/kern_svc_physical_memory.cpp b/libraries/libmesosphere/source/svc/kern_svc_physical_memory.cpp index 1c800096c..c7cb9a7c6 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_physical_memory.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_physical_memory.cpp @@ -21,7 +21,16 @@ namespace ams::kern::svc { namespace { + Result SetUnsafeLimit(size_t limit) { + /* Ensure the size is aligned. */ + R_UNLESS(util::IsAligned(limit, PageSize), svc::ResultInvalidSize()); + /* Ensure that the size is not bigger than we can accommodate. */ + R_UNLESS(limit <= Kernel::GetMemoryManager().GetSize(KMemoryManager::Pool_Unsafe), svc::ResultOutOfRange()); + + /* Set the size. */ + return Kernel::GetUnsafeMemory().SetLimitSize(limit); + } } @@ -48,7 +57,7 @@ namespace ams::kern::svc { } Result SetUnsafeLimit64(ams::svc::Size limit) { - MESOSPHERE_PANIC("Stubbed SvcSetUnsafeLimit64 was called."); + return SetUnsafeLimit(limit); } /* ============================= 64From32 ABI ============================= */ @@ -74,7 +83,7 @@ namespace ams::kern::svc { } Result SetUnsafeLimit64From32(ams::svc::Size limit) { - MESOSPHERE_PANIC("Stubbed SvcSetUnsafeLimit64From32 was called."); + return SetUnsafeLimit(limit); } }