kern: fix support for virtual core IDs

This commit is contained in:
Michael Scire 2021-02-05 14:59:03 -08:00
parent 846cc0b47a
commit 621520c30b
5 changed files with 29 additions and 16 deletions

View file

@ -45,7 +45,21 @@
namespace ams::kern { namespace ams::kern {
static_assert(cpu::NumCores <= static_cast<s32>(BITSIZEOF(u64))); namespace cpu {
static_assert(util::size(cpu::VirtualToPhysicalCoreMap) == BITSIZEOF(u64));
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);
} }

View file

@ -22,7 +22,7 @@ namespace ams::kern {
/* Most fields have already been cleared by our constructor. */ /* Most fields have already been cleared by our constructor. */
/* Initial processes may run on all cores. */ /* 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. */ /* Initial processes may use any user priority they like. */
m_priority_mask = ~0xFul; m_priority_mask = ~0xFul;
@ -57,16 +57,15 @@ namespace ams::kern {
R_UNLESS(min_core <= max_core, svc::ResultInvalidCombination()); R_UNLESS(min_core <= max_core, svc::ResultInvalidCombination());
R_UNLESS(min_prio <= max_prio, svc::ResultInvalidCombination()); R_UNLESS(min_prio <= max_prio, svc::ResultInvalidCombination());
R_UNLESS(max_core < cpu::NumCores, svc::ResultInvalidCoreId()); R_UNLESS(max_core < cpu::NumVirtualCores, svc::ResultInvalidCoreId());
MESOSPHERE_ASSERT(max_core < BITSIZEOF(u64));
MESOSPHERE_ASSERT(max_prio < BITSIZEOF(u64)); MESOSPHERE_ASSERT(max_prio < BITSIZEOF(u64));
/* Set core mask. */ /* Set core mask. */
for (auto core_id = min_core; core_id <= max_core; core_id++) { for (auto core_id = min_core; core_id <= max_core; core_id++) {
m_core_mask |= (1ul << 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. */ /* Set priority mask. */
for (auto prio = min_prio; prio <= max_prio; prio++) { for (auto prio = min_prio; prio <= max_prio; prio++) {

View file

@ -216,7 +216,7 @@ namespace ams::kern::svc {
case ams::svc::InfoType_ThreadTickCount: case ams::svc::InfoType_ThreadTickCount:
{ {
/* Verify the requested core is valid. */ /* Verify the requested core is valid. */
const bool core_valid = (info_subtype == static_cast<u64>(-1ul)) || (info_subtype < util::size(cpu::VirtualToPhysicalCoreMap)); const bool core_valid = (info_subtype == static_cast<u64>(-1ul)) || (info_subtype < cpu::NumVirtualCores);
R_UNLESS(core_valid, svc::ResultInvalidCombination()); R_UNLESS(core_valid, svc::ResultInvalidCombination());
/* Get the thread from its handle. */ /* Get the thread from its handle. */

View file

@ -21,8 +21,8 @@ namespace ams::kern::svc {
namespace { namespace {
constexpr bool IsValidCoreId(int32_t core_id) { constexpr bool IsValidVirtualCoreId(int32_t core_id) {
return (0 <= core_id && core_id < static_cast<int32_t>(cpu::NumCores)); return (0 <= core_id && core_id < static_cast<int32_t>(cpu::NumVirtualCores));
} }
void ExitProcess() { void ExitProcess() {
@ -275,7 +275,7 @@ namespace ams::kern::svc {
R_UNLESS(process.IsNotNull(), svc::ResultInvalidHandle()); R_UNLESS(process.IsNotNull(), svc::ResultInvalidHandle());
/* Validate the core id. */ /* 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()); R_UNLESS(((1ul << core_id) & process->GetCoreMask()) != 0, svc::ResultInvalidCoreId());
/* Validate the priority. */ /* Validate the priority. */

View file

@ -21,8 +21,8 @@ namespace ams::kern::svc {
namespace { namespace {
constexpr bool IsValidCoreId(int32_t core_id) { constexpr bool IsValidVirtualCoreId(int32_t core_id) {
return (0 <= core_id && core_id < static_cast<int32_t>(cpu::NumCores)); return (0 <= core_id && core_id < static_cast<int32_t>(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) { 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. */ /* 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(((1ul << core_id) & process.GetCoreMask()) != 0, svc::ResultInvalidCoreId());
R_UNLESS(ams::svc::HighestThreadPriority <= priority && priority <= ams::svc::LowestThreadPriority, svc::ResultInvalidPriority()); 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()); R_UNLESS(affinity_mask != 0, svc::ResultInvalidCombination());
/* Validate the core id. */ /* Validate the core id. */
if (IsValidCoreId(core_id)) { if (IsValidVirtualCoreId(core_id)) {
R_UNLESS(((1ul << core_id) & affinity_mask) != 0, svc::ResultInvalidCombination()); R_UNLESS(((1ul << core_id) & affinity_mask) != 0, svc::ResultInvalidCombination());
} else { } else {
R_UNLESS(core_id == ams::svc::IdealCoreNoUpdate || core_id == ams::svc::IdealCoreDontCare, svc::ResultInvalidCoreId()); R_UNLESS(core_id == ams::svc::IdealCoreNoUpdate || core_id == ams::svc::IdealCoreDontCare, svc::ResultInvalidCoreId());