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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.