Skip to content

Commit 86956e7

Browse files
Tony KrowiakAlex Williamson
authored andcommitted
s390/vfio-ap: replace open coded locks for VFIO_GROUP_NOTIFY_SET_KVM notification
It was pointed out during an unrelated patch review that locks should not be open coded - i.e., writing the algorithm of a standard lock in a function instead of using a lock from the standard library. The setting and testing of a busy flag and sleeping on a wait_event is the same thing a lock does. The open coded locks are invisible to lockdep, so potential locking problems are not detected. This patch removes the open coded locks used during VFIO_GROUP_NOTIFY_SET_KVM notification. The busy flag and wait queue were introduced to resolve a possible circular locking dependency reported by lockdep when starting a secure execution guest configured with AP adapters and domains. Reversing the order in which the kvm->lock mutex and matrix_dev->lock mutex are locked resolves the issue reported by lockdep, thus enabling the removal of the open coded locks. Signed-off-by: Tony Krowiak <akrowiak@linux.ibm.com> Acked-by: Halil Pasic <pasic@linux.ibm.com> Link: https://lore.kernel.org/r/20210823212047.1476436-3-akrowiak@linux.ibm.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
1 parent 1e75373 commit 86956e7

3 files changed

Lines changed: 67 additions & 98 deletions

File tree

arch/s390/kvm/kvm-s390.c

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2559,12 +2559,26 @@ static void kvm_s390_set_crycb_format(struct kvm *kvm)
25592559
kvm->arch.crypto.crycbd |= CRYCB_FORMAT1;
25602560
}
25612561

