Commit b25f62cc authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'vfio-v6.5-rc1' of https://github.com/awilliam/linux-vfio

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
parents 9070577a ff598081
......@@ -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
......
......@@ -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"
......@@ -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/
# 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.
# 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
// 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");
/* 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 */
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
......@@ -8,3 +10,5 @@ config VFIO_FSL_MC
fsl-mc bus devices using the VFIO framework.
If you don't know what to do here, say N.
endmenu
......@@ -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;
......@@ -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);
}
......
# SPDX-License-Identifier: GPL-2.0-only
if PCI && MMU
menu "VFIO support for PCI devices"
depends on PCI && MMU
config VFIO_PCI_CORE
tristate
select VFIO_VIRQFD
......@@ -7,9 +9,11 @@ config VFIO_PCI_CORE
config VFIO_PCI_MMAP
def_bool y if !S390
depends on VFIO_PCI_CORE
config VFIO_PCI_INTX
def_bool y if !S390
depends on VFIO_PCI_CORE
config VFIO_PCI
tristate "Generic VFIO support for any PCI device"
......@@ -59,4 +63,4 @@ source "drivers/vfio/pci/mlx5/Kconfig"
source "drivers/vfio/pci/hisilicon/Kconfig"
endif
endmenu
# SPDX-License-Identifier: GPL-2.0-only
config HISI_ACC_VFIO_PCI
tristate "VFIO PCI support for HiSilicon ACC devices"
tristate "VFIO support for HiSilicon ACC PCI devices"
depends on ARM64 || (COMPILE_TEST && 64BIT)
depends on VFIO_PCI_CORE
depends on PCI_MSI
depends on CRYPTO_DEV_HISI_QM
depends on CRYPTO_DEV_HISI_HPRE
depends on CRYPTO_DEV_HISI_SEC2
depends on CRYPTO_DEV_HISI_ZIP
select VFIO_PCI_CORE
help
This provides generic PCI support for HiSilicon ACC devices
using the VFIO framework.
......
......@@ -2,7 +2,7 @@
config MLX5_VFIO_PCI
tristate "VFIO support for MLX5 PCI devices"
depends on MLX5_CORE
depends on VFIO_PCI_CORE
select VFIO_PCI_CORE
help
This provides migration support for MLX5 devices using the VFIO
framework.
......
......@@ -1566,8 +1566,8 @@ static int vfio_cap_init(struct vfio_pci_core_device *vdev)
}
if (!len) {
pci_info(pdev, "%s: hiding cap %#x@%#x\n", __func__,
cap, pos);
pci_dbg(pdev, "%s: hiding cap %#x@%#x\n", __func__,
cap, pos);
*prev = next;
pos = next;
continue;
......@@ -1643,8 +1643,8 @@ static int vfio_ecap_init(struct vfio_pci_core_device *vdev)
}
if (!len) {
pci_info(pdev, "%s: hiding ecap %#x@%#x\n",
__func__, ecap, epos);
pci_dbg(pdev, "%s: hiding ecap %#x@%#x\n",
__func__, ecap, epos);
/* If not the first in the chain, we can skip over it */
if (prev) {
......
......@@ -530,8 +530,11 @@ int vfio_pci_core_enable(struct vfio_pci_core_device *vdev)
vdev->msix_bar = table & PCI_MSIX_TABLE_BIR;
vdev->msix_offset = table & PCI_MSIX_TABLE_OFFSET;
vdev->msix_size = ((flags & PCI_MSIX_FLAGS_QSIZE) + 1) * 16;
} else
vdev->has_dyn_msix = pci_msix_can_alloc_dyn(pdev);
} else {
vdev->msix_bar = 0xFF;
vdev->has_dyn_msix = false;
}
if (!vfio_vga_disabled() && vfio_pci_is_vga(pdev))
vdev->has_vga = true;
......@@ -882,6 +885,37 @@ int vfio_pci_core_register_dev_region(struct vfio_pci_core_device *vdev,
}
EXPORT_SYMBOL_GPL(vfio_pci_core_register_dev_region);
static int vfio_pci_info_atomic_cap(struct vfio_pci_core_device *vdev,
struct vfio_info_cap *caps)
{
struct vfio_device_info_cap_pci_atomic_comp cap = {
.header.id = VFIO_DEVICE_INFO_CAP_PCI_ATOMIC_COMP,
.header.version = 1
};
struct pci_dev *pdev = pci_physfn(vdev->pdev);
u32 devcap2;
pcie_capability_read_dword(pdev, PCI_EXP_DEVCAP2, &devcap2);
if ((devcap2 & PCI_EXP_DEVCAP2_ATOMIC_COMP32) &&
!pci_enable_atomic_ops_to_root(pdev, PCI_EXP_DEVCAP2_ATOMIC_COMP32))
cap.flags |= VFIO_PCI_ATOMIC_COMP32;
if ((devcap2 & PCI_EXP_DEVCAP2_ATOMIC_COMP64) &&
!pci_enable_atomic_ops_to_root(pdev, PCI_EXP_DEVCAP2_ATOMIC_COMP64))
cap.flags |= VFIO_PCI_ATOMIC_COMP64;
if ((devcap2 & PCI_EXP_DEVCAP2_ATOMIC_COMP128) &&
!pci_enable_atomic_ops_to_root(pdev,
PCI_EXP_DEVCAP2_ATOMIC_COMP128))
cap.flags |= VFIO_PCI_ATOMIC_COMP128;
if (!cap.flags)
return -ENODEV;
return vfio_info_add_capability(caps, &cap.header, sizeof(cap));
}
static int vfio_pci_ioctl_get_info(struct vfio_pci_core_device *vdev,
struct vfio_device_info __user *arg)
{
......@@ -920,6 +954,13 @@ static int vfio_pci_ioctl_get_info(struct vfio_pci_core_device *vdev,
return ret;
}
ret = vfio_pci_info_atomic_cap(vdev, &caps);
if (ret && ret != -ENODEV) {
pci_warn(vdev->pdev,
"Failed to setup AtomicOps info capability\n");
return ret;
}
if (caps.size) {
info.flags |= VFIO_DEVICE_FLAGS_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
......@@ -1111,7 +1152,7 @@ static int vfio_pci_ioctl_get_irq_info(struct vfio_pci_core_device *vdev,
if (info.index == VFIO_PCI_INTX_IRQ_INDEX)
info.flags |=
(VFIO_IRQ_INFO_MASKABLE | VFIO_IRQ_INFO_AUTOMASKED);
else
else if (info.index != VFIO_PCI_MSIX_IRQ_INDEX || !vdev->has_dyn_msix)
info.flags |= VFIO_IRQ_INFO_NORESIZE;
return copy_to_user(arg, &info, minsz) ? -EFAULT : 0;
......@@ -2102,6 +2143,7 @@ int vfio_pci_core_init_dev(struct vfio_device *core_vdev)
INIT_LIST_HEAD(&vdev->vma_list);
INIT_LIST_HEAD(&vdev->sriov_pfs_item);
init_rwsem(&vdev->memory_lock);
xa_init(&vdev->ctx);
return 0;
}
......
This diff is collapsed.
# SPDX-License-Identifier: GPL-2.0-only
config VFIO_PLATFORM
tristate "VFIO support for platform devices"
menu "VFIO support for platform devices"
depends on ARM || ARM64 || COMPILE_TEST
config VFIO_PLATFORM_BASE
tristate
select VFIO_VIRQFD
config VFIO_PLATFORM
tristate "Generic VFIO support for any platform device"
select VFIO_PLATFORM_BASE
help
Support for platform devices with VFIO. This is required to make
use of platform devices present on the system using the VFIO
......@@ -10,10 +16,10 @@ config VFIO_PLATFORM
If you don't know what to do here, say N.
if VFIO_PLATFORM
config VFIO_AMBA
tristate "VFIO support for AMBA devices"
depends on ARM_AMBA || COMPILE_TEST
select VFIO_PLATFORM_BASE
help
Support for ARM AMBA devices with VFIO. This is required to make
use of ARM AMBA devices present on the system using the VFIO
......@@ -21,5 +27,9 @@ config VFIO_AMBA
If you don't know what to do here, say N.
menu "VFIO platform reset drivers"
depends on VFIO_PLATFORM_BASE
source "drivers/vfio/platform/reset/Kconfig"
endif
endmenu
endmenu
# SPDX-License-Identifier: GPL-2.0
vfio-platform-base-y := vfio_platform_common.o vfio_platform_irq.o
vfio-platform-y := vfio_platform.o
obj-$(CONFIG_VFIO_PLATFORM_BASE) += vfio-platform-base.o
obj-$(CONFIG_VFIO_PLATFORM_BASE) += reset/
vfio-platform-y := vfio_platform.o
obj-$(CONFIG_VFIO_PLATFORM) += vfio-platform.o
obj-$(CONFIG_VFIO_PLATFORM) += vfio-platform-base.o
obj-$(CONFIG_VFIO_PLATFORM) += reset/
vfio-amba-y := vfio_amba.o
obj-$(CONFIG_VFIO_AMBA) += vfio-amba.o
obj-$(CONFIG_VFIO_AMBA) += vfio-platform-base.o
obj-$(CONFIG_VFIO_AMBA) += reset/
# SPDX-License-Identifier: GPL-2.0-only
if VFIO_PLATFORM
config VFIO_PLATFORM_CALXEDAXGMAC_RESET
tristate "VFIO support for calxeda xgmac reset"
help
......@@ -21,3 +22,4 @@ config VFIO_PLATFORM_BCMFLEXRM_RESET
Enables the VFIO platform driver to handle reset for Broadcom FlexRM
If you don't know what to do here, say N.
endif
......@@ -14,7 +14,6 @@
#include <linux/mod_devicetable.h>
#define MAX_CDX_DEV_RESOURCES 4
#define CDX_ANY_ID (0xFFFF)
#define CDX_CONTROLLER_ID_SHIFT 4
#define CDX_BUS_NUM_MASK 0xF
......
......@@ -912,6 +912,12 @@ struct ishtp_device_id {
kernel_ulong_t driver_data;
};
#define CDX_ANY_ID (0xFFFF)
enum {
CDX_ID_F_VFIO_DRIVER_OVERRIDE = 1,
};
/**
* struct cdx_device_id - CDX device identifier
* @vendor: Vendor ID
......
......@@ -59,8 +59,7 @@ struct vfio_pci_core_device {
struct perm_bits *msi_perm;
spinlock_t irqlock;
struct mutex igate;
struct vfio_pci_irq_ctx *ctx;
int num_ctx;
struct xarray ctx;
int irq_type;
int num_regions;
struct vfio_pci_region *region;
......@@ -69,17 +68,18 @@ struct vfio_pci_core_device {
u16 msix_size;
u32 msix_offset;
u32 rbar[7];
bool pci_2_3;
bool virq_disabled;
bool reset_works;
bool extended_caps;
bool bardirty;
bool has_vga;
bool needs_reset;
bool nointx;
bool needs_pm_restore;
bool pm_intx_masked;
bool pm_runtime_engaged;
bool has_dyn_msix:1;
bool pci_2_3:1;
bool virq_disabled:1;
bool reset_works:1;
bool extended_caps:1;
bool bardirty:1;
bool has_vga:1;
bool needs_reset:1;
bool nointx:1;
bool needs_pm_restore:1;
bool pm_intx_masked:1;
bool pm_runtime_engaged:1;
struct pci_saved_state *pci_saved_state;
struct pci_saved_state *pm_save;
int ioeventfds_nr;
......
......@@ -213,6 +213,7 @@ struct vfio_device_info {
#define VFIO_DEVICE_FLAGS_AP (1 << 5) /* vfio-ap device */
#define VFIO_DEVICE_FLAGS_FSL_MC (1 << 6) /* vfio-fsl-mc device */
#define VFIO_DEVICE_FLAGS_CAPS (1 << 7) /* Info supports caps */
#define VFIO_DEVICE_FLAGS_CDX (1 << 8) /* vfio-cdx device */
__u32 num_regions; /* Max region index + 1 */
__u32 num_irqs; /* Max IRQ index + 1 */
__u32 cap_offset; /* Offset within info struct of first cap */
......@@ -240,6 +241,20 @@ struct vfio_device_info {
#define VFIO_DEVICE_INFO_CAP_ZPCI_UTIL 3
#define VFIO_DEVICE_INFO_CAP_ZPCI_PFIP 4
/*
* The following VFIO_DEVICE_INFO capability reports support for PCIe AtomicOp
* completion to the root bus with supported widths provided via flags.
*/
#define VFIO_DEVICE_INFO_CAP_PCI_ATOMIC_COMP 5
struct vfio_device_info_cap_pci_atomic_comp {
struct vfio_info_cap_header header;
__u32 flags;
#define VFIO_PCI_ATOMIC_COMP32 (1 << 0)
#define VFIO_PCI_ATOMIC_COMP64 (1 << 1)
#define VFIO_PCI_ATOMIC_COMP128 (1 << 2)
__u32 reserved;
};
/**
* VFIO_DEVICE_GET_REGION_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 8,
* struct vfio_region_info)
......@@ -511,6 +526,9 @@ struct vfio_region_info_cap_nvlink2_lnkspd {
* then add and unmask vectors, it's up to userspace to make the decision
* whether to allocate the maximum supported number of vectors or tear
* down setup and incrementally increase the vectors as each is enabled.
* Absence of the NORESIZE flag indicates that vectors can be enabled
* and disabled dynamically without impacting other vectors within the
* index.
*/
struct vfio_irq_info {
__u32 argsz;
......
......@@ -265,6 +265,7 @@ int main(void)
DEVID(cdx_device_id);
DEVID_FIELD(cdx_device_id, vendor);
DEVID_FIELD(cdx_device_id, device);
DEVID_FIELD(cdx_device_id, override_only);
return 0;
}
......@@ -1458,8 +1458,23 @@ static int do_cdx_entry(const char *filename, void *symval,
{
DEF_FIELD(symval, cdx_device_id, vendor);
DEF_FIELD(symval, cdx_device_id, device);
DEF_FIELD(symval, cdx_device_id, override_only);
sprintf(alias, "cdx:v%08Xd%08Xd", vendor, device);
switch (override_only) {
case 0:
strcpy(alias, "cdx:");
break;
case CDX_ID_F_VFIO_DRIVER_OVERRIDE:
strcpy(alias, "vfio_cdx:");
break;
default:
warn("Unknown CDX driver_override alias %08X\n",
override_only);
return 0;
}
ADD(alias, "v", vendor != CDX_ANY_ID, vendor);
ADD(alias, "d", device != CDX_ANY_ID, device);
return 1;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment