From 991f51831dd16f648712bd3b9180bd05e545eb2e Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Tue, 7 Jul 2020 23:27:15 +0100 Subject: [PATCH] kext: add hid/ir thread locking --- k11_extension/include/synchronization.h | 14 +++++-- k11_extension/source/svc.c | 2 +- k11_extension/source/svc/KernelSetState.c | 20 +++++++-- k11_extension/source/synchronization.c | 50 ++++++++++++++--------- 4 files changed, 58 insertions(+), 28 deletions(-) diff --git a/k11_extension/include/synchronization.h b/k11_extension/include/synchronization.h index 32635a7..b577e2e 100644 --- a/k11_extension/include/synchronization.h +++ b/k11_extension/include/synchronization.h @@ -36,11 +36,12 @@ void executeFunctionOnCores(SGI0Handler_t func, u8 targetList, u8 targetListFilt void KScheduler__TriggerCrossCoreInterrupt(KScheduler *this); void KThread__DebugReschedule(KThread *this, bool lock); -bool rosalinaThreadLockPredicate(KThread *thread); + +bool rosalinaThreadLockPredicate(KThread *thread, u32 mask); void rosalinaRescheduleThread(KThread *thread, bool lock); -void rosalinaLockThread(KThread *thread); -void rosalinaLockAllThreads(void); -void rosalinaUnlockAllThreads(void); + +void rosalinaLockThreads(u32 mask); +void rosalinaUnlockThreads(u32 mask); // Taken from ctrulib: @@ -49,6 +50,11 @@ static inline void __dsb(void) __asm__ __volatile__("mcr p15, 0, %[val], c7, c10, 4" :: [val] "r" (0) : "memory"); } +static inline void __dmb(void) +{ + __asm__ __volatile__("mcr p15, 0, %[val], c7, c10, 5" :: [val] "r" (0) : "memory"); +} + static inline void __clrex(void) { __asm__ __volatile__("clrex" ::: "memory"); diff --git a/k11_extension/source/svc.c b/k11_extension/source/svc.c index 9f929bc..3045794 100644 --- a/k11_extension/source/svc.c +++ b/k11_extension/source/svc.c @@ -78,7 +78,7 @@ void signalSvcReturn(u8 *pageEnd) void postprocessSvc(void) { KThread *currentThread = currentCoreContext->objectContext.currentThread; - if(!currentThread->shallTerminate && rosalinaThreadLockPredicate(currentThread)) + if(!currentThread->shallTerminate && rosalinaThreadLockPredicate(currentThread, rosalinaState & 5)) rosalinaRescheduleThread(currentThread, true); officialPostProcessSvc(); diff --git a/k11_extension/source/svc/KernelSetState.c b/k11_extension/source/svc/KernelSetState.c index 7bf6048..2b944aa 100644 --- a/k11_extension/source/svc/KernelSetState.c +++ b/k11_extension/source/svc/KernelSetState.c @@ -104,14 +104,26 @@ Result KernelSetStateHook(u32 type, u32 varg1, u32 varg2, u32 varg3) __ldrex((s32 *)&rosalinaState); } while(__strex((s32 *)&rosalinaState, (s32)(rosalinaState ^ varg1))); + __dmb(); if(rosalinaState & 2) hasStartedRosalinaNetworkFuncsOnce = true; - if(rosalinaState & 1) - rosalinaLockAllThreads(); - else if(varg1 & 1) - rosalinaUnlockAllThreads(); + // 1: all applet/app/gsp/dsp... threads 4: hid/ir + if(varg1 & 1) + { + if (rosalinaState & 1) + rosalinaLockThreads(1); + else + rosalinaUnlockThreads(1); + } + if(varg1 & 4) + { + if (rosalinaState & 4) + rosalinaLockThreads(4); + else + rosalinaUnlockThreads(4); + } break; } diff --git a/k11_extension/source/synchronization.c b/k11_extension/source/synchronization.c index eb88c6a..d6dc6cb 100644 --- a/k11_extension/source/synchronization.c +++ b/k11_extension/source/synchronization.c @@ -66,17 +66,12 @@ void KThread__DebugReschedule(KThread *this, bool lock) KRecursiveLock__Unlock(criticalSectionLock); } -bool rosalinaThreadLockPredicate(KThread *thread) +static void rosalinaLockThread(KThread *thread) { - KProcess *process = thread->ownerProcess; - if(process == NULL) - return false; + KThread *syncThread = synchronizationMutex->owner; - u64 titleId = codeSetOfProcess(process)->titleId; - u32 highTitleId = (u32)(titleId >> 32), lowTitleId = (u32)(titleId & ~0xF0000001); // clear N3DS and SAFE_FIRM bits - return - ((rosalinaState & 1) && idOfProcess(process) >= nbSection0Modules && - (highTitleId != 0x00040130 || (highTitleId == 0x00040130 && (lowTitleId == 0x1A02 || lowTitleId == 0x1C02)))); + if(syncThread == NULL || syncThread != thread) + rosalinaRescheduleThread(thread, true); } void rosalinaRescheduleThread(KThread *thread, bool lock) @@ -89,20 +84,37 @@ void rosalinaRescheduleThread(KThread *thread, bool lock) else thread->schedulingMask &= ~0x40; - KScheduler__AdjustThread(currentCoreContext->objectContext.currentScheduler, thread, oldSchedulingMask); + if (oldSchedulingMask != thread->schedulingMask) + KScheduler__AdjustThread(currentCoreContext->objectContext.currentScheduler, thread, oldSchedulingMask); KRecursiveLock__Unlock(criticalSectionLock); } -void rosalinaLockThread(KThread *thread) +bool rosalinaThreadLockPredicate(KThread *thread, u32 mask) { - KThread *syncThread = synchronizationMutex->owner; + KProcess *process = thread->ownerProcess; + if(process == NULL || idOfProcess(process) < nbSection0Modules) + return false; - if(syncThread == NULL || syncThread != thread) - rosalinaRescheduleThread(thread, true); + u64 titleId = codeSetOfProcess(process)->titleId; + u32 highTitleId = (u32)(titleId >> 32), lowTitleId = (u32)(titleId & ~0xF0000001); // clear N3DS and SAFE_FIRM bits + + if (mask & 1) + { + if (highTitleId != 0x00040130) // non-sysmodules + return true; + else + return lowTitleId == 0x1A02 || lowTitleId == 0x1C02 || lowTitleId == 0x2702; // dsp, gsp, csnd + } + if (mask & 4) + { + return lowTitleId == 0x1D02 || lowTitleId == 0x3302; + } + + return false; } -void rosalinaLockAllThreads(void) +void rosalinaLockThreads(u32 mask) { bool currentThreadsFound = false; @@ -110,7 +122,7 @@ void rosalinaLockAllThreads(void) for(KLinkedListNode *node = threadList->list.nodes.first; node != (KLinkedListNode *)&threadList->list.nodes; node = node->next) { KThread *thread = (KThread *)node->key; - if(!rosalinaThreadLockPredicate(thread)) + if(!rosalinaThreadLockPredicate(thread, mask)) continue; if(thread == coreCtxs[thread->coreId].objectContext.currentThread) currentThreadsFound = true; @@ -123,7 +135,7 @@ void rosalinaLockAllThreads(void) for(KLinkedListNode *node = threadList->list.nodes.first; node != (KLinkedListNode *)&threadList->list.nodes; node = node->next) { KThread *thread = (KThread *)node->key; - if(!rosalinaThreadLockPredicate(thread)) + if(!rosalinaThreadLockPredicate(thread, mask)) continue; if(!(thread->schedulingMask & 0x40)) { @@ -145,7 +157,7 @@ void rosalinaLockAllThreads(void) KRecursiveLock__Unlock(criticalSectionLock); } -void rosalinaUnlockAllThreads(void) +void rosalinaUnlockThreads(u32 mask) { for(KLinkedListNode *node = threadList->list.nodes.first; node != (KLinkedListNode *)&threadList->list.nodes; node = node->next) { @@ -154,7 +166,7 @@ void rosalinaUnlockAllThreads(void) if((thread->schedulingMask & 0xF) == 2) // thread is terminating continue; - if(thread->schedulingMask & 0x40) + if((thread->schedulingMask & 0x40) && rosalinaThreadLockPredicate(thread, mask)) rosalinaRescheduleThread(thread, false); } }