37
37
#define vfio_ioread8 ioread8
38
38
#define vfio_iowrite8 iowrite8
39
39
40
+ #define VFIO_IOWRITE (size ) \
41
+ static int vfio_pci_iowrite##size(struct vfio_pci_device *vdev, \
42
+ bool test_mem, u##size val, void __iomem *io) \
43
+ { \
44
+ if (test_mem) { \
45
+ down_read(&vdev->memory_lock); \
46
+ if (!__vfio_pci_memory_enabled(vdev)) { \
47
+ up_read(&vdev->memory_lock); \
48
+ return -EIO; \
49
+ } \
50
+ } \
51
+ \
52
+ vfio_iowrite##size(val, io); \
53
+ \
54
+ if (test_mem) \
55
+ up_read(&vdev->memory_lock); \
56
+ \
57
+ return 0; \
58
+ }
59
+
60
+ VFIO_IOWRITE (8 )
61
+ VFIO_IOWRITE (16 )
62
+ VFIO_IOWRITE (32 )
63
+ #ifdef iowrite64
64
+ VFIO_IOWRITE (64 )
65
+ #endif
66
+
67
+ #define VFIO_IOREAD (size ) \
68
+ static int vfio_pci_ioread##size(struct vfio_pci_device *vdev, \
69
+ bool test_mem, u##size *val, void __iomem *io) \
70
+ { \
71
+ if (test_mem) { \
72
+ down_read(&vdev->memory_lock); \
73
+ if (!__vfio_pci_memory_enabled(vdev)) { \
74
+ up_read(&vdev->memory_lock); \
75
+ return -EIO; \
76
+ } \
77
+ } \
78
+ \
79
+ *val = vfio_ioread##size(io); \
80
+ \
81
+ if (test_mem) \
82
+ up_read(&vdev->memory_lock); \
83
+ \
84
+ return 0; \
85
+ }
86
+
87
+ VFIO_IOREAD (8 )
88
+ VFIO_IOREAD (16 )
89
+ VFIO_IOREAD (32 )
90
+
40
91
/*
41
92
* Read or write from an __iomem region (MMIO or I/O port) with an excluded
42
93
* range which is inaccessible. The excluded range drops writes and fills
43
94
* reads with -1. This is intended for handling MSI-X vector tables and
44
95
* leftover space for ROM BARs.
45
96
*/
46
- static ssize_t do_io_rw (void __iomem * io , char __user * buf ,
97
+ static ssize_t do_io_rw (struct vfio_pci_device * vdev , bool test_mem ,
98
+ void __iomem * io , char __user * buf ,
47
99
loff_t off , size_t count , size_t x_start ,
48
100
size_t x_end , bool iswrite )
49
101
{
50
102
ssize_t done = 0 ;
103
+ int ret ;
51
104
52
105
while (count ) {
53
106
size_t fillable , filled ;
@@ -66,9 +119,15 @@ static ssize_t do_io_rw(void __iomem *io, char __user *buf,
66
119
if (copy_from_user (& val , buf , 4 ))
67
120
return - EFAULT ;
68
121
69
- vfio_iowrite32 (val , io + off );
122
+ ret = vfio_pci_iowrite32 (vdev , test_mem ,
123
+ val , io + off );
124
+ if (ret )
125
+ return ret ;
70
126
} else {
71
- val = vfio_ioread32 (io + off );
127
+ ret = vfio_pci_ioread32 (vdev , test_mem ,
128
+ & val , io + off );
129
+ if (ret )
130
+ return ret ;
72
131
73
132
if (copy_to_user (buf , & val , 4 ))
74
133
return - EFAULT ;
@@ -82,9 +141,15 @@ static ssize_t do_io_rw(void __iomem *io, char __user *buf,
82
141
if (copy_from_user (& val , buf , 2 ))
83
142
return - EFAULT ;
84
143
85
- vfio_iowrite16 (val , io + off );
144
+ ret = vfio_pci_iowrite16 (vdev , test_mem ,
145
+ val , io + off );
146
+ if (ret )
147
+ return ret ;
86
148
} else {
87
- val = vfio_ioread16 (io + off );
149
+ ret = vfio_pci_ioread16 (vdev , test_mem ,
150
+ & val , io + off );
151
+ if (ret )
152
+ return ret ;
88
153
89
154
if (copy_to_user (buf , & val , 2 ))
90
155
return - EFAULT ;
@@ -98,9 +163,15 @@ static ssize_t do_io_rw(void __iomem *io, char __user *buf,
98
163
if (copy_from_user (& val , buf , 1 ))
99
164
return - EFAULT ;
100
165
101
- vfio_iowrite8 (val , io + off );
166
+ ret = vfio_pci_iowrite8 (vdev , test_mem ,
167
+ val , io + off );
168
+ if (ret )
169
+ return ret ;
102
170
} else {
103
- val = vfio_ioread8 (io + off );
171
+ ret = vfio_pci_ioread8 (vdev , test_mem ,
172
+ & val , io + off );
173
+ if (ret )
174
+ return ret ;
104
175
105
176
if (copy_to_user (buf , & val , 1 ))
106
177
return - EFAULT ;
@@ -178,14 +249,6 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_device *vdev, char __user *buf,
178
249
179
250
count = min (count , (size_t )(end - pos ));
180
251
181
- if (res -> flags & IORESOURCE_MEM ) {
182
- down_read (& vdev -> memory_lock );
183
- if (!__vfio_pci_memory_enabled (vdev )) {
184
- up_read (& vdev -> memory_lock );
185
- return - EIO ;
186
- }
187
- }
188
-
189
252
if (bar == PCI_ROM_RESOURCE ) {
190
253
/*
191
254
* The ROM can fill less space than the BAR, so we start the
@@ -213,17 +276,15 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_device *vdev, char __user *buf,
213
276
x_end = vdev -> msix_offset + vdev -> msix_size ;
214
277
}
215
278
216
- done = do_io_rw (io , buf , pos , count , x_start , x_end , iswrite );
279
+ done = do_io_rw (vdev , res -> flags & IORESOURCE_MEM , io , buf , pos ,
280
+ count , x_start , x_end , iswrite );
217
281
218
282
if (done >= 0 )
219
283
* ppos += done ;
220
284
221
285
if (bar == PCI_ROM_RESOURCE )
222
286
pci_unmap_rom (pdev , io );
223
287
out :
224
- if (res -> flags & IORESOURCE_MEM )
225
- up_read (& vdev -> memory_lock );
226
-
227
288
return done ;
228
289
}
229
290
@@ -278,7 +339,12 @@ ssize_t vfio_pci_vga_rw(struct vfio_pci_device *vdev, char __user *buf,
278
339
return ret ;
279
340
}
280
341
281
- done = do_io_rw (iomem , buf , off , count , 0 , 0 , iswrite );
342
+ /*
343
+ * VGA MMIO is a legacy, non-BAR resource that hopefully allows
344
+ * probing, so we don't currently worry about access in relation
345
+ * to the memory enable bit in the command register.
346
+ */
347
+ done = do_io_rw (vdev , false, iomem , buf , off , count , 0 , 0 , iswrite );
282
348
283
349
vga_put (vdev -> pdev , rsrc );
284
350
@@ -296,17 +362,21 @@ static int vfio_pci_ioeventfd_handler(void *opaque, void *unused)
296
362
297
363
switch (ioeventfd -> count ) {
298
364
case 1 :
299
- vfio_iowrite8 (ioeventfd -> data , ioeventfd -> addr );
365
+ vfio_pci_iowrite8 (ioeventfd -> vdev , ioeventfd -> test_mem ,
366
+ ioeventfd -> data , ioeventfd -> addr );
300
367
break ;
301
368
case 2 :
302
- vfio_iowrite16 (ioeventfd -> data , ioeventfd -> addr );
369
+ vfio_pci_iowrite16 (ioeventfd -> vdev , ioeventfd -> test_mem ,
370
+ ioeventfd -> data , ioeventfd -> addr );
303
371
break ;
304
372
case 4 :
305
- vfio_iowrite32 (ioeventfd -> data , ioeventfd -> addr );
373
+ vfio_pci_iowrite32 (ioeventfd -> vdev , ioeventfd -> test_mem ,
374
+ ioeventfd -> data , ioeventfd -> addr );
306
375
break ;
307
376
#ifdef iowrite64
308
377
case 8 :
309
- vfio_iowrite64 (ioeventfd -> data , ioeventfd -> addr );
378
+ vfio_pci_iowrite64 (ioeventfd -> vdev , ioeventfd -> test_mem ,
379
+ ioeventfd -> data , ioeventfd -> addr );
310
380
break ;
311
381
#endif
312
382
}
@@ -378,11 +448,13 @@ long vfio_pci_ioeventfd(struct vfio_pci_device *vdev, loff_t offset,
378
448
goto out_unlock ;
379
449
}
380
450
451
+ ioeventfd -> vdev = vdev ;
381
452
ioeventfd -> addr = vdev -> barmap [bar ] + pos ;
382
453
ioeventfd -> data = data ;
383
454
ioeventfd -> pos = pos ;
384
455
ioeventfd -> bar = bar ;
385
456
ioeventfd -> count = count ;
457
+ ioeventfd -> test_mem = vdev -> pdev -> resource [bar ].flags & IORESOURCE_MEM ;
386
458
387
459
ret = vfio_virqfd_enable (ioeventfd , vfio_pci_ioeventfd_handler ,
388
460
NULL , NULL , & ioeventfd -> virqfd , fd );
0 commit comments