Skip to content

Commit a9cf69d

Browse files
committed
Merge tag 'vfio-v6.0-rc1' of https://github.com/awilliam/linux-vfio
Pull VFIO updates from Alex Williamson: - Cleanup use of extern in function prototypes (Alex Williamson) - Simplify bus_type usage and convert to device IOMMU interfaces (Robin Murphy) - Check missed return value and fix comment typos (Bo Liu) - Split migration ops from device ops and fix races in mlx5 migration support (Yishai Hadas) - Fix missed return value check in noiommu support (Liam Ni) - Hardening to clear buffer pointer to avoid use-after-free (Schspa Shi) - Remove requirement that only the same mm can unmap a previously mapped range (Li Zhe) - Adjust semaphore release vs device open counter (Yi Liu) - Remove unused arg from SPAPR support code (Deming Wang) - Rework vfio-ccw driver to better fit new mdev framework (Eric Farman, Michael Kawano) - Replace DMA unmap notifier with callbacks (Jason Gunthorpe) - Clarify SPAPR support comment relative to iommu_ops (Alexey Kardashevskiy) - Revise page pinning API towards compatibility with future iommufd support (Nicolin Chen) - Resolve issues in vfio-ccw, including use of DMA unmap callback (Eric Farman) * tag 'vfio-v6.0-rc1' of https://github.com/awilliam/linux-vfio: (40 commits) vfio/pci: fix the wrong word vfio/ccw: Check return code from subchannel quiesce vfio/ccw: Remove FSM Close from remove handlers vfio/ccw: Add length to DMA_UNMAP checks vfio: Replace phys_pfn with pages for vfio_pin_pages() vfio/ccw: Add kmap_local_page() for memcpy vfio: Rename user_iova of vfio_dma_rw() vfio/ccw: Change pa_pfn list to pa_iova list vfio/ap: Change saved_pfn to saved_iova vfio: Pass in starting IOVA to vfio_pin/unpin_pages API vfio/ccw: Only pass in contiguous pages vfio/ap: Pass in physical address of ind to ap_aqic() drm/i915/gvt: Replace roundup with DIV_ROUND_UP vfio: Make vfio_unpin_pages() return void vfio/spapr_tce: Fix the comment vfio: Replace the iommu notifier with a device list vfio: Replace the DMA unmapping notifier with a callback vfio/ccw: Move FSM open/close to MDEV open/close vfio/ccw: Refactor vfio_ccw_mdev_reset vfio/ccw: Create a CLOSE FSM event ...
2 parents 6614a3c + 099fd2c commit a9cf69d

29 files changed

+659
-768
lines changed

Documentation/driver-api/vfio-mediated-device.rst

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,11 @@ to register and unregister itself with the core driver:
112112

113113
* Register::
114114

115-
extern int mdev_register_driver(struct mdev_driver *drv);
115+
int mdev_register_driver(struct mdev_driver *drv);
116116

117117
* Unregister::
118118

119-
extern void mdev_unregister_driver(struct mdev_driver *drv);
119+
void mdev_unregister_driver(struct mdev_driver *drv);
120120

121121
The mediated bus driver's probe function should create a vfio_device on top of
122122
the mdev_device and connect it to an appropriate implementation of
@@ -125,16 +125,16 @@ vfio_device_ops.
125125
When a driver wants to add the GUID creation sysfs to an existing device it has
126126
probe'd to then it should call::
127127

128-
extern int mdev_register_device(struct device *dev,
129-
struct mdev_driver *mdev_driver);
128+
int mdev_register_device(struct device *dev,
129+
struct mdev_driver *mdev_driver);
130130

131131
This will provide the 'mdev_supported_types/XX/create' files which can then be
132132
used to trigger the creation of a mdev_device. The created mdev_device will be
133133
attached to the specified driver.
134134

135135
When the driver needs to remove itself it calls::
136136

137-
extern void mdev_unregister_device(struct device *dev);
137+
void mdev_unregister_device(struct device *dev);
138138

139139
Which will unbind and destroy all the created mdevs and remove the sysfs files.
140140

@@ -260,10 +260,10 @@ Translation APIs for Mediated Devices
260260
The following APIs are provided for translating user pfn to host pfn in a VFIO
261261
driver::
262262

263-
int vfio_pin_pages(struct vfio_device *device, unsigned long *user_pfn,
264-
int npage, int prot, unsigned long *phys_pfn);
263+
int vfio_pin_pages(struct vfio_device *device, dma_addr_t iova,
264+
int npage, int prot, struct page **pages);
265265

