From 008eb974d43658d96c0b8d667975d3897303b42a Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 21 Feb 2023 10:42:24 -0700 Subject: [PATCH] kern: KConditionVariable::SignalToAddress now emits dmb before userspace write --- .../source/kern_k_condition_variable.cpp | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/libraries/libmesosphere/source/kern_k_condition_variable.cpp b/libraries/libmesosphere/source/kern_k_condition_variable.cpp index 6dc2b25b6..138602cfb 100644 --- a/libraries/libmesosphere/source/kern_k_condition_variable.cpp +++ b/libraries/libmesosphere/source/kern_k_condition_variable.cpp @@ -78,7 +78,7 @@ namespace ams::kern { /* Remove waiter thread. */ s32 num_waiters; - KThread *next_owner_thread = owner_thread->RemoveWaiterByKey(std::addressof(num_waiters), addr); + KThread * const next_owner_thread = owner_thread->RemoveWaiterByKey(std::addressof(num_waiters), addr); /* Determine the next tag. */ u32 next_value = 0; @@ -87,24 +87,25 @@ namespace ams::kern { if (num_waiters > 1) { next_value |= ams::svc::HandleWaitMask; } - - /* Write the value to userspace. */ - Result result; - if (AMS_LIKELY(WriteToUser(addr, std::addressof(next_value)))) { - result = ResultSuccess(); - } else { - result = svc::ResultInvalidCurrentMemory(); - } - - /* Signal the next owner thread. */ - next_owner_thread->EndWait(result); - R_RETURN(result); - } else { - /* Just write the value to userspace. */ - R_UNLESS(WriteToUser(addr, std::addressof(next_value)), svc::ResultInvalidCurrentMemory()); - - R_SUCCEED(); } + + /* Synchronize memory before proceeding. */ + cpu::DataMemoryBarrierInnerShareable(); + + /* Write the value to userspace. */ + Result result; + if (AMS_LIKELY(WriteToUser(addr, std::addressof(next_value)))) { + result = ResultSuccess(); + } else { + result = svc::ResultInvalidCurrentMemory(); + } + + /* If necessary, signal the next owner thread. */ + if (next_owner_thread != nullptr) { + next_owner_thread->EndWait(result); + } + + R_RETURN(result); } }