From: Yazen Ghannam <yazen.ghannam@amd.com>
To: Rui Qi <qirui.001@bytedance.com>
Cc: tony.luck@intel.com, bp@alien8.de, linux-edac@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 4/4] RAS/AMD/FMPM: Fix spurious BUG when ERST record enumeration fails
Date: Thu, 24 Sep 2026 12:17:46 -0400 [thread overview]
Message-ID: <20260924161746.GI1080284@yaz-khff2.amd.com> (raw)
In-Reply-To: <20260826035314.1536340-5-qirui.001@bytedance.com>
On Wed, Aug 26, 2026 at 11:53:14AM +0800, Rui Qi wrote:
> When erst_get_record_id_begin() returns an error, get_saved_records()
> jumps to the out_end label which unconditionally calls
> erst_get_record_id_end(). This is wrong because:
>
> - If erst_disable is true, begin() returns -ENODEV without
> incrementing the refcount. Then end() hits BUG_ON(erst_disable)
> and panics.
>
> - If mutex_lock_interruptible() is interrupted, begin() returns
> -EINTR without incrementing the refcount. Then end() decrements
> refcount below zero, hitting BUG_ON(refcount < 0).
>
> The comment in erst_get_record_id_end() warns that it should not be
> called when erst_disable is true, so callers must not invoke it after
> begin() fails.
>
> Fix by jumping to the out label when begin() fails, skipping the
> erst_get_record_id_end() call. This is safe because kfree() handles
> NULL pointers.
>
> Fixes: 6f15e617cc99 ("RAS: Introduce a FRU memory poison manager")
> Signed-off-by: Rui Qi <qirui.001@bytedance.com>
> ---
> drivers/ras/amd/fmpm.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/ras/amd/fmpm.c b/drivers/ras/amd/fmpm.c
> index c13db1f743e5..48a437042953 100644
> --- a/drivers/ras/amd/fmpm.c
> +++ b/drivers/ras/amd/fmpm.c
> @@ -673,7 +673,7 @@ static int get_saved_records(void)
>
> ret = erst_get_record_id_begin(&pos);
> if (ret < 0)
> - goto out_end;
> + goto out;
>
> while (!erst_get_record_id_next(&pos, &record_id)) {
> if (record_id == APEI_ERST_INVALID_RECORD_ID)
> @@ -714,8 +714,8 @@ static int get_saved_records(void)
>
> out_end:
> erst_get_record_id_end();
> - kfree(old);
> out:
> + kfree(old);
> return ret;
> }
>
> --
The patch is okay, but the 'erst_disable' part didn't make sense to me.
So I went over it with an AI assistant. Response is below.
Basically, the commit message needs to be reworded to cover the actual
issue.
Thanks,
Yazen
=========================
`erst_get_record_id_begin()` has two ways to fail, and the commit
message describes both. Only one of them can happen when fmpm calls it.
```c
int erst_get_record_id_begin(int *pos)
{
if (erst_disable)
return -ENODEV; /* case 1 */
rc = mutex_lock_interruptible(&erst_record_id_cache.lock);
if (rc)
return rc; /* case 2: -EINTR */
erst_record_id_cache.refcount++;
...
```
**Case 1 (`-ENODEV`) can't happen from `get_saved_records()`:**
- `fru_mem_poison_init()` already returns `-ENODEV` when `erst_disable`
is set, before it calls `get_saved_records()`.
- `erst_disable` has only two writers: the `erst_disable` boot parameter
(`__setup`) and the error path of `erst_init()`.
- `erst_init()` is a `device_initcall` in `drivers/acpi/`, which links
ahead of `drivers/ras/`. When fmpm is built in, `erst_init()` has
already run by the time fmpm's initcall runs. When fmpm is a module,
it loads later still.
- So `erst_disable` can't change between fmpm's check and the `begin()`
call, and the `BUG_ON(erst_disable)` in `end()` can't fire here.
**Case 2 (`-EINTR`) can happen, but only under narrow conditions:**
- The lock has to be contended. `mutex_lock_interruptible()` takes an
uncontended lock without checking for signals. Other code that takes
`erst_record_id_cache.lock` includes the other `begin()` callers:
`erst_open_pstore()`, `erst_dbg_open()` and `apei_read_mce()`.
- A signal has to be pending while the task waits. That's realistic when
fmpm is a module, for example Ctrl-C or SIGKILL sent to `modprobe`
while pstore or erst-dbg holds the lock. When fmpm is built in, its
init runs in the `kernel_init` thread before userspace starts, so no
signal can reach it.
- Before the patch, this path calls `end()`. The refcount drops to -1
and hits `BUG_ON(refcount < 0)` while `erst_record_id_cache.lock` is
held. The oops kills the task with the mutex still locked, so every
later ERST user blocks on it forever.
In short, "reachable" was loose wording. The `-ENODEV` case can't happen
from fmpm at all. The `-EINTR` case can happen, but only when fmpm is a
module, the lock is contended, and the load is interrupted by a signal.
The patch fixes that case, which is real. The commit message just leads
with the case that can't happen from fmpm and understates the
consequence of the one that can.
next prev parent reply other threads:[~2026-09-24 16:17 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-21 9:47 [PATCH 0/4] RAS/amd/fmpm: Fix OOB, uninitialized data, and error-handling bugs Rui Qi
2026-08-21 9:47 ` [PATCH 1/4] RAS/amd/fmpm: Fix out-of-bounds read in for_each_fru macro Rui Qi
2026-08-25 17:14 ` Yazen Ghannam
2026-08-21 9:47 ` [PATCH 2/4] RAS/amd/fmpm: Clear new records bitmap before rollback Rui Qi
2026-08-25 19:56 ` Yazen Ghannam
2026-08-21 9:47 ` [PATCH 3/4] RAS/amd/fmpm: Make max_nr_entries read-only Rui Qi
2026-08-25 20:06 ` Yazen Ghannam
2026-08-21 9:47 ` [PATCH 4/4] RAS/amd/fmpm: Fix spurious BUG when ERST record enumeration fails Rui Qi
2026-08-25 20:21 ` Yazen Ghannam
2026-08-26 3:53 ` [PATCH v2 0/4] RAS/AMD/FMPM: Fix OOB, uninitialized data, and error-handling bugs Rui Qi
2026-08-26 3:53 ` [PATCH v2 1/4] RAS/AMD/FMPM: Fix out-of-bounds read in for_each_fru macro Rui Qi
2026-09-24 15:26 ` Yazen Ghannam
2026-08-26 3:53 ` [PATCH v2 2/4] RAS/AMD/FMPM: Clear new records bitmap before rollback Rui Qi
2026-09-24 15:29 ` Yazen Ghannam
2026-08-26 3:53 ` [PATCH v2 3/4] RAS/AMD/FMPM: Make max_nr_entries read-only Rui Qi
2026-09-24 15:31 ` Yazen Ghannam
2026-08-26 3:53 ` [PATCH v2 4/4] RAS/AMD/FMPM: Fix spurious BUG when ERST record enumeration fails Rui Qi
2026-09-24 16:17 ` Yazen Ghannam [this message]
2026-09-24 2:24 ` [PATCH v2 0/4] RAS/AMD/FMPM: Fix OOB, uninitialized data, and error-handling bugs Rui Qi
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=20260924161746.GI1080284@yaz-khff2.amd.com \
--to=yazen.ghannam@amd.com \
--cc=bp@alien8.de \
--cc=linux-edac@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=qirui.001@bytedance.com \
--cc=tony.luck@intel.com \
/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
all inboxes | Powered by JetHome®