diff options
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 71 |
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 | ||
| 1746 | static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, u32 core, | 1746 | static 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 | ||