aboutsummaryrefslogtreecommitdiff
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.cpp73
1 files changed, 58 insertions, 15 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index c826dfd96..2e80b48c2 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -391,7 +391,7 @@ static ResultCode SendSyncRequest(Handle handle) {
}
/// Get the ID for the specified thread.
-static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) {
+static ResultCode GetThreadId(u64* thread_id, Handle thread_handle) {
LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
@@ -405,20 +405,33 @@ static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) {
return RESULT_SUCCESS;
}
-/// Get the ID of the specified process
-static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
- LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle);
+/// Gets the ID of the specified process or a specified thread's owning process.
+static ResultCode GetProcessId(u64* process_id, Handle handle) {
+ LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle);
const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
- const SharedPtr<Process> process = handle_table.Get<Process>(process_handle);
- if (!process) {
- LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
- process_handle);
- return ERR_INVALID_HANDLE;
+ const SharedPtr<Process> process = handle_table.Get<Process>(handle);
+ if (process) {
+ *process_id = process->GetProcessID();
+ return RESULT_SUCCESS;
}
- *process_id = process->GetProcessID();
- return RESULT_SUCCESS;
+ const SharedPtr<Thread> thread = handle_table.Get<Thread>(handle);
+ if (thread) {
+ const Process* const owner_process = thread->GetOwnerProcess();
+ if (!owner_process) {
+ LOG_ERROR(Kernel_SVC, "Non-existent owning process encountered.");
+ return ERR_INVALID_HANDLE;
+ }
+
+ *process_id = owner_process->GetProcessID();
+ return RESULT_SUCCESS;
+ }
+
+ // NOTE: This should also handle debug objects before returning.
+
+ LOG_ERROR(Kernel_SVC, "Handle does not exist, handle=0x{:08X}", handle);
+ return ERR_INVALID_HANDLE;
}
/// Default thread wakeup callback for WaitSynchronization
@@ -919,8 +932,35 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
}
/// Sets the thread activity
-static ResultCode SetThreadActivity(Handle handle, u32 unknown) {
- LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x{:08X}, unknown=0x{:08X}", handle, unknown);
+static ResultCode SetThreadActivity(Handle handle, u32 activity) {
+ LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", handle, activity);
+ if (activity > static_cast<u32>(ThreadActivity::Paused)) {
+ return ERR_INVALID_ENUM_VALUE;
+ }
+
+ const auto* current_process = Core::CurrentProcess();
+ const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
+ if (!thread) {
+ LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
+ return ERR_INVALID_HANDLE;
+ }
+
+ if (thread->GetOwnerProcess() != current_process) {
+ LOG_ERROR(Kernel_SVC,
+ "The current process does not own the current thread, thread_handle={:08X} "
+ "thread_pid={}, "
+ "current_process_pid={}",
+ handle, thread->GetOwnerProcess()->GetProcessID(),
+ current_process->GetProcessID());
+ return ERR_INVALID_HANDLE;
+ }
+
+ if (thread == GetCurrentThread()) {
+ LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread");
+ return ERR_BUSY;
+ }
+
+ thread->SetActivity(static_cast<ThreadActivity>(activity));
return RESULT_SUCCESS;
}
@@ -947,7 +987,7 @@ static ResultCode GetThreadContext(VAddr thread_context, Handle handle) {
if (thread == GetCurrentThread()) {
LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread");
- return ERR_ALREADY_REGISTERED;
+ return ERR_BUSY;
}
Core::ARM_Interface::ThreadContext ctx = thread->GetContext();
@@ -1232,7 +1272,10 @@ static ResultCode StartThread(Handle thread_handle) {
ASSERT(thread->GetStatus() == ThreadStatus::Dormant);
thread->ResumeFromWait();
- Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();
+
+ if (thread->GetStatus() == ThreadStatus::Ready) {
+ Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();
+ }
return RESULT_SUCCESS;
}