Kernel/SVC: Support special core values -2 and -3 in svcSetThreadCoreMask.

Also added some proper error handling.
This commit is contained in:
Subv 2018-05-30 12:03:19 -05:00
parent d1f9c750a6
commit 3957b0c34e
2 changed files with 28 additions and 1 deletions

View file

@ -21,7 +21,9 @@ enum {
// Confirmed Switch OS error codes
MisalignedAddress = 102,
InvalidProcessorId = 113,
InvalidHandle = 114,
InvalidCombination = 116,
Timeout = 117,
SynchronizationCanceled = 118,
TooLarge = 119,

View file

@ -732,7 +732,7 @@ static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask)
}
static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
NGLOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:08X}, core=0x{:X}", thread_handle,
NGLOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:16X}, core=0x{:X}", thread_handle,
mask, core);
const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
@ -740,6 +740,31 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
return ERR_INVALID_HANDLE;
}
if (core == THREADPROCESSORID_DEFAULT) {
ASSERT(thread->owner_process->ideal_processor != THREADPROCESSORID_DEFAULT);
// Set the target CPU to the one specified in the process' exheader.
core = thread->owner_process->ideal_processor;
mask = 1 << core;
}
if (mask == 0) {
return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidCombination);
}
/// This value is used to only change the affinity mask without changing the current ideal core.
static constexpr u32 OnlyChangeMask = static_cast<u32>(-3);
if (core == OnlyChangeMask) {
core = thread->ideal_core;
} else if (core >= Core::NUM_CPU_CORES && core != -1) {
return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidProcessorId);
}
// Error out if the input core isn't enabled in the input mask.
if (core < Core::NUM_CPU_CORES && (mask & (1 << core)) == 0) {
return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidCombination);
}
thread->ChangeCore(core, mask);
return RESULT_SUCCESS;