Skip to content

Commit

Permalink
Merge tag 'vfio-v6.5-rc1' of https://github.com/awilliam/linux-vfio
Browse files Browse the repository at this point in the history
Pull VFIO updates from Alex Williamson:

 - Adjust log levels for common messages (Oleksandr Natalenko, Alex
   Williamson)

 - Support for dynamic MSI-X allocation (Reinette Chatre)

 - Enable and report PCIe AtomicOp Completer capabilities (Alex
   Williamson)

 - Cleanup Kconfigs for vfio bus drivers (Alex Williamson)

 - Add support for CDX bus based devices (Nipun Gupta)

 - Fix race with concurrent mdev initialization (Eric Farman)

* tag 'vfio-v6.5-rc1' of https://github.com/awilliam/linux-vfio:
  vfio/mdev: Move the compat_class initialization to module init
  vfio/cdx: add support for CDX bus
  vfio/fsl: Create Kconfig sub-menu
  vfio/platform: Cleanup Kconfig
  vfio/pci: Cleanup Kconfig
  vfio/pci-core: Add capability for AtomicOp completer support
  vfio/pci: Also demote hiding standard cap messages
  vfio/pci: Clear VFIO_IRQ_INFO_NORESIZE for MSI-X
  vfio/pci: Support dynamic MSI-X
  vfio/pci: Probe and store ability to support dynamic MSI-X
  vfio/pci: Use bitfield for struct vfio_pci_core_device flags
  vfio/pci: Update stale comment
  vfio/pci: Remove interrupt context counter
  vfio/pci: Use xarray for interrupt context storage
  vfio/pci: Move to single error path
  vfio/pci: Prepare for dynamic interrupt context storage
  vfio/pci: Remove negative check on unsigned vector
  vfio/pci: Consolidate irq cleanup on MSI/MSI-X disable
  vfio/pci: demote hiding ecap messages to debug level
  • Loading branch information
Linus Torvalds committed Jun 30, 2023
2 parents 9070577 + ff59808 commit b25f62c
Show file tree
Hide file tree
Showing 24 changed files with 654 additions and 146 deletions.
7 changes: 7 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -22254,6 +22254,13 @@ F: Documentation/filesystems/vfat.rst
F: fs/fat/
F: tools/testing/selftests/filesystems/fat/

VFIO CDX DRIVER
M: Nipun Gupta <nipun.gupta@amd.com>
M: Nikhil Agarwal <nikhil.agarwal@amd.com>
L: kvm@vger.kernel.org
S: Maintained
F: drivers/vfio/cdx/*

VFIO DRIVER
M: Alex Williamson <alex.williamson@redhat.com>
L: kvm@vger.kernel.org
Expand Down
1 change: 1 addition & 0 deletions drivers/vfio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ source "drivers/vfio/pci/Kconfig"
source "drivers/vfio/platform/Kconfig"
source "drivers/vfio/mdev/Kconfig"
source "drivers/vfio/fsl-mc/Kconfig"
source "drivers/vfio/cdx/Kconfig"
endif

source "virt/lib/Kconfig"
5 changes: 3 additions & 2 deletions drivers/vfio/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ vfio-$(CONFIG_VFIO_VIRQFD) += virqfd.o

obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o
obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o
obj-$(CONFIG_VFIO_PCI) += pci/
obj-$(CONFIG_VFIO_PLATFORM) += platform/
obj-$(CONFIG_VFIO_PCI_CORE) += pci/
obj-$(CONFIG_VFIO_PLATFORM_BASE) += platform/
obj-$(CONFIG_VFIO_MDEV) += mdev/
obj-$(CONFIG_VFIO_FSL_MC) += fsl-mc/
obj-$(CONFIG_VFIO_CDX) += cdx/
17 changes: 17 additions & 0 deletions drivers/vfio/cdx/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# SPDX-License-Identifier: GPL-2.0
#
# VFIO CDX configuration
#
# Copyright (C) 2022-2023, Advanced Micro Devices, Inc.
#

config VFIO_CDX
tristate "VFIO support for CDX bus devices"
depends on CDX_BUS
select EVENTFD
help
Driver to enable VFIO support for the devices on CDX bus.
This is required to make use of CDX devices present in
the system using the VFIO framework.

If you don't know what to do here, say N.
8 changes: 8 additions & 0 deletions drivers/vfio/cdx/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2022-2023, Advanced Micro Devices, Inc.
#

obj-$(CONFIG_VFIO_CDX) += vfio-cdx.o

vfio-cdx-objs := main.o
234 changes: 234 additions & 0 deletions drivers/vfio/cdx/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2022-2023, Advanced Micro Devices, Inc.
*/

#include <linux/vfio.h>
#include <linux/cdx/cdx_bus.h>

#include "private.h"

