diff --git a/src/core/kernel/events.cpp b/src/core/kernel/events.cpp index e771f750..a63eb9ed 100644 --- a/src/core/kernel/events.cpp +++ b/src/core/kernel/events.cpp @@ -111,12 +111,15 @@ void Kernel::svcClearEvent() { void Kernel::svcSignalEvent() { const Handle handle = regs[0]; logSVC("SignalEvent(event handle = %X)\n", handle); - - if (!signalEvent(handle)) { + KernelObject* object = getObject(handle, KernelObjectType::Event); + + if (object == nullptr) { Helpers::panic("Signalled non-existent event: %X\n", handle); regs[0] = SVCResult::BadHandle; } else { + // We must signalEvent after setting r0, otherwise the r0 of the new thread will ne corrupted regs[0] = SVCResult::Success; + signalEvent(handle); } } diff --git a/src/core/kernel/ports.cpp b/src/core/kernel/ports.cpp index 85a7aaf5..71446454 100644 --- a/src/core/kernel/ports.cpp +++ b/src/core/kernel/ports.cpp @@ -78,24 +78,26 @@ void Kernel::sendSyncRequest() { // The sync request is being sent at a service rather than whatever port, so have the service manager intercept it if (KernelHandles::isServiceHandle(handle)) { - serviceManager.sendCommandToService(messagePointer, handle); + // The service call might cause a reschedule and change threads. Hence, set r0 before executing the service call + // Because if the service call goes first, we might corrupt the new thread's r0!! regs[0] = SVCResult::Success; + serviceManager.sendCommandToService(messagePointer, handle); return; } // Check if our sync request is targetting a file instead of a service bool isFileOperation = getObject(handle, KernelObjectType::File) != nullptr; if (isFileOperation) { + regs[0] = SVCResult::Success; // r0 goes first here too handleFileOperation(messagePointer, handle); - regs[0] = SVCResult::Success; return; } // Check if our sync request is targetting a directory instead of a service bool isDirectoryOperation = getObject(handle, KernelObjectType::Directory) != nullptr; if (isDirectoryOperation) { + regs[0] = SVCResult::Success; // r0 goes first here too handleDirectoryOperation(messagePointer, handle); - regs[0] = SVCResult::Success; return; } @@ -111,13 +113,13 @@ void Kernel::sendSyncRequest() { const Handle portHandle = sessionData->portHandle; if (portHandle == srvHandle) { // Special-case SendSyncRequest targetting the "srv: port" + regs[0] = SVCResult::Success; serviceManager.handleSyncRequest(messagePointer); } else if (portHandle == errorPortHandle) { // Special-case "err:f" for juicy logs too + regs[0] = SVCResult::Success; handleErrorSyncRequest(messagePointer); } else { const auto portData = objects[portHandle].getData(); Helpers::panic("SendSyncRequest targetting port %s\n", portData->name); } - - regs[0] = SVCResult::Success; } \ No newline at end of file