Skip to content

Commit ce4b465

Browse files
jgunthorpeawilliam
authored andcommitted
vfio: Replace the DMA unmapping notifier with a callback
Instead of having drivers register the notifier with explicit code just have them provide a dma_unmap callback op in their driver ops and rely on the core code to wire it up. Suggested-by: Christoph Hellwig <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Reviewed-by: Tony Krowiak <[email protected]> Reviewed-by: Eric Farman <[email protected]> Reviewed-by: Zhenyu Wang <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alex Williamson <[email protected]>
1 parent 2a8ed7e commit ce4b465

File tree

9 files changed

+86
-240
lines changed

9 files changed

+86
-240
lines changed

drivers/gpu/drm/i915/gvt/gvt.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,6 @@ struct intel_vgpu {
226226
unsigned long nr_cache_entries;
227227
struct mutex cache_lock;
228228

229-
struct notifier_block iommu_notifier;
230229
atomic_t released;
231230

232231
struct kvm_page_track_notifier_node track_node;

drivers/gpu/drm/i915/gvt/kvmgt.c

Lines changed: 19 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -729,34 +729,25 @@ int intel_gvt_set_edid(struct intel_vgpu *vgpu, int port_num)
729729
return ret;
730730
}
731731

732-
static int intel_vgpu_iommu_notifier(struct notifier_block *nb,
733-
unsigned long action, void *data)
732+
static void intel_vgpu_dma_unmap(struct vfio_device *vfio_dev, u64 iova,
733+
u64 length)
734734
{
735-
struct intel_vgpu *vgpu =
736-
container_of(nb, struct intel_vgpu, iommu_notifier);
737-
738-
if (action == VFIO_IOMMU_NOTIFY_DMA_UNMAP) {
739-
struct vfio_iommu_type1_dma_unmap *unmap = data;
740-
struct gvt_dma *entry;
741-
unsigned long iov_pfn, end_iov_pfn;
735+
struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
736+
struct gvt_dma *entry;
737+
u64 iov_pfn = iova >> PAGE_SHIFT;
738+
u64 end_iov_pfn = iov_pfn + length / PAGE_SIZE;
742739

743-
iov_pfn = unmap->iova >> PAGE_SHIFT;
744-
end_iov_pfn = iov_pfn + unmap->size / PAGE_SIZE;
740+
mutex_lock(&vgpu->cache_lock);
741+
for (; iov_pfn < end_iov_pfn; iov_pfn++) {
742+
entry = __gvt_cache_find_gfn(vgpu, iov_pfn);
743+
if (!entry)
744+
continue;
745745

746-
mutex_lock(&vgpu->cache_lock);
747-
for (; iov_pfn < end_iov_pfn; iov_pfn++) {
748-
entry = __gvt_cache_find_gfn(vgpu, iov_pfn);
749-
if (!entry)
750-
continue;
751-
752-
gvt_dma_unmap_page(vgpu, entry->gfn, entry->dma_addr,
753-
entry->size);
754-
__gvt_cache_remove_entry(vgpu, entry);
755-
}
756-
mutex_unlock(&vgpu->cache_lock);
746+
gvt_dma_unmap_page(vgpu, entry->gfn, entry->dma_addr,
747+
entry->size);
748+
__gvt_cache_remove_entry(vgpu, entry);
757749
}
758-
759-
return NOTIFY_OK;
750+
mutex_unlock(&vgpu->cache_lock);
760751
}
761752

762753
static bool __kvmgt_vgpu_exist(struct intel_vgpu *vgpu)
@@ -783,36 +774,20 @@ static bool __kvmgt_vgpu_exist(struct intel_vgpu *vgpu)
783774
static int intel_vgpu_open_device(struct vfio_device *vfio_dev)
784775
{
785776
struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
786-
unsigned long events;
787-
int ret;
788-
789-
vgpu->iommu_notifier.notifier_call = intel_vgpu_iommu_notifier;
790777

791-
events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
792-
ret = vfio_register_notifier(vfio_dev, VFIO_IOMMU_NOTIFY, &events,
793-
&vgpu->iommu_notifier);
794-
if (ret != 0) {
795-
gvt_vgpu_err("vfio_register_notifier for iommu failed: %d\n",
796-
ret);
797-
goto out;
798-
}
799-
800-
ret = -EEXIST;
801778
if (vgpu->attached)
802-
goto undo_iommu;
779+
return -EEXIST;
803780

804-
ret = -ESRCH;
805781
if (!vgpu->vfio_device.kvm ||
806782
vgpu->vfio_device.kvm->mm != current->mm) {
807783
gvt_vgpu_err("KVM is required to use Intel vGPU\n");
808-
goto undo_iommu;
784+
return -ESRCH;
809785
}
810786

811787
kvm_get_kvm(vgpu->vfio_device.kvm);
812788

813-
ret = -EEXIST;
814789
if (__kvmgt_vgpu_exist(vgpu))
815-
goto undo_iommu;
790+
return -EEXIST;
816791

817792
vgpu->attached = true;
818793

@@ -831,12 +806,6 @@ static int intel_vgpu_open_device(struct vfio_device *vfio_dev)
831806

832807
atomic_set(&vgpu->released, 0);
833808
return 0;
834-
835-
undo_iommu:
836-
vfio_unregister_notifier(vfio_dev, VFIO_IOMMU_NOTIFY,
837-
&vgpu->iommu_notifier);
838-
out:
839-
return ret;
840809
}
841810

842811
static void intel_vgpu_release_msi_eventfd_ctx(struct intel_vgpu *vgpu)
@@ -853,8 +822,6 @@ static void intel_vgpu_release_msi_eventfd_ctx(struct intel_vgpu *vgpu)
853822
static void intel_vgpu_close_device(struct vfio_device *vfio_dev)
854823
{
855824
struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
856-
struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
857-
int ret;
858825

859826
if (!vgpu->attached)
860827
return;
@@ -864,11 +831,6 @@ static void intel_vgpu_close_device(struct vfio_device *vfio_dev)
864831

865832
intel_gvt_release_vgpu(vgpu);
866833

867-
ret = vfio_unregister_notifier(&vgpu->vfio_device, VFIO_IOMMU_NOTIFY,
868-
&vgpu->iommu_notifier);
869-
drm_WARN(&i915->drm, ret,
870-
"vfio_unregister_notifier for iommu failed: %d\n", ret);
871-
872834
debugfs_remove(debugfs_lookup(KVMGT_DEBUGFS_FILENAME, vgpu->debugfs));
873835

874836
kvm_page_track_unregister_notifier(vgpu->vfio_device.kvm,
@@ -1610,6 +1572,7 @@ static const struct vfio_device_ops intel_vgpu_dev_ops = {
16101572
.write = intel_vgpu_write,
16111573
.mmap = intel_vgpu_mmap,
16121574
.ioctl = intel_vgpu_ioctl,
1575+
.dma_unmap = intel_vgpu_dma_unmap,
16131576
};
16141577

16151578
static int intel_vgpu_probe(struct mdev_device *mdev)

drivers/s390/cio/vfio_ccw_ops.c

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -33,30 +33,16 @@ static int vfio_ccw_mdev_reset(struct vfio_ccw_private *private)
3333
return 0;
3434
}
3535

36-
static int vfio_ccw_mdev_notifier(struct notifier_block *nb,
37-
unsigned long action,
38-
void *data)
36+
static void vfio_ccw_dma_unmap(struct vfio_device *vdev, u64 iova, u64 length)
3937
{
4038
struct vfio_ccw_private *private =
41-
container_of(nb, struct vfio_ccw_private, nb);
42-
43-
/*
44-
* Vendor drivers MUST unpin pages in response to an
45-
* invalidation.
46-
*/
47-
if (action == VFIO_IOMMU_NOTIFY_DMA_UNMAP) {
48-
struct vfio_iommu_type1_dma_unmap *unmap = data;
49-
50-
if (!cp_iova_pinned(&private->cp, unmap->iova))
51-
return NOTIFY_OK;
52-
53-
if (vfio_ccw_mdev_reset(private))
54-
return NOTIFY_BAD;
39+
container_of(vdev, struct vfio_ccw_private, vdev);
5540

56-
return NOTIFY_OK;
57-
}
41+
/* Drivers MUST unpin pages in response to an invalidation. */
42+
if (!cp_iova_pinned(&private->cp, iova))
43+
return;
5844

59-
return NOTIFY_DONE;
45+
vfio_ccw_mdev_reset(private);
6046
}
6147

6248
static ssize_t name_show(struct mdev_type *mtype,
@@ -154,23 +140,15 @@ static int vfio_ccw_mdev_open_device(struct vfio_device *vdev)
154140
{
155141
struct vfio_ccw_private *private =
156142
container_of(vdev, struct vfio_ccw_private, vdev);
157-
unsigned long events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
158143
int ret;
159144

160145
/* Device cannot simply be opened again from this state */
161146
if (private->state == VFIO_CCW_STATE_NOT_OPER)
162147
return -EINVAL;
163148

164-
private->nb.notifier_call = vfio_ccw_mdev_notifier;
165-
166-
ret = vfio_register_notifier(vdev, VFIO_IOMMU_NOTIFY,
167-
&events, &private->nb);
168-
if (ret)
169-
return ret;
170-
171149
ret = vfio_ccw_register_async_dev_regions(private);
172150
if (ret)
173-
goto out_unregister;
151+
return ret;
174152

175153
ret = vfio_ccw_register_schib_dev_regions(private);
176154
if (ret)
@@ -190,7 +168,6 @@ static int vfio_ccw_mdev_open_device(struct vfio_device *vdev)
190168

191169
out_unregister:
192170
vfio_ccw_unregister_dev_regions(private);
193-
vfio_unregister_notifier(vdev, VFIO_IOMMU_NOTIFY, &private->nb);
194171
return ret;
195172
}
196173

@@ -201,7 +178,6 @@ static void vfio_ccw_mdev_close_device(struct vfio_device *vdev)
201178

202179
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_CLOSE);
203180
vfio_ccw_unregister_dev_regions(private);
204-
vfio_unregister_notifier(vdev, VFIO_IOMMU_NOTIFY, &private->nb);
205181
}
206182

207183
static ssize_t vfio_ccw_mdev_read_io_region(struct vfio_ccw_private *private,
@@ -624,6 +600,7 @@ static const struct vfio_device_ops vfio_ccw_dev_ops = {
624600
.write = vfio_ccw_mdev_write,
625601
.ioctl = vfio_ccw_mdev_ioctl,
626602
.request = vfio_ccw_mdev_request,
603+
.dma_unmap = vfio_ccw_dma_unmap,
627604
};
628605

629606
struct mdev_driver vfio_ccw_mdev_driver = {

drivers/s390/cio/vfio_ccw_private.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ struct vfio_ccw_crw {
7373
* @state: internal state of the device
7474
* @completion: synchronization helper of the I/O completion
7575
* @avail: available for creating a mediated device
76-
* @nb: notifier for vfio events
7776
* @io_region: MMIO region to input/output I/O arguments/results
7877
* @io_mutex: protect against concurrent update of I/O regions
7978
* @region: additional regions for other subchannel operations
@@ -96,7 +95,6 @@ struct vfio_ccw_private {
9695
int state;
9796
struct completion *completion;
9897
atomic_t avail;
99-
struct notifier_block nb;
10098
struct ccw_io_region *io_region;
10199
struct mutex io_mutex;
102100
struct vfio_ccw_region *region;

drivers/s390/crypto/vfio_ap_ops.c

Lines changed: 8 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,34 +1226,14 @@ static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,
12261226
return 0;
12271227
}
12281228

1229-
/**
1230-
* vfio_ap_mdev_iommu_notifier - IOMMU notifier callback
1231-
*
1232-
* @nb: The notifier block
1233-
* @action: Action to be taken
1234-
* @data: data associated with the request
1235-
*
1236-
* For an UNMAP request, unpin the guest IOVA (the NIB guest address we
1237-
* pinned before). Other requests are ignored.
1238-
*
1239-
* Return: for an UNMAP request, NOFITY_OK; otherwise NOTIFY_DONE.
1240-
*/
1241-
static int vfio_ap_mdev_iommu_notifier(struct notifier_block *nb,
1242-
unsigned long action, void *data)
1229+
static void vfio_ap_mdev_dma_unmap(struct vfio_device *vdev, u64 iova,
1230+
u64 length)
12431231
{
1244-
struct ap_matrix_mdev *matrix_mdev;
1245-
1246-
matrix_mdev = container_of(nb, struct ap_matrix_mdev, iommu_notifier);
1247-
1248-
if (action == VFIO_IOMMU_NOTIFY_DMA_UNMAP) {
1249-
struct vfio_iommu_type1_dma_unmap *unmap = data;
1250-
unsigned long g_pfn = unmap->iova >> PAGE_SHIFT;
1251-
1252-
vfio_unpin_pages(&matrix_mdev->vdev, &g_pfn, 1);
1253-
return NOTIFY_OK;
1254-
}
1232+
struct ap_matrix_mdev *matrix_mdev =
1233+
container_of(vdev, struct ap_matrix_mdev, vdev);
1234+
unsigned long g_pfn = iova >> PAGE_SHIFT;
12551235

1256-
return NOTIFY_DONE;
1236+
vfio_unpin_pages(&matrix_mdev->vdev, &g_pfn, 1);
12571237
}
12581238

12591239
/**
@@ -1380,36 +1360,18 @@ static int vfio_ap_mdev_open_device(struct vfio_device *vdev)
13801360
{
13811361
struct ap_matrix_mdev *matrix_mdev =
13821362
container_of(vdev, struct ap_matrix_mdev, vdev);
1383-
unsigned long events;
1384-
int ret;
13851363

13861364
if (!vdev->kvm)
13871365
return -EINVAL;
13881366

1389-
ret = vfio_ap_mdev_set_kvm(matrix_mdev, vdev->kvm);
1390-
if (ret)
1391-
return ret;
1392-
1393-
matrix_mdev->iommu_notifier.notifier_call = vfio_ap_mdev_iommu_notifier;
1394-
events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
1395-
ret = vfio_register_notifier(vdev, VFIO_IOMMU_NOTIFY, &events,
1396-
&matrix_mdev->iommu_notifier);
1397-
if (ret)
1398-
goto err_kvm;
1399-
return 0;
1400-
1401-
err_kvm:
1402-
vfio_ap_mdev_unset_kvm(matrix_mdev);
1403-
return ret;
1367+
return vfio_ap_mdev_set_kvm(matrix_mdev, vdev->kvm);
14041368
}
14051369

14061370
static void vfio_ap_mdev_close_device(struct vfio_device *vdev)
14071371
{
14081372
struct ap_matrix_mdev *matrix_mdev =
14091373
container_of(vdev, struct ap_matrix_mdev, vdev);
14101374

1411-
vfio_unregister_notifier(vdev, VFIO_IOMMU_NOTIFY,
1412-
&matrix_mdev->iommu_notifier);
14131375
vfio_ap_mdev_unset_kvm(matrix_mdev);
14141376
}
14151377

@@ -1461,6 +1423,7 @@ static const struct vfio_device_ops vfio_ap_matrix_dev_ops = {
14611423
.open_device = vfio_ap_mdev_open_device,
14621424
.close_device = vfio_ap_mdev_close_device,
14631425
.ioctl = vfio_ap_mdev_ioctl,
1426+
.dma_unmap = vfio_ap_mdev_dma_unmap,
14641427
};
14651428

14661429
static struct mdev_driver vfio_ap_matrix_driver = {

drivers/s390/crypto/vfio_ap_private.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,6 @@ struct ap_matrix {
8181
* @node: allows the ap_matrix_mdev struct to be added to a list
8282
* @matrix: the adapters, usage domains and control domains assigned to the
8383
* mediated matrix device.
84-
* @iommu_notifier: notifier block used for specifying callback function for
85-
* handling the VFIO_IOMMU_NOTIFY_DMA_UNMAP even
8684
* @kvm: the struct holding guest's state
8785
* @pqap_hook: the function pointer to the interception handler for the
8886
* PQAP(AQIC) instruction.
@@ -92,7 +90,6 @@ struct ap_matrix_mdev {
9290
struct vfio_device vdev;
9391
struct list_head node;
9492
struct ap_matrix matrix;
95-
struct notifier_block iommu_notifier;
9693
struct kvm *kvm;
9794
crypto_hook pqap_hook;
9895
struct mdev_device *mdev;

0 commit comments

Comments
 (0)