static int vfio_cdx_open_device(struct vfio_device *core_vdev)
{
struct vfio_cdx_device *vdev =
container_of(core_vdev, struct vfio_cdx_device, vdev);
struct cdx_device *cdx_dev = to_cdx_device(core_vdev->dev);
int count = cdx_dev->res_count;
int i;

vdev->regions = kcalloc(count, sizeof(struct vfio_cdx_region),
GFP_KERNEL_ACCOUNT);
if (!vdev->regions)
return -ENOMEM;

for (i = 0; i < count; i++) {
struct resource *res = &cdx_dev->res[i];

vdev->regions[i].addr = res->start;
vdev->regions[i].size = resource_size(res);
vdev->regions[i].type = res->flags;
/*
* Only regions addressed with PAGE granularity may be
* MMAP'ed securely.
*/
if (!(vdev->regions[i].addr & ~PAGE_MASK) &&
!(vdev->regions[i].size & ~PAGE_MASK))
vdev->regions[i].flags |=
VFIO_REGION_INFO_FLAG_MMAP;
vdev->regions[i].flags |= VFIO_REGION_INFO_FLAG_READ;
if (!(cdx_dev->res[i].flags & IORESOURCE_READONLY))
vdev->regions[i].flags |= VFIO_REGION_INFO_FLAG_WRITE;
}

return 0;
}

static void vfio_cdx_close_device(struct vfio_device *core_vdev)
{
struct vfio_cdx_device *vdev =
container_of(core_vdev, struct vfio_cdx_device, vdev);

kfree(vdev->regions);
cdx_dev_reset(core_vdev->dev);
}

static int vfio_cdx_ioctl_get_info(struct vfio_cdx_device *vdev,
struct vfio_device_info __user *arg)
{
unsigned long minsz = offsetofend(struct vfio_device_info, num_irqs);
struct cdx_device *cdx_dev = to_cdx_device(vdev->vdev.dev);
struct vfio_device_info info;

if (copy_from_user(&info, arg, minsz))
return -EFAULT;

if (info.argsz < minsz)
return -EINVAL;

info.flags = VFIO_DEVICE_FLAGS_CDX;
info.flags |= VFIO_DEVICE_FLAGS_RESET;

info.num_regions = cdx_dev->res_count;
info.num_irqs = 0;

return copy_to_user(arg, &info, minsz) ? -EFAULT : 0;
}

static int vfio_cdx_ioctl_get_region_info(struct vfio_cdx_device *vdev,
struct vfio_region_info __user *arg)
{
unsigned long minsz = offsetofend(struct vfio_region_info, offset);
struct cdx_device *cdx_dev = to_cdx_device(vdev->vdev.dev);
struct vfio_region_info info;

if (copy_from_user(&info, arg, minsz))
return -EFAULT;

if (info.argsz < minsz)
return -EINVAL;

if (info.index >= cdx_dev->res_count)
return -EINVAL;

/* map offset to the physical address */
info.offset = vfio_cdx_index_to_offset(info.index);
info.size = vdev->regions[info.index].size;
info.flags = vdev->regions[info.index].flags;

return copy_to_user(arg, &info, minsz) ? -EFAULT : 0;
}

static long vfio_cdx_ioctl(struct vfio_device *core_vdev,
unsigned int cmd, unsigned long arg)
{
struct vfio_cdx_device *vdev =
container_of(core_vdev, struct vfio_cdx_device, vdev);
void __user *uarg = (void __user *)arg;

switch (cmd) {
case VFIO_DEVICE_GET_INFO:
return vfio_cdx_ioctl_get_info(vdev, uarg);
case VFIO_DEVICE_GET_REGION_INFO:
return vfio_cdx_ioctl_get_region_info(vdev, uarg);
case VFIO_DEVICE_RESET:
return cdx_dev_reset(core_vdev->dev);
default:
return -ENOTTY;
}
}

static int vfio_cdx_mmap_mmio(struct vfio_cdx_region region,
struct vm_area_struct *vma)
{
u64 size = vma->vm_end - vma->vm_start;
u64 pgoff, base;

pgoff = vma->vm_pgoff &
((1U << (VFIO_CDX_OFFSET_SHIFT - PAGE_SHIFT)) - 1);
base = pgoff << PAGE_SHIFT;

if (base + size > region.size)
return -EINVAL;

vma->vm_pgoff = (region.addr >> PAGE_SHIFT) + pgoff;
vma->vm_page_prot = pgprot_device(vma->vm_page_prot);

return io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
size, vma->vm_page_prot);
}

static int vfio_cdx_mmap(struct vfio_device *core_vdev,
struct vm_area_struct *vma)
{
struct vfio_cdx_device *vdev =
container_of(core_vdev, struct vfio_cdx_device, vdev);
struct cdx_device *cdx_dev = to_cdx_device(core_vdev->dev);
unsigned int index;

index = vma->vm_pgoff >> (VFIO_CDX_OFFSET_SHIFT - PAGE_SHIFT);

if (index >= cdx_dev->res_count)
return -EINVAL;

if (!(vdev->regions[index].flags & VFIO_REGION_INFO_FLAG_MMAP))
return -EINVAL;

if (!(vdev->regions[index].flags & VFIO_REGION_INFO_FLAG_READ) &&
(vma->vm_flags & VM_READ))
return -EPERM;

if (!(vdev->regions[index].flags & VFIO_REGION_INFO_FLAG_WRITE) &&
(vma->vm_flags & VM_WRITE))
return -EPERM;

return vfio_cdx_mmap_mmio(vdev->regions[index], vma);
}

