Skip to content

Commit 349bd28

Browse files
committed
Merge tag 'vfio-v6.19-rc4' of https://github.com/awilliam/linux-vfio
Pull VFIO fixes from Alex Williamson: - Restrict ROM access to dword to resolve a regression introduced with qword access seen on some Intel NICs. Update VGA region access to the same given lack of precedent for 64-bit users (Kevin Tian) - Fix missing .get_region_info_caps callback in the xe-vfio-pci variant driver due to integration through the DRM tree (Michal Wajdeczko) - Add aligned 64-bit access macros to tools/include/linux/types.h, allowing removal of uapi/linux/type.h includes from various vfio selftest, resolving redefinition warnings for integration with KVM selftests (David Matlack) - Fix error path memory leak in pds-vfio-pci variant driver (Zilin Guan) - Fix error path use-after-free in xe-vfio-pci variant driver (Alper Ak) * tag 'vfio-v6.19-rc4' of https://github.com/awilliam/linux-vfio: vfio/xe: Fix use-after-free in xe_vfio_pci_alloc_file() vfio/pds: Fix memory leak in pds_vfio_dirty_enable() vfio: selftests: Drop <uapi/linux/types.h> includes tools include: Add definitions for __aligned_{l,b}e64 vfio/xe: Add default handler for .get_region_info_caps vfio/pci: Disable qword access to the VGA region vfio/pci: Disable qword access to the PCI ROM bar
2 parents c8ebd43 + acf44a2 commit 349bd28

12 files changed

Lines changed: 46 additions & 19 deletions

File tree

drivers/vfio/pci/nvgrace-gpu/main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ nvgrace_gpu_map_and_read(struct nvgrace_gpu_pci_core_device *nvdev,
561561
ret = vfio_pci_core_do_io_rw(&nvdev->core_device, false,
562562
nvdev->resmem.ioaddr,
563563
buf, offset, mem_count,
564-
0, 0, false);
564+
0, 0, false, VFIO_PCI_IO_WIDTH_8);
565565
}
566566

567567
return ret;
@@ -693,7 +693,7 @@ nvgrace_gpu_map_and_write(struct nvgrace_gpu_pci_core_device *nvdev,
693693
ret = vfio_pci_core_do_io_rw(&nvdev->core_device, false,
694694
nvdev->resmem.ioaddr,
695695
(char __user *)buf, pos, mem_count,
696-
0, 0, true);
696+
0, 0, true, VFIO_PCI_IO_WIDTH_8);
697697
}
698698

699699
return ret;

