Skip to content

Commit 1918f2b

Browse files
Tony KrowiakVasily Gorbik
authored andcommitted
s390/vfio-ap: bypass unnecessary processing of AP resources
It is not necessary to go through the process of validation, linking of queues to mdev and vice versa and filtering the APQNs assigned to the matrix mdev to build an AP configuration for a guest if an adapter or domain being assigned is already assigned to the matrix mdev. Likewise, it is not necessary to proceed through the process the unassignment of an adapter, domain or control domain if it is not assigned to the matrix mdev. Since it is not necessary to process assignment of a resource already assigned or process unassignment of a resource that is been assigned, this patch will bypass all assignment/unassignment operations for an adapter, domain or control domain under these circumstances. Not only is assignment of a duplicate adapter or domain unnecessary, it will also cause a hang situation when removing the matrix mdev to which it is assigned. The reason is because the same vfio_ap_queue objects with an APQN containing the APID of the adapter or APQI of the domain being assigned will get added multiple times to the hashtable that holds them. This results in the pprev and next pointers of the hlist_node (mdev_qnode field in the vfio_ap_queue object) pointing to the queue object itself resulting in an interminable loop when the mdev is removed and the queue table is iterated to reset the queues. Cc: stable@vger.kernel.org Fixes: 11cb241 ("s390/vfio-ap: manage link between queue struct and matrix mdev") Reported-by: Matthew Rosato <mjrosato@linux.ibm.com> Signed-off-by: Tony Krowiak <akrowiak@linux.ibm.com> Reviewed-by: Halil Pasic <pasic@linux.ibm.com> Signed-off-by: Halil Pasic <pasic@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
1 parent 8d96bba commit 1918f2b

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

drivers/s390/crypto/vfio_ap_ops.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,11 @@ static ssize_t assign_adapter_store(struct device *dev,
984984
goto done;
985985
}
986986

987+
if (test_bit_inv(apid, matrix_mdev->matrix.apm)) {
988+
ret = count;
989+
goto done;
990+
}
991+
987992
set_bit_inv(apid, matrix_mdev->matrix.apm);
988993

989994
ret = vfio_ap_mdev_validate_masks(matrix_mdev);
@@ -1109,6 +1114,11 @@ static ssize_t unassign_adapter_store(struct device *dev,
11091114
goto done;
11101115
}
11111116

1117+
if (!test_bit_inv(apid, matrix_mdev->matrix.apm)) {
1118+
ret = count;
1119+
goto done;
1120+
}
1121+
11121122
clear_bit_inv((unsigned long)apid, matrix_mdev->matrix.apm);
11131123
vfio_ap_mdev_hot_unplug_adapter(matrix_mdev, apid);
11141124
ret = count;
@@ -1183,6 +1193,11 @@ static ssize_t assign_domain_store(struct device *dev,
11831193
goto done;
11841194
}
11851195

1196+
if (test_bit_inv(apqi, matrix_mdev->matrix.aqm)) {
1197+
ret = count;
1198+
goto done;
1199+
}
1200+
11861201
set_bit_inv(apqi, matrix_mdev->matrix.aqm);
11871202

11881203
ret = vfio_ap_mdev_validate_masks(matrix_mdev);
@@ -1286,6 +1301,11 @@ static ssize_t unassign_domain_store(struct device *dev,
12861301
goto done;
12871302
}
12881303

1304+
if (!test_bit_inv(apqi, matrix_mdev->matrix.aqm)) {
1305+
ret = count;
1306+
goto done;
1307+
}
1308+
12891309
clear_bit_inv((unsigned long)apqi, matrix_mdev->matrix.aqm);
12901310
vfio_ap_mdev_hot_unplug_domain(matrix_mdev, apqi);
12911311
ret = count;
@@ -1329,6 +1349,11 @@ static ssize_t assign_control_domain_store(struct device *dev,
13291349
goto done;
13301350
}
13311351

1352+
if (test_bit_inv(id, matrix_mdev->matrix.adm)) {
1353+
ret = count;
1354+
goto done;
1355+
}
1356+
13321357
/* Set the bit in the ADM (bitmask) corresponding to the AP control
13331358
* domain number (id). The bits in the mask, from most significant to
13341359
* least significant, correspond to IDs 0 up to the one less than the
@@ -1378,6 +1403,11 @@ static ssize_t unassign_control_domain_store(struct device *dev,
13781403
goto done;
13791404
}
13801405

1406+
if (!test_bit_inv(domid, matrix_mdev->matrix.adm)) {
1407+
ret = count;
1408+
goto done;
1409+
}
1410+
13811411
clear_bit_inv(domid, matrix_mdev->matrix.adm);
13821412

13831413
if (test_bit_inv(domid, matrix_mdev->shadow_apcb.adm)) {

0 commit comments

Comments
 (0)