static const struct vfio_device_ops vfio_cdx_ops = {
.name = "vfio-cdx",
.open_device = vfio_cdx_open_device,
.close_device = vfio_cdx_close_device,
.ioctl = vfio_cdx_ioctl,
.mmap = vfio_cdx_mmap,
.bind_iommufd = vfio_iommufd_physical_bind,
.unbind_iommufd = vfio_iommufd_physical_unbind,
.attach_ioas = vfio_iommufd_physical_attach_ioas,
};

static int vfio_cdx_probe(struct cdx_device *cdx_dev)
{
struct vfio_cdx_device *vdev;
struct device *dev = &cdx_dev->dev;
int ret;

vdev = vfio_alloc_device(vfio_cdx_device, vdev, dev,
&vfio_cdx_ops);
if (IS_ERR(vdev))
return PTR_ERR(vdev);

ret = vfio_register_group_dev(&vdev->vdev);
if (ret)
goto out_uninit;

dev_set_drvdata(dev, vdev);
return 0;

out_uninit:
vfio_put_device(&vdev->vdev);
return ret;
}

static int vfio_cdx_remove(struct cdx_device *cdx_dev)
{
struct device *dev = &cdx_dev->dev;
struct vfio_cdx_device *vdev = dev_get_drvdata(dev);

vfio_unregister_group_dev(&vdev->vdev);
vfio_put_device(&vdev->vdev);

return 0;
}

static const struct cdx_device_id vfio_cdx_table[] = {
{ CDX_DEVICE_DRIVER_OVERRIDE(CDX_ANY_ID, CDX_ANY_ID,
CDX_ID_F_VFIO_DRIVER_OVERRIDE) }, /* match all by default */
{}
};

MODULE_DEVICE_TABLE(cdx, vfio_cdx_table);

static struct cdx_driver vfio_cdx_driver = {
.probe = vfio_cdx_probe,
.remove = vfio_cdx_remove,
.match_id_table = vfio_cdx_table,
.driver = {
.name = "vfio-cdx",
.owner = THIS_MODULE,
},
.driver_managed_dma = true,
};

module_driver(vfio_cdx_driver, cdx_driver_register, cdx_driver_unregister);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("VFIO for CDX devices - User Level meta-driver");
28 changes: 28 additions & 0 deletions drivers/vfio/cdx/private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2022-2023, Advanced Micro Devices, Inc.
*/

#ifndef VFIO_CDX_PRIVATE_H
#define VFIO_CDX_PRIVATE_H

#define VFIO_CDX_OFFSET_SHIFT 40

static inline u64 vfio_cdx_index_to_offset(u32 index)
{
return ((u64)(index) << VFIO_CDX_OFFSET_SHIFT);
}

struct vfio_cdx_region {
u32 flags;
u32 type;
u64 addr;
resource_size_t size;
};

struct vfio_cdx_device {
struct vfio_device vdev;
struct vfio_cdx_region *regions;
};

#endif /* VFIO_CDX_PRIVATE_H */
6 changes: 5 additions & 1 deletion drivers/vfio/fsl-mc/Kconfig
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
menu "VFIO support for FSL_MC bus devices"
depends on FSL_MC_BUS

config VFIO_FSL_MC
tristate "VFIO support for QorIQ DPAA2 fsl-mc bus devices"
depends on FSL_MC_BUS
select EVENTFD
help
Driver to enable support for the VFIO QorIQ DPAA2 fsl-mc
(Management Complex) devices. This is required to passthrough
fsl-mc bus devices using the VFIO framework.

If you don't know what to do here, say N.

endmenu
23 changes: 14 additions & 9 deletions drivers/vfio/mdev/mdev_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,6 @@ int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
parent->nr_types = nr_types;
atomic_set(&parent->available_instances, mdev_driver->max_instances);

if (!mdev_bus_compat_class) {
mdev_bus_compat_class = class_compat_register("mdev_bus");
if (!mdev_bus_compat_class)
return -ENOMEM;
}

ret = parent_create_sysfs_files(parent);
if (ret)
return ret;
Expand Down Expand Up @@ -251,13 +245,24 @@ int mdev_device_remove(struct mdev_device *mdev)

static int __init mdev_init(void)
{
return bus_register(&mdev_bus_type);
int ret;

ret = bus_register(&mdev_bus_type);
if (ret)
return ret;

mdev_bus_compat_class = class_compat_register("mdev_bus");
if (!mdev_bus_compat_class) {
bus_unregister(&mdev_bus_type);
return -ENOMEM;
}

return 0;
}

static void __exit mdev_exit(void)
{
if (mdev_bus_compat_class)
class_compat_unregister(mdev_bus_compat_class);
class_compat_unregister(mdev_bus_compat_class);
bus_unregister(&mdev_bus_type);
}

Expand Down
Loading

0 comments on commit b25f62c

Please sign in to comment.