2562+
/*
2563+
* kvm_arch_crypto_set_masks
2564+
*
2565+
* @kvm: pointer to the target guest's KVM struct containing the crypto masks
2566+
* to be set.
2567+
* @apm: the mask identifying the accessible AP adapters
2568+
* @aqm: the mask identifying the accessible AP domains
2569+
* @adm: the mask identifying the accessible AP control domains
2570+
*
2571+
* Set the masks that identify the adapters, domains and control domains to
2572+
* which the KVM guest is granted access.
2573+
*
2574+
* Note: The kvm->lock mutex must be locked by the caller before invoking this
2575+
* function.
2576+
*/
25622577
void kvm_arch_crypto_set_masks(struct kvm *kvm, unsigned long *apm,
25632578
unsigned long *aqm, unsigned long *adm)
25642579
{
25652580
struct kvm_s390_crypto_cb *crycb = kvm->arch.crypto.crycb;
25662581

2567-
mutex_lock(&kvm->lock);
25682582
kvm_s390_vcpu_block_all(kvm);
25692583

25702584
switch (kvm->arch.crypto.crycbd & CRYCB_FORMAT_MASK) {
@@ -2595,13 +2609,23 @@ void kvm_arch_crypto_set_masks(struct kvm *kvm, unsigned long *apm,
25952609
/* recreate the shadow crycb for each vcpu */
25962610
kvm_s390_sync_request_broadcast(kvm, KVM_REQ_VSIE_RESTART);
25972611
kvm_s390_vcpu_unblock_all(kvm);
2598-
mutex_unlock(&kvm->lock);
25992612
}
26002613
EXPORT_SYMBOL_GPL(kvm_arch_crypto_set_masks);
26012614

2615+
/*
2616+
* kvm_arch_crypto_clear_masks
2617+
*
2618+
* @kvm: pointer to the target guest's KVM struct containing the crypto masks
2619+
* to be cleared.
2620+
*
2621+
* Clear the masks that identify the adapters, domains and control domains to
2622+
* which the KVM guest is granted access.
2623+
*
2624+
* Note: The kvm->lock mutex must be locked by the caller before invoking this
2625+
* function.
2626+
*/
26022627
void kvm_arch_crypto_clear_masks(struct kvm *kvm)
26032628
{
2604-
mutex_lock(&kvm->lock);
26052629
kvm_s390_vcpu_block_all(kvm);
26062630

26072631
memset(&kvm->arch.crypto.crycb->apcb0, 0,
@@ -2613,7 +2637,6 @@ void kvm_arch_crypto_clear_masks(struct kvm *kvm)
26132637
/* recreate the shadow crycb for each vcpu */
26142638
kvm_s390_sync_request_broadcast(kvm, KVM_REQ_VSIE_RESTART);
26152639
kvm_s390_vcpu_unblock_all(kvm);
2616-
mutex_unlock(&kvm->lock);
26172640
}
26182641
EXPORT_SYMBOL_GPL(kvm_arch_crypto_clear_masks);
26192642

drivers/s390/crypto/vfio_ap_ops.c

Lines changed: 40 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -294,15 +294,6 @@ static int handle_pqap(struct kvm_vcpu *vcpu)
294294
matrix_mdev = container_of(vcpu->kvm->arch.crypto.pqap_hook,
295295
struct ap_matrix_mdev, pqap_hook);
296296

297-
/*
298-
* If the KVM pointer is in the process of being set, wait until the
299-
* process has completed.
300-
*/
301-
wait_event_cmd(matrix_mdev->wait_for_kvm,
302-
!matrix_mdev->kvm_busy,
303-
mutex_unlock(&matrix_dev->lock),
304-
mutex_lock(&matrix_dev->lock));
305-
306297
/* If the there is no guest using the mdev, there is nothing to do */
307298
if (!matrix_mdev->kvm)
308299
goto out_unlock;
@@ -350,7 +341,6 @@ static int vfio_ap_mdev_create(struct mdev_device *mdev)
350341

351342
matrix_mdev->mdev = mdev;
352343
vfio_ap_matrix_init(&matrix_dev->info, &matrix_mdev->matrix);
353-
init_waitqueue_head(&matrix_mdev->wait_for_kvm);
354344
mdev_set_drvdata(mdev, matrix_mdev);
355345
matrix_mdev->pqap_hook = handle_pqap;
356346
mutex_lock(&matrix_dev->lock);
@@ -619,11 +609,8 @@ static ssize_t assign_adapter_store(struct device *dev,
619609

620610
mutex_lock(&matrix_dev->lock);
621611

622-
/*
623-
* If the KVM pointer is in flux or the guest is running, disallow
624-
* un-assignment of adapter
625-
*/
626-
if (matrix_mdev->kvm_busy || matrix_mdev->kvm) {
612+
/* If the KVM guest is running, disallow assignment of adapter */
613+
if (matrix_mdev->kvm) {
627614
ret = -EBUSY;
628615
goto done;
629616
}
@@ -692,11 +679,8 @@ static ssize_t unassign_adapter_store(struct device *dev,
692679

693680
mutex_lock(&matrix_dev->lock);
694681

695-
/*
696-
* If the KVM pointer is in flux or the guest is running, disallow
697-
* un-assignment of adapter
698-
*/
699-
if (matrix_mdev->kvm_busy || matrix_mdev->kvm) {
682+
/* If the KVM guest is running, disallow unassignment of adapter */
683+
if (matrix_mdev->kvm) {
700684
ret = -EBUSY;
701685
goto done;
702686
}
@@ -782,11 +766,8 @@ static ssize_t assign_domain_store(struct device *dev,
782766

783767
mutex_lock(&matrix_dev->lock);
784768

785-
/*
786-
* If the KVM pointer is in flux or the guest is running, disallow
787-
* assignment of domain
788-
*/
789-
if (matrix_mdev->kvm_busy || matrix_mdev->kvm) {
769+
/* If the KVM guest is running, disallow assignment of domain */
770+
if (matrix_mdev->kvm) {
790771
ret = -EBUSY;
791772
goto done;
792773
}
@@ -850,11 +831,8 @@ static ssize_t unassign_domain_store(struct device *dev,
850831

851832
mutex_lock(&matrix_dev->lock);
852833

853-
/*
854-
* If the KVM pointer is in flux or the guest is running, disallow
855-
* un-assignment of domain
856-
*/
857-
if (matrix_mdev->kvm_busy || matrix_mdev->kvm) {
834+
/* If the KVM guest is running, disallow unassignment of domain */
835+
if (matrix_mdev->kvm) {
858836
ret = -EBUSY;
859837
goto done;
860838
}
@@ -904,11 +882,8 @@ static ssize_t assign_control_domain_store(struct device *dev,
904882

905883
mutex_lock(&matrix_dev->lock);
906884

907-
/*
908-
* If the KVM pointer is in flux or the guest is running, disallow
909-
* assignment of control domain.
910-
*/
911-
if (matrix_mdev->kvm_busy || matrix_mdev->kvm) {
885+
/* If the KVM guest is running, disallow assignment of control domain */
886+
if (matrix_mdev->kvm) {
912887
ret = -EBUSY;
913888
goto done;
914889
}
@@ -963,11 +938,8 @@ static ssize_t unassign_control_domain_store(struct device *dev,
963938

964939
mutex_lock(&matrix_dev->lock);
965940

966-
/*
967-
* If the KVM pointer is in flux or the guest is running, disallow
968-
* un-assignment of control domain.
969-
*/
970-
if (matrix_mdev->kvm_busy || matrix_mdev->kvm) {
941+
/* If a KVM guest is running, disallow unassignment of control domain */
942+
if (matrix_mdev->kvm) {
971943
ret = -EBUSY;
972944
goto done;
973945
}
@@ -1108,28 +1080,30 @@ static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,
11081080
struct ap_matrix_mdev *m;
11091081

11101082
if (kvm->arch.crypto.crycbd) {
1083+
down_write(&kvm->arch.crypto.pqap_hook_rwsem);
1084+
kvm->arch.crypto.pqap_hook = &matrix_mdev->pqap_hook;
1085+
up_write(&kvm->arch.crypto.pqap_hook_rwsem);
1086+
1087+
mutex_lock(&kvm->lock);
1088+
mutex_lock(&matrix_dev->lock);
1089+
11111090
list_for_each_entry(m, &matrix_dev->mdev_list, node) {
1112-
if (m != matrix_mdev && m->kvm == kvm)
1091+
if (m != matrix_mdev && m->kvm == kvm) {
1092+
mutex_unlock(&kvm->lock);
1093+
mutex_unlock(&matrix_dev->lock);
11131094
return -EPERM;
1095+
}
11141096
}
11151097

11161098
kvm_get_kvm(kvm);
11171099
matrix_mdev->kvm = kvm;
1118-
matrix_mdev->kvm_busy = true;
1119-
mutex_unlock(&matrix_dev->lock);
1120-
1121-
down_write(&matrix_mdev->kvm->arch.crypto.pqap_hook_rwsem);
1122-
kvm->arch.crypto.pqap_hook = &matrix_mdev->pqap_hook;
1123-
up_write(&matrix_mdev->kvm->arch.crypto.pqap_hook_rwsem);
1124-
11251100
kvm_arch_crypto_set_masks(kvm,
11261101
matrix_mdev->matrix.apm,
11271102
matrix_mdev->matrix.aqm,
11281103
matrix_mdev->matrix.adm);
11291104

1130-
mutex_lock(&matrix_dev->lock);
1131-
matrix_mdev->kvm_busy = false;
1132-
wake_up_all(&matrix_mdev->wait_for_kvm);
1105+
mutex_unlock(&kvm->lock);
1106+
mutex_unlock(&matrix_dev->lock);
11331107
}
11341108

11351109
return 0;
@@ -1179,35 +1153,24 @@ static int vfio_ap_mdev_iommu_notifier(struct notifier_block *nb,
11791153
* done under the @matrix_mdev->lock.
11801154
*
11811155
*/
1182-
static void vfio_ap_mdev_unset_kvm(struct ap_matrix_mdev *matrix_mdev)
1156+
static void vfio_ap_mdev_unset_kvm(struct ap_matrix_mdev *matrix_mdev,
1157+
struct kvm *kvm)
11831158
{
1184-
/*
1185-
* If the KVM pointer is in the process of being set, wait until the
1186-
* process has completed.
1187-
*/
1188-
wait_event_cmd(matrix_mdev->wait_for_kvm,
1189-
!matrix_mdev->kvm_busy,
1190-
mutex_unlock(&matrix_dev->lock),
1191-
mutex_lock(&matrix_dev->lock));
1192-
1193-
if (matrix_mdev->kvm) {
1194-
matrix_mdev->kvm_busy = true;
1195-
mutex_unlock(&matrix_dev->lock);
1196-
1197-
if (matrix_mdev->kvm->arch.crypto.crycbd) {
1198-
down_write(&matrix_mdev->kvm->arch.crypto.pqap_hook_rwsem);
1199-
matrix_mdev->kvm->arch.crypto.pqap_hook = NULL;
1200-
up_write(&matrix_mdev->kvm->arch.crypto.pqap_hook_rwsem);
1201-
1202-
kvm_arch_crypto_clear_masks(matrix_mdev->kvm);
1203-
}
1159+
if (kvm && kvm->arch.crypto.crycbd) {
1160+
down_write(&kvm->arch.crypto.pqap_hook_rwsem);
1161+
kvm->arch.crypto.pqap_hook = NULL;
1162+
up_write(&kvm->arch.crypto.pqap_hook_rwsem);
12041163

1164+
mutex_lock(&kvm->lock);
12051165
mutex_lock(&matrix_dev->lock);
1166+
1167+
kvm_arch_crypto_clear_masks(kvm);
12061168
vfio_ap_mdev_reset_queues(matrix_mdev->mdev);
1207-
kvm_put_kvm(matrix_mdev->kvm);
1169+
kvm_put_kvm(kvm);
12081170
matrix_mdev->kvm = NULL;
1209-
matrix_mdev->kvm_busy = false;
1210-
wake_up_all(&matrix_mdev->wait_for_kvm);
1171+
1172+
mutex_unlock(&kvm->lock);
1173+
mutex_unlock(&matrix_dev->lock);
12111174
}
12121175
}
12131176

@@ -1220,16 +1183,13 @@ static int vfio_ap_mdev_group_notifier(struct notifier_block *nb,
12201183
if (action != VFIO_GROUP_NOTIFY_SET_KVM)
12211184
return NOTIFY_OK;
12221185

1223-
mutex_lock(&matrix_dev->lock);
12241186
matrix_mdev = container_of(nb, struct ap_matrix_mdev, group_notifier);
12251187

12261188
if (!data)
1227-
vfio_ap_mdev_unset_kvm(matrix_mdev);
1189+
vfio_ap_mdev_unset_kvm(matrix_mdev, matrix_mdev->kvm);
12281190
else if (vfio_ap_mdev_set_kvm(matrix_mdev, data))
12291191
notify_rc = NOTIFY_DONE;
12301192

1231-
mutex_unlock(&matrix_dev->lock);
1232-
12331193
return notify_rc;
12341194
}
12351195

@@ -1363,14 +1323,11 @@ static void vfio_ap_mdev_close_device(struct mdev_device *mdev)
13631323
{
13641324
struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
13651325

1366-
mutex_lock(&matrix_dev->lock);
1367-
vfio_ap_mdev_unset_kvm(matrix_mdev);
1368-
mutex_unlock(&matrix_dev->lock);
1369-
13701326
vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
13711327
&matrix_mdev->iommu_notifier);
13721328
vfio_unregister_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY,
13731329
&matrix_mdev->group_notifier);
1330+
vfio_ap_mdev_unset_kvm(matrix_mdev, matrix_mdev->kvm);
13741331
module_put(THIS_MODULE);
13751332
}
13761333

@@ -1412,15 +1369,6 @@ static ssize_t vfio_ap_mdev_ioctl(struct mdev_device *mdev,
14121369
break;
14131370
}
14141371

1415-
/*
1416-
* If the KVM pointer is in the process of being set, wait until
1417-
* the process has completed.
1418-
*/
1419-
wait_event_cmd(matrix_mdev->wait_for_kvm,
1420-
!matrix_mdev->kvm_busy,
1421-
mutex_unlock(&matrix_dev->lock),
1422-
mutex_lock(&matrix_dev->lock));
1423-
14241372
ret = vfio_ap_mdev_reset_queues(mdev);
14251373
break;
14261374
default:

drivers/s390/crypto/vfio_ap_private.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,6 @@ struct ap_matrix_mdev {
8383
struct ap_matrix matrix;
8484
struct notifier_block group_notifier;
8585
struct notifier_block iommu_notifier;
86-
bool kvm_busy;
87-
wait_queue_head_t wait_for_kvm;
8886
struct kvm *kvm;
8987
crypto_hook pqap_hook;
9088
struct mdev_device *mdev;

0 commit comments

Comments
 (0)