Skip to content

Commit 1669ecf

Browse files
committed
Merge tag 'vfio-v5.10-rc3' of git://github.com/awilliam/linux-vfio
Pull VFIO fixes from Alex Williamson: - Remove code by using existing helper (Zenghui Yu) - fsl-mc copy-user return and underflow fixes (Dan Carpenter) - fsl-mc static function declaration (Diana Craciun) - Fix ioeventfd sleeping under spinlock (Alex Williamson) - Fix pm reference count leak in vfio-platform (Zhang Qilong) - Allow opening IGD device w/o OpRegion support (Fred Gao) * tag 'vfio-v5.10-rc3' of git://github.com/awilliam/linux-vfio: vfio/pci: Bypass IGD init in case of -ENODEV vfio: platform: fix reference leak in vfio_platform_open vfio/pci: Implement ioeventfd thread handler for contended memory lock vfio/fsl-mc: Make vfio_fsl_mc_irqs_allocate static vfio/fsl-mc: prevent underflow in vfio_fsl_mc_mmap() vfio/fsl-mc: return -EFAULT if copy_to_user() fails vfio/type1: Use the new helper to find vfio_group
2 parents 30f3f68 + e4eccb8 commit 1669ecf

6 files changed

Lines changed: 50 additions & 27 deletions

File tree

