All of lore.kernel.org
 help / color / mirror / Atom feed
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

      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 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.