From: sashiko-bot@kernel.org
To: "Mete Durlu" <meted@linux.ibm.com>
Cc: linux-s390@vger.kernel.org, "Heiko Carstens" <hca@linux.ibm.com>,
"Vasily Gorbik" <gor@linux.ibm.com>,
"Alexander Gordeev" <agordeev@linux.ibm.com>,
"Christian Borntraeger" <borntraeger@linux.ibm.com>
Subject: Re: [PATCH v4] s390/diag204: Introduce diag204 rework
Date: Tue, 27 Oct 2026 10:55:40 +0000 [thread overview]
Message-ID: <sashiko-outbox-186407@kernel.org> (raw)
In-Reply-To: <20261027-diag204ioctl-v4-1-d5e90b56112b@linux.ibm.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] s390/diag204: unexpected signal interruption and -EBUSY in diag204_store()
- [Medium] s390/diag204: misplaced signal_pending() check in diag204_update_cache()
--
commit f09eadeabe189d5ced7bd69c8dae7f95a7f3195f
Author: Mete Durlu <meted@linux.ibm.com>
s390/diag204: Introduce diag204 rework
This commit reworks diag204 support to rate-limit hypervisor calls to at
most once per second using a shared cache, delayed work for buffer cleanup,
and a common kernel interface. Existing in-kernel users in hypfs and sthyi
are updated to use the new interface.
> diff --git a/arch/s390/kernel/diag/diag204.c b/arch/s390/kernel/diag/diag204.c
> new file mode 100644
> index 0000000000000..a68961bb8998d
> --- /dev/null
> +++ b/arch/s390/kernel/diag/diag204.c
> @@ -0,0 +1,271 @@
[ ... ]
> +static int diag204_update_cache(int allow_busy, int allow_busy_wait)
> +{
> + unsigned long subcode;
> + void *buf;
> + int rc;
> +
> + buf = diag204_allocate_buffer();
> + if (!buf)
> + return -ENOMEM;
> + subcode = g_cache.type | g_cache.subcode;
> + if (g_cache.has_bif && allow_busy)
> + subcode |= DIAG204_BIF_BIT;
> + WRITE_ONCE(g_cache.updating, true);
> + mutex_unlock(&diag204_mutex);
> + do {
> + rc = diag204(subcode, g_cache.pages, buf);
> + if (!allow_busy_wait || rc != -EBUSY)
> + break;
> + if (signal_pending(current)) {
> + rc = -ERESTARTSYS;
> + break;
> + }
> + schedule_timeout_interruptible(HZ);
> + } while (1);
[Severity: Medium]
When diag204_update_cache() is called with allow_busy_wait set (for example,
via hypfs_diag_create_files() or dbfs_d204_create()) and diag204() returns
-EBUSY, a signal arriving while the task is sleeping in
schedule_timeout_interruptible(HZ) wakes the task early.
Because the loop immediately starts the next iteration and calls diag204()
before checking signal_pending(current) again, doesn't a signal during the
sleep trigger another expensive diag204() call immediately without waiting
for the 1-second interval, and potentially miss returning -ERESTARTSYS if the
second diag204() call succeeds?
> + mutex_lock(&diag204_mutex);
> + if (rc >= 0) {
> + diag204_replace_cache(buf);
> + mod_delayed_work(system_dfl_wq, &diag204_work, DIAG204_WORK_DELAY);
> + } else {
> + diag204_free_buffer(buf);
> + }
> + WRITE_ONCE(g_cache.updating, false);
> + return rc;
> +}
[ ... ]
> +int diag204_store(void *buf, int allow_busy, int allow_busy_wait)
> +{
> + int rc;
> +
> + if (!diag204_is_available())
> + return -EOPNOTSUPP;
> + if (!allow_busy && allow_busy_wait)
> + return -EOPNOTSUPP;
> + if (!buf)
> + return -ENOMEM;
> + rc = 0;
> + while (1) {
> + rc = mutex_lock_interruptible(&diag204_mutex);
> + if (rc)
> + return rc;
> + /* Exit loop with lock taken if there is no concurrent update */
> + if (!READ_ONCE(g_cache.updating))
> + break;
> + mutex_unlock(&diag204_mutex);
> + if (allow_busy && !allow_busy_wait)
> + return -EBUSY;
> + /* Update in progress, wait until flag is cleared */
> + rc = wait_event_interruptible(g_cache.wq, !READ_ONCE(g_cache.updating));
> + if (rc)
> + return rc;
> + }
[Severity: High]
Can this loop in diag204_store() return unexpected -EINTR, -ERESTARTSYS, or
-EBUSY errors to callers that pass allow_busy_wait as 0?
Specifically, sthyi_fill() -> sthyi_update_cache() -> fill_dst() ->
diag204_get_data() calls diag204_store(diag204_buf, diag204_allow_busy, 0):
arch/s390/kernel/sthyi.c:diag204_get_data() {
...
rc = diag204_store(diag204_buf, diag204_allow_busy, 0);
if (rc < 0) {
diag204_free_buffer(diag204_buf);
return ERR_PTR(rc);
}
...
}
Even though allow_busy_wait is 0, diag204_store() unconditionally uses
mutex_lock_interruptible() and wait_event_interruptible(), which return
-EINTR or -ERESTARTSYS if a signal or notify_signal is pending while
contending on diag204_mutex or waiting for g_cache.updating.
When sthyi_fill() is invoked from KVM's SIE intercept handler in
arch/s390/kvm/s390/intercept.c:handle_sthyi():
cc = sthyi_fill(sctns, &rc);
if (cc < 0)
return cc;
and arch/s390/kvm/s390/s390.c:kvm_arch_vcpu_ioctl_run():
rc = __vcpu_run(vcpu);
if (signal_pending(current) && !rc) {
kvm_run->exit_reason = KVM_EXIT_INTR;
vcpu->stat.signal_exits++;
rc = -EINTR;
}
if a signal is pending on the vCPU thread during a concurrent diag204 cache
update, sthyi_fill() fails with -EINTR or -ERESTARTSYS after SIE has already
advanced the guest PSW past the STHYI instruction, leaving the guest buffer
and condition code unupdated and preventing kvm_arch_vcpu_ioctl_run() from
setting KVM_EXIT_INTR.
Also, when g_cache.updating is true and allow_busy && !allow_busy_wait holds,
diag204_store() returns -EBUSY without checking g_cache.has_bif, whereas
diag204_update_cache() checks g_cache.has_bif && allow_busy. Should the
concurrent update check also gate -EBUSY on g_cache.has_bif, and use
uninterruptible locking and waiting when allow_busy_wait is 0?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261027-diag204ioctl-v4-1-d5e90b56112b@linux.ibm.com?part=1
next prev parent reply other threads:[~2026-10-27 10:55 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-27 10:40 [PATCH v4] s390/diag204: Introduce diag204 rework Mete Durlu
2026-10-27 10:55 ` sashiko-bot [this message]
2026-10-27 11:32 ` Heiko Carstens
2026-10-27 11:53 ` Mete Durlu
2026-10-27 14:08 ` Heiko Carstens
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=sashiko-outbox-186407@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=agordeev@linux.ibm.com \
--cc=borntraeger@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=linux-s390@vger.kernel.org \
--cc=meted@linux.ibm.com \
--cc=sashiko-reviews@lists.linux.dev \
/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