From: sashiko-bot@kernel.org
To: "Anthony Krowiak" <akrowiak@linux.ibm.com>
Cc: kvm@vger.kernel.org, linux-s390@vger.kernel.org,
"Vasily Gorbik" <gor@linux.ibm.com>,
"Christian Borntraeger" <borntraeger@linux.ibm.com>,
"Heiko Carstens" <hca@linux.ibm.com>,
"Alexander Gordeev" <agordeev@linux.ibm.com>
Subject: Re: [PATCH v9 6/6] s390/vfio-ap: replace guest-reachable WARNs with ratelimited warnings
Date: Tue, 29 Sep 2026 12:41:25 +0000 [thread overview]
Message-ID: <20260929124126.71F571F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260929121837.2715710-7-akrowiak@linux.ibm.com>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] vfio_ap: AB-BA deadlock between guests_lock and pqap_hook_rwsem
- [High] vfio_ap: returning negative errors from handle_pqap() causes guest-triggerable VM crash
- [High] vfio_ap: clobbering guest registers before fallback to userspace breaks emulation
- [High] vfio_ap: 3-way SRCU deadlock via guests_lock and kvm->lock
- [Medium] vfio_ap: dev_warn_ratelimited() uses static state, breaking per-mdev isolation
--
commit 5bf97ebc06bca2480f470ccf5163316139db70cc
Author: Anthony Krowiak <akrowiak@linux.ibm.com>
s390/vfio-ap: replace guest-reachable WARNs with ratelimited warnings
This commit replaces WARN and WARN_ONCE macros in code paths reachable by a
guest with ratelimited warning functions to prevent malicious guests from
flooding the kernel log. It also refactors handle_pqap() to hold both
guests_lock and mdevs_lock during execution, using a single exit point to
prevent one guest's mdev from suppressing messages for another.
> diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
> index 89efb73d70355..7b1da96146271 100644
> --- a/drivers/s390/crypto/vfio_ap_ops.c
> +++ b/drivers/s390/crypto/vfio_ap_ops.c
> @@ -226,6 +226,58 @@ static struct vfio_ap_queue *vfio_ap_mdev_get_queue(
> return NULL;
> }
>
> +static void report_tapq_rc(struct vfio_ap_queue *q, u8 rc)
> +{
> + if (q->matrix_mdev)
> + dev_warn_ratelimited(mdev_dev(q->matrix_mdev->mdev),
> + "PQAP(TAPQ) for %02x.%04x failed with invalid rc=%#02x\n",
> + AP_QID_CARD(q->apqn),
> + AP_QID_QUEUE(q->apqn), rc);
[Severity: Medium]
Will this actually provide per-mdev isolation?
The commit explicitly states that dev_warn_ratelimited() was chosen so the
rate limit state is per-mdev. However, dev_warn_ratelimited() relies on
dev_level_ratelimited(), which defines a static DEFINE_RATELIMIT_STATE at
the call site:
include/linux/dev_printk.h:dev_level_ratelimited() {
...
static DEFINE_RATELIMIT_STATE(_rs, ...);
...
}
Does this mean any guest spamming invalid requests will exhaust the static
rate limit for this source line, silencing the warnings for all other guests?
[ ... ]
> @@ -787,32 +836,39 @@ static int handle_pqap(struct kvm_vcpu *vcpu)
>
> apqn = vcpu->run->s.regs.gprs[0] & 0xffff;
>
> - /* If we do not use the AIV facility just go to userland */
> - if (!(vcpu->arch.sie_block->eca & ECA_AIV)) {
> - VFIO_AP_DBF_WARN("%s: AIV facility not installed: apqn=0x%04x, eca=0x%04x\n",
> - __func__, apqn, vcpu->arch.sie_block->eca);
> -
> - return -EOPNOTSUPP;
> - }
> -
> + mutex_lock(&matrix_dev->guests_lock);
[Severity: High]
Does this code introduce an AB-BA deadlock between guests_lock and
pqap_hook_rwsem?
A guest executing PQAP causes KVM to call handle_pqap() under the read-side
of pqap_hook_rwsem:
arch/s390/kvm/s390/priv.c:kvm_s390_handle_b2() {
...
down_read(&vcpu->kvm->arch.crypto.pqap_hook_rwsem);
...
}
This patch makes handle_pqap() unconditionally acquire guests_lock here.
Concurrently, a host thread executing a configuration change (e.g. via
get_update_locks_for_kvm()) acquires guests_lock and then attempts to
acquire the write-side of pqap_hook_rwsem:
drivers/s390/crypto/vfio_ap_ops.c:get_update_locks_for_kvm() {
...
mutex_lock(&matrix_dev->guests_lock);
if (kvm) {
mutex_lock(&kvm->lock);
down_write(&kvm->arch.crypto.pqap_hook_rwsem);
}
...
}
[Severity: High]
Does acquiring guests_lock here also introduce a 3-way SRCU deadlock?
KVM holds srcu_read_lock(&kvm->srcu) when calling the instruction intercept
handlers. The KVM locking documentation explicitly forbids acquiring any lock
that wraps kvm->lock while holding KVM's SRCU read lock:
Documentation/virt/kvm/locking.rst:
synchronize_srcu(&kvm->srcu) is called inside critical sections for
kvm->lock ... These locks _cannot_ be taken inside a kvm->srcu read-side
critical section.
Can this result in a circular dependency where:
1. The vCPU thread holds SRCU and waits for guests_lock.
2. The mdev configuration thread holds guests_lock and waits for kvm->lock
(via get_update_locks_for_kvm()).
3. Another KVM thread holding kvm->lock calls synchronize_srcu(&kvm->srcu),
waiting on the vCPU thread?
> mutex_lock(&matrix_dev->mdevs_lock);
> + matrix_mdev = vfio_ap_mdev_for_apqn(apqn);
> + if (!matrix_mdev || !matrix_mdev->kvm) {
> + ret = -ENODEV;
> + goto out_unlock;
> + }
[Severity: High]
Can returning a negative error code here cause a guest-triggerable VM crash?
If a guest executes PQAP for an unassigned queue or missing mdev, the patched
handle_pqap() returns -ENODEV or -EINVAL instead of returning 0 and setting a
guest CC.
KVM's instruction intercept handler (__vcpu_run) propagates non-EOPNOTSUPP
negative errors directly to userspace:
arch/s390/kvm/s390/s390.c:vcpu_post_run() {
...
if (rc != -EOPNOTSUPP)
return rc;
...
}
QEMU treats an unexpected KVM_RUN failure as a fatal error and terminates
the VM, allowing an unprivileged guest to crash its hypervisor process.
[ ... ]
> - matrix_mdev = container_of(vcpu->kvm->arch.crypto.pqap_hook,
> - struct ap_matrix_mdev, pqap_hook);
> -
> - /* If the there is no guest using the mdev, there is nothing to do */
> - if (!matrix_mdev->kvm) {
> - vfio_ap_le_guid_to_be_uuid(&matrix_mdev->mdev->uuid, uuid);
> - VFIO_AP_DBF_WARN("%s: mdev %08lx-%04lx-%04lx-%04lx-%04lx%08lx not in use: apqn=0x%04x\n",
> - __func__, uuid[0], uuid[1], uuid[2],
> - uuid[3], uuid[4], uuid[5], apqn);
> + /* If we do not use the AIV facility just go to userland */
> + if (!(vcpu->arch.sie_block->eca & ECA_AIV)) {
> + VFIO_AP_DBF_WARN("%s: AIV facility not installed: apqn=0x%04x, eca=0x%04x\n",
> + __func__, apqn, vcpu->arch.sie_block->eca);
> + dev_warn_ratelimited(mdev_dev(matrix_mdev->mdev),
> + "PQAP(AQIC) for %02x.%04x: AIV facility not installed\n",
> + AP_QID_CARD(apqn), AP_QID_QUEUE(apqn));
> + ret = -EOPNOTSUPP;
> goto out_unlock;
> }
[ ... ]
> @@ -835,7 +895,8 @@ static int handle_pqap(struct kvm_vcpu *vcpu)
> memcpy(&vcpu->run->s.regs.gprs[1], &qstatus, sizeof(qstatus));
> vcpu->run->s.regs.gprs[1] >>= 32;
> mutex_unlock(&matrix_dev->mdevs_lock);
> - return 0;
> + mutex_unlock(&matrix_dev->guests_lock);
> + return ret;
> }
[Severity: High]
Does routing the -EOPNOTSUPP fallback through out_unlock clobber guest
registers and break emulation?
If the KVM AIV facility is not installed, handle_pqap() returns -EOPNOTSUPP
to defer emulation to userspace.
However, since this now passes through out_unlock, it unconditionally
executes memcpy(&vcpu->run->s.regs.gprs[1], &qstatus, sizeof(qstatus)).
Will this overwrite the guest's actual instruction parameters in gprs[1]
with an error code before KVM exits to userspace, causing QEMU to attempt
emulation with corrupted inputs?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260929121837.2715710-1-akrowiak@linux.ibm.com?part=6
prev parent reply other threads:[~2026-09-29 12:41 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-29 12:18 [PATCH v9 0/6] s390/vfio-ap: Fix pre-existing bugs in vfio_ap device driver Anthony Krowiak
2026-09-29 12:18 ` [PATCH v9 1/6] s390/vfio-ap: Fix leaks of pinned NIB and registered GISC Anthony Krowiak
2026-09-29 12:33 ` sashiko-bot
2026-09-29 13:38 ` Anthony Krowiak
2026-09-29 12:18 ` [PATCH v9 2/6] s390/vfio-ap: Fix failure to release IRQ notification eventfd contexts Anthony Krowiak
2026-09-29 12:25 ` sashiko-bot
2026-09-29 12:18 ` [PATCH v9 3/6] s390/vfio-ap: Fix unbounded loop in apq_reset_check() Anthony Krowiak
2026-09-29 12:38 ` sashiko-bot
2026-09-29 16:57 ` Anthony Krowiak
2026-09-29 12:18 ` [PATCH v9 4/6] s390/vfio-ap: Use AP_DOMAINS for adm_add bitmap size in vfio_ap_mdev_cfg_add() Anthony Krowiak
2026-09-29 12:27 ` sashiko-bot
2026-09-29 12:18 ` [PATCH v9 5/6] s390/vfio-ap: fix queue state leakage to guest and host Anthony Krowiak
2026-09-29 12:33 ` sashiko-bot
2026-09-29 12:18 ` [PATCH v9 6/6] s390/vfio-ap: replace guest-reachable WARNs with ratelimited warnings Anthony Krowiak
2026-09-29 12:41 ` sashiko-bot [this message]
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=20260929124126.71F571F000FF@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=agordeev@linux.ibm.com \
--cc=akrowiak@linux.ibm.com \
--cc=borntraeger@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--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