summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp71
1 files changed, 39 insertions, 32 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index bb12f9ac7..5ed00d451 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1744,52 +1744,59 @@ static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle,
1744} 1744}
1745 1745
1746static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, u32 core, 1746static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, u32 core,
1747 u64 mask) { 1747 u64 affinity_mask) {
1748 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:016X}, core=0x{:X}", thread_handle, 1748 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, core=0x{:X}, affinity_mask=0x{:016X}",
1749 mask, core); 1749 thread_handle, core, affinity_mask);
1750 1750
1751 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 1751 const auto* const current_process = system.Kernel().CurrentProcess();
1752 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
1753 if (!thread) {
1754 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
1755 thread_handle);
1756 return ERR_INVALID_HANDLE;
1757 }
1758 1752
1759 if (core == static_cast<u32>(THREADPROCESSORID_IDEAL)) { 1753 if (core == static_cast<u32>(THREADPROCESSORID_IDEAL)) {
1760 const u8 ideal_cpu_core = thread->GetOwnerProcess()->GetIdealCore(); 1754 const u8 ideal_cpu_core = current_process->GetIdealCore();
1761 1755
1762 ASSERT(ideal_cpu_core != static_cast<u8>(THREADPROCESSORID_IDEAL)); 1756 ASSERT(ideal_cpu_core != static_cast<u8>(THREADPROCESSORID_IDEAL));
1763 1757
1764 // Set the target CPU to the ideal core specified by the process. 1758 // Set the target CPU to the ideal core specified by the process.
1765 core = ideal_cpu_core; 1759 core = ideal_cpu_core;
1766 mask = 1ULL << core; 1760 affinity_mask = 1ULL << core;
1767 } 1761 } else {
1768 1762 const u64 core_mask = current_process->GetCoreMask();
1769 if (mask == 0) { 1763
1770 LOG_ERROR(Kernel_SVC, "Mask is 0"); 1764 if ((core_mask | affinity_mask) != core_mask) {
1771 return ERR_INVALID_COMBINATION; 1765 LOG_ERROR(
1772 } 1766 Kernel_SVC,
1767 "Invalid processor ID specified (core_mask=0x{:08X}, affinity_mask=0x{:016X})",
1768 core_mask, affinity_mask);
1769 return ERR_INVALID_PROCESSOR_ID;
1770 }
1773 1771
1774 /// This value is used to only change the affinity mask without changing the current ideal core. 1772 if (affinity_mask == 0) {
1775 static constexpr u32 OnlyChangeMask = static_cast<u32>(-3); 1773 LOG_ERROR(Kernel_SVC, "Specfified affinity mask is zero.");
1774 return ERR_INVALID_COMBINATION;
1775 }
1776 1776
1777 if (core == OnlyChangeMask) { 1777 if (core < Core::NUM_CPU_CORES) {
1778 core = thread->GetIdealCore(); 1778 if ((affinity_mask & (1ULL << core)) == 0) {
1779 } else if (core >= Core::NUM_CPU_CORES && core != static_cast<u32>(THREADPROCESSORID_DONT_UPDATE)) { 1779 LOG_ERROR(Kernel_SVC,
1780 LOG_ERROR(Kernel_SVC, "Invalid core specified, got {}", core); 1780 "Core is not enabled for the current mask, core={}, mask={:016X}", core,
1781 return ERR_INVALID_PROCESSOR_ID; 1781 affinity_mask);
1782 return ERR_INVALID_COMBINATION;
1783 }
1784 } else if (core != static_cast<u32>(THREADPROCESSORID_DONT_CARE) &&
1785 core != static_cast<u32>(THREADPROCESSORID_DONT_UPDATE)) {
1786 LOG_ERROR(Kernel_SVC, "Invalid processor ID specified (core={}).", core);
1787 return ERR_INVALID_PROCESSOR_ID;
1788 }
1782 } 1789 }
1783 1790
1784 // Error out if the input core isn't enabled in the input mask. 1791 const auto& handle_table = current_process->GetHandleTable();
1785 if (core < Core::NUM_CPU_CORES && (mask & (1ull << core)) == 0) { 1792 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
1786 LOG_ERROR(Kernel_SVC, "Core is not enabled for the current mask, core={}, mask={:016X}", 1793 if (!thread) {
1787 core, mask); 1794 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
1788 return ERR_INVALID_COMBINATION; 1795 thread_handle);
1796 return ERR_INVALID_HANDLE;
1789 } 1797 }
1790 1798
1791 thread->ChangeCore(core, mask); 1799 thread->ChangeCore(core, affinity_mask);
1792
1793 return RESULT_SUCCESS; 1800 return RESULT_SUCCESS;
1794} 1801}
1795 1802