drivers/vfio/pci/pds/dirty.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,11 @@ static int pds_vfio_dirty_enable(struct pds_vfio_pci_device *pds_vfio,
292292
len = num_ranges * sizeof(*region_info);
293293

294294
node = interval_tree_iter_first(ranges, 0, ULONG_MAX);
295-
if (!node)
296-
return -EINVAL;
295+
if (!node) {
296+
err = -EINVAL;
297+
goto out_free_region_info;
298+
}
299+
297300
for (int i = 0; i < num_ranges; i++) {
298301
struct pds_lm_dirty_region_info *ri = &region_info[i];
299302
u64 region_size = node->last - node->start + 1;

drivers/vfio/pci/vfio_pci_rdwr.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ VFIO_IORDWR(64)
135135
ssize_t vfio_pci_core_do_io_rw(struct vfio_pci_core_device *vdev, bool test_mem,
136136
void __iomem *io, char __user *buf,
137137
loff_t off, size_t count, size_t x_start,
138-
size_t x_end, bool iswrite)
138+
size_t x_end, bool iswrite,
139+
enum vfio_pci_io_width max_width)
139140
{
140141
ssize_t done = 0;
141142
int ret;
@@ -150,20 +151,19 @@ ssize_t vfio_pci_core_do_io_rw(struct vfio_pci_core_device *vdev, bool test_mem,
150151
else
151152
fillable = 0;
152153

153-
if (fillable >= 8 && !(off % 8)) {
154+
if (fillable >= 8 && !(off % 8) && max_width >= 8) {
154155
ret = vfio_pci_iordwr64(vdev, iswrite, test_mem,
155156
io, buf, off, &filled);
156157
if (ret)
157158
return ret;
158159

159-
} else
160-
if (fillable >= 4 && !(off % 4)) {
160+
} else if (fillable >= 4 && !(off % 4) && max_width >= 4) {
161161
ret = vfio_pci_iordwr32(vdev, iswrite, test_mem,
162162
io, buf, off, &filled);
163163
if (ret)
164164
return ret;
165165

166-
} else if (fillable >= 2 && !(off % 2)) {
166+
} else if (fillable >= 2 && !(off % 2) && max_width >= 2) {
167167
ret = vfio_pci_iordwr16(vdev, iswrite, test_mem,
168168
io, buf, off, &filled);
169169
if (ret)
@@ -234,6 +234,7 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf,
234234
void __iomem *io;
235235
struct resource *res = &vdev->pdev->resource[bar];
236236
ssize_t done;
237+
enum vfio_pci_io_width max_width = VFIO_PCI_IO_WIDTH_8;
237238

238239
if (pci_resource_start(pdev, bar))
239240
end = pci_resource_len(pdev, bar);
@@ -262,6 +263,16 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf,
262263
if (!io)
263264
return -ENOMEM;
264265
x_end = end;
266+
267+
/*
268+
* Certain devices (e.g. Intel X710) don't support qword
269+
* access to the ROM bar. Otherwise PCI AER errors might be
270+
* triggered.
271+
*
272+
* Disable qword access to the ROM bar universally, which
273+
* worked reliably for years before qword access is enabled.
274+
*/
275+
max_width = VFIO_PCI_IO_WIDTH_4;
265276
} else {
266277
int ret = vfio_pci_core_setup_barmap(vdev, bar);
267278
if (ret) {
@@ -278,7 +289,7 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf,
278289
}
279290

280291
done = vfio_pci_core_do_io_rw(vdev, res->flags & IORESOURCE_MEM, io, buf, pos,
281-
count, x_start, x_end, iswrite);
292+
count, x_start, x_end, iswrite, max_width);
282293

283294
if (done >= 0)
284295
*ppos += done;
@@ -352,7 +363,7 @@ ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev, char __user *buf,
352363
* to the memory enable bit in the command register.
353364
*/
354365
done = vfio_pci_core_do_io_rw(vdev, false, iomem, buf, off, count,
355-
0, 0, iswrite);
366+
0, 0, iswrite, VFIO_PCI_IO_WIDTH_4);
356367

357368
vga_put(vdev->pdev, rsrc);
358369

drivers/vfio/pci/xe/main.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ xe_vfio_pci_alloc_file(struct xe_vfio_pci_core_device *xe_vdev,
250250
struct xe_vfio_pci_migration_file *migf;
251251
const struct file_operations *fops;
252252
int flags;
253+
int ret;
253254

254255
migf = kzalloc(sizeof(*migf), GFP_KERNEL_ACCOUNT);
255256
if (!migf)
@@ -259,8 +260,9 @@ xe_vfio_pci_alloc_file(struct xe_vfio_pci_core_device *xe_vdev,
259260
flags = type == XE_VFIO_FILE_SAVE ? O_RDONLY : O_WRONLY;
260261
migf->filp = anon_inode_getfile("xe_vfio_mig", fops, migf, flags);
261262
if (IS_ERR(migf->filp)) {
263+
ret = PTR_ERR(migf->filp);
262264
kfree(migf);
263-
return ERR_CAST(migf->filp);
265+
return ERR_PTR(ret);
264266
}
265267

266268
mutex_init(&migf->lock);
@@ -504,6 +506,7 @@ static const struct vfio_device_ops xe_vfio_pci_ops = {
504506
.open_device = xe_vfio_pci_open_device,
505507
.close_device = xe_vfio_pci_close_device,
506508
.ioctl = vfio_pci_core_ioctl,
509+
.get_region_info_caps = vfio_pci_ioctl_get_region_info,
507510
.device_feature = vfio_pci_core_ioctl_feature,
508511
.read = vfio_pci_core_read,
509512
.write = vfio_pci_core_write,

include/linux/vfio_pci_core.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,13 @@ struct vfio_pci_core_device {
145145
struct list_head dmabufs;
146146
};
147147

148+
enum vfio_pci_io_width {
149+
VFIO_PCI_IO_WIDTH_1 = 1,
150+
VFIO_PCI_IO_WIDTH_2 = 2,
151+
VFIO_PCI_IO_WIDTH_4 = 4,
152+
VFIO_PCI_IO_WIDTH_8 = 8,
153+
};
154+
148155
/* Will be exported for vfio pci drivers usage */
149156
int vfio_pci_core_register_dev_region(struct vfio_pci_core_device *vdev,
150157
unsigned int type, unsigned int subtype,
@@ -188,7 +195,8 @@ pci_ers_result_t vfio_pci_core_aer_err_detected(struct pci_dev *pdev,
188195
ssize_t vfio_pci_core_do_io_rw(struct vfio_pci_core_device *vdev, bool test_mem,
189196
void __iomem *io, char __user *buf,
190197
loff_t off, size_t count, size_t x_start,
191-
size_t x_end, bool iswrite);
198+
size_t x_end, bool iswrite,
199+
enum vfio_pci_io_width max_width);
192200
bool __vfio_pci_memory_enabled(struct vfio_pci_core_device *vdev);
193201
bool vfio_pci_core_range_intersect_range(loff_t buf_start, size_t buf_cnt,
194202
loff_t reg_start, size_t reg_cnt,

tools/include/linux/types.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ typedef struct {
8888
# define __aligned_u64 __u64 __attribute__((aligned(8)))
8989
#endif
9090

91+
#ifndef __aligned_be64
92+
# define __aligned_be64 __be64 __attribute__((aligned(8)))
93+
#endif
94+
95+
#ifndef __aligned_le64
96+
# define __aligned_le64 __le64 __attribute__((aligned(8)))
97+
#endif
98+
9199
struct list_head {
92100
struct list_head *next, *prev;
93101
};

tools/testing/selftests/vfio/lib/include/libvfio/iova_allocator.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#ifndef SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_IOVA_ALLOCATOR_H
33
#define SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_IOVA_ALLOCATOR_H
44

5-
#include <uapi/linux/types.h>
65
#include <linux/list.h>
76
#include <linux/types.h>
87
#include <linux/iommufd.h>

tools/testing/selftests/vfio/lib/iommu.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include <sys/ioctl.h>
1212
#include <sys/mman.h>
1313

14-
#include <uapi/linux/types.h>
1514
#include <linux/limits.h>
1615
#include <linux/mman.h>
1716
#include <linux/types.h>

tools/testing/selftests/vfio/lib/iova_allocator.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include <sys/ioctl.h>
1212
#include <sys/mman.h>
1313

14-
#include <uapi/linux/types.h>
1514
#include <linux/iommufd.h>
1615
#include <linux/limits.h>
1716
#include <linux/mman.h>

tools/testing/selftests/vfio/lib/vfio_pci_device.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include <sys/ioctl.h>
1212
#include <sys/mman.h>
1313

14-
#include <uapi/linux/types.h>
1514
#include <linux/iommufd.h>
1615
#include <linux/limits.h>
1716
#include <linux/mman.h>

0 commit comments

Comments
 (0)