Commit 7fa005ca authored by Max Gurtovoy's avatar Max Gurtovoy Committed by Alex Williamson

vfio/pci: Introduce vfio_pci_core.ko

Now that vfio_pci has been split into two source modules, one focusing on
the "struct pci_driver" (vfio_pci.c) and a toolbox library of code
(vfio_pci_core.c), complete the split and move them into two different
kernel modules.

As before vfio_pci.ko continues to present the same interface under sysfs
and this change will have no functional impact.

Splitting into another module and adding exports allows creating new HW
specific VFIO PCI drivers that can implement device specific
functionality, such as VFIO migration interfaces or specialized device
requirements.
Signed-off-by: default avatarMax Gurtovoy <mgurtovoy@nvidia.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarYishai Hadas <yishaih@nvidia.com>
Link: https://lore.kernel.org/r/20210826103912.128972-14-yishaih@nvidia.comSigned-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
parent 85c94dcf
...@@ -19466,6 +19466,7 @@ T: git git://github.com/awilliam/linux-vfio.git ...@@ -19466,6 +19466,7 @@ T: git git://github.com/awilliam/linux-vfio.git
F: Documentation/driver-api/vfio.rst F: Documentation/driver-api/vfio.rst
F: drivers/vfio/ F: drivers/vfio/
F: include/linux/vfio.h F: include/linux/vfio.h
F: include/linux/vfio_pci_core.h
F: include/uapi/linux/vfio.h F: include/uapi/linux/vfio.h
VFIO FSL-MC DRIVER VFIO FSL-MC DRIVER
......
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
config VFIO_PCI if PCI && MMU
tristate "VFIO support for PCI devices" config VFIO_PCI_CORE
depends on PCI tristate
depends on MMU
select VFIO_VIRQFD select VFIO_VIRQFD
select IRQ_BYPASS_MANAGER select IRQ_BYPASS_MANAGER
config VFIO_PCI_MMAP
def_bool y if !S390
config VFIO_PCI_INTX
def_bool y if !S390
config VFIO_PCI
tristate "Generic VFIO support for any PCI device"
select VFIO_PCI_CORE
help help
Support for the PCI VFIO bus driver. This is required to make Support for the generic PCI VFIO bus driver which can connect any
use of PCI drivers using the VFIO framework. PCI device to the VFIO framework.
If you don't know what to do here, say N. If you don't know what to do here, say N.
if VFIO_PCI if VFIO_PCI
config VFIO_PCI_VGA config VFIO_PCI_VGA
bool "VFIO PCI support for VGA devices" bool "Generic VFIO PCI support for VGA devices"
depends on X86 && VGA_ARB depends on X86 && VGA_ARB
help help
Support for VGA extension to VFIO PCI. This exposes an additional Support for VGA extension to VFIO PCI. This exposes an additional
...@@ -22,14 +31,8 @@ config VFIO_PCI_VGA ...@@ -22,14 +31,8 @@ config VFIO_PCI_VGA
If you don't know what to do here, say N. If you don't know what to do here, say N.
config VFIO_PCI_MMAP
def_bool y if !S390
config VFIO_PCI_INTX
def_bool y if !S390
config VFIO_PCI_IGD config VFIO_PCI_IGD
bool "VFIO PCI extensions for Intel graphics (GVT-d)" bool "Generic VFIO PCI extensions for Intel graphics (GVT-d)"
depends on X86 depends on X86
default y default y
help help
...@@ -39,5 +42,5 @@ config VFIO_PCI_IGD ...@@ -39,5 +42,5 @@ config VFIO_PCI_IGD
and LPC bridge config space. and LPC bridge config space.
To enable Intel IGD assignment through vfio-pci, say Y. To enable Intel IGD assignment through vfio-pci, say Y.
endif
endif endif
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
vfio-pci-y := vfio_pci.o vfio_pci_core.o vfio_pci_intrs.o vfio_pci_rdwr.o vfio_pci_config.o vfio-pci-core-y := vfio_pci_core.o vfio_pci_intrs.o vfio_pci_rdwr.o vfio_pci_config.o
vfio-pci-$(CONFIG_VFIO_PCI_IGD) += vfio_pci_igd.o vfio-pci-core-$(CONFIG_S390) += vfio_pci_zdev.o
vfio-pci-$(CONFIG_S390) += vfio_pci_zdev.o obj-$(CONFIG_VFIO_PCI_CORE) += vfio-pci-core.o
vfio-pci-y := vfio_pci.o
vfio-pci-$(CONFIG_VFIO_PCI_IGD) += vfio_pci_igd.o
obj-$(CONFIG_VFIO_PCI) += vfio-pci.o obj-$(CONFIG_VFIO_PCI) += vfio-pci.o
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include "vfio_pci_core.h" #include <linux/vfio_pci_core.h>
#define DRIVER_AUTHOR "Alex Williamson <alex.williamson@redhat.com>" #define DRIVER_AUTHOR "Alex Williamson <alex.williamson@redhat.com>"
#define DRIVER_DESC "VFIO PCI - User Level meta-driver" #define DRIVER_DESC "VFIO PCI - User Level meta-driver"
...@@ -153,6 +153,7 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -153,6 +153,7 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ret = vfio_pci_core_register_device(vdev); ret = vfio_pci_core_register_device(vdev);
if (ret) if (ret)
goto out_free; goto out_free;
dev_set_drvdata(&pdev->dev, vdev);
return 0; return 0;
out_free: out_free:
...@@ -246,14 +247,10 @@ static int __init vfio_pci_init(void) ...@@ -246,14 +247,10 @@ static int __init vfio_pci_init(void)
vfio_pci_core_set_params(nointxmask, is_disable_vga, disable_idle_d3); vfio_pci_core_set_params(nointxmask, is_disable_vga, disable_idle_d3);
ret = vfio_pci_core_init();
if (ret)
return ret;
/* Register and scan for devices */ /* Register and scan for devices */
ret = pci_register_driver(&vfio_pci_driver); ret = pci_register_driver(&vfio_pci_driver);
if (ret) if (ret)
goto out; return ret;
vfio_pci_fill_ids(); vfio_pci_fill_ids();
...@@ -261,17 +258,12 @@ static int __init vfio_pci_init(void) ...@@ -261,17 +258,12 @@ static int __init vfio_pci_init(void)
pr_warn("device denylist disabled.\n"); pr_warn("device denylist disabled.\n");
return 0; return 0;
out:
vfio_pci_core_cleanup();
return ret;
} }
module_init(vfio_pci_init); module_init(vfio_pci_init);
static void __exit vfio_pci_cleanup(void) static void __exit vfio_pci_cleanup(void)
{ {
pci_unregister_driver(&vfio_pci_driver); pci_unregister_driver(&vfio_pci_driver);
vfio_pci_core_cleanup();
} }
module_exit(vfio_pci_cleanup); module_exit(vfio_pci_cleanup);
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <linux/vfio.h> #include <linux/vfio.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "vfio_pci_core.h" #include <linux/vfio_pci_core.h>
/* Fake capability ID for standard config space */ /* Fake capability ID for standard config space */
#define PCI_CAP_ID_BASIC 0 #define PCI_CAP_ID_BASIC 0
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
* Author: Tom Lyon, pugs@cisco.com * Author: Tom Lyon, pugs@cisco.com
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/device.h> #include <linux/device.h>
#include <linux/eventfd.h> #include <linux/eventfd.h>
#include <linux/file.h> #include <linux/file.h>
...@@ -25,7 +27,10 @@ ...@@ -25,7 +27,10 @@
#include <linux/nospec.h> #include <linux/nospec.h>
#include <linux/sched/mm.h> #include <linux/sched/mm.h>
#include "vfio_pci_core.h" #include <linux/vfio_pci_core.h>
#define DRIVER_AUTHOR "Alex Williamson <alex.williamson@redhat.com>"
#define DRIVER_DESC "core driver for VFIO based PCI devices"
static bool nointxmask; static bool nointxmask;
static bool disable_vga; static bool disable_vga;
...@@ -306,6 +311,7 @@ int vfio_pci_core_enable(struct vfio_pci_core_device *vdev) ...@@ -306,6 +311,7 @@ int vfio_pci_core_enable(struct vfio_pci_core_device *vdev)
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_enable);
void vfio_pci_core_disable(struct vfio_pci_core_device *vdev) void vfio_pci_core_disable(struct vfio_pci_core_device *vdev)
{ {
...@@ -403,6 +409,7 @@ void vfio_pci_core_disable(struct vfio_pci_core_device *vdev) ...@@ -403,6 +409,7 @@ void vfio_pci_core_disable(struct vfio_pci_core_device *vdev)
if (!vfio_pci_dev_set_try_reset(vdev->vdev.dev_set) && !disable_idle_d3) if (!vfio_pci_dev_set_try_reset(vdev->vdev.dev_set) && !disable_idle_d3)
vfio_pci_set_power_state(vdev, PCI_D3hot); vfio_pci_set_power_state(vdev, PCI_D3hot);
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_disable);
static struct vfio_pci_core_device *get_pf_vdev(struct vfio_pci_core_device *vdev) static struct vfio_pci_core_device *get_pf_vdev(struct vfio_pci_core_device *vdev)
{ {
...@@ -459,6 +466,7 @@ void vfio_pci_core_close_device(struct vfio_device *core_vdev) ...@@ -459,6 +466,7 @@ void vfio_pci_core_close_device(struct vfio_device *core_vdev)
} }
mutex_unlock(&vdev->igate); mutex_unlock(&vdev->igate);
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_close_device);
void vfio_pci_core_finish_enable(struct vfio_pci_core_device *vdev) void vfio_pci_core_finish_enable(struct vfio_pci_core_device *vdev)
{ {
...@@ -466,6 +474,7 @@ void vfio_pci_core_finish_enable(struct vfio_pci_core_device *vdev) ...@@ -466,6 +474,7 @@ void vfio_pci_core_finish_enable(struct vfio_pci_core_device *vdev)
vfio_spapr_pci_eeh_open(vdev->pdev); vfio_spapr_pci_eeh_open(vdev->pdev);
vfio_pci_vf_token_user_add(vdev, 1); vfio_pci_vf_token_user_add(vdev, 1);
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_finish_enable);
static int vfio_pci_get_irq_count(struct vfio_pci_core_device *vdev, int irq_type) static int vfio_pci_get_irq_count(struct vfio_pci_core_device *vdev, int irq_type)
{ {
...@@ -624,6 +633,7 @@ int vfio_pci_register_dev_region(struct vfio_pci_core_device *vdev, ...@@ -624,6 +633,7 @@ int vfio_pci_register_dev_region(struct vfio_pci_core_device *vdev,
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(vfio_pci_register_dev_region);
long vfio_pci_core_ioctl(struct vfio_device *core_vdev, unsigned int cmd, long vfio_pci_core_ioctl(struct vfio_device *core_vdev, unsigned int cmd,
unsigned long arg) unsigned long arg)
...@@ -1168,6 +1178,7 @@ long vfio_pci_core_ioctl(struct vfio_device *core_vdev, unsigned int cmd, ...@@ -1168,6 +1178,7 @@ long vfio_pci_core_ioctl(struct vfio_device *core_vdev, unsigned int cmd,
return -ENOTTY; return -ENOTTY;
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_ioctl);
static ssize_t vfio_pci_rw(struct vfio_pci_core_device *vdev, char __user *buf, static ssize_t vfio_pci_rw(struct vfio_pci_core_device *vdev, char __user *buf,
size_t count, loff_t *ppos, bool iswrite) size_t count, loff_t *ppos, bool iswrite)
...@@ -1211,6 +1222,7 @@ ssize_t vfio_pci_core_read(struct vfio_device *core_vdev, char __user *buf, ...@@ -1211,6 +1222,7 @@ ssize_t vfio_pci_core_read(struct vfio_device *core_vdev, char __user *buf,
return vfio_pci_rw(vdev, buf, count, ppos, false); return vfio_pci_rw(vdev, buf, count, ppos, false);
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_read);
ssize_t vfio_pci_core_write(struct vfio_device *core_vdev, const char __user *buf, ssize_t vfio_pci_core_write(struct vfio_device *core_vdev, const char __user *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
...@@ -1223,6 +1235,7 @@ ssize_t vfio_pci_core_write(struct vfio_device *core_vdev, const char __user *bu ...@@ -1223,6 +1235,7 @@ ssize_t vfio_pci_core_write(struct vfio_device *core_vdev, const char __user *bu
return vfio_pci_rw(vdev, (char __user *)buf, count, ppos, true); return vfio_pci_rw(vdev, (char __user *)buf, count, ppos, true);
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_write);
/* Return 1 on zap and vma_lock acquired, 0 on contention (only with @try) */ /* Return 1 on zap and vma_lock acquired, 0 on contention (only with @try) */
static int vfio_pci_zap_and_vma_lock(struct vfio_pci_core_device *vdev, bool try) static int vfio_pci_zap_and_vma_lock(struct vfio_pci_core_device *vdev, bool try)
...@@ -1501,6 +1514,7 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma ...@@ -1501,6 +1514,7 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_mmap);
void vfio_pci_core_request(struct vfio_device *core_vdev, unsigned int count) void vfio_pci_core_request(struct vfio_device *core_vdev, unsigned int count)
{ {
...@@ -1523,6 +1537,7 @@ void vfio_pci_core_request(struct vfio_device *core_vdev, unsigned int count) ...@@ -1523,6 +1537,7 @@ void vfio_pci_core_request(struct vfio_device *core_vdev, unsigned int count)
mutex_unlock(&vdev->igate); mutex_unlock(&vdev->igate);
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_request);
static int vfio_pci_validate_vf_token(struct vfio_pci_core_device *vdev, static int vfio_pci_validate_vf_token(struct vfio_pci_core_device *vdev,
bool vf_token, uuid_t *uuid) bool vf_token, uuid_t *uuid)
...@@ -1667,6 +1682,7 @@ int vfio_pci_core_match(struct vfio_device *core_vdev, char *buf) ...@@ -1667,6 +1682,7 @@ int vfio_pci_core_match(struct vfio_device *core_vdev, char *buf)
return 1; /* Match */ return 1; /* Match */
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_match);
static int vfio_pci_bus_notifier(struct notifier_block *nb, static int vfio_pci_bus_notifier(struct notifier_block *nb,
unsigned long action, void *data) unsigned long action, void *data)
...@@ -1775,6 +1791,7 @@ void vfio_pci_core_init_device(struct vfio_pci_core_device *vdev, ...@@ -1775,6 +1791,7 @@ void vfio_pci_core_init_device(struct vfio_pci_core_device *vdev,
INIT_LIST_HEAD(&vdev->vma_list); INIT_LIST_HEAD(&vdev->vma_list);
init_rwsem(&vdev->memory_lock); init_rwsem(&vdev->memory_lock);
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_init_device);
void vfio_pci_core_uninit_device(struct vfio_pci_core_device *vdev) void vfio_pci_core_uninit_device(struct vfio_pci_core_device *vdev)
{ {
...@@ -1785,6 +1802,7 @@ void vfio_pci_core_uninit_device(struct vfio_pci_core_device *vdev) ...@@ -1785,6 +1802,7 @@ void vfio_pci_core_uninit_device(struct vfio_pci_core_device *vdev)
kfree(vdev->region); kfree(vdev->region);
kfree(vdev->pm_save); kfree(vdev->pm_save);
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_uninit_device);
int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev) int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev)
{ {
...@@ -1852,7 +1870,6 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev) ...@@ -1852,7 +1870,6 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev)
ret = vfio_register_group_dev(&vdev->vdev); ret = vfio_register_group_dev(&vdev->vdev);
if (ret) if (ret)
goto out_power; goto out_power;
dev_set_drvdata(&pdev->dev, vdev);
return 0; return 0;
out_power: out_power:
...@@ -1864,6 +1881,7 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev) ...@@ -1864,6 +1881,7 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev)
vfio_iommu_group_put(group, &pdev->dev); vfio_iommu_group_put(group, &pdev->dev);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_register_device);
void vfio_pci_core_unregister_device(struct vfio_pci_core_device *vdev) void vfio_pci_core_unregister_device(struct vfio_pci_core_device *vdev)
{ {
...@@ -1881,6 +1899,7 @@ void vfio_pci_core_unregister_device(struct vfio_pci_core_device *vdev) ...@@ -1881,6 +1899,7 @@ void vfio_pci_core_unregister_device(struct vfio_pci_core_device *vdev)
if (!disable_idle_d3) if (!disable_idle_d3)
vfio_pci_set_power_state(vdev, PCI_D0); vfio_pci_set_power_state(vdev, PCI_D0);
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_unregister_device);
static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev, static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev,
pci_channel_state_t state) pci_channel_state_t state)
...@@ -1924,10 +1943,12 @@ int vfio_pci_core_sriov_configure(struct pci_dev *pdev, int nr_virtfn) ...@@ -1924,10 +1943,12 @@ int vfio_pci_core_sriov_configure(struct pci_dev *pdev, int nr_virtfn)
return ret < 0 ? ret : nr_virtfn; return ret < 0 ? ret : nr_virtfn;
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_sriov_configure);
const struct pci_error_handlers vfio_pci_core_err_handlers = { const struct pci_error_handlers vfio_pci_core_err_handlers = {
.error_detected = vfio_pci_aer_err_detected, .error_detected = vfio_pci_aer_err_detected,
}; };
EXPORT_SYMBOL_GPL(vfio_pci_core_err_handlers);
static bool vfio_dev_in_groups(struct vfio_pci_core_device *vdev, static bool vfio_dev_in_groups(struct vfio_pci_core_device *vdev,
struct vfio_pci_group_info *groups) struct vfio_pci_group_info *groups)
...@@ -2116,16 +2137,22 @@ void vfio_pci_core_set_params(bool is_nointxmask, bool is_disable_vga, ...@@ -2116,16 +2137,22 @@ void vfio_pci_core_set_params(bool is_nointxmask, bool is_disable_vga,
disable_vga = is_disable_vga; disable_vga = is_disable_vga;
disable_idle_d3 = is_disable_idle_d3; disable_idle_d3 = is_disable_idle_d3;
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_set_params);
/* This will become the __exit function of vfio_pci_core.ko */ static void vfio_pci_core_cleanup(void)
void vfio_pci_core_cleanup(void)
{ {
vfio_pci_uninit_perm_bits(); vfio_pci_uninit_perm_bits();
} }
/* This will become the __init function of vfio_pci_core.ko */ static int __init vfio_pci_core_init(void)
int __init vfio_pci_core_init(void)
{ {
/* Allocate shared config space permission data used by all devices */ /* Allocate shared config space permission data used by all devices */
return vfio_pci_init_perm_bits(); return vfio_pci_init_perm_bits();
} }
module_init(vfio_pci_core_init);
module_exit(vfio_pci_core_cleanup);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/vfio.h> #include <linux/vfio.h>
#include "vfio_pci_core.h" #include <linux/vfio_pci_core.h>
#define OPREGION_SIGNATURE "IntelGraphicsMem" #define OPREGION_SIGNATURE "IntelGraphicsMem"
#define OPREGION_SIZE (8 * 1024) #define OPREGION_SIZE (8 * 1024)
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "vfio_pci_core.h" #include <linux/vfio_pci_core.h>
/* /*
* INTx * INTx
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include <linux/vfio.h> #include <linux/vfio.h>
#include <linux/vgaarb.h> #include <linux/vgaarb.h>
#include "vfio_pci_core.h" #include <linux/vfio_pci_core.h>
#ifdef __LITTLE_ENDIAN #ifdef __LITTLE_ENDIAN
#define vfio_ioread64 ioread64 #define vfio_ioread64 ioread64
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <asm/pci_clp.h> #include <asm/pci_clp.h>
#include <asm/pci_io.h> #include <asm/pci_io.h>
#include "vfio_pci_core.h" #include <linux/vfio_pci_core.h>
/* /*
* Add the Base PCI Function information to the device info region. * Add the Base PCI Function information to the device info region.
......
...@@ -207,8 +207,6 @@ static inline int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev, ...@@ -207,8 +207,6 @@ static inline int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev,
#endif #endif
/* Will be exported for vfio pci drivers usage */ /* Will be exported for vfio pci drivers usage */
void vfio_pci_core_cleanup(void);
int vfio_pci_core_init(void);
void vfio_pci_core_set_params(bool nointxmask, bool is_disable_vga, void vfio_pci_core_set_params(bool nointxmask, bool is_disable_vga,
bool is_disable_idle_d3); bool is_disable_idle_d3);
void vfio_pci_core_close_device(struct vfio_device *core_vdev); void vfio_pci_core_close_device(struct vfio_device *core_vdev);
......
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