266-
int vfio_unpin_pages(struct vfio_device *device, unsigned long *user_pfn,
266+
void vfio_unpin_pages(struct vfio_device *device, dma_addr_t iova,
267267
int npage);
268268

269269
These functions call back into the back-end IOMMU module by using the pin_pages

arch/s390/include/asm/ap.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,21 +227,21 @@ struct ap_qirq_ctrl {
227227
* ap_aqic(): Control interruption for a specific AP.
228228
* @qid: The AP queue number
229229
* @qirqctrl: struct ap_qirq_ctrl (64 bit value)
230-
* @ind: The notification indicator byte
230+
* @pa_ind: Physical address of the notification indicator byte
231231
*
232232
* Returns AP queue status.
233233
*/
234234
static inline struct ap_queue_status ap_aqic(ap_qid_t qid,
235235
struct ap_qirq_ctrl qirqctrl,
236-
void *ind)
236+
phys_addr_t pa_ind)
237237
{
238238
unsigned long reg0 = qid | (3UL << 24); /* fc 3UL is AQIC */
239239
union {
240240
unsigned long value;
241241
struct ap_qirq_ctrl qirqctrl;
242242
struct ap_queue_status status;
243243
} reg1;
244-
unsigned long reg2 = virt_to_phys(ind);
244+
unsigned long reg2 = pa_ind;
245245

246246
reg1.qirqctrl = qirqctrl;
247247

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: 32 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -231,65 +231,46 @@ static void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt)
231231
static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
232232
unsigned long size)
233233
{
234-
struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
235-
int total_pages;
236-
int npage;
237-
int ret;
238-
239-
total_pages = roundup(size, PAGE_SIZE) / PAGE_SIZE;
240-
241-
for (npage = 0; npage < total_pages; npage++) {
242-
unsigned long cur_gfn = gfn + npage;
243-
244-
ret = vfio_unpin_pages(&vgpu->vfio_device, &cur_gfn, 1);
245-
drm_WARN_ON(&i915->drm, ret != 1);
246-
}
234+
vfio_unpin_pages(&vgpu->vfio_device, gfn << PAGE_SHIFT,
235+
DIV_ROUND_UP(size, PAGE_SIZE));
247236
}
248237

249238
/* Pin a normal or compound guest page for dma. */
250239
static int gvt_pin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
251240
unsigned long size, struct page **page)
252241
{
253-
unsigned long base_pfn = 0;
254-
int total_pages;
242+
int total_pages = DIV_ROUND_UP(size, PAGE_SIZE);
243+
struct page *base_page = NULL;
255244
int npage;
256245
int ret;
257246

258-
total_pages = roundup(size, PAGE_SIZE) / PAGE_SIZE;
259247
/*
260248
* We pin the pages one-by-one to avoid allocating a big arrary
261249
* on stack to hold pfns.
262250
*/
263251
for (npage = 0; npage < total_pages; npage++) {
264-
unsigned long cur_gfn = gfn + npage;
265-
unsigned long pfn;
252+
dma_addr_t cur_iova = (gfn + npage) << PAGE_SHIFT;
253+
struct page *cur_page;
266254

267-
ret = vfio_pin_pages(&vgpu->vfio_device, &cur_gfn, 1,
268-
IOMMU_READ | IOMMU_WRITE, &pfn);
255+
ret = vfio_pin_pages(&vgpu->vfio_device, cur_iova, 1,
256+
IOMMU_READ | IOMMU_WRITE, &cur_page);
269257
if (ret != 1) {
270-
gvt_vgpu_err("vfio_pin_pages failed for gfn 0x%lx, ret %d\n",
271-
cur_gfn, ret);
272-
goto err;
273-
}
274-
275-
if (!pfn_valid(pfn)) {
276-
gvt_vgpu_err("pfn 0x%lx is not mem backed\n", pfn);
277-
npage++;
278-
ret = -EFAULT;
258+
gvt_vgpu_err("vfio_pin_pages failed for iova %pad, ret %d\n",
259+
&cur_iova, ret);
279260
goto err;
280261
}
281262

282263
if (npage == 0)
283-
base_pfn = pfn;
284-
else if (base_pfn + npage != pfn) {
264+
base_page = cur_page;
265+
else if (base_page + npage != cur_page) {
285266
gvt_vgpu_err("The pages are not continuous\n");
286267
ret = -EINVAL;
287268
npage++;
288269
goto err;
289270
}
290271
}
291272

292-
*page = pfn_to_page(base_pfn);
273+
*page = base_page;
293274
return 0;
294275
err:
295276
gvt_unpin_guest_page(vgpu, gfn, npage * PAGE_SIZE);
@@ -729,34 +710,25 @@ int intel_gvt_set_edid(struct intel_vgpu *vgpu, int port_num)
729710
return ret;
730711
}
731712

732-
static int intel_vgpu_iommu_notifier(struct notifier_block *nb,
733-
unsigned long action, void *data)
713+
static void intel_vgpu_dma_unmap(struct vfio_device *vfio_dev, u64 iova,
714+
u64 length)
734715
{
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;
716+
struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
717+
struct gvt_dma *entry;
718+
u64 iov_pfn = iova >> PAGE_SHIFT;
719+
u64 end_iov_pfn = iov_pfn + length / PAGE_SIZE;
742720

743-
iov_pfn = unmap->iova >> PAGE_SHIFT;
744-
end_iov_pfn = iov_pfn + unmap->size / PAGE_SIZE;
721+
mutex_lock(&vgpu->cache_lock);
722+
for (; iov_pfn < end_iov_pfn; iov_pfn++) {
723+
entry = __gvt_cache_find_gfn(vgpu, iov_pfn);
724+
if (!entry)
725+
continue;
745726

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);
727+
gvt_dma_unmap_page(vgpu, entry->gfn, entry->dma_addr,
728+
entry->size);
729+
__gvt_cache_remove_entry(vgpu, entry);
757730
}
758-
759-
return NOTIFY_OK;
731+
mutex_unlock(&vgpu->cache_lock);
760732
}
761733

