* [PATCH] s390/vfio-ap: Fix control domain removal in vfio_ap_mdev_cfg_remove
@ 2026-08-07 22:39 Anthony Krowiak
2026-08-07 22:58 ` sashiko-bot
0 siblings, 1 reply; 3+ messages in thread
From: Anthony Krowiak @ 2026-08-07 22:39 UTC (permalink / raw)
To: linux-s390, linux-kernel, kvm
Cc: jjherne, borntraeger, mjrosato, pasic, alex, kwankhede, hca, gor,
agordeev, stable
The vfio_ap_config_remove function uses the bitmap_andnot function to clear
bits from the matrix_mdev->matrix.adm (specifies the control domains
assigned to the mdev). This prevents the explicitly unplugged control
domains from being removed the KVM guest. The bitmap_and function is used
instead.
Fixes: eeb386aeb5b7c ("s390/vfio-ap: handle config changed and scan complete notification")
Cc: stable@vger.kernel.org
Signed-off-by: Anthony Krowiak <akrowiak@linux.ibm.com>
---
drivers/s390/crypto/vfio_ap_ops.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 44b3a1dcc1b3..1bfdbe85023d 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -2615,9 +2615,9 @@ static void vfio_ap_mdev_cfg_remove(unsigned long *ap_remove,
do_remove |= bitmap_and(aqrem, aq_remove,
matrix_mdev->matrix.aqm,
AP_DOMAINS);
- do_remove |= bitmap_andnot(cdrem, cd_remove,
- matrix_mdev->matrix.adm,
- AP_DOMAINS);
+ do_remove |= bitmap_and(cdrem, cd_remove,
+ matrix_mdev->matrix.adm,
+ AP_DOMAINS);
if (do_remove)
vfio_ap_mdev_hot_unplug_cfg(matrix_mdev, aprem, aqrem,
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] s390/vfio-ap: Fix control domain removal in vfio_ap_mdev_cfg_remove
2026-08-07 22:39 [PATCH] s390/vfio-ap: Fix control domain removal in vfio_ap_mdev_cfg_remove Anthony Krowiak
@ 2026-08-07 22:58 ` sashiko-bot
2026-08-08 12:05 ` Anthony Krowiak
0 siblings, 1 reply; 3+ messages in thread
From: sashiko-bot @ 2026-08-07 22:58 UTC (permalink / raw)
To: Anthony Krowiak
Cc: Vasily Gorbik, linux-s390, Heiko Carstens, Alexander Gordeev, kvm
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [High] Missing NULL check on `matrix_mdev->kvm` before acquiring its lock on AP configuration change paths, leading to a kernel panic if a mediated device is unattached.
- [High] Guest APCB is not updated when the last adapter or domain is removed, leaving the guest with unauthorized hardware access.
- [High] Iterating `mdev_list` without the appropriate mutex allows concurrent list modifications, leading to list corruption or use-after-free.
--
--- Patch [1]: [PATCH] s390/vfio-ap: Fix control domain removal in vfio_ap_mdev_cfg_remove ---
commit 934a77df4b71bb3ee940f94ad6abdd8290e96d28
Author: Anthony Krowiak <akrowiak@linux.ibm.com>
Subject: s390/vfio-ap: Fix control domain removal in vfio_ap_mdev_cfg_remove
This commit modifies the vfio_ap_config_remove function to use bitmap_and()
instead of bitmap_andnot() when clearing bits from matrix_mdev->matrix.adm.
This ensures that explicitly unplugged control domains are correctly removed
from the KVM guest.
> diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
> index 44b3a1dcc1b36..1bfdbe85023dd 100644
> --- a/drivers/s390/crypto/vfio_ap_ops.c
> +++ b/drivers/s390/crypto/vfio_ap_ops.c
> @@ -2615,9 +2615,9 @@ static void vfio_ap_mdev_cfg_remove(unsigned long *ap_remove,
[Severity: High]
This is a pre-existing issue, but does vfio_ap_mdev_cfg_remove() safely handle
unattached mediated devices?
If an mdev is created via sysfs, matrix_mdev->kvm is initialized to NULL. If a
host AP configuration change occurs before this mdev is attached to a guest,
the loop in this function:
drivers/s390/crypto/vfio_ap_ops.c:vfio_ap_mdev_cfg_remove() {
...
list_for_each_entry(matrix_mdev, &matrix_dev->mdev_list, node) {
mutex_lock(&matrix_mdev->kvm->lock);
...
}
will unconditionally dereference the NULL kvm pointer. Is there a missing NULL
check for matrix_mdev->kvm before acquiring its lock on AP configuration change
paths?
[Severity: High]
This isn't a bug introduced by this patch, but can the iteration over
mdev_list in vfio_ap_mdev_cfg_remove() race with mdev creation?
vfio_ap_mdev_probe() adds a new mdev to matrix_dev->mdev_list using list_add()
while holding only matrix_dev->mdevs_lock:
drivers/s390/crypto/vfio_ap_ops.c:vfio_ap_mdev_probe() {
...
mutex_lock(&matrix_dev->mdevs_lock);
list_add(&matrix_mdev->node, &matrix_dev->mdev_list);
mutex_unlock(&matrix_dev->mdevs_lock);
...
}
However, vfio_ap_mdev_cfg_remove() iterates over mdev_list using
list_for_each_entry() holding only matrix_dev->guests_lock, as mdevs_lock is
only acquired individually inside the loop body.
Could this lead to kernel memory corruption or use-after-free if a user
creates a new mdev concurrently with an asynchronous host AP configuration
change?
> do_remove |= bitmap_and(aqrem, aq_remove,
> matrix_mdev->matrix.aqm,
> AP_DOMAINS);
> - do_remove |= bitmap_andnot(cdrem, cd_remove,
> - matrix_mdev->matrix.adm,
> - AP_DOMAINS);
> + do_remove |= bitmap_and(cdrem, cd_remove,
> + matrix_mdev->matrix.adm,
> + AP_DOMAINS);
>
> if (do_remove)
> vfio_ap_mdev_hot_unplug_cfg(matrix_mdev, aprem, aqrem,
[Severity: High]
This is a pre-existing issue, but does vfio_ap_mdev_hot_unplug_cfg() properly
update the guest APCB when the last device is removed?
In vfio_ap_mdev_hot_unplug_cfg(), the decision to update the guest's APCB
relies on bitmap_andnot():
drivers/s390/crypto/vfio_ap_ops.c:vfio_ap_mdev_hot_unplug_cfg() {
...
if (!bitmap_empty(cdrem, AP_DOMAINS))
do_hotplug |= bitmap_andnot(matrix_mdev->shadow_apcb.adm,
matrix_mdev->shadow_apcb.adm,
cdrem, AP_DOMAINS);
...
}
The kernel's bitmap_andnot() function returns true only if the resulting
destination bitmap is non-empty. If the last adapter, domain, or control domain
is explicitly removed, the destination shadow APCB becomes entirely empty,
causing bitmap_andnot() to return false.
Since do_hotplug remains false, vfio_ap_mdev_update_guest_apcb() is skipped.
Does this leave KVM guests with unauthorized access to physical hardware devices
that have been explicitly removed from the host's AP configuration?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260807223939.573718-1-akrowiak@linux.ibm.com?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] s390/vfio-ap: Fix control domain removal in vfio_ap_mdev_cfg_remove
2026-08-07 22:58 ` sashiko-bot
@ 2026-08-08 12:05 ` Anthony Krowiak
0 siblings, 0 replies; 3+ messages in thread
From: Anthony Krowiak @ 2026-08-08 12:05 UTC (permalink / raw)
To: sashiko-reviews
Cc: Vasily Gorbik, linux-s390, Heiko Carstens, Alexander Gordeev, kvm
On 8/7/26 6:58 PM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
>
> Pre-existing issues:
> - [High] Missing NULL check on `matrix_mdev->kvm` before acquiring its lock on AP configuration change paths, leading to a kernel panic if a mediated device is unattached.
> - [High] Guest APCB is not updated when the last adapter or domain is removed, leaving the guest with unauthorized hardware access.
> - [High] Iterating `mdev_list` without the appropriate mutex allows concurrent list modifications, leading to list corruption or use-after-free.
> --
>
> --- Patch [1]: [PATCH] s390/vfio-ap: Fix control domain removal in vfio_ap_mdev_cfg_remove ---
> commit 934a77df4b71bb3ee940f94ad6abdd8290e96d28
> Author: Anthony Krowiak <akrowiak@linux.ibm.com>
> Subject: s390/vfio-ap: Fix control domain removal in vfio_ap_mdev_cfg_remove
>
> This commit modifies the vfio_ap_config_remove function to use bitmap_and()
> instead of bitmap_andnot() when clearing bits from matrix_mdev->matrix.adm.
> This ensures that explicitly unplugged control domains are correctly removed
> from the KVM guest.
>
>> diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
>> index 44b3a1dcc1b36..1bfdbe85023dd 100644
>> --- a/drivers/s390/crypto/vfio_ap_ops.c
>> +++ b/drivers/s390/crypto/vfio_ap_ops.c
>> @@ -2615,9 +2615,9 @@ static void vfio_ap_mdev_cfg_remove(unsigned long *ap_remove,
> [Severity: High]
> This is a pre-existing issue, but does vfio_ap_mdev_cfg_remove() safely handle
> unattached mediated devices?
>
> If an mdev is created via sysfs, matrix_mdev->kvm is initialized to NULL. If a
> host AP configuration change occurs before this mdev is attached to a guest,
> the loop in this function:
>
> drivers/s390/crypto/vfio_ap_ops.c:vfio_ap_mdev_cfg_remove() {
> ...
> list_for_each_entry(matrix_mdev, &matrix_dev->mdev_list, node) {
> mutex_lock(&matrix_mdev->kvm->lock);
> ...
> }
>
> will unconditionally dereference the NULL kvm pointer. Is there a missing NULL
> check for matrix_mdev->kvm before acquiring its lock on AP configuration change
> paths?
A patch has already been posted for this:
https://lkml.org/lkml/2026/8/7/1453
I think it would be wise to submit that patch and this as a series since
both bugs were introduced with the same patch, so the Fixes: tag
for each would be the same.
>
> [Severity: High]
> This isn't a bug introduced by this patch, but can the iteration over
> mdev_list in vfio_ap_mdev_cfg_remove() race with mdev creation?
>
> vfio_ap_mdev_probe() adds a new mdev to matrix_dev->mdev_list using list_add()
> while holding only matrix_dev->mdevs_lock:
>
> drivers/s390/crypto/vfio_ap_ops.c:vfio_ap_mdev_probe() {
> ...
> mutex_lock(&matrix_dev->mdevs_lock);
> list_add(&matrix_mdev->node, &matrix_dev->mdev_list);
> mutex_unlock(&matrix_dev->mdevs_lock);
> ...
> }
>
> However, vfio_ap_mdev_cfg_remove() iterates over mdev_list using
> list_for_each_entry() holding only matrix_dev->guests_lock, as mdevs_lock is
> only acquired individually inside the loop body.
>
> Could this lead to kernel memory corruption or use-after-free if a user
> creates a new mdev concurrently with an asynchronous host AP configuration
> change?
This needs to be fixed.
>
>> do_remove |= bitmap_and(aqrem, aq_remove,
>> matrix_mdev->matrix.aqm,
>> AP_DOMAINS);
>> - do_remove |= bitmap_andnot(cdrem, cd_remove,
>> - matrix_mdev->matrix.adm,
>> - AP_DOMAINS);
>> + do_remove |= bitmap_and(cdrem, cd_remove,
>> + matrix_mdev->matrix.adm,
>> + AP_DOMAINS);
>>
>> if (do_remove)
>> vfio_ap_mdev_hot_unplug_cfg(matrix_mdev, aprem, aqrem,
> [Severity: High]
> This is a pre-existing issue, but does vfio_ap_mdev_hot_unplug_cfg() properly
> update the guest APCB when the last device is removed?
>
> In vfio_ap_mdev_hot_unplug_cfg(), the decision to update the guest's APCB
> relies on bitmap_andnot():
>
> drivers/s390/crypto/vfio_ap_ops.c:vfio_ap_mdev_hot_unplug_cfg() {
> ...
> if (!bitmap_empty(cdrem, AP_DOMAINS))
> do_hotplug |= bitmap_andnot(matrix_mdev->shadow_apcb.adm,
> matrix_mdev->shadow_apcb.adm,
> cdrem, AP_DOMAINS);
> ...
> }
>
> The kernel's bitmap_andnot() function returns true only if the resulting
> destination bitmap is non-empty. If the last adapter, domain, or control domain
> is explicitly removed, the destination shadow APCB becomes entirely empty,
> causing bitmap_andnot() to return false.
>
> Since do_hotplug remains false, vfio_ap_mdev_update_guest_apcb() is skipped.
> Does this leave KVM guests with unauthorized access to physical hardware devices
> that have been explicitly removed from the host's AP configuration?
The logic here is correct. The
concern rests on a misreading of what bitmap_andnot() returns
and what the bitmaps represent.
There are three functions that form a pipeline:
vfio_ap_mdev_on_cfg_remove() computes which adapters,
domains and control domains have been removed from the host
AP configuration by comparing the previous and current config
info bitmaps. If nothing was removed from a given bitmap,
that bitmap is empty and there is nothing to do.
vfio_ap_mdev_cfg_remove() intersects each of those
removed-from-host bitmaps against matrix_mdev->matrix,
which represents what the administrator has assigned to the
mdev. If the intersection is empty — none of the host-removed
resources were assigned to this mdev — there is nothing to
hot-unplug for this mdev.
vfio_ap_mdev_hot_unplug_cfg() intersects those
mdev-assigned-and-host-removed bitmaps against
matrix_mdev->shadow_apcb, which represents what is actually
passed through to the guest after filtering. The shadow_apcb
is a filtered subset of matrix — a resource assigned to the
mdev may not be in the shadow APCB if it was previously
filtered out (e.g., the queue was not passable, or the
resource was not in the host config at the time of the last
filter pass). If bitmap_andnot() returns false here, it
means none of the removed resources were present in the shadow
APCB to begin with — the guest never had access to them — so
skipping vfio_ap_mdev_update_guest_apcb() is correct.
Furthermore, bitmap_andnot(dst, src, rem) returns false only
when the result dst = src & ~rem is all zeros. If none of the
rem bits are present in src, then ~rem clears nothing and
dst == src. If src was non-empty, the return value is true
and vfio_ap_mdev_update_guest_apcb() is called — even though
the APCB content is unchanged. So there is no path through this
function where a genuine removal from the guest's APCB is
silently dropped.
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-08-08 12:05 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-07 22:39 [PATCH] s390/vfio-ap: Fix control domain removal in vfio_ap_mdev_cfg_remove Anthony Krowiak
2026-08-07 22:58 ` sashiko-bot
2026-08-08 12:05 ` Anthony Krowiak
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.