1ff53edf6SMax Gurtovoy // SPDX-License-Identifier: GPL-2.0-only 2ff53edf6SMax Gurtovoy /* 3ff53edf6SMax Gurtovoy * Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved 4ff53edf6SMax Gurtovoy * 5ff53edf6SMax Gurtovoy * Copyright (C) 2012 Red Hat, Inc. All rights reserved. 6ff53edf6SMax Gurtovoy * Author: Alex Williamson <alex.williamson@redhat.com> 7ff53edf6SMax Gurtovoy * 8ff53edf6SMax Gurtovoy * Derived from original vfio: 9ff53edf6SMax Gurtovoy * Copyright 2010 Cisco Systems, Inc. All rights reserved. 10ff53edf6SMax Gurtovoy * Author: Tom Lyon, pugs@cisco.com 11ff53edf6SMax Gurtovoy */ 12ff53edf6SMax Gurtovoy 13ff53edf6SMax Gurtovoy #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 14ff53edf6SMax Gurtovoy 15ff53edf6SMax Gurtovoy #include <linux/device.h> 16ff53edf6SMax Gurtovoy #include <linux/eventfd.h> 17ff53edf6SMax Gurtovoy #include <linux/file.h> 18ff53edf6SMax Gurtovoy #include <linux/interrupt.h> 19ff53edf6SMax Gurtovoy #include <linux/iommu.h> 20ff53edf6SMax Gurtovoy #include <linux/module.h> 21ff53edf6SMax Gurtovoy #include <linux/mutex.h> 22ff53edf6SMax Gurtovoy #include <linux/notifier.h> 23ff53edf6SMax Gurtovoy #include <linux/pm_runtime.h> 24ff53edf6SMax Gurtovoy #include <linux/slab.h> 25ff53edf6SMax Gurtovoy #include <linux/types.h> 26ff53edf6SMax Gurtovoy #include <linux/uaccess.h> 27ff53edf6SMax Gurtovoy 28e34a0425SJason Gunthorpe #include "vfio_pci_priv.h" 29ff53edf6SMax Gurtovoy 30ff53edf6SMax Gurtovoy #define DRIVER_AUTHOR "Alex Williamson <alex.williamson@redhat.com>" 31ff53edf6SMax Gurtovoy #define DRIVER_DESC "VFIO PCI - User Level meta-driver" 32ff53edf6SMax Gurtovoy 33ff53edf6SMax Gurtovoy static char ids[1024] __initdata; 34ff53edf6SMax Gurtovoy module_param_string(ids, ids, sizeof(ids), 0); 35ff53edf6SMax Gurtovoy MODULE_PARM_DESC(ids, "Initial PCI IDs to add to the vfio driver, format is \"vendor:device[:subvendor[:subdevice[:class[:class_mask]]]]\" and multiple comma separated entries can be specified"); 36ff53edf6SMax Gurtovoy 37c61302aaSYishai Hadas static bool nointxmask; 38c61302aaSYishai Hadas module_param_named(nointxmask, nointxmask, bool, S_IRUGO | S_IWUSR); 39c61302aaSYishai Hadas MODULE_PARM_DESC(nointxmask, 40c61302aaSYishai Hadas "Disable support for PCI 2.3 style INTx masking. If this resolves problems for specific devices, report lspci -vvvxxx to linux-pci@vger.kernel.org so the device can be fixed automatically via the broken_intx_masking flag."); 41c61302aaSYishai Hadas 42c61302aaSYishai Hadas #ifdef CONFIG_VFIO_PCI_VGA 43c61302aaSYishai Hadas static bool disable_vga; 44c61302aaSYishai Hadas module_param(disable_vga, bool, S_IRUGO); 45c61302aaSYishai Hadas MODULE_PARM_DESC(disable_vga, "Disable VGA resource access through vfio-pci"); 46c61302aaSYishai Hadas #endif 47c61302aaSYishai Hadas 48c61302aaSYishai Hadas static bool disable_idle_d3; 49c61302aaSYishai Hadas module_param(disable_idle_d3, bool, S_IRUGO | S_IWUSR); 50c61302aaSYishai Hadas MODULE_PARM_DESC(disable_idle_d3, 51c61302aaSYishai Hadas "Disable using the PCI D3 low power state for idle, unused devices"); 52c61302aaSYishai Hadas 53ff53edf6SMax Gurtovoy static bool enable_sriov; 54ff53edf6SMax Gurtovoy #ifdef CONFIG_PCI_IOV 55ff53edf6SMax Gurtovoy module_param(enable_sriov, bool, 0644); 56ff53edf6SMax Gurtovoy MODULE_PARM_DESC(enable_sriov, "Enable support for SR-IOV configuration. Enabling SR-IOV on a PF typically requires support of the userspace PF driver, enabling VFs without such support may result in non-functional VFs or PF."); 57ff53edf6SMax Gurtovoy #endif 58ff53edf6SMax Gurtovoy 59ff53edf6SMax Gurtovoy static bool disable_denylist; 60ff53edf6SMax Gurtovoy module_param(disable_denylist, bool, 0444); 61ff53edf6SMax Gurtovoy MODULE_PARM_DESC(disable_denylist, "Disable use of device denylist. Disabling the denylist allows binding to devices with known errata that may lead to exploitable stability or security issues when accessed by untrusted users."); 62ff53edf6SMax Gurtovoy 63ff53edf6SMax Gurtovoy static bool vfio_pci_dev_in_denylist(struct pci_dev *pdev) 64ff53edf6SMax Gurtovoy { 65ff53edf6SMax Gurtovoy switch (pdev->vendor) { 66ff53edf6SMax Gurtovoy case PCI_VENDOR_ID_INTEL: 67ff53edf6SMax Gurtovoy switch (pdev->device) { 68ff53edf6SMax Gurtovoy case PCI_DEVICE_ID_INTEL_QAT_C3XXX: 69ff53edf6SMax Gurtovoy case PCI_DEVICE_ID_INTEL_QAT_C3XXX_VF: 70ff53edf6SMax Gurtovoy case PCI_DEVICE_ID_INTEL_QAT_C62X: 71ff53edf6SMax Gurtovoy case PCI_DEVICE_ID_INTEL_QAT_C62X_VF: 72ff53edf6SMax Gurtovoy case PCI_DEVICE_ID_INTEL_QAT_DH895XCC: 73ff53edf6SMax Gurtovoy case PCI_DEVICE_ID_INTEL_QAT_DH895XCC_VF: 74ff53edf6SMax Gurtovoy return true; 75ff53edf6SMax Gurtovoy default: 76ff53edf6SMax Gurtovoy return false; 77ff53edf6SMax Gurtovoy } 78ff53edf6SMax Gurtovoy } 79ff53edf6SMax Gurtovoy 80ff53edf6SMax Gurtovoy return false; 81ff53edf6SMax Gurtovoy } 82ff53edf6SMax Gurtovoy 83ff53edf6SMax Gurtovoy static bool vfio_pci_is_denylisted(struct pci_dev *pdev) 84ff53edf6SMax Gurtovoy { 85ff53edf6SMax Gurtovoy if (!vfio_pci_dev_in_denylist(pdev)) 86ff53edf6SMax Gurtovoy return false; 87ff53edf6SMax Gurtovoy 88ff53edf6SMax Gurtovoy if (disable_denylist) { 89ff53edf6SMax Gurtovoy pci_warn(pdev, 90ff53edf6SMax Gurtovoy "device denylist disabled - allowing device %04x:%04x.\n", 91ff53edf6SMax Gurtovoy pdev->vendor, pdev->device); 92ff53edf6SMax Gurtovoy return false; 93ff53edf6SMax Gurtovoy } 94ff53edf6SMax Gurtovoy 95ff53edf6SMax Gurtovoy pci_warn(pdev, "%04x:%04x exists in vfio-pci device denylist, driver probing disallowed.\n", 96ff53edf6SMax Gurtovoy pdev->vendor, pdev->device); 97ff53edf6SMax Gurtovoy 98ff53edf6SMax Gurtovoy return true; 99ff53edf6SMax Gurtovoy } 100ff53edf6SMax Gurtovoy 1012fb89f56SMax Gurtovoy static int vfio_pci_open_device(struct vfio_device *core_vdev) 1022fb89f56SMax Gurtovoy { 1032fb89f56SMax Gurtovoy struct vfio_pci_core_device *vdev = 1042fb89f56SMax Gurtovoy container_of(core_vdev, struct vfio_pci_core_device, vdev); 1052fb89f56SMax Gurtovoy struct pci_dev *pdev = vdev->pdev; 1062fb89f56SMax Gurtovoy int ret; 1072fb89f56SMax Gurtovoy 1082fb89f56SMax Gurtovoy ret = vfio_pci_core_enable(vdev); 1092fb89f56SMax Gurtovoy if (ret) 1102fb89f56SMax Gurtovoy return ret; 1112fb89f56SMax Gurtovoy 1122fb89f56SMax Gurtovoy if (vfio_pci_is_vga(pdev) && 1132fb89f56SMax Gurtovoy pdev->vendor == PCI_VENDOR_ID_INTEL && 1142fb89f56SMax Gurtovoy IS_ENABLED(CONFIG_VFIO_PCI_IGD)) { 1152fb89f56SMax Gurtovoy ret = vfio_pci_igd_init(vdev); 1162fb89f56SMax Gurtovoy if (ret && ret != -ENODEV) { 1172fb89f56SMax Gurtovoy pci_warn(pdev, "Failed to setup Intel IGD regions\n"); 1182fb89f56SMax Gurtovoy vfio_pci_core_disable(vdev); 1192fb89f56SMax Gurtovoy return ret; 1202fb89f56SMax Gurtovoy } 1212fb89f56SMax Gurtovoy } 1222fb89f56SMax Gurtovoy 1232fb89f56SMax Gurtovoy vfio_pci_core_finish_enable(vdev); 1242fb89f56SMax Gurtovoy 1252fb89f56SMax Gurtovoy return 0; 1262fb89f56SMax Gurtovoy } 1272fb89f56SMax Gurtovoy 128ff53edf6SMax Gurtovoy static const struct vfio_device_ops vfio_pci_ops = { 129ff53edf6SMax Gurtovoy .name = "vfio-pci", 13063d7c779SYi Liu .init = vfio_pci_core_init_dev, 13163d7c779SYi Liu .release = vfio_pci_core_release_dev, 1322fb89f56SMax Gurtovoy .open_device = vfio_pci_open_device, 133ff53edf6SMax Gurtovoy .close_device = vfio_pci_core_close_device, 134ff53edf6SMax Gurtovoy .ioctl = vfio_pci_core_ioctl, 135445ad495SJason Gunthorpe .device_feature = vfio_pci_core_ioctl_feature, 136ff53edf6SMax Gurtovoy .read = vfio_pci_core_read, 137ff53edf6SMax Gurtovoy .write = vfio_pci_core_write, 138ff53edf6SMax Gurtovoy .mmap = vfio_pci_core_mmap, 139ff53edf6SMax Gurtovoy .request = vfio_pci_core_request, 140ff53edf6SMax Gurtovoy .match = vfio_pci_core_match, 141*a4d1f91dSJason Gunthorpe .bind_iommufd = vfio_iommufd_physical_bind, 142*a4d1f91dSJason Gunthorpe .unbind_iommufd = vfio_iommufd_physical_unbind, 143*a4d1f91dSJason Gunthorpe .attach_ioas = vfio_iommufd_physical_attach_ioas, 144ff53edf6SMax Gurtovoy }; 145ff53edf6SMax Gurtovoy 146ff53edf6SMax Gurtovoy static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 147ff53edf6SMax Gurtovoy { 148ff53edf6SMax Gurtovoy struct vfio_pci_core_device *vdev; 149ff53edf6SMax Gurtovoy int ret; 150ff53edf6SMax Gurtovoy 151ff53edf6SMax Gurtovoy if (vfio_pci_is_denylisted(pdev)) 152ff53edf6SMax Gurtovoy return -EINVAL; 153ff53edf6SMax Gurtovoy 15463d7c779SYi Liu vdev = vfio_alloc_device(vfio_pci_core_device, vdev, &pdev->dev, 15563d7c779SYi Liu &vfio_pci_ops); 15663d7c779SYi Liu if (IS_ERR(vdev)) 15763d7c779SYi Liu return PTR_ERR(vdev); 158ff53edf6SMax Gurtovoy 15991be0bd6SJason Gunthorpe dev_set_drvdata(&pdev->dev, vdev); 160ff53edf6SMax Gurtovoy ret = vfio_pci_core_register_device(vdev); 161ff53edf6SMax Gurtovoy if (ret) 16263d7c779SYi Liu goto out_put_vdev; 163ff53edf6SMax Gurtovoy return 0; 164ff53edf6SMax Gurtovoy 16563d7c779SYi Liu out_put_vdev: 16663d7c779SYi Liu vfio_put_device(&vdev->vdev); 167ff53edf6SMax Gurtovoy return ret; 168ff53edf6SMax Gurtovoy } 169ff53edf6SMax Gurtovoy 170ff53edf6SMax Gurtovoy static void vfio_pci_remove(struct pci_dev *pdev) 171ff53edf6SMax Gurtovoy { 172ff53edf6SMax Gurtovoy struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev); 173ff53edf6SMax Gurtovoy 174ff53edf6SMax Gurtovoy vfio_pci_core_unregister_device(vdev); 17563d7c779SYi Liu vfio_put_device(&vdev->vdev); 176ff53edf6SMax Gurtovoy } 177ff53edf6SMax Gurtovoy 178ff53edf6SMax Gurtovoy static int vfio_pci_sriov_configure(struct pci_dev *pdev, int nr_virtfn) 179ff53edf6SMax Gurtovoy { 180ff806cbdSJason Gunthorpe struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev); 181ff806cbdSJason Gunthorpe 182ff53edf6SMax Gurtovoy if (!enable_sriov) 183ff53edf6SMax Gurtovoy return -ENOENT; 184ff53edf6SMax Gurtovoy 185ff806cbdSJason Gunthorpe return vfio_pci_core_sriov_configure(vdev, nr_virtfn); 186ff53edf6SMax Gurtovoy } 187ff53edf6SMax Gurtovoy 188cc6711b0SMax Gurtovoy static const struct pci_device_id vfio_pci_table[] = { 189cc6711b0SMax Gurtovoy { PCI_DRIVER_OVERRIDE_DEVICE_VFIO(PCI_ANY_ID, PCI_ANY_ID) }, /* match all by default */ 190cc6711b0SMax Gurtovoy {} 191cc6711b0SMax Gurtovoy }; 192cc6711b0SMax Gurtovoy 193cc6711b0SMax Gurtovoy MODULE_DEVICE_TABLE(pci, vfio_pci_table); 194cc6711b0SMax Gurtovoy 195ff53edf6SMax Gurtovoy static struct pci_driver vfio_pci_driver = { 196ff53edf6SMax Gurtovoy .name = "vfio-pci", 197cc6711b0SMax Gurtovoy .id_table = vfio_pci_table, 198ff53edf6SMax Gurtovoy .probe = vfio_pci_probe, 199ff53edf6SMax Gurtovoy .remove = vfio_pci_remove, 200ff53edf6SMax Gurtovoy .sriov_configure = vfio_pci_sriov_configure, 201ff53edf6SMax Gurtovoy .err_handler = &vfio_pci_core_err_handlers, 20270693f47SLu Baolu .driver_managed_dma = true, 203ff53edf6SMax Gurtovoy }; 204ff53edf6SMax Gurtovoy 205ff53edf6SMax Gurtovoy static void __init vfio_pci_fill_ids(void) 206ff53edf6SMax Gurtovoy { 207ff53edf6SMax Gurtovoy char *p, *id; 208ff53edf6SMax Gurtovoy int rc; 209ff53edf6SMax Gurtovoy 210ff53edf6SMax Gurtovoy /* no ids passed actually */ 211ff53edf6SMax Gurtovoy if (ids[0] == '\0') 212ff53edf6SMax Gurtovoy return; 213ff53edf6SMax Gurtovoy 214ff53edf6SMax Gurtovoy /* add ids specified in the module parameter */ 215ff53edf6SMax Gurtovoy p = ids; 216ff53edf6SMax Gurtovoy while ((id = strsep(&p, ","))) { 217ff53edf6SMax Gurtovoy unsigned int vendor, device, subvendor = PCI_ANY_ID, 218ff53edf6SMax Gurtovoy subdevice = PCI_ANY_ID, class = 0, class_mask = 0; 219ff53edf6SMax Gurtovoy int fields; 220ff53edf6SMax Gurtovoy 221ff53edf6SMax Gurtovoy if (!strlen(id)) 222ff53edf6SMax Gurtovoy continue; 223ff53edf6SMax Gurtovoy 224ff53edf6SMax Gurtovoy fields = sscanf(id, "%x:%x:%x:%x:%x:%x", 225ff53edf6SMax Gurtovoy &vendor, &device, &subvendor, &subdevice, 226ff53edf6SMax Gurtovoy &class, &class_mask); 227ff53edf6SMax Gurtovoy 228ff53edf6SMax Gurtovoy if (fields < 2) { 229ff53edf6SMax Gurtovoy pr_warn("invalid id string \"%s\"\n", id); 230ff53edf6SMax Gurtovoy continue; 231ff53edf6SMax Gurtovoy } 232ff53edf6SMax Gurtovoy 233ff53edf6SMax Gurtovoy rc = pci_add_dynid(&vfio_pci_driver, vendor, device, 234ff53edf6SMax Gurtovoy subvendor, subdevice, class, class_mask, 0); 235ff53edf6SMax Gurtovoy if (rc) 236ff53edf6SMax Gurtovoy pr_warn("failed to add dynamic id [%04x:%04x[%04x:%04x]] class %#08x/%08x (%d)\n", 237ff53edf6SMax Gurtovoy vendor, device, subvendor, subdevice, 238ff53edf6SMax Gurtovoy class, class_mask, rc); 239ff53edf6SMax Gurtovoy else 240ff53edf6SMax Gurtovoy pr_info("add [%04x:%04x[%04x:%04x]] class %#08x/%08x\n", 241ff53edf6SMax Gurtovoy vendor, device, subvendor, subdevice, 242ff53edf6SMax Gurtovoy class, class_mask); 243ff53edf6SMax Gurtovoy } 244ff53edf6SMax Gurtovoy } 245ff53edf6SMax Gurtovoy 246ff53edf6SMax Gurtovoy static int __init vfio_pci_init(void) 247ff53edf6SMax Gurtovoy { 248ff53edf6SMax Gurtovoy int ret; 249c61302aaSYishai Hadas bool is_disable_vga = true; 250c61302aaSYishai Hadas 251c61302aaSYishai Hadas #ifdef CONFIG_VFIO_PCI_VGA 252c61302aaSYishai Hadas is_disable_vga = disable_vga; 253c61302aaSYishai Hadas #endif 254c61302aaSYishai Hadas 255c61302aaSYishai Hadas vfio_pci_core_set_params(nointxmask, is_disable_vga, disable_idle_d3); 256ff53edf6SMax Gurtovoy 257ff53edf6SMax Gurtovoy /* Register and scan for devices */ 258ff53edf6SMax Gurtovoy ret = pci_register_driver(&vfio_pci_driver); 259ff53edf6SMax Gurtovoy if (ret) 2607fa005caSMax Gurtovoy return ret; 261ff53edf6SMax Gurtovoy 262ff53edf6SMax Gurtovoy vfio_pci_fill_ids(); 263ff53edf6SMax Gurtovoy 264ff53edf6SMax Gurtovoy if (disable_denylist) 265ff53edf6SMax Gurtovoy pr_warn("device denylist disabled.\n"); 266ff53edf6SMax Gurtovoy 267ff53edf6SMax Gurtovoy return 0; 268ff53edf6SMax Gurtovoy } 269ff53edf6SMax Gurtovoy module_init(vfio_pci_init); 270ff53edf6SMax Gurtovoy 271ff53edf6SMax Gurtovoy static void __exit vfio_pci_cleanup(void) 272ff53edf6SMax Gurtovoy { 273ff53edf6SMax Gurtovoy pci_unregister_driver(&vfio_pci_driver); 274ff53edf6SMax Gurtovoy } 275ff53edf6SMax Gurtovoy module_exit(vfio_pci_cleanup); 276ff53edf6SMax Gurtovoy 277ff53edf6SMax Gurtovoy MODULE_LICENSE("GPL v2"); 278ff53edf6SMax Gurtovoy MODULE_AUTHOR(DRIVER_AUTHOR); 279ff53edf6SMax Gurtovoy MODULE_DESCRIPTION(DRIVER_DESC); 280