On Tue, 9 Feb 2021 14:48:30 -0500 Tony Krowiak <akrowiak@xxxxxxxxxxxxx> wrote: > This patch fixes a circular locking dependency in the CI introduced by > commit f21916ec4826 ("s390/vfio-ap: clean up vfio_ap resources when KVM > pointer invalidated"). The lockdep only occurs when starting a Secure > Execution guest. Crypto virtualization (vfio_ap) is not yet supported for > SE guests; however, in order to avoid CI errors, this fix is being > provided. > > The circular lockdep was introduced when the masks in the guest's APCB > were taken under the matrix_dev->lock. While the lock is definitely > needed to protect the setting/unsetting of the KVM pointer, it is not > necessarily critical for setting the masks, so this will not be done under > protection of the matrix_dev->lock. > > Fixes: f21916ec4826 ("s390/vfio-ap: clean up vfio_ap resources when KVM pointer invalidated") > Cc: stable@xxxxxxxxxxxxxxx > Signed-off-by: Tony Krowiak <akrowiak@xxxxxxxxxxxxx> > --- > drivers/s390/crypto/vfio_ap_ops.c | 75 ++++++++++++++++++------------- > 1 file changed, 45 insertions(+), 30 deletions(-) > > static void vfio_ap_mdev_unset_kvm(struct ap_matrix_mdev *matrix_mdev) > { > - kvm_arch_crypto_clear_masks(matrix_mdev->kvm); > - matrix_mdev->kvm->arch.crypto.pqap_hook = NULL; > - vfio_ap_mdev_reset_queues(matrix_mdev->mdev); > - kvm_put_kvm(matrix_mdev->kvm); > - matrix_mdev->kvm = NULL; > + if (matrix_mdev->kvm) { If you're doing setting/unsetting under matrix_dev->lock, is it possible that matrix_mdev->kvm gets unset between here and the next line, as you don't hold the lock? Maybe you could - grab a reference to kvm while holding the lock - call the mask handling functions with that kvm reference - lock again, drop the reference, and do the rest of the processing? > + kvm_arch_crypto_clear_masks(matrix_mdev->kvm); > + mutex_lock(&matrix_dev->lock); > + matrix_mdev->kvm->arch.crypto.pqap_hook = NULL; > + vfio_ap_mdev_reset_queues(matrix_mdev->mdev); > + kvm_put_kvm(matrix_mdev->kvm); > + matrix_mdev->kvm = NULL; > + mutex_unlock(&matrix_dev->lock); > + } > }