From 621520c30b2c22ee728b9fed85088d8d0cc1d81e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 5 Feb 2021 14:59:03 -0800 Subject: [PATCH] kern: fix support for virtual core IDs --- .../include/mesosphere/kern_select_cpu.hpp | 18 ++++++++++++++++-- .../source/kern_k_capabilities.cpp | 11 +++++------ .../libmesosphere/source/svc/kern_svc_info.cpp | 2 +- .../source/svc/kern_svc_process.cpp | 6 +++--- .../source/svc/kern_svc_thread.cpp | 8 ++++---- 5 files changed, 29 insertions(+), 16 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_select_cpu.hpp b/libraries/libmesosphere/include/mesosphere/kern_select_cpu.hpp index 3bd1b054c..1b3469772 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_select_cpu.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_select_cpu.hpp @@ -45,7 +45,21 @@ namespace ams::kern { - static_assert(cpu::NumCores <= static_cast(BITSIZEOF(u64))); - static_assert(util::size(cpu::VirtualToPhysicalCoreMap) == BITSIZEOF(u64)); + namespace cpu { + + static constexpr inline size_t NumVirtualCores = BITSIZEOF(u64); + + static constexpr inline u64 VirtualCoreMask = [] { + u64 mask = 0; + for (size_t i = 0; i < NumVirtualCores; ++i) { + mask |= (UINT64_C(1) << i); + } + return mask; + }(); + + } + + static_assert(cpu::NumCores <= cpu::NumVirtualCores); + static_assert(util::size(cpu::VirtualToPhysicalCoreMap) == cpu::NumVirtualCores); } diff --git a/libraries/libmesosphere/source/kern_k_capabilities.cpp b/libraries/libmesosphere/source/kern_k_capabilities.cpp index a8d2c550e..336ac46fc 100644 --- a/libraries/libmesosphere/source/kern_k_capabilities.cpp +++ b/libraries/libmesosphere/source/kern_k_capabilities.cpp @@ -22,7 +22,7 @@ namespace ams::kern { /* Most fields have already been cleared by our constructor. */ /* Initial processes may run on all cores. */ - m_core_mask = (1ul << cpu::NumCores) - 1; + m_core_mask = cpu::VirtualCoreMask; /* Initial processes may use any user priority they like. */ m_priority_mask = ~0xFul; @@ -55,18 +55,17 @@ namespace ams::kern { const auto max_prio = cap.Get(); const auto min_prio = cap.Get(); - R_UNLESS(min_core <= max_core, svc::ResultInvalidCombination()); - R_UNLESS(min_prio <= max_prio, svc::ResultInvalidCombination()); - R_UNLESS(max_core < cpu::NumCores, svc::ResultInvalidCoreId()); + R_UNLESS(min_core <= max_core, svc::ResultInvalidCombination()); + R_UNLESS(min_prio <= max_prio, svc::ResultInvalidCombination()); + R_UNLESS(max_core < cpu::NumVirtualCores, svc::ResultInvalidCoreId()); - MESOSPHERE_ASSERT(max_core < BITSIZEOF(u64)); MESOSPHERE_ASSERT(max_prio < BITSIZEOF(u64)); /* Set core mask. */ for (auto core_id = min_core; core_id <= max_core; core_id++) { m_core_mask |= (1ul << core_id); } - MESOSPHERE_ASSERT((m_core_mask & ((1ul << cpu::NumCores) - 1)) == m_core_mask); + MESOSPHERE_ASSERT((m_core_mask & cpu::VirtualCoreMask) == m_core_mask); /* Set priority mask. */ for (auto prio = min_prio; prio <= max_prio; prio++) { diff --git a/libraries/libmesosphere/source/svc/kern_svc_info.cpp b/libraries/libmesosphere/source/svc/kern_svc_info.cpp index fda723182..60a72fbc0 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_info.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_info.cpp @@ -216,7 +216,7 @@ namespace ams::kern::svc { case ams::svc::InfoType_ThreadTickCount: { /* Verify the requested core is valid. */ - const bool core_valid = (info_subtype == static_cast(-1ul)) || (info_subtype < util::size(cpu::VirtualToPhysicalCoreMap)); + const bool core_valid = (info_subtype == static_cast(-1ul)) || (info_subtype < cpu::NumVirtualCores); R_UNLESS(core_valid, svc::ResultInvalidCombination()); /* Get the thread from its handle. */ diff --git a/libraries/libmesosphere/source/svc/kern_svc_process.cpp b/libraries/libmesosphere/source/svc/kern_svc_process.cpp index 33c8d8926..7625cbf3b 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_process.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_process.cpp @@ -21,8 +21,8 @@ namespace ams::kern::svc { namespace { - constexpr bool IsValidCoreId(int32_t core_id) { - return (0 <= core_id && core_id < static_cast(cpu::NumCores)); + constexpr bool IsValidVirtualCoreId(int32_t core_id) { + return (0 <= core_id && core_id < static_cast(cpu::NumVirtualCores)); } void ExitProcess() { @@ -275,7 +275,7 @@ namespace ams::kern::svc { R_UNLESS(process.IsNotNull(), svc::ResultInvalidHandle()); /* Validate the core id. */ - R_UNLESS(IsValidCoreId(core_id), svc::ResultInvalidCoreId()); + R_UNLESS(IsValidVirtualCoreId(core_id), svc::ResultInvalidCoreId()); R_UNLESS(((1ul << core_id) & process->GetCoreMask()) != 0, svc::ResultInvalidCoreId()); /* Validate the priority. */ diff --git a/libraries/libmesosphere/source/svc/kern_svc_thread.cpp b/libraries/libmesosphere/source/svc/kern_svc_thread.cpp index 81a35a171..c887c5f56 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_thread.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_thread.cpp @@ -21,8 +21,8 @@ namespace ams::kern::svc { namespace { - constexpr bool IsValidCoreId(int32_t core_id) { - return (0 <= core_id && core_id < static_cast(cpu::NumCores)); + constexpr bool IsValidVirtualCoreId(int32_t core_id) { + return (0 <= core_id && core_id < static_cast(cpu::NumVirtualCores)); } Result CreateThread(ams::svc::Handle *out, ams::svc::ThreadFunc f, uintptr_t arg, uintptr_t stack_bottom, int32_t priority, int32_t core_id) { @@ -33,7 +33,7 @@ namespace ams::kern::svc { } /* Validate arguments. */ - R_UNLESS(IsValidCoreId(core_id), svc::ResultInvalidCoreId()); + R_UNLESS(IsValidVirtualCoreId(core_id), svc::ResultInvalidCoreId()); R_UNLESS(((1ul << core_id) & process.GetCoreMask()) != 0, svc::ResultInvalidCoreId()); R_UNLESS(ams::svc::HighestThreadPriority <= priority && priority <= ams::svc::LowestThreadPriority, svc::ResultInvalidPriority()); @@ -168,7 +168,7 @@ namespace ams::kern::svc { R_UNLESS(affinity_mask != 0, svc::ResultInvalidCombination()); /* Validate the core id. */ - if (IsValidCoreId(core_id)) { + if (IsValidVirtualCoreId(core_id)) { R_UNLESS(((1ul << core_id) & affinity_mask) != 0, svc::ResultInvalidCombination()); } else { R_UNLESS(core_id == ams::svc::IdealCoreNoUpdate || core_id == ams::svc::IdealCoreDontCare, svc::ResultInvalidCoreId());