1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved |
4 | * |
5 | * Copyright (C) 2012 Red Hat, Inc. All rights reserved. |
6 | * Author: Alex Williamson <alex.williamson@redhat.com> |
7 | * |
8 | * Derived from original vfio: |
9 | * Copyright 2010 Cisco Systems, Inc. All rights reserved. |
10 | * Author: Tom Lyon, pugs@cisco.com |
11 | */ |
12 | |
13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
14 | |
15 | #include <linux/device.h> |
16 | #include <linux/eventfd.h> |
17 | #include <linux/file.h> |
18 | #include <linux/interrupt.h> |
19 | #include <linux/iommu.h> |
20 | #include <linux/module.h> |
21 | #include <linux/mutex.h> |
22 | #include <linux/notifier.h> |
23 | #include <linux/pm_runtime.h> |
24 | #include <linux/slab.h> |
25 | #include <linux/types.h> |
26 | #include <linux/uaccess.h> |
27 | |
28 | #include "vfio_pci_priv.h" |
29 | |
30 | #define DRIVER_AUTHOR "Alex Williamson <alex.williamson@redhat.com>" |
31 | #define DRIVER_DESC "VFIO PCI - User Level meta-driver" |
32 | |
33 | static char ids[1024] __initdata; |
34 | module_param_string(ids, ids, sizeof(ids), 0); |
35 | 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" ); |
36 | |
37 | static bool nointxmask; |
38 | module_param_named(nointxmask, nointxmask, bool, S_IRUGO | S_IWUSR); |
39 | MODULE_PARM_DESC(nointxmask, |
40 | "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." ); |
41 | |
42 | #ifdef CONFIG_VFIO_PCI_VGA |
43 | static bool disable_vga; |
44 | module_param(disable_vga, bool, S_IRUGO); |
45 | MODULE_PARM_DESC(disable_vga, "Disable VGA resource access through vfio-pci" ); |
46 | #endif |
47 | |
48 | static bool disable_idle_d3; |
49 | module_param(disable_idle_d3, bool, S_IRUGO | S_IWUSR); |
50 | MODULE_PARM_DESC(disable_idle_d3, |
51 | "Disable using the PCI D3 low power state for idle, unused devices" ); |
52 | |
53 | static bool enable_sriov; |
54 | #ifdef CONFIG_PCI_IOV |
55 | module_param(enable_sriov, bool, 0644); |
56 | 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." ); |
57 | #endif |
58 | |
59 | static bool disable_denylist; |
60 | module_param(disable_denylist, bool, 0444); |
61 | 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." ); |
62 | |
63 | static bool vfio_pci_dev_in_denylist(struct pci_dev *pdev) |
64 | { |
65 | switch (pdev->vendor) { |
66 | case PCI_VENDOR_ID_INTEL: |
67 | switch (pdev->device) { |
68 | case PCI_DEVICE_ID_INTEL_QAT_C3XXX: |
69 | case PCI_DEVICE_ID_INTEL_QAT_C3XXX_VF: |
70 | case PCI_DEVICE_ID_INTEL_QAT_C62X: |
71 | case PCI_DEVICE_ID_INTEL_QAT_C62X_VF: |
72 | case PCI_DEVICE_ID_INTEL_QAT_DH895XCC: |
73 | case PCI_DEVICE_ID_INTEL_QAT_DH895XCC_VF: |
74 | return true; |
75 | default: |
76 | return false; |
77 | } |
78 | } |
79 | |
80 | return false; |
81 | } |
82 | |
83 | static bool vfio_pci_is_denylisted(struct pci_dev *pdev) |
84 | { |
85 | if (!vfio_pci_dev_in_denylist(pdev)) |
86 | return false; |
87 | |
88 | if (disable_denylist) { |
89 | pci_warn(pdev, |
90 | "device denylist disabled - allowing device %04x:%04x.\n" , |
91 | pdev->vendor, pdev->device); |
92 | return false; |
93 | } |
94 | |
95 | pci_warn(pdev, "%04x:%04x exists in vfio-pci device denylist, driver probing disallowed.\n" , |
96 | pdev->vendor, pdev->device); |
97 | |
98 | return true; |
99 | } |
100 | |
101 | static int vfio_pci_open_device(struct vfio_device *core_vdev) |
102 | { |
103 | struct vfio_pci_core_device *vdev = |
104 | container_of(core_vdev, struct vfio_pci_core_device, vdev); |
105 | struct pci_dev *pdev = vdev->pdev; |
106 | int ret; |
107 | |
108 | ret = vfio_pci_core_enable(vdev); |
109 | if (ret) |
110 | return ret; |
111 | |
112 | if (vfio_pci_is_vga(pdev) && |
113 | pdev->vendor == PCI_VENDOR_ID_INTEL && |
114 | IS_ENABLED(CONFIG_VFIO_PCI_IGD)) { |
115 | ret = vfio_pci_igd_init(vdev); |
116 | if (ret && ret != -ENODEV) { |
117 | pci_warn(pdev, "Failed to setup Intel IGD regions\n" ); |
118 | vfio_pci_core_disable(vdev); |
119 | return ret; |
120 | } |
121 | } |
122 | |
123 | vfio_pci_core_finish_enable(vdev); |
124 | |
125 | return 0; |
126 | } |
127 | |
128 | static const struct vfio_device_ops vfio_pci_ops = { |
129 | .name = "vfio-pci" , |
130 | .init = vfio_pci_core_init_dev, |
131 | .release = vfio_pci_core_release_dev, |
132 | .open_device = vfio_pci_open_device, |
133 | .close_device = vfio_pci_core_close_device, |
134 | .ioctl = vfio_pci_core_ioctl, |
135 | .device_feature = vfio_pci_core_ioctl_feature, |
136 | .read = vfio_pci_core_read, |
137 | .write = vfio_pci_core_write, |
138 | .mmap = vfio_pci_core_mmap, |
139 | .request = vfio_pci_core_request, |
140 | .match = vfio_pci_core_match, |
141 | .bind_iommufd = vfio_iommufd_physical_bind, |
142 | .unbind_iommufd = vfio_iommufd_physical_unbind, |
143 | .attach_ioas = vfio_iommufd_physical_attach_ioas, |
144 | .detach_ioas = vfio_iommufd_physical_detach_ioas, |
145 | }; |
146 | |
147 | static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
148 | { |
149 | struct vfio_pci_core_device *vdev; |
150 | int ret; |
151 | |
152 | if (vfio_pci_is_denylisted(pdev)) |
153 | return -EINVAL; |
154 | |
155 | vdev = vfio_alloc_device(vfio_pci_core_device, vdev, &pdev->dev, |
156 | &vfio_pci_ops); |
157 | if (IS_ERR(ptr: vdev)) |
158 | return PTR_ERR(ptr: vdev); |
159 | |
160 | dev_set_drvdata(dev: &pdev->dev, data: vdev); |
161 | ret = vfio_pci_core_register_device(vdev); |
162 | if (ret) |
163 | goto out_put_vdev; |
164 | return 0; |
165 | |
166 | out_put_vdev: |
167 | vfio_put_device(device: &vdev->vdev); |
168 | return ret; |
169 | } |
170 | |
171 | static void vfio_pci_remove(struct pci_dev *pdev) |
172 | { |
173 | struct vfio_pci_core_device *vdev = dev_get_drvdata(dev: &pdev->dev); |
174 | |
175 | vfio_pci_core_unregister_device(vdev); |
176 | vfio_put_device(device: &vdev->vdev); |
177 | } |
178 | |
179 | static int vfio_pci_sriov_configure(struct pci_dev *pdev, int nr_virtfn) |
180 | { |
181 | struct vfio_pci_core_device *vdev = dev_get_drvdata(dev: &pdev->dev); |
182 | |
183 | if (!enable_sriov) |
184 | return -ENOENT; |
185 | |
186 | return vfio_pci_core_sriov_configure(vdev, nr_virtfn); |
187 | } |
188 | |
189 | static const struct pci_device_id vfio_pci_table[] = { |
190 | { PCI_DRIVER_OVERRIDE_DEVICE_VFIO(PCI_ANY_ID, PCI_ANY_ID) }, /* match all by default */ |
191 | {} |
192 | }; |
193 | |
194 | MODULE_DEVICE_TABLE(pci, vfio_pci_table); |
195 | |
196 | static struct pci_driver vfio_pci_driver = { |
197 | .name = "vfio-pci" , |
198 | .id_table = vfio_pci_table, |
199 | .probe = vfio_pci_probe, |
200 | .remove = vfio_pci_remove, |
201 | .sriov_configure = vfio_pci_sriov_configure, |
202 | .err_handler = &vfio_pci_core_err_handlers, |
203 | .driver_managed_dma = true, |
204 | }; |
205 | |
206 | static void __init vfio_pci_fill_ids(void) |
207 | { |
208 | char *p, *id; |
209 | int rc; |
210 | |
211 | /* no ids passed actually */ |
212 | if (ids[0] == '\0') |
213 | return; |
214 | |
215 | /* add ids specified in the module parameter */ |
216 | p = ids; |
217 | while ((id = strsep(&p, "," ))) { |
218 | unsigned int vendor, device, subvendor = PCI_ANY_ID, |
219 | subdevice = PCI_ANY_ID, class = 0, class_mask = 0; |
220 | int fields; |
221 | |
222 | if (!strlen(id)) |
223 | continue; |
224 | |
225 | fields = sscanf(id, "%x:%x:%x:%x:%x:%x" , |
226 | &vendor, &device, &subvendor, &subdevice, |
227 | &class, &class_mask); |
228 | |
229 | if (fields < 2) { |
230 | pr_warn("invalid id string \"%s\"\n" , id); |
231 | continue; |
232 | } |
233 | |
234 | rc = pci_add_dynid(drv: &vfio_pci_driver, vendor, device, |
235 | subvendor, subdevice, class, class_mask, driver_data: 0); |
236 | if (rc) |
237 | pr_warn("failed to add dynamic id [%04x:%04x[%04x:%04x]] class %#08x/%08x (%d)\n" , |
238 | vendor, device, subvendor, subdevice, |
239 | class, class_mask, rc); |
240 | else |
241 | pr_info("add [%04x:%04x[%04x:%04x]] class %#08x/%08x\n" , |
242 | vendor, device, subvendor, subdevice, |
243 | class, class_mask); |
244 | } |
245 | } |
246 | |
247 | static int __init vfio_pci_init(void) |
248 | { |
249 | int ret; |
250 | bool is_disable_vga = true; |
251 | |
252 | #ifdef CONFIG_VFIO_PCI_VGA |
253 | is_disable_vga = disable_vga; |
254 | #endif |
255 | |
256 | vfio_pci_core_set_params(nointxmask, is_disable_vga, is_disable_idle_d3: disable_idle_d3); |
257 | |
258 | /* Register and scan for devices */ |
259 | ret = pci_register_driver(&vfio_pci_driver); |
260 | if (ret) |
261 | return ret; |
262 | |
263 | vfio_pci_fill_ids(); |
264 | |
265 | if (disable_denylist) |
266 | pr_warn("device denylist disabled.\n" ); |
267 | |
268 | return 0; |
269 | } |
270 | module_init(vfio_pci_init); |
271 | |
272 | static void __exit vfio_pci_cleanup(void) |
273 | { |
274 | pci_unregister_driver(dev: &vfio_pci_driver); |
275 | } |
276 | module_exit(vfio_pci_cleanup); |
277 | |
278 | MODULE_LICENSE("GPL v2" ); |
279 | MODULE_AUTHOR(DRIVER_AUTHOR); |
280 | MODULE_DESCRIPTION(DRIVER_DESC); |
281 | |