Skip to content

Commit 16950b6

Browse files
Alex Mastroawilliam
authored andcommitted
vfio: selftests: update DMA map/unmap helpers to support more test kinds
Add __vfio_pci_dma_*() helpers which return -errno from the underlying ioctls. Add __vfio_pci_dma_unmap_all() to test more unmapping code paths. Add an out unmapped arg to report the unmapped byte size. The existing vfio_pci_dma_*() functions, which are intended for happy-path usage (assert on failure) are now thin wrappers on top of the double-underscore helpers. Reviewed-by: David Matlack <[email protected]> Signed-off-by: Alex Mastro <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alex Williamson <[email protected]>
1 parent ef270ec commit 16950b6

File tree

3 files changed

+108
-28
lines changed

3 files changed

+108
-28
lines changed

tools/testing/selftests/vfio/lib/include/vfio_util.h

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,29 @@ struct vfio_pci_device *vfio_pci_device_init(const char *bdf, const char *iommu_
206206
void vfio_pci_device_cleanup(struct vfio_pci_device *device);
207207
void vfio_pci_device_reset(struct vfio_pci_device *device);
208208

209-
void vfio_pci_dma_map(struct vfio_pci_device *device,
210-
struct vfio_dma_region *region);
211-
void vfio_pci_dma_unmap(struct vfio_pci_device *device,
212-
struct vfio_dma_region *region);
209+
int __vfio_pci_dma_map(struct vfio_pci_device *device,
210+
struct vfio_dma_region *region);
211+
int __vfio_pci_dma_unmap(struct vfio_pci_device *device,
212+
struct vfio_dma_region *region,
213+
u64 *unmapped);
214+
int __vfio_pci_dma_unmap_all(struct vfio_pci_device *device, u64 *unmapped);
215+
216+
static inline void vfio_pci_dma_map(struct vfio_pci_device *device,
217+
struct vfio_dma_region *region)
218+
{
219+
VFIO_ASSERT_EQ(__vfio_pci_dma_map(device, region), 0);
220+
}
221+
222+
static inline void vfio_pci_dma_unmap(struct vfio_pci_device *device,
223+
struct vfio_dma_region *region)
224+
{
225+
VFIO_ASSERT_EQ(__vfio_pci_dma_unmap(device, region, NULL), 0);
226+
}
227+
228+
static inline void vfio_pci_dma_unmap_all(struct vfio_pci_device *device)
229+
{
230+
VFIO_ASSERT_EQ(__vfio_pci_dma_unmap_all(device, NULL), 0);
231+
}
213232

214233
void vfio_pci_config_access(struct vfio_pci_device *device, bool write,
215234
size_t config, size_t size, void *data);

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

Lines changed: 81 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <dirent.h>
33
#include <fcntl.h>
44
#include <libgen.h>
5+
#include <stdint.h>
56
#include <stdlib.h>
67
#include <string.h>
78
#include <unistd.h>
@@ -141,7 +142,7 @@ static void vfio_pci_irq_get(struct vfio_pci_device *device, u32 index,
141142
ioctl_assert(device->fd, VFIO_DEVICE_GET_IRQ_INFO, irq_info);
142143
}
143144

144-
static void vfio_iommu_dma_map(struct vfio_pci_device *device,
145+
static int vfio_iommu_dma_map(struct vfio_pci_device *device,
145146
struct vfio_dma_region *region)
146147
{
147148
struct vfio_iommu_type1_dma_map args = {
@@ -152,10 +153,13 @@ static void vfio_iommu_dma_map(struct vfio_pci_device *device,
152153
.size = region->size,
153154
};
154155

155-
ioctl_assert(device->container_fd, VFIO_IOMMU_MAP_DMA, &args);
156+
if (ioctl(device->container_fd, VFIO_IOMMU_MAP_DMA, &args))
157+
return -errno;
158+
159+
return 0;
156160
}
157161

158-
static void iommufd_dma_map(struct vfio_pci_device *device,
162+
static int iommufd_dma_map(struct vfio_pci_device *device,
159163
struct vfio_dma_region *region)
160164
{
161165
struct iommu_ioas_map args = {
@@ -169,54 +173,108 @@ static void iommufd_dma_map(struct vfio_pci_device *device,
169173
.ioas_id = device->ioas_id,
170174
};
171175

172-
ioctl_assert(device->iommufd, IOMMU_IOAS_MAP, &args);
176+
if (ioctl(device->iommufd, IOMMU_IOAS_MAP, &args))
177+
return -errno;
178+
179+
return 0;
173180
}
174181

175-
void vfio_pci_dma_map(struct vfio_pci_device *device,
182+
int __vfio_pci_dma_map(struct vfio_pci_device *device,
176183
struct vfio_dma_region *region)
177184
{
185+
int ret;
186+
178187
if (device->iommufd)
179-
iommufd_dma_map(device, region);
188+
ret = iommufd_dma_map(device, region);
180189
else
181-
vfio_iommu_dma_map(device, region);
190+
ret = vfio_iommu_dma_map(device, region);
191+
192+
if (ret)
193+
return ret;
182194

183195
list_add(&region->link, &device->dma_regions);
196+
197+
return 0;
184198
}
185199

186-
static void vfio_iommu_dma_unmap(struct vfio_pci_device *device,
187-
struct vfio_dma_region *region)
200+
static int vfio_iommu_dma_unmap(int fd, u64 iova, u64 size, u32 flags,
201+
u64 *unmapped)
188202
{
189203
struct vfio_iommu_type1_dma_unmap args = {
190204
.argsz = sizeof(args),
191-
.iova = region->iova,
192-
.size = region->size,
205+
.iova = iova,
206+
.size = size,
207+
.flags = flags,
193208
};
194209

195-
ioctl_assert(device->container_fd, VFIO_IOMMU_UNMAP_DMA, &args);
210+
if (ioctl(fd, VFIO_IOMMU_UNMAP_DMA, &args))
211+
return -errno;
212+
213+
if (unmapped)
214+
*unmapped = args.size;
215+
216+
return 0;
196217
}
197218

198-
static void iommufd_dma_unmap(struct vfio_pci_device *device,
199-
struct vfio_dma_region *region)
219+
static int iommufd_dma_unmap(int fd, u64 iova, u64 length, u32 ioas_id,
220+
u64 *unmapped)
200221
{
201222
struct iommu_ioas_unmap args = {
202223
.size = sizeof(args),
203-
.iova = region->iova,
204-
.length = region->size,
205-
.ioas_id = device->ioas_id,
224+
.iova = iova,
225+
.length = length,
226+
.ioas_id = ioas_id,
206227
};
207228

208-
ioctl_assert(device->iommufd, IOMMU_IOAS_UNMAP, &args);
229+
if (ioctl(fd, IOMMU_IOAS_UNMAP, &args))
230+
return -errno;
231+
232+
if (unmapped)
233+
*unmapped = args.length;
234+
235+
return 0;
209236
}
210237

211-
void vfio_pci_dma_unmap(struct vfio_pci_device *device,
212-
struct vfio_dma_region *region)
238+
int __vfio_pci_dma_unmap(struct vfio_pci_device *device,
239+
struct vfio_dma_region *region, u64 *unmapped)
213240
{
241+
int ret;
242+
243+
if (device->iommufd)
244+
ret = iommufd_dma_unmap(device->iommufd, region->iova,
245+
region->size, device->ioas_id,
246+
unmapped);
247+
else
248+
ret = vfio_iommu_dma_unmap(device->container_fd, region->iova,
249+
region->size, 0, unmapped);
250+
251+
if (ret)
252+
return ret;
253+
254+
list_del_init(&region->link);
255+
256+
return 0;
257+
}
258+
259+
int __vfio_pci_dma_unmap_all(struct vfio_pci_device *device, u64 *unmapped)
260+
{
261+
int ret;
262+
struct vfio_dma_region *curr, *next;
263+
214264
if (device->iommufd)
215-
iommufd_dma_unmap(device, region);
265+
ret = iommufd_dma_unmap(device->iommufd, 0, UINT64_MAX,
266+
device->ioas_id, unmapped);
216267
else
217-
vfio_iommu_dma_unmap(device, region);
268+
ret = vfio_iommu_dma_unmap(device->container_fd, 0, 0,
269+
VFIO_DMA_UNMAP_FLAG_ALL, unmapped);
270+
271+
if (ret)
272+
return ret;
273+
274+
list_for_each_entry_safe(curr, next, &device->dma_regions, link)
275+
list_del_init(&curr->link);
218276

219-
list_del(&region->link);
277+
return 0;
220278
}
221279

222280
static void vfio_pci_region_get(struct vfio_pci_device *device, int index,

tools/testing/selftests/vfio/vfio_dma_mapping_test.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ TEST_F(vfio_dma_mapping_test, dma_map_unmap)
129129
struct vfio_dma_region region;
130130
struct iommu_mapping mapping;
131131
u64 mapping_size = size;
132+
u64 unmapped;
132133
int rc;
133134

134135
region.vaddr = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, -1, 0);
@@ -184,7 +185,9 @@ TEST_F(vfio_dma_mapping_test, dma_map_unmap)
184185
}
185186

186187
unmap:
187-
vfio_pci_dma_unmap(self->device, &region);
188+
rc = __vfio_pci_dma_unmap(self->device, &region, &unmapped);
189+
ASSERT_EQ(rc, 0);
190+
ASSERT_EQ(unmapped, region.size);
188191
printf("Unmapped IOVA 0x%lx\n", region.iova);
189192
ASSERT_EQ(INVALID_IOVA, __to_iova(self->device, region.vaddr));
190193
ASSERT_NE(0, iommu_mapping_get(device_bdf, region.iova, &mapping));

0 commit comments

Comments
 (0)