From: Greg Kroah-Hartman Date: Sat, 22 Apr 2023 15:36:09 +0000 (+0200) Subject: 5.15-stable patches X-Git-Tag: v4.14.314~75 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5be13ea226eeaeee1f826929e6801af704811379;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: pwm-meson-explicitly-set-.polarity-in-.get_state.patch rtmutex-add-acquire-semantics-for-rtmutex-lock-acquisition-slow-path.patch --- diff --git a/queue-5.15/pwm-meson-explicitly-set-.polarity-in-.get_state.patch b/queue-5.15/pwm-meson-explicitly-set-.polarity-in-.get_state.patch new file mode 100644 index 00000000000..f138060a22c --- /dev/null +++ b/queue-5.15/pwm-meson-explicitly-set-.polarity-in-.get_state.patch @@ -0,0 +1,62 @@ +From 8caa81eb950cb2e9d2d6959b37d853162d197f57 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Wed, 22 Mar 2023 22:45:44 +0100 +Subject: pwm: meson: Explicitly set .polarity in .get_state() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +commit 8caa81eb950cb2e9d2d6959b37d853162d197f57 upstream. + +The driver only supports normal polarity. Complete the implementation of +.get_state() by setting .polarity accordingly. + +This fixes a regression that was possible since commit c73a3107624d +("pwm: Handle .get_state() failures") which stopped to zero-initialize +the state passed to the .get_state() callback. This was reported at +https://forum.odroid.com/viewtopic.php?f=177&t=46360 . While this was an +unintended side effect, the real issue is the driver's callback not +setting the polarity. + +There is a complicating fact, that the .apply() callback fakes support +for inversed polarity. This is not (and cannot) be matched by +.get_state(). As fixing this isn't easy, only point it out in a comment +to prevent authors of other drivers from copying that approach. + +Fixes: c375bcbaabdb ("pwm: meson: Read the full hardware state in meson_pwm_get_state()") +Reported-by: Munehisa Kamata +Acked-by: Martin Blumenstingl +Link: https://lore.kernel.org/r/20230310191405.2606296-1-u.kleine-koenig@pengutronix.de +Signed-off-by: Uwe Kleine-König +Signed-off-by: Thierry Reding +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pwm/pwm-meson.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/pwm/pwm-meson.c ++++ b/drivers/pwm/pwm-meson.c +@@ -168,6 +168,12 @@ static int meson_pwm_calc(struct meson_p + duty = state->duty_cycle; + period = state->period; + ++ /* ++ * Note this is wrong. The result is an output wave that isn't really ++ * inverted and so is wrongly identified by .get_state as normal. ++ * Fixing this needs some care however as some machines might rely on ++ * this. ++ */ + if (state->polarity == PWM_POLARITY_INVERSED) + duty = period - duty; + +@@ -304,6 +310,8 @@ static int meson_pwm_apply(struct pwm_ch + meson_pwm_enable(meson, pwm); + } + ++ state->polarity = PWM_POLARITY_NORMAL; ++ + return 0; + } + diff --git a/queue-5.15/rtmutex-add-acquire-semantics-for-rtmutex-lock-acquisition-slow-path.patch b/queue-5.15/rtmutex-add-acquire-semantics-for-rtmutex-lock-acquisition-slow-path.patch new file mode 100644 index 00000000000..5d125003918 --- /dev/null +++ b/queue-5.15/rtmutex-add-acquire-semantics-for-rtmutex-lock-acquisition-slow-path.patch @@ -0,0 +1,220 @@ +From 1c0908d8e441631f5b8ba433523cf39339ee2ba0 Mon Sep 17 00:00:00 2001 +From: Mel Gorman +Date: Fri, 2 Dec 2022 10:02:23 +0000 +Subject: rtmutex: Add acquire semantics for rtmutex lock acquisition slow path + +From: Mel Gorman + +commit 1c0908d8e441631f5b8ba433523cf39339ee2ba0 upstream. + +Jan Kara reported the following bug triggering on 6.0.5-rt14 running dbench +on XFS on arm64. + + kernel BUG at fs/inode.c:625! + Internal error: Oops - BUG: 0 [#1] PREEMPT_RT SMP + CPU: 11 PID: 6611 Comm: dbench Tainted: G E 6.0.0-rt14-rt+ #1 + pc : clear_inode+0xa0/0xc0 + lr : clear_inode+0x38/0xc0 + Call trace: + clear_inode+0xa0/0xc0 + evict+0x160/0x180 + iput+0x154/0x240 + do_unlinkat+0x184/0x300 + __arm64_sys_unlinkat+0x48/0xc0 + el0_svc_common.constprop.4+0xe4/0x2c0 + do_el0_svc+0xac/0x100 + el0_svc+0x78/0x200 + el0t_64_sync_handler+0x9c/0xc0 + el0t_64_sync+0x19c/0x1a0 + +It also affects 6.1-rc7-rt5 and affects a preempt-rt fork of 5.14 so this +is likely a bug that existed forever and only became visible when ARM +support was added to preempt-rt. The same problem does not occur on x86-64 +and he also reported that converting sb->s_inode_wblist_lock to +raw_spinlock_t makes the problem disappear indicating that the RT spinlock +variant is the problem. + +Which in turn means that RT mutexes on ARM64 and any other weakly ordered +architecture are affected by this independent of RT. + +Will Deacon observed: + + "I'd be more inclined to be suspicious of the slowpath tbh, as we need to + make sure that we have acquire semantics on all paths where the lock can + be taken. Looking at the rtmutex code, this really isn't obvious to me + -- for example, try_to_take_rt_mutex() appears to be able to return via + the 'takeit' label without acquire semantics and it looks like we might + be relying on the caller's subsequent _unlock_ of the wait_lock for + ordering, but that will give us release semantics which aren't correct." + +Sebastian Andrzej Siewior prototyped a fix that does work based on that +comment but it was a little bit overkill and added some fences that should +not be necessary. + +The lock owner is updated with an IRQ-safe raw spinlock held, but the +spin_unlock does not provide acquire semantics which are needed when +acquiring a mutex. + +Adds the necessary acquire semantics for lock owner updates in the slow path +acquisition and the waiter bit logic. + +It successfully completed 10 iterations of the dbench workload while the +vanilla kernel fails on the first iteration. + +[ bigeasy@linutronix.de: Initial prototype fix ] + +Fixes: 700318d1d7b38 ("locking/rtmutex: Use acquire/release semantics") +Fixes: 23f78d4a03c5 ("[PATCH] pi-futex: rt mutex core") +Reported-by: Jan Kara +Signed-off-by: Mel Gorman +Signed-off-by: Thomas Gleixner +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20221202100223.6mevpbl7i6x5udfd@techsingularity.net +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Greg Kroah-Hartman +--- + kernel/locking/rtmutex.c | 55 +++++++++++++++++++++++++++++++++++-------- + kernel/locking/rtmutex_api.c | 6 ++-- + 2 files changed, 49 insertions(+), 12 deletions(-) + +--- a/kernel/locking/rtmutex.c ++++ b/kernel/locking/rtmutex.c +@@ -87,15 +87,31 @@ static inline int __ww_mutex_check_kill( + * set this bit before looking at the lock. + */ + +-static __always_inline void +-rt_mutex_set_owner(struct rt_mutex_base *lock, struct task_struct *owner) ++static __always_inline struct task_struct * ++rt_mutex_owner_encode(struct rt_mutex_base *lock, struct task_struct *owner) + { + unsigned long val = (unsigned long)owner; + + if (rt_mutex_has_waiters(lock)) + val |= RT_MUTEX_HAS_WAITERS; + +- WRITE_ONCE(lock->owner, (struct task_struct *)val); ++ return (struct task_struct *)val; ++} ++ ++static __always_inline void ++rt_mutex_set_owner(struct rt_mutex_base *lock, struct task_struct *owner) ++{ ++ /* ++ * lock->wait_lock is held but explicit acquire semantics are needed ++ * for a new lock owner so WRITE_ONCE is insufficient. ++ */ ++ xchg_acquire(&lock->owner, rt_mutex_owner_encode(lock, owner)); ++} ++ ++static __always_inline void rt_mutex_clear_owner(struct rt_mutex_base *lock) ++{ ++ /* lock->wait_lock is held so the unlock provides release semantics. */ ++ WRITE_ONCE(lock->owner, rt_mutex_owner_encode(lock, NULL)); + } + + static __always_inline void clear_rt_mutex_waiters(struct rt_mutex_base *lock) +@@ -104,7 +120,8 @@ static __always_inline void clear_rt_mut + ((unsigned long)lock->owner & ~RT_MUTEX_HAS_WAITERS); + } + +-static __always_inline void fixup_rt_mutex_waiters(struct rt_mutex_base *lock) ++static __always_inline void ++fixup_rt_mutex_waiters(struct rt_mutex_base *lock, bool acquire_lock) + { + unsigned long owner, *p = (unsigned long *) &lock->owner; + +@@ -170,8 +187,21 @@ static __always_inline void fixup_rt_mut + * still set. + */ + owner = READ_ONCE(*p); +- if (owner & RT_MUTEX_HAS_WAITERS) +- WRITE_ONCE(*p, owner & ~RT_MUTEX_HAS_WAITERS); ++ if (owner & RT_MUTEX_HAS_WAITERS) { ++ /* ++ * See rt_mutex_set_owner() and rt_mutex_clear_owner() on ++ * why xchg_acquire() is used for updating owner for ++ * locking and WRITE_ONCE() for unlocking. ++ * ++ * WRITE_ONCE() would work for the acquire case too, but ++ * in case that the lock acquisition failed it might ++ * force other lockers into the slow path unnecessarily. ++ */ ++ if (acquire_lock) ++ xchg_acquire(p, owner & ~RT_MUTEX_HAS_WAITERS); ++ else ++ WRITE_ONCE(*p, owner & ~RT_MUTEX_HAS_WAITERS); ++ } + } + + /* +@@ -206,6 +236,13 @@ static __always_inline void mark_rt_mute + owner = *p; + } while (cmpxchg_relaxed(p, owner, + owner | RT_MUTEX_HAS_WAITERS) != owner); ++ ++ /* ++ * The cmpxchg loop above is relaxed to avoid back-to-back ACQUIRE ++ * operations in the event of contention. Ensure the successful ++ * cmpxchg is visible. ++ */ ++ smp_mb__after_atomic(); + } + + /* +@@ -1232,7 +1269,7 @@ static int __sched __rt_mutex_slowtryloc + * try_to_take_rt_mutex() sets the lock waiters bit + * unconditionally. Clean this up. + */ +- fixup_rt_mutex_waiters(lock); ++ fixup_rt_mutex_waiters(lock, true); + + return ret; + } +@@ -1592,7 +1629,7 @@ static int __sched __rt_mutex_slowlock(s + * try_to_take_rt_mutex() sets the waiter bit + * unconditionally. We might have to fix that up. + */ +- fixup_rt_mutex_waiters(lock); ++ fixup_rt_mutex_waiters(lock, true); + return ret; + } + +@@ -1702,7 +1739,7 @@ static void __sched rtlock_slowlock_lock + * try_to_take_rt_mutex() sets the waiter bit unconditionally. + * We might have to fix that up: + */ +- fixup_rt_mutex_waiters(lock); ++ fixup_rt_mutex_waiters(lock, true); + debug_rt_mutex_free_waiter(&waiter); + } + +--- a/kernel/locking/rtmutex_api.c ++++ b/kernel/locking/rtmutex_api.c +@@ -245,7 +245,7 @@ void __sched rt_mutex_init_proxy_locked( + void __sched rt_mutex_proxy_unlock(struct rt_mutex_base *lock) + { + debug_rt_mutex_proxy_unlock(lock); +- rt_mutex_set_owner(lock, NULL); ++ rt_mutex_clear_owner(lock); + } + + /** +@@ -360,7 +360,7 @@ int __sched rt_mutex_wait_proxy_lock(str + * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might + * have to fix that up. + */ +- fixup_rt_mutex_waiters(lock); ++ fixup_rt_mutex_waiters(lock, true); + raw_spin_unlock_irq(&lock->wait_lock); + + return ret; +@@ -416,7 +416,7 @@ bool __sched rt_mutex_cleanup_proxy_lock + * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might + * have to fix that up. + */ +- fixup_rt_mutex_waiters(lock); ++ fixup_rt_mutex_waiters(lock, false); + + raw_spin_unlock_irq(&lock->wait_lock); + diff --git a/queue-5.15/series b/queue-5.15/series index 046a9c78396..389a8c55a1e 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -33,3 +33,5 @@ s390-ptrace-fix-ptrace_get_last_break-error-handling.patch nvme-tcp-fix-a-possible-uaf-when-failing-to-allocate.patch xen-netback-use-same-error-messages-for-same-errors.patch platform-x86-gigabyte-wmi-add-support-for-x570s-aoru.patch +pwm-meson-explicitly-set-.polarity-in-.get_state.patch +rtmutex-add-acquire-semantics-for-rtmutex-lock-acquisition-slow-path.patch