diff options
| author | Liam <byteslice@airmail.cc> | 2023-01-23 20:31:03 -0500 | 
|---|---|---|
| committer | Liam <byteslice@airmail.cc> | 2023-01-23 20:31:03 -0500 | 
| commit | 693cad8e9b45cb61370bbc05e8e0022ea42044f9 (patch) | |
| tree | 7a64dd5d228f3d1611f6df381504ace9a9bf863a | |
| parent | 5086380a63bfbaa118ff48da14f505f842ac19cc (diff) | |
kernel: split SetAddressKey into user and kernel variants
| -rw-r--r-- | src/core/hle/kernel/k_condition_variable.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_light_lock.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_memory_layout.h | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.h | 22 | 
5 files changed, 29 insertions, 11 deletions
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index 124149697..0c6b20db3 100644 --- a/src/core/hle/kernel/k_condition_variable.cpp +++ b/src/core/hle/kernel/k_condition_variable.cpp @@ -171,7 +171,7 @@ Result KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 value)          R_UNLESS(owner_thread != nullptr, ResultInvalidHandle);          // Update the lock. -        cur_thread->SetAddressKey(addr, value); +        cur_thread->SetUserAddressKey(addr, value);          owner_thread->AddWaiter(cur_thread);          // Begin waiting. diff --git a/src/core/hle/kernel/k_light_lock.cpp b/src/core/hle/kernel/k_light_lock.cpp index 43185320d..d791acbe3 100644 --- a/src/core/hle/kernel/k_light_lock.cpp +++ b/src/core/hle/kernel/k_light_lock.cpp @@ -68,7 +68,7 @@ bool KLightLock::LockSlowPath(uintptr_t _owner, uintptr_t _cur_thread) {          // Add the current thread as a waiter on the owner.          KThread* owner_thread = reinterpret_cast<KThread*>(_owner & ~1ULL); -        cur_thread->SetAddressKey(reinterpret_cast<uintptr_t>(std::addressof(tag))); +        cur_thread->SetKernelAddressKey(reinterpret_cast<uintptr_t>(std::addressof(tag)));          owner_thread->AddWaiter(cur_thread);          // Begin waiting to hold the lock. diff --git a/src/core/hle/kernel/k_memory_layout.h b/src/core/hle/kernel/k_memory_layout.h index fd6e1d3e6..17fa1a6ed 100644 --- a/src/core/hle/kernel/k_memory_layout.h +++ b/src/core/hle/kernel/k_memory_layout.h @@ -67,9 +67,9 @@ constexpr size_t KernelPageBufferAdditionalSize = 0x33C000;  constexpr std::size_t KernelResourceSize = KernelPageTableHeapSize + KernelInitialPageHeapSize +                                             KernelSlabHeapSize + KernelPageBufferHeapSize; -constexpr bool IsKernelAddressKey(VAddr key) { -    return KernelVirtualAddressSpaceBase <= key && key <= KernelVirtualAddressSpaceLast; -} +//! NB: Use KThread::GetAddressKeyIsKernel(). +//! See explanation for deviation of GetAddressKey. +bool IsKernelAddressKey(VAddr key) = delete;  constexpr bool IsKernelAddress(VAddr address) {      return KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd; diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 7c7c2459c..84ff3c64b 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -330,7 +330,7 @@ void KThread::Finalize() {              KThread* const waiter = std::addressof(*it);              // The thread shouldn't be a kernel waiter. -            ASSERT(!IsKernelAddressKey(waiter->GetAddressKey())); +            ASSERT(!waiter->GetAddressKeyIsKernel());              // Clear the lock owner.              waiter->SetLockOwner(nullptr); @@ -884,7 +884,7 @@ void KThread::AddWaiterImpl(KThread* thread) {      }      // Keep track of how many kernel waiters we have. -    if (IsKernelAddressKey(thread->GetAddressKey())) { +    if (thread->GetAddressKeyIsKernel()) {          ASSERT((num_kernel_waiters++) >= 0);          KScheduler::SetSchedulerUpdateNeeded(kernel);      } @@ -898,7 +898,7 @@ void KThread::RemoveWaiterImpl(KThread* thread) {      ASSERT(kernel.GlobalSchedulerContext().IsLocked());      // Keep track of how many kernel waiters we have. -    if (IsKernelAddressKey(thread->GetAddressKey())) { +    if (thread->GetAddressKeyIsKernel()) {          ASSERT((num_kernel_waiters--) > 0);          KScheduler::SetSchedulerUpdateNeeded(kernel);      } @@ -974,7 +974,7 @@ KThread* KThread::RemoveWaiterByKey(s32* out_num_waiters, VAddr key) {              KThread* thread = std::addressof(*it);              // Keep track of how many kernel waiters we have. -            if (IsKernelAddressKey(thread->GetAddressKey())) { +            if (thread->GetAddressKeyIsKernel()) {                  ASSERT((num_kernel_waiters--) > 0);                  KScheduler::SetSchedulerUpdateNeeded(kernel);              } diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 083f4962d..9d771de0e 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h @@ -605,13 +605,30 @@ public:          return address_key_value;      } -    void SetAddressKey(VAddr key) { +    [[nodiscard]] bool GetAddressKeyIsKernel() const { +        return address_key_is_kernel; +    } + +    //! NB: intentional deviation from official kernel. +    // +    // Separate SetAddressKey into user and kernel versions +    // to cope with arbitrary host pointers making their way +    // into things. + +    void SetUserAddressKey(VAddr key) {          address_key = key; +        address_key_is_kernel = false;      } -    void SetAddressKey(VAddr key, u32 val) { +    void SetUserAddressKey(VAddr key, u32 val) {          address_key = key;          address_key_value = val; +        address_key_is_kernel = false; +    } + +    void SetKernelAddressKey(VAddr key) { +        address_key = key; +        address_key_is_kernel = true;      }      void ClearWaitQueue() { @@ -770,6 +787,7 @@ private:      bool debug_attached{};      s8 priority_inheritance_count{};      bool resource_limit_release_hint{}; +    bool address_key_is_kernel{};      StackParameters stack_parameters{};      Common::SpinLock context_guard{};  | 
