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
222280static void vfio_pci_region_get (struct vfio_pci_device * device , int index ,
0 commit comments