mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-05-01 15:15:19 -04:00
s390/vfio-ap: r/w lock for PQAP interception handler function pointer
The function pointer to the interception handler for the PQAP instruction can get changed during the interception process. Let's add a semaphore to struct kvm_s390_crypto to control read/write access to the function pointer contained therein. The semaphore must be locked for write access by the vfio_ap device driver when notified that the KVM pointer has been set or cleared. It must be locked for read access by the interception framework when the PQAP instruction is intercepted. Signed-off-by: Tony Krowiak <akrowiak@linux.ibm.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com> Link: https://lore.kernel.org/r/20210823212047.1476436-2-akrowiak@linux.ibm.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
committed by
Alex Williamson
parent
eb24c1007e
commit
1e753732bd
@@ -352,8 +352,7 @@ static int vfio_ap_mdev_create(struct mdev_device *mdev)
|
||||
vfio_ap_matrix_init(&matrix_dev->info, &matrix_mdev->matrix);
|
||||
init_waitqueue_head(&matrix_mdev->wait_for_kvm);
|
||||
mdev_set_drvdata(mdev, matrix_mdev);
|
||||
matrix_mdev->pqap_hook.hook = handle_pqap;
|
||||
matrix_mdev->pqap_hook.owner = THIS_MODULE;
|
||||
matrix_mdev->pqap_hook = handle_pqap;
|
||||
mutex_lock(&matrix_dev->lock);
|
||||
list_add(&matrix_mdev->node, &matrix_dev->mdev_list);
|
||||
mutex_unlock(&matrix_dev->lock);
|
||||
@@ -1115,15 +1114,20 @@ static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,
|
||||
}
|
||||
|
||||
kvm_get_kvm(kvm);
|
||||
matrix_mdev->kvm = kvm;
|
||||
matrix_mdev->kvm_busy = true;
|
||||
mutex_unlock(&matrix_dev->lock);
|
||||
|
||||
down_write(&matrix_mdev->kvm->arch.crypto.pqap_hook_rwsem);
|
||||
kvm->arch.crypto.pqap_hook = &matrix_mdev->pqap_hook;
|
||||
up_write(&matrix_mdev->kvm->arch.crypto.pqap_hook_rwsem);
|
||||
|
||||
kvm_arch_crypto_set_masks(kvm,
|
||||
matrix_mdev->matrix.apm,
|
||||
matrix_mdev->matrix.aqm,
|
||||
matrix_mdev->matrix.adm);
|
||||
|
||||
mutex_lock(&matrix_dev->lock);
|
||||
kvm->arch.crypto.pqap_hook = &matrix_mdev->pqap_hook;
|
||||
matrix_mdev->kvm = kvm;
|
||||
matrix_mdev->kvm_busy = false;
|
||||
wake_up_all(&matrix_mdev->wait_for_kvm);
|
||||
}
|
||||
@@ -1189,10 +1193,17 @@ static void vfio_ap_mdev_unset_kvm(struct ap_matrix_mdev *matrix_mdev)
|
||||
if (matrix_mdev->kvm) {
|
||||
matrix_mdev->kvm_busy = true;
|
||||
mutex_unlock(&matrix_dev->lock);
|
||||
kvm_arch_crypto_clear_masks(matrix_mdev->kvm);
|
||||
|
||||
if (matrix_mdev->kvm->arch.crypto.crycbd) {
|
||||
down_write(&matrix_mdev->kvm->arch.crypto.pqap_hook_rwsem);
|
||||
matrix_mdev->kvm->arch.crypto.pqap_hook = NULL;
|
||||
up_write(&matrix_mdev->kvm->arch.crypto.pqap_hook_rwsem);
|
||||
|
||||
kvm_arch_crypto_clear_masks(matrix_mdev->kvm);
|
||||
}
|
||||
|
||||
mutex_lock(&matrix_dev->lock);
|
||||
vfio_ap_mdev_reset_queues(matrix_mdev->mdev);
|
||||
matrix_mdev->kvm->arch.crypto.pqap_hook = NULL;
|
||||
kvm_put_kvm(matrix_mdev->kvm);
|
||||
matrix_mdev->kvm = NULL;
|
||||
matrix_mdev->kvm_busy = false;
|
||||
|
||||
@@ -86,7 +86,7 @@ struct ap_matrix_mdev {
|
||||
bool kvm_busy;
|
||||
wait_queue_head_t wait_for_kvm;
|
||||
struct kvm *kvm;
|
||||
struct kvm_s390_module_hook pqap_hook;
|
||||
crypto_hook pqap_hook;
|
||||
struct mdev_device *mdev;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user