drivers/vfio/fsl-mc/vfio_fsl_mc.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,9 @@ static long vfio_fsl_mc_ioctl(void *device_data, unsigned int cmd,
248248
info.size = vdev->regions[info.index].size;
249249
info.flags = vdev->regions[info.index].flags;
250250

251-
return copy_to_user((void __user *)arg, &info, minsz);
251+
if (copy_to_user((void __user *)arg, &info, minsz))
252+
return -EFAULT;
253+
return 0;
252254
}
253255
case VFIO_DEVICE_GET_IRQ_INFO:
254256
{
@@ -267,7 +269,9 @@ static long vfio_fsl_mc_ioctl(void *device_data, unsigned int cmd,
267269
info.flags = VFIO_IRQ_INFO_EVENTFD;
268270
info.count = 1;
269271

270-
return copy_to_user((void __user *)arg, &info, minsz);
272+
if (copy_to_user((void __user *)arg, &info, minsz))
273+
return -EFAULT;
274+
return 0;
271275
}
272276
case VFIO_DEVICE_SET_IRQS:
273277
{
@@ -468,7 +472,7 @@ static int vfio_fsl_mc_mmap(void *device_data, struct vm_area_struct *vma)
468472
{
469473
struct vfio_fsl_mc_device *vdev = device_data;
470474
struct fsl_mc_device *mc_dev = vdev->mc_dev;
471-
int index;
475+
unsigned int index;
472476

473477
index = vma->vm_pgoff >> (VFIO_FSL_MC_OFFSET_SHIFT - PAGE_SHIFT);
474478

drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include "linux/fsl/mc.h"
1414
#include "vfio_fsl_mc_private.h"
1515

16-
int vfio_fsl_mc_irqs_allocate(struct vfio_fsl_mc_device *vdev)
16+
static int vfio_fsl_mc_irqs_allocate(struct vfio_fsl_mc_device *vdev)
1717
{
1818
struct fsl_mc_device *mc_dev = vdev->mc_dev;
1919
struct vfio_fsl_mc_irq *mc_irq;

drivers/vfio/pci/vfio_pci.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev)
385385
pdev->vendor == PCI_VENDOR_ID_INTEL &&
386386
IS_ENABLED(CONFIG_VFIO_PCI_IGD)) {
387387
ret = vfio_pci_igd_init(vdev);
388-
if (ret) {
388+
if (ret && ret != -ENODEV) {
389389
pci_warn(pdev, "Failed to setup Intel IGD regions\n");
390390
goto disable_exit;
391391
}

drivers/vfio/pci/vfio_pci_rdwr.c

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -356,34 +356,60 @@ ssize_t vfio_pci_vga_rw(struct vfio_pci_device *vdev, char __user *buf,
356356
return done;
357357
}
358358

359-
static int vfio_pci_ioeventfd_handler(void *opaque, void *unused)
359+
static void vfio_pci_ioeventfd_do_write(struct vfio_pci_ioeventfd *ioeventfd,
360+
bool test_mem)
360361
{
361-
struct vfio_pci_ioeventfd *ioeventfd = opaque;
362-
363362
switch (ioeventfd->count) {
364363
case 1:
365-
vfio_pci_iowrite8(ioeventfd->vdev, ioeventfd->test_mem,
364+
vfio_pci_iowrite8(ioeventfd->vdev, test_mem,
366365
ioeventfd->data, ioeventfd->addr);
367366
break;
368367
case 2:
369-
vfio_pci_iowrite16(ioeventfd->vdev, ioeventfd->test_mem,
368+
vfio_pci_iowrite16(ioeventfd->vdev, test_mem,
370369
ioeventfd->data, ioeventfd->addr);
371370
break;
372371
case 4:
373-
vfio_pci_iowrite32(ioeventfd->vdev, ioeventfd->test_mem,
372+
vfio_pci_iowrite32(ioeventfd->vdev, test_mem,
374373
ioeventfd->data, ioeventfd->addr);
375374
break;
376375
#ifdef iowrite64
377376
case 8:
378-
vfio_pci_iowrite64(ioeventfd->vdev, ioeventfd->test_mem,
377+
vfio_pci_iowrite64(ioeventfd->vdev, test_mem,
379378
ioeventfd->data, ioeventfd->addr);
380379
break;
381380
#endif
382381
}
382+
}
383+
384+
static int vfio_pci_ioeventfd_handler(void *opaque, void *unused)
385+
{
386+
struct vfio_pci_ioeventfd *ioeventfd = opaque;
387+
struct vfio_pci_device *vdev = ioeventfd->vdev;
388+
389+
if (ioeventfd->test_mem) {
390+
if (!down_read_trylock(&vdev->memory_lock))
391+
return 1; /* Lock contended, use thread */
392+
if (!__vfio_pci_memory_enabled(vdev)) {
393+
up_read(&vdev->memory_lock);
394+
return 0;
395+
}
396+
}
397+
398+
vfio_pci_ioeventfd_do_write(ioeventfd, false);
399+
400+
if (ioeventfd->test_mem)
401+
up_read(&vdev->memory_lock);
383402

384403
return 0;
385404
}
386405

406+
static void vfio_pci_ioeventfd_thread(void *opaque, void *unused)
407+
{
408+
struct vfio_pci_ioeventfd *ioeventfd = opaque;
409+
410+
vfio_pci_ioeventfd_do_write(ioeventfd, ioeventfd->test_mem);
411+
}
412+
387413
long vfio_pci_ioeventfd(struct vfio_pci_device *vdev, loff_t offset,
388414
uint64_t data, int count, int fd)
389415
{
@@ -457,7 +483,8 @@ long vfio_pci_ioeventfd(struct vfio_pci_device *vdev, loff_t offset,
457483
ioeventfd->test_mem = vdev->pdev->resource[bar].flags & IORESOURCE_MEM;
458484

459485
ret = vfio_virqfd_enable(ioeventfd, vfio_pci_ioeventfd_handler,
460-
NULL, NULL, &ioeventfd->virqfd, fd);
486+
vfio_pci_ioeventfd_thread, NULL,
487+
&ioeventfd->virqfd, fd);
461488
if (ret) {
462489
kfree(ioeventfd);
463490
goto out_unlock;

drivers/vfio/platform/vfio_platform_common.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ static int vfio_platform_open(void *device_data)
267267

268268
ret = pm_runtime_get_sync(vdev->device);
269269
if (ret < 0)
270-
goto err_pm;
270+
goto err_rst;
271271

272272
ret = vfio_platform_call_reset(vdev, &extra_dbg);
273273
if (ret && vdev->reset_required) {
@@ -284,7 +284,6 @@ static int vfio_platform_open(void *device_data)
284284

285285
err_rst:
286286
pm_runtime_put(vdev->device);
287-
err_pm:
288287
vfio_platform_irq_cleanup(vdev);
289288
err_irq:
290289
vfio_platform_regions_cleanup(vdev);

drivers/vfio/vfio_iommu_type1.c

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1993,6 +1993,7 @@ static void vfio_iommu_iova_insert_copy(struct vfio_iommu *iommu,
19931993

19941994
list_splice_tail(iova_copy, iova);
19951995
}
1996+
19961997
static int vfio_iommu_type1_attach_group(void *iommu_data,
19971998
struct iommu_group *iommu_group)
19981999
{
@@ -2009,18 +2010,10 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
20092010

20102011
mutex_lock(&iommu->lock);
20112012

2012-
list_for_each_entry(d, &iommu->domain_list, next) {
2013-
if (find_iommu_group(d, iommu_group)) {
2014-
mutex_unlock(&iommu->lock);
2015-
return -EINVAL;
2016-
}
2017-
}
2018-
2019-
if (iommu->external_domain) {
2020-
if (find_iommu_group(iommu->external_domain, iommu_group)) {
2021-
mutex_unlock(&iommu->lock);
2022-
return -EINVAL;
2023-
}
2013+
/* Check for duplicates */
2014+
if (vfio_iommu_find_iommu_group(iommu, iommu_group)) {
2015+
mutex_unlock(&iommu->lock);
2016+
return -EINVAL;
20242017
}
20252018

20262019
group = kzalloc(sizeof(*group), GFP_KERNEL);

0 commit comments

Comments
 (0)