public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
From: Tudor Ambarus <tudor.ambarus@linaro.org>
To: Krzysztof Kozlowski <krzk@kernel.org>,
	Alim Akhtar <alim.akhtar@samsung.com>
Cc: linux-kernel@vger.kernel.org, linux-samsung-soc@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, peter.griffin@linaro.org,
	andre.draszik@linaro.org, jyescas@google.com,
	kernel-team@android.com, stable@vger.kernel.org
Subject: Re: [PATCH v2 4/6] firmware: samsung: acpm: Fix memory ordering race in RX path
Date: Tue, 28 Apr 2026 15:57:39 +0300	[thread overview]
Message-ID: <4421c95f-3ee7-40ac-b239-d877709b498a@linaro.org> (raw)
In-Reply-To: <6bba950c-5527-4613-8c16-b52534bc75a5@kernel.org>

Hi, Krzysztof,

Thanks for the review! I indeed missed something in the acquire path,
details below.

On 4/28/26 12:52 PM, Krzysztof Kozlowski wrote:
> On 27/04/2026 17:04, Tudor Ambarus wrote:
>> Sashiko identified a memory ordering race in RX path [1].
>>
>> When draining the RX queue or reading saved responses, the driver uses
>> clear_bit() to release the sequence number back to the available pool.
>> However, on weakly ordered architectures like ARM64, clear_bit() does
>> not provide implicit memory barriers.
> 
> And it does not have to if entire access is synchronized by other locks.

Right.

> You need to analyze also this and mention here path which is not
> synchronized and uses these weakly ordered atomic operations.
>

The TX path is protected by tx_lock, and the RX path is protected by
rx_lock. Because the bitmap_seqnum is modified by the RX thread
(clearing the bit) and the TX thread (setting the bit), the bitmap is
accessed across two different lock domains. Therefore, from the
bitmap's perspective, the synchronization is entirely lockless, and
explicit memory barriers are required. I'll add a comment in the
commit message.

>>
>> This allows the CPU to reorder instructions, making the cleared bit
>> globally visible before the preceding memory operations (memcpy() or
>> __ioread32_copy()) have completed. If a concurrent thread allocates the
>> newly freed sequence number, it can execute acpm_prepare_xfer() and
>> zero out the buffer via memset() while the RX thread is still actively
>> reading from it, leading to silent data corruption.
>>
>> Fix this by replacing clear_bit() with clear_bit_unlock() across the
>> RX path. This provides release semantics, guaranteeing that all prior
>> memory reads and writes are fully completed and visible before the
>> sequence number is marked as free.
> 
> Barriers should be paired and release is paired with acquire.
> bitmap_seqnum() is used with test_bit() and a separate set_bit(), which
> do not have acquire semantics, although in some calls it is within lock.
> Problem is I guess acpm_dequeue_by_polling() which is called without any
> locks.
> 
> This means that other thread won't see updated values.
> 
> I think you also need to investigate and fix that acquire path.

:) thanks for the challenge!

In acpm_dequeue_by_polling(), zero-lenght messages (rxcnt == 0) can have
their bits cleared by a concurrent thread draining the queue. If we have
our thread sitting in the do...while loop and calling test_bit() we risk
speculative execution of the caller's subsequent instructions before the
bit actually flips to zero. The fix is to s/test_bit()/test_bit_acquire().

In what concerns acpm_prepare_xfer(), where we use set_bit(), I find it
safe as it is, I don't think we need an acquire barrier. By the time the
test_bit() loop observes a 0, the RX's clear_bit_unlock() has guaranteed
that the payload was copied out. The rx_data->cmd buffer is dead.

Another thing that I thought about was about the reordering of memset
and set_bit in acpm_prepare_xfer(), but even there, the internal
execution order doesn't matter. Both are guaranteed to be completed
before writel (wmb). One may notice that I even reordered the memset and
set_bit in patch 6/6.

Also, test_bit() in acpm_prepare_xfer() will be replaced in patch 6/6
by find_next_zero_bit(), they are functionally equivalent.

I'll send a v3, s/test_bit()/test_bit_acquire()/ in RX path and update
the commit message with the details described above.

Cheers,
ta


  reply	other threads:[~2026-04-28 12:57 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-27 15:04 [PATCH v2 0/6] firmware: samsung: acpm: Various fixes for sashiko bug reports Tudor Ambarus
2026-04-27 15:04 ` [PATCH v2 1/6] firmware: samsung: acpm: Fix cross-thread RX length corruption Tudor Ambarus
2026-04-27 15:04 ` [PATCH v2 2/6] firmware: samsung: acpm: Fix mailbox channel leak on probe error Tudor Ambarus
2026-04-27 15:04 ` [PATCH v2 3/6] firmware: samsung: acpm: Fix dummy stubs to return ERR_PTR Tudor Ambarus
2026-04-27 15:04 ` [PATCH v2 4/6] firmware: samsung: acpm: Fix memory ordering race in RX path Tudor Ambarus
2026-04-28  9:52   ` Krzysztof Kozlowski
2026-04-28 12:57     ` Tudor Ambarus [this message]
2026-04-29 11:05       ` Tudor Ambarus
2026-04-27 15:04 ` [PATCH v2 5/6] firmware: samsung: acpm: Fix out-of-bounds read and infinite loop " Tudor Ambarus
2026-04-28 13:04   ` Tudor Ambarus
2026-04-27 15:04 ` [PATCH v2 6/6] firmware: samsung: acpm: Fix infinite loop on sequence number exhaustion Tudor Ambarus

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4421c95f-3ee7-40ac-b239-d877709b498a@linaro.org \
    --to=tudor.ambarus@linaro.org \
    --cc=alim.akhtar@samsung.com \
    --cc=andre.draszik@linaro.org \
    --cc=jyescas@google.com \
    --cc=kernel-team@android.com \
    --cc=krzk@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=peter.griffin@linaro.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox