Skip to content

Commit 62e358c

Browse files
Pierre MorelVasily Gorbik
authored andcommitted
vfio: ap: register IOMMU VFIO notifier
To be able to use the VFIO interface to facilitate the mediated device memory pinning/unpinning we need to register a notifier for IOMMU. While we will start to pin one guest page for the interrupt indicator byte, this is still ok with ballooning as this page will never be used by the guest virtio-balloon driver. So the pinned page will never be freed. And even a broken guest does so, that would not impact the host as the original page is still in control by vfio. Signed-off-by: Pierre Morel <[email protected]> Reviewed-by: Cornelia Huck <[email protected]> Reviewed-by: Tony Krowiak <[email protected]> Acked-by: Harald Freudenberger <[email protected]> Signed-off-by: Halil Pasic <[email protected]> Signed-off-by: Vasily Gorbik <[email protected]>
1 parent e5282de commit 62e358c

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

drivers/s390/crypto/vfio_ap_ops.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,35 @@ static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,
759759
return 0;
760760
}
761761

762+
/*
763+
* vfio_ap_mdev_iommu_notifier: IOMMU notifier callback
764+
*
765+
* @nb: The notifier block
766+
* @action: Action to be taken
767+
* @data: data associated with the request
768+
*
769+
* For an UNMAP request, unpin the guest IOVA (the NIB guest address we
770+
* pinned before). Other requests are ignored.
771+
*
772+
*/
773+
static int vfio_ap_mdev_iommu_notifier(struct notifier_block *nb,
774+
unsigned long action, void *data)
775+
{
776+
struct ap_matrix_mdev *matrix_mdev;
777+
778+
matrix_mdev = container_of(nb, struct ap_matrix_mdev, iommu_notifier);
779+
780+
if (action == VFIO_IOMMU_NOTIFY_DMA_UNMAP) {
781+
struct vfio_iommu_type1_dma_unmap *unmap = data;
782+
unsigned long g_pfn = unmap->iova >> PAGE_SHIFT;
783+
784+
vfio_unpin_pages(mdev_dev(matrix_mdev->mdev), &g_pfn, 1);
785+
return NOTIFY_OK;
786+
}
787+
788+
return NOTIFY_DONE;
789+
}
790+
762791
static int vfio_ap_mdev_group_notifier(struct notifier_block *nb,
763792
unsigned long action, void *data)
764793
{
@@ -858,7 +887,17 @@ static int vfio_ap_mdev_open(struct mdev_device *mdev)
858887
return ret;
859888
}
860889

861-
return 0;
890+
matrix_mdev->iommu_notifier.notifier_call = vfio_ap_mdev_iommu_notifier;
891+
events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
892+
ret = vfio_register_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
893+
&events, &matrix_mdev->iommu_notifier);
894+
if (!ret)
895+
return ret;
896+
897+
vfio_unregister_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY,
898+
&matrix_mdev->group_notifier);
899+
module_put(THIS_MODULE);
900+
return ret;
862901
}
863902

864903
static void vfio_ap_mdev_release(struct mdev_device *mdev)
@@ -869,6 +908,8 @@ static void vfio_ap_mdev_release(struct mdev_device *mdev)
869908
kvm_arch_crypto_clear_masks(matrix_mdev->kvm);
870909

871910
vfio_ap_mdev_reset_queues(mdev);
911+
vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
912+
&matrix_mdev->iommu_notifier);
872913
vfio_unregister_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY,
873914
&matrix_mdev->group_notifier);
874915
matrix_mdev->kvm = NULL;

drivers/s390/crypto/vfio_ap_private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,10 @@ struct ap_matrix_mdev {
8181
struct list_head node;
8282
struct ap_matrix matrix;
8383
struct notifier_block group_notifier;
84+
struct notifier_block iommu_notifier;
8485
struct kvm *kvm;
8586
struct kvm_s390_module_hook pqap_hook;
87+
struct mdev_device *mdev;
8688
};
8789

8890
extern int vfio_ap_mdev_register(void);

0 commit comments

Comments
 (0)