762734
static bool __kvmgt_vgpu_exist(struct intel_vgpu *vgpu)
@@ -783,36 +755,20 @@ static bool __kvmgt_vgpu_exist(struct intel_vgpu *vgpu)
783755
static int intel_vgpu_open_device(struct vfio_device *vfio_dev)
784756
{
785757
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;
790-
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-
}
799758

800-
ret = -EEXIST;
801759
if (vgpu->attached)
802-
goto undo_iommu;
760+
return -EEXIST;
803761

804-
ret = -ESRCH;
805762
if (!vgpu->vfio_device.kvm ||
806763
vgpu->vfio_device.kvm->mm != current->mm) {
807764
gvt_vgpu_err("KVM is required to use Intel vGPU\n");
808-
goto undo_iommu;
765+
return -ESRCH;
809766
}
810767

811768
kvm_get_kvm(vgpu->vfio_device.kvm);
812769

813-
ret = -EEXIST;
814770
if (__kvmgt_vgpu_exist(vgpu))
815-
goto undo_iommu;
771+
return -EEXIST;
816772

817773
vgpu->attached = true;
818774

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

832788
atomic_set(&vgpu->released, 0);
833789
return 0;
834-
835-
undo_iommu:
836-
vfio_unregister_notifier(vfio_dev, VFIO_IOMMU_NOTIFY,
837-
&vgpu->iommu_notifier);
838-
out:
839-
return ret;
840790
}
841791

842792
static void intel_vgpu_release_msi_eventfd_ctx(struct intel_vgpu *vgpu)
@@ -853,8 +803,6 @@ static void intel_vgpu_release_msi_eventfd_ctx(struct intel_vgpu *vgpu)
853803
static void intel_vgpu_close_device(struct vfio_device *vfio_dev)
854804
{
855805
struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
856-
struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
857-
int ret;
858806

859807
if (!vgpu->attached)
860808
return;
@@ -864,11 +812,6 @@ static void intel_vgpu_close_device(struct vfio_device *vfio_dev)
864812

865813
intel_gvt_release_vgpu(vgpu);
866814

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-
872815
debugfs_remove(debugfs_lookup(KVMGT_DEBUGFS_FILENAME, vgpu->debugfs));
873816

874817
kvm_page_track_unregister_notifier(vgpu->vfio_device.kvm,
@@ -1610,6 +1553,7 @@ static const struct vfio_device_ops intel_vgpu_dev_ops = {
16101553
.write = intel_vgpu_write,
16111554
.mmap = intel_vgpu_mmap,
16121555
.ioctl = intel_vgpu_ioctl,
1556+
.dma_unmap = intel_vgpu_dma_unmap,
16131557
};
16141558

16151559
static int intel_vgpu_probe(struct mdev_device *mdev)

drivers/s390/cio/vfio_ccw_async.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
*/
99

1010
#include <linux/vfio.h>
11-
#include <linux/mdev.h>
1211

1312
#include "vfio_ccw_private.h"
1413

0 commit comments

Comments
 (0)