* [PATCH v2 0/8] s390/vfio-ap: Fix bugs in vfio_ap device driver callback functions
@ 2026-08-10 19:22 Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 1/8] s390/vfio-ap: Fix stale do_remove flag across iterations in vfio_ap_mdev_cfg_remove Anthony Krowiak
` (7 more replies)
0 siblings, 8 replies; 9+ messages in thread
From: Anthony Krowiak @ 2026-08-10 19:22 UTC (permalink / raw)
To: linux-s390, linux-kernel, kvm
Cc: jjherne, borntraeger, mjrosato, pasic, alex, kwankhede, fiuczy,
pbonzini, frankja, imbrenda, agordeev, hca, gor
Patches 2/5 and 5/5 in this series were previously posted as individual
fixes upstream. During review of those patches, the reviewer identified
several pre-existing problems in the same code paths that are addressed
by the remaining three patches. All five patches are fixes for
pre-existing bugs and are tagged for stable.
Patches 1/5, 3/5 and 4/5 fix bugs in the call trees of the two
callback functions implemented by the vfio_ap device
driver -- vfio_ap_on_cfg_changed and vfio_ap_on_scan_complete:
* Patch 1/5 fixes a stale do_remove flag in vfio_ap_mdev_cfg_remove
that causes spurious hot-unplug operations on mdevs that have no
assigned adapters, domains or control domains in common with those
removed from the host AP configuration.
* Patch 3/5 fixes the use of the wrong lock to protect the addition of
a newly created ap_matrix_mdev object to the mdev_list in the
vfio_ap_mdev_probe function.
* Patch 4/5 fixes the missing mdevs_lock while updating the apm_add,
aqm_add and adm_add fields of an ap_matrix_mdev object in
vfio_ap_mdev_cfg_add.
Patches 6-8 fix additional pre-existing bugs and were added as
responses to reviews of v1 of this patch series. The change log below
identifies the patch reviewed and the resulting change:
Change log v1 => v2:
~~~~~~~~~~~~~~~~~~~
Patch 2/5: Fix dereference matrix_mdev->kvm without checking for NULL
* Added new patch to fix the potential use of an uninitialized apm_filtered
object passed to rest_queues_for_apids called from the
vfio_ap_mdev_hot_plug_cfg function. This is a pre-existing condition
discovered during patch review of 2/5 for v1 of the series.
Patch 3/5: Fix use of wrong lock in mdev probe function
* Added new patch to guard the traversal of the matrix_dev->mdev_list in
the vfio_ap_mdev_for_queue function called from the status_show funciton.
This is a pre-existing condition discovered during review of patch 3/5
for v1 of the series.
Patch 5/5: Fix control domain removal in vfio_ap_mdev_cfg_remove
* Added new patch to fix skipping of hot-unplug in
vfio_ap_mdev_hot_unplug_cfg function when the last adpater or domain is
removed from the host's AP configuration. This is a pre-existing
condition discovered during review of patch 5/5 for v1 of the series.
Anthony Krowiak (8):
s390/vfio-ap: Fix stale do_remove flag across iterations in
vfio_ap_mdev_cfg_remove
s390/vfio-ap: Fix dereference matrix_mdev->kvm without checking for
NULL
s390/vfio-ap: Fix use of wrong lock in mdev probe function
s390/vfio-ap: Fix required lock not held during update of
ap_matrix_mdev object
s390/vfio-ap: Fix control domain removal in vfio_ap_mdev_cfg_remove
s390/vfio-ap: fix potential use of uninitialized apm_filtered bitmap
s390/vfio-ap: Fix required lock not held during display of sysfs
status attribute
s390/vfio-ap: Fix hot-unplug skipped when last AP adapter or domain
removed
drivers/s390/crypto/vfio_ap_ops.c | 93 +++++++++++++++++++++----------
1 file changed, 63 insertions(+), 30 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 1/8] s390/vfio-ap: Fix stale do_remove flag across iterations in vfio_ap_mdev_cfg_remove
2026-08-10 19:22 [PATCH v2 0/8] s390/vfio-ap: Fix bugs in vfio_ap device driver callback functions Anthony Krowiak
@ 2026-08-10 19:22 ` Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 2/8] s390/vfio-ap: Fix dereference matrix_mdev->kvm without checking for NULL Anthony Krowiak
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Anthony Krowiak @ 2026-08-10 19:22 UTC (permalink / raw)
To: linux-s390, linux-kernel, kvm
Cc: jjherne, borntraeger, mjrosato, pasic, alex, kwankhede, fiuczy,
pbonzini, frankja, imbrenda, agordeev, hca, gor, stable
The do_remove flag in vfio_ap_mdev_cfg_remove() is initialised to zero
before the loop that iterates over the list of matrix mdevs, but is
never reset at the start of each iteration. Since do_remove is
OR-accumulated across iterations, a positive result from one mdev
carries over to subsequent mdevs.
The fix is to set the do_remove flag with the first call to bitmap_and;
for example: do_remove = bitmap_an rather than do_remove |= bitmap_and.
Fixes: eeb386aeb5b7 ("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 | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 44b3a1dcc1b3..845c86ba8bc3 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -2603,15 +2603,15 @@ static void vfio_ap_mdev_cfg_remove(unsigned long *ap_remove,
DECLARE_BITMAP(aprem, AP_DEVICES);
DECLARE_BITMAP(aqrem, AP_DOMAINS);
DECLARE_BITMAP(cdrem, AP_DOMAINS);
- int do_remove = 0;
+ int do_remove;
list_for_each_entry(matrix_mdev, &matrix_dev->mdev_list, node) {
mutex_lock(&matrix_mdev->kvm->lock);
mutex_lock(&matrix_dev->mdevs_lock);
- do_remove |= bitmap_and(aprem, ap_remove,
- matrix_mdev->matrix.apm,
- AP_DEVICES);
+ do_remove = bitmap_and(aprem, ap_remove,
+ matrix_mdev->matrix.apm,
+ AP_DEVICES);
do_remove |= bitmap_and(aqrem, aq_remove,
matrix_mdev->matrix.aqm,
AP_DOMAINS);
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 2/8] s390/vfio-ap: Fix dereference matrix_mdev->kvm without checking for NULL
2026-08-10 19:22 [PATCH v2 0/8] s390/vfio-ap: Fix bugs in vfio_ap device driver callback functions Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 1/8] s390/vfio-ap: Fix stale do_remove flag across iterations in vfio_ap_mdev_cfg_remove Anthony Krowiak
@ 2026-08-10 19:22 ` Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 3/8] s390/vfio-ap: Fix use of wrong lock in mdev probe function Anthony Krowiak
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Anthony Krowiak @ 2026-08-10 19:22 UTC (permalink / raw)
To: linux-s390, linux-kernel, kvm
Cc: jjherne, borntraeger, mjrosato, pasic, alex, kwankhede, fiuczy,
pbonzini, frankja, imbrenda, agordeev, hca, gor, stable
The ap_driver structure has two fields which are function pointers to
callbacks:
* .on_config_changed: called at the start of the AP bus scan function to
notify the device driver that the host AP
configuration has changed and the associated AP
devices will be added or removed accordingly. This
gives the implementor a chance to evaluate the
configuration changes and respond to them before
the associated devices are added or removed.
* .on_scan_complete: Called at the end of the AP bus scan function to
notify the device driver that the host AP
configuration has changed and the AP devices have
been added or removed accordingly. This gives the
implementor the opportunity to respond to the
changes after the associated devices are added or
removed.
These two callbacks are implemented in the vfio_ap device driver via the
vfio_ap_on_cfg_changed and vfio_ap_on_scan_complete functions respectively.
Within the call stack of these two callback functions the
matrix_mdev->kvm->lock mutex is taken without checking whether
matrix_mdev->kvm is NULL or not. If matrix_mdev->kvm has never been set,
trying to take the lock will trigger a NULL pointer dereference. This patch
adds checks for matrix_mdev->kvm == NULL before taking the
matrix_mdev->kvm->lock mutex.
Note that the matrix_mdev->kvm->lock mutex taken in the
vfio_ap_mdev_hot_plug_config function is moved to the calling function
along with the matrix_dev->mdevs_lock which is needed there to access
the fields of the matrix_mdev. It makes little sense to make the change
the check for matrix_mdev->kvm there before taking the kvm->lock
mutex only to have to move it out via another patch, so it is done in
this patch.
It is important to make note of the following:
1. The matrix_dev->guests_lock is acquired at the start of both callback
functions. This ensures that matrix_mdev will not be removed via the
vfio_ap_mdev_remove function because it too takes matrix_dev_guests_lock
before removing the object; so, matrix_mdev will be available for the
duration of the callback functions.
2. The matrix_dev->mdevs_lock mutex must be taken in order to access
fields within the matrix_mdev structure
3. matrix_mdev->kvm->lock mutex must be taken before the
matrix_dev->mdevs_lock to prevent a lockdep splat.
4: The kvm->lock must be held while plugging the guest's AP configuration
into its SIE state description via the vfio_ap_mdev_update_guest_apcb
function.
5. The vfio_ap_mdev_update_guest_apcb checks matrix_mdev->kvm to verify it
is not NULL before doing the hot plug of the guest's AP configuration.
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 | 33 ++++++++++++++++++++++---------
1 file changed, 24 insertions(+), 9 deletions(-)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 845c86ba8bc3..e382e5a1cb99 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -2606,7 +2606,13 @@ static void vfio_ap_mdev_cfg_remove(unsigned long *ap_remove,
int do_remove;
list_for_each_entry(matrix_mdev, &matrix_dev->mdev_list, node) {
- mutex_lock(&matrix_mdev->kvm->lock);
+ /*
+ * The mdevs_lock must be held to access fields within matrix_mdev,
+ * and kvm->lock must be taken before mdevs_lock to satisfy the lock
+ * ordering requirement and prevent a lockdep splat.
+ */
+ if (matrix_mdev->kvm)
+ mutex_lock(&matrix_mdev->kvm->lock);
mutex_lock(&matrix_dev->mdevs_lock);
do_remove = bitmap_and(aprem, ap_remove,
@@ -2624,7 +2630,8 @@ static void vfio_ap_mdev_cfg_remove(unsigned long *ap_remove,
cdrem);
mutex_unlock(&matrix_dev->mdevs_lock);
- mutex_unlock(&matrix_mdev->kvm->lock);
+ if (matrix_mdev->kvm)
+ mutex_unlock(&matrix_mdev->kvm->lock);
}
}
@@ -2821,9 +2828,6 @@ static void vfio_ap_mdev_hot_plug_cfg(struct ap_matrix_mdev *matrix_mdev)
DECLARE_BITMAP(apm_filtered, AP_DEVICES);
bool filter_domains, filter_adapters, filter_cdoms, do_hotplug = false;
- mutex_lock(&matrix_mdev->kvm->lock);
- mutex_lock(&matrix_dev->mdevs_lock);
-
filter_adapters = bitmap_intersects(matrix_mdev->matrix.apm,
matrix_mdev->apm_add, AP_DEVICES);
filter_domains = bitmap_intersects(matrix_mdev->matrix.aqm,
@@ -2841,9 +2845,6 @@ static void vfio_ap_mdev_hot_plug_cfg(struct ap_matrix_mdev *matrix_mdev)
vfio_ap_mdev_update_guest_apcb(matrix_mdev);
reset_queues_for_apids(matrix_mdev, apm_filtered);
-
- mutex_unlock(&matrix_dev->mdevs_lock);
- mutex_unlock(&matrix_mdev->kvm->lock);
}
void vfio_ap_on_scan_complete(struct ap_config_info *new_config_info,
@@ -2854,15 +2855,29 @@ void vfio_ap_on_scan_complete(struct ap_config_info *new_config_info,
mutex_lock(&matrix_dev->guests_lock);
list_for_each_entry(matrix_mdev, &matrix_dev->mdev_list, node) {
+ /*
+ * The mdevs_lock must be held to access fields within matrix_mdev,
+ * and kvm->lock must be taken before mdevs_lock to satisfy the lock
+ * ordering requirement and prevent a lockdep splat.
+ */
+ if (matrix_mdev->kvm)
+ mutex_lock(&matrix_mdev->kvm->lock);
+ mutex_lock(&matrix_dev->mdevs_lock);
+
if (bitmap_empty(matrix_mdev->apm_add, AP_DEVICES) &&
bitmap_empty(matrix_mdev->aqm_add, AP_DOMAINS) &&
bitmap_empty(matrix_mdev->adm_add, AP_DOMAINS))
- continue;
+ goto do_unlock;
vfio_ap_mdev_hot_plug_cfg(matrix_mdev);
bitmap_clear(matrix_mdev->apm_add, 0, AP_DEVICES);
bitmap_clear(matrix_mdev->aqm_add, 0, AP_DOMAINS);
bitmap_clear(matrix_mdev->adm_add, 0, AP_DOMAINS);
+
+do_unlock:
+ mutex_unlock(&matrix_dev->mdevs_lock);
+ if (matrix_mdev->kvm)
+ mutex_unlock(&matrix_mdev->kvm->lock);
}
mutex_unlock(&matrix_dev->guests_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 3/8] s390/vfio-ap: Fix use of wrong lock in mdev probe function
2026-08-10 19:22 [PATCH v2 0/8] s390/vfio-ap: Fix bugs in vfio_ap device driver callback functions Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 1/8] s390/vfio-ap: Fix stale do_remove flag across iterations in vfio_ap_mdev_cfg_remove Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 2/8] s390/vfio-ap: Fix dereference matrix_mdev->kvm without checking for NULL Anthony Krowiak
@ 2026-08-10 19:22 ` Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 4/8] s390/vfio-ap: Fix required lock not held during update of ap_matrix_mdev object Anthony Krowiak
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Anthony Krowiak @ 2026-08-10 19:22 UTC (permalink / raw)
To: linux-s390, linux-kernel, kvm
Cc: jjherne, borntraeger, mjrosato, pasic, alex, kwankhede, fiuczy,
pbonzini, frankja, imbrenda, agordeev, hca, gor, stable
The vfio_ap_mdev_probe function uses the matrix_dev->mdevs_lock
mutex to guard the add of a newly created ap_matrix_mdev object to the
matrix_dev->mdev_list. This mutex does not protect against traversal
of the list; its purpose is to guard against concurrent access to fields
contained in an ap_matrix_mdev object. This could lead to kernel memory
corruption or use-after-free if another mdev is created concurrently.
The adding of an ap_matrix_mdev object to matrix_dev->mdev_list
is now guarded by the matrix_dev->guests_lock which is the correct
way to protect against concurrent mdev_list access.
See the vfio-ap-locking.rst in the linux kernel tree.
Fixes: 2c1ee8983aa3 ("s390/vfio-ap: prepare for dynamic update of guest's APCB on queue probe/remove")
Cc: stable@vger.kernel.org
Signed-off-by: Anthony Krowiak <akrowiak@linux.ibm.com>
---
drivers/s390/crypto/vfio_ap_ops.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index e382e5a1cb99..a472de00bc14 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -803,9 +803,9 @@ static int vfio_ap_mdev_probe(struct mdev_device *mdev)
matrix_mdev->req_trigger = NULL;
matrix_mdev->cfg_chg_trigger = NULL;
dev_set_drvdata(&mdev->dev, matrix_mdev);
- mutex_lock(&matrix_dev->mdevs_lock);
+ mutex_lock(&matrix_dev->guests_lock);
list_add(&matrix_mdev->node, &matrix_dev->mdev_list);
- mutex_unlock(&matrix_dev->mdevs_lock);
+ mutex_unlock(&matrix_dev->guests_lock);
return 0;
err_put_vdev:
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 4/8] s390/vfio-ap: Fix required lock not held during update of ap_matrix_mdev object
2026-08-10 19:22 [PATCH v2 0/8] s390/vfio-ap: Fix bugs in vfio_ap device driver callback functions Anthony Krowiak
` (2 preceding siblings ...)
2026-08-10 19:22 ` [PATCH v2 3/8] s390/vfio-ap: Fix use of wrong lock in mdev probe function Anthony Krowiak
@ 2026-08-10 19:22 ` Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 5/8] s390/vfio-ap: Fix control domain removal in vfio_ap_mdev_cfg_remove Anthony Krowiak
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Anthony Krowiak @ 2026-08-10 19:22 UTC (permalink / raw)
To: linux-s390, linux-kernel, kvm
Cc: jjherne, borntraeger, mjrosato, pasic, alex, kwankhede, fiuczy,
pbonzini, frankja, imbrenda, agordeev, hca, gor, stable
In the vfio_ap_mdev_cfg_add function, the apm_add, aqm_add and adm_add
fields of an ap_matrix_mdev object fields are modified while not holding
the matrix_dev->mdevs_lock. This lock must be held while making these
to guard against a race condition with another caller that may be
concurrently modifying these fields or any of the fields in the
matrix_mdev->matrix.
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 | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index a472de00bc14..897518b88c28 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -2756,12 +2756,20 @@ static void vfio_ap_mdev_cfg_add(unsigned long *apm_add, unsigned long *aqm_add,
vfio_ap_filter_apid_by_qtype(apm_add, aqm_add);
list_for_each_entry(matrix_mdev, &matrix_dev->mdev_list, node) {
+ /*
+ * The mdevs_lock must be held in order to access fields
+ * within matrix_mdev
+ */
+ mutex_lock(&matrix_dev->mdevs_lock);
+
bitmap_and(matrix_mdev->apm_add,
matrix_mdev->matrix.apm, apm_add, AP_DEVICES);
bitmap_and(matrix_mdev->aqm_add,
matrix_mdev->matrix.aqm, aqm_add, AP_DOMAINS);
bitmap_and(matrix_mdev->adm_add,
matrix_mdev->matrix.adm, adm_add, AP_DEVICES);
+
+ mutex_unlock(&matrix_dev->mdevs_lock);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 5/8] s390/vfio-ap: Fix control domain removal in vfio_ap_mdev_cfg_remove
2026-08-10 19:22 [PATCH v2 0/8] s390/vfio-ap: Fix bugs in vfio_ap device driver callback functions Anthony Krowiak
` (3 preceding siblings ...)
2026-08-10 19:22 ` [PATCH v2 4/8] s390/vfio-ap: Fix required lock not held during update of ap_matrix_mdev object Anthony Krowiak
@ 2026-08-10 19:22 ` Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 6/8] s390/vfio-ap: fix potential use of uninitialized apm_filtered bitmap Anthony Krowiak
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Anthony Krowiak @ 2026-08-10 19:22 UTC (permalink / raw)
To: linux-s390, linux-kernel, kvm
Cc: jjherne, borntraeger, mjrosato, pasic, alex, kwankhede, fiuczy,
pbonzini, frankja, imbrenda, agordeev, hca, gor, stable
The vfio_ap_config_remove function uses the bitmap_andnot function to clear
bits from the matrix_mdev->matrix.adm bitmap (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 897518b88c28..9c7257c179a7 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -2621,9 +2621,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] 9+ messages in thread
* [PATCH v2 6/8] s390/vfio-ap: fix potential use of uninitialized apm_filtered bitmap
2026-08-10 19:22 [PATCH v2 0/8] s390/vfio-ap: Fix bugs in vfio_ap device driver callback functions Anthony Krowiak
` (4 preceding siblings ...)
2026-08-10 19:22 ` [PATCH v2 5/8] s390/vfio-ap: Fix control domain removal in vfio_ap_mdev_cfg_remove Anthony Krowiak
@ 2026-08-10 19:22 ` Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 7/8] s390/vfio-ap: Fix required lock not held during display of sysfs status attribute Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 8/8] s390/vfio-ap: Fix hot-unplug skipped when last AP adapter or domain removed Anthony Krowiak
7 siblings, 0 replies; 9+ messages in thread
From: Anthony Krowiak @ 2026-08-10 19:22 UTC (permalink / raw)
To: linux-s390, linux-kernel, kvm
Cc: jjherne, borntraeger, mjrosato, pasic, alex, kwankhede, fiuczy,
pbonzini, frankja, imbrenda, agordeev, hca, gor, stable
The DECLARE_BITMAP(apm_filtered, AP_DEVICES) macro allocates the bitmap
on the stack without zero-initializing it.
In vfio_ap_mdev_hot_plug_cfg(), the vfio_ap_mdev_filter_matrix() function
is only called to initialize and populate apm_filtered if either
filter_adapters or filter_domains is true. If the hot plug configuration
change only adds control domains (meaning filter_cdoms is true, but
filter_adapters and filter_domains are both false),
vfio_ap_mdev_filter_matrix() is bypassed.
Consequently, apm_filtered is passed to reset_queues_for_apids() with
uninitialized stack garbage. This can cause reset_queues_for_apids() to
interpret arbitrary stack garbage bits as valid APIDs to reset, potentially
performing unintended guest hardware queue resets.
Fix this by zero-initializing the apm_filtered bitmap at the beginning of
vfio_ap_mdev_hot_plug_cfg() using bitmap_zero().
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 | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 9c7257c179a7..061bbad20291 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -2836,6 +2836,8 @@ static void vfio_ap_mdev_hot_plug_cfg(struct ap_matrix_mdev *matrix_mdev)
DECLARE_BITMAP(apm_filtered, AP_DEVICES);
bool filter_domains, filter_adapters, filter_cdoms, do_hotplug = false;
+ bitmap_zero(apm_filtered, AP_DEVICES);
+
filter_adapters = bitmap_intersects(matrix_mdev->matrix.apm,
matrix_mdev->apm_add, AP_DEVICES);
filter_domains = bitmap_intersects(matrix_mdev->matrix.aqm,
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 7/8] s390/vfio-ap: Fix required lock not held during display of sysfs status attribute
2026-08-10 19:22 [PATCH v2 0/8] s390/vfio-ap: Fix bugs in vfio_ap device driver callback functions Anthony Krowiak
` (5 preceding siblings ...)
2026-08-10 19:22 ` [PATCH v2 6/8] s390/vfio-ap: fix potential use of uninitialized apm_filtered bitmap Anthony Krowiak
@ 2026-08-10 19:22 ` Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 8/8] s390/vfio-ap: Fix hot-unplug skipped when last AP adapter or domain removed Anthony Krowiak
7 siblings, 0 replies; 9+ messages in thread
From: Anthony Krowiak @ 2026-08-10 19:22 UTC (permalink / raw)
To: linux-s390, linux-kernel, kvm
Cc: jjherne, borntraeger, mjrosato, pasic, alex, kwankhede, fiuczy,
pbonzini, frankja, imbrenda, agordeev, hca, gor, stable
The status_show function that supports display of the status attribute of
the devices in /sys/bus/ap/devices calls the vfio_ap_mdev_for_queue
function which iterates the matrix_dev->mdev_list to find the object
representing the queue device whose status is to be displayed. In order to
traverse this list, the matrix_dev->guests_lock mutex must be held which is
not the case.
To fix this, the guests_lock mutex is taken prior to taking the
matrix_dev->mdevs_lock mutex in the status_show function. It is taken
there rather than the vfio_ap_mdev_for_queue function - where it is
needed - because it must be taken prior to the mdevs_lock mutex in order to
adhere to the proper locking order and prevent a lockdep splat; also
because the mdevs_lock is needed there to access fields within
the matrix_mdev object in that function.
Fixes: f139862b92cf ("s390/vfio-ap: add status attribute to AP queue device's sysfs dir")
Cc: stable@vger.kernel.org
Signed-off-by: Anthony Krowiak <akrowiak@linux.ibm.com>
---
drivers/s390/crypto/vfio_ap_ops.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 061bbad20291..cdc9bf5c5e53 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -2297,6 +2297,8 @@ static struct ap_matrix_mdev *vfio_ap_mdev_for_queue(struct vfio_ap_queue *q)
unsigned long apid = AP_QID_CARD(q->apqn);
unsigned long apqi = AP_QID_QUEUE(q->apqn);
+ lockdep_assert_held(&matrix_dev->guests_lock);
+
list_for_each_entry(matrix_mdev, &matrix_dev->mdev_list, node) {
if (test_bit_inv(apid, matrix_mdev->matrix.apm) &&
test_bit_inv(apqi, matrix_mdev->matrix.aqm))
@@ -2316,6 +2318,7 @@ static ssize_t status_show(struct device *dev,
struct ap_matrix_mdev *matrix_mdev;
struct ap_device *apdev = to_ap_dev(dev);
+ mutex_lock(&matrix_dev->guests_lock);
mutex_lock(&matrix_dev->mdevs_lock);
q = dev_get_drvdata(&apdev->device);
matrix_mdev = vfio_ap_mdev_for_queue(q);
@@ -2343,6 +2346,7 @@ static ssize_t status_show(struct device *dev,
}
mutex_unlock(&matrix_dev->mdevs_lock);
+ mutex_unlock(&matrix_dev->guests_lock);
return nchars;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 8/8] s390/vfio-ap: Fix hot-unplug skipped when last AP adapter or domain removed
2026-08-10 19:22 [PATCH v2 0/8] s390/vfio-ap: Fix bugs in vfio_ap device driver callback functions Anthony Krowiak
` (6 preceding siblings ...)
2026-08-10 19:22 ` [PATCH v2 7/8] s390/vfio-ap: Fix required lock not held during display of sysfs status attribute Anthony Krowiak
@ 2026-08-10 19:22 ` Anthony Krowiak
7 siblings, 0 replies; 9+ messages in thread
From: Anthony Krowiak @ 2026-08-10 19:22 UTC (permalink / raw)
To: linux-s390, linux-kernel, kvm
Cc: jjherne, borntraeger, mjrosato, pasic, alex, kwankhede, fiuczy,
pbonzini, frankja, imbrenda, agordeev, hca, gor, stable
The vfio_ap_mdev_hot_unplug_cfg() function uses the return value of
bitmap_andnot() to determine whether the guest APCB needs to be updated.
However, bitmap_andnot() returns false when the resulting destination
bitmap is empty. This means that if the only adapter, domain or control
domain assigned to an mdev is removed from the host's AP confikguration,
the bit is correctly cleared from the shadow APCB, but bitmap_andnot()
returns false because the result is an empty bitmap. Consequently,
do_hotplug remains 0 and vfio_ap_mdev_update_guest_apcb() is never called,
leaving the KVM guest with stale hardware access to the unplugged AP
devices.
Fix this by replacing the bitmap_andnot() return value check with
bitmap_intersects() to determine whether the shadow APCB actually
overlaps with the removal mask. If there is an intersection, call
bitmap_andnot() solely for its side effect of clearing the bits, then
unconditionally set do_hotplug to trigger the guest APCB update.
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 | 30 +++++++++++++++++-------------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index cdc9bf5c5e53..cb1e5db69d8a 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -2563,24 +2563,28 @@ static void vfio_ap_mdev_hot_unplug_cfg(struct ap_matrix_mdev *matrix_mdev,
unsigned long *aqrem,
unsigned long *cdrem)
{
- int do_hotplug = 0;
+ bool do_hotplug = false;
- if (!bitmap_empty(aprem, AP_DEVICES)) {
- do_hotplug |= bitmap_andnot(matrix_mdev->shadow_apcb.apm,
- matrix_mdev->shadow_apcb.apm,
- aprem, AP_DEVICES);
+ if (bitmap_intersects(matrix_mdev->shadow_apcb.apm, aprem, AP_DEVICES)) {
+ bitmap_andnot(matrix_mdev->shadow_apcb.apm,
+ matrix_mdev->shadow_apcb.apm,
+ aprem, AP_DEVICES);
+ do_hotplug = true;
}
- if (!bitmap_empty(aqrem, AP_DOMAINS)) {
- do_hotplug |= bitmap_andnot(matrix_mdev->shadow_apcb.aqm,
- matrix_mdev->shadow_apcb.aqm,
- aqrem, AP_DEVICES);
+ if (bitmap_intersects(matrix_mdev->shadow_apcb.aqm, aqrem, AP_DOMAINS)) {
+ bitmap_andnot(matrix_mdev->shadow_apcb.aqm,
+ matrix_mdev->shadow_apcb.aqm,
+ aqrem, AP_DOMAINS);
+ do_hotplug = true;
}
- if (!bitmap_empty(cdrem, AP_DOMAINS))
- do_hotplug |= bitmap_andnot(matrix_mdev->shadow_apcb.adm,
- matrix_mdev->shadow_apcb.adm,
- cdrem, AP_DOMAINS);
+ if (bitmap_intersects(matrix_mdev->shadow_apcb.adm, cdrem, AP_DOMAINS)) {
+ bitmap_andnot(matrix_mdev->shadow_apcb.adm,
+ matrix_mdev->shadow_apcb.adm,
+ cdrem, AP_DOMAINS);
+ do_hotplug = true;
+ }
if (do_hotplug)
vfio_ap_mdev_update_guest_apcb(matrix_mdev);
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-08-10 19:23 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-10 19:22 [PATCH v2 0/8] s390/vfio-ap: Fix bugs in vfio_ap device driver callback functions Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 1/8] s390/vfio-ap: Fix stale do_remove flag across iterations in vfio_ap_mdev_cfg_remove Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 2/8] s390/vfio-ap: Fix dereference matrix_mdev->kvm without checking for NULL Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 3/8] s390/vfio-ap: Fix use of wrong lock in mdev probe function Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 4/8] s390/vfio-ap: Fix required lock not held during update of ap_matrix_mdev object Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 5/8] s390/vfio-ap: Fix control domain removal in vfio_ap_mdev_cfg_remove Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 6/8] s390/vfio-ap: fix potential use of uninitialized apm_filtered bitmap Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 7/8] s390/vfio-ap: Fix required lock not held during display of sysfs status attribute Anthony Krowiak
2026-08-10 19:22 ` [PATCH v2 8/8] s390/vfio-ap: Fix hot-unplug skipped when last AP adapter or domain removed Anthony Krowiak
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox