mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-09-09 00:07:57 -06:00
vfio: add unmap_all flag to DMA unmap callback
We'll use this parameter shortly; this just adds the plumbing. Signed-off-by: John Levon <john.levon@nutanix.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20250507152020.1254632-9-john.levon@nutanix.com Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
parent
cae04b5634
commit
5a22b50591
5 changed files with 30 additions and 11 deletions
|
@ -85,12 +85,12 @@ int vfio_container_dma_map(VFIOContainerBase *bcontainer,
|
|||
|
||||
int vfio_container_dma_unmap(VFIOContainerBase *bcontainer,
|
||||
hwaddr iova, ram_addr_t size,
|
||||
IOMMUTLBEntry *iotlb)
|
||||
IOMMUTLBEntry *iotlb, bool unmap_all)
|
||||
{
|
||||
VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
|
||||
|
||||
g_assert(vioc->dma_unmap);
|
||||
return vioc->dma_unmap(bcontainer, iova, size, iotlb);
|
||||
return vioc->dma_unmap(bcontainer, iova, size, iotlb, unmap_all);
|
||||
}
|
||||
|
||||
bool vfio_container_add_section_window(VFIOContainerBase *bcontainer,
|
||||
|
|
|
@ -124,7 +124,7 @@ unmap_exit:
|
|||
*/
|
||||
static int vfio_legacy_dma_unmap(const VFIOContainerBase *bcontainer,
|
||||
hwaddr iova, ram_addr_t size,
|
||||
IOMMUTLBEntry *iotlb)
|
||||
IOMMUTLBEntry *iotlb, bool unmap_all)
|
||||
{
|
||||
const VFIOContainer *container = container_of(bcontainer, VFIOContainer,
|
||||
bcontainer);
|
||||
|
@ -138,6 +138,10 @@ static int vfio_legacy_dma_unmap(const VFIOContainerBase *bcontainer,
|
|||
int ret;
|
||||
Error *local_err = NULL;
|
||||
|
||||
if (unmap_all) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (iotlb && vfio_container_dirty_tracking_is_started(bcontainer)) {
|
||||
if (!vfio_container_devices_dirty_tracking_is_supported(bcontainer) &&
|
||||
bcontainer->dirty_pages_supported) {
|
||||
|
@ -205,7 +209,7 @@ static int vfio_legacy_dma_map(const VFIOContainerBase *bcontainer, hwaddr iova,
|
|||
*/
|
||||
if (ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0 ||
|
||||
(errno == EBUSY &&
|
||||
vfio_legacy_dma_unmap(bcontainer, iova, size, NULL) == 0 &&
|
||||
vfio_legacy_dma_unmap(bcontainer, iova, size, NULL, false) == 0 &&
|
||||
ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -46,11 +46,15 @@ static int iommufd_cdev_map(const VFIOContainerBase *bcontainer, hwaddr iova,
|
|||
|
||||
static int iommufd_cdev_unmap(const VFIOContainerBase *bcontainer,
|
||||
hwaddr iova, ram_addr_t size,
|
||||
IOMMUTLBEntry *iotlb)
|
||||
IOMMUTLBEntry *iotlb, bool unmap_all)
|
||||
{
|
||||
const VFIOIOMMUFDContainer *container =
|
||||
container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer);
|
||||
|
||||
if (unmap_all) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/* TODO: Handle dma_unmap_bitmap with iotlb args (migration) */
|
||||
return iommufd_backend_unmap_dma(container->be,
|
||||
container->ioas_id, iova, size);
|
||||
|
|
|
@ -172,7 +172,7 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
|
|||
}
|
||||
} else {
|
||||
ret = vfio_container_dma_unmap(bcontainer, iova,
|
||||
iotlb->addr_mask + 1, iotlb);
|
||||
iotlb->addr_mask + 1, iotlb, false);
|
||||
if (ret) {
|
||||
error_setg(&local_err,
|
||||
"vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", "
|
||||
|
@ -201,7 +201,7 @@ static void vfio_ram_discard_notify_discard(RamDiscardListener *rdl,
|
|||
int ret;
|
||||
|
||||
/* Unmap with a single call. */
|
||||
ret = vfio_container_dma_unmap(bcontainer, iova, size , NULL);
|
||||
ret = vfio_container_dma_unmap(bcontainer, iova, size , NULL, false);
|
||||
if (ret) {
|
||||
error_report("%s: vfio_container_dma_unmap() failed: %s", __func__,
|
||||
strerror(-ret));
|
||||
|
@ -638,7 +638,7 @@ static void vfio_listener_region_del(MemoryListener *listener,
|
|||
/* The unmap ioctl doesn't accept a full 64-bit span. */
|
||||
llsize = int128_rshift(llsize, 1);
|
||||
ret = vfio_container_dma_unmap(bcontainer, iova,
|
||||
int128_get64(llsize), NULL);
|
||||
int128_get64(llsize), NULL, false);
|
||||
if (ret) {
|
||||
error_report("vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", "
|
||||
"0x%"HWADDR_PRIx") = %d (%s)",
|
||||
|
@ -648,7 +648,7 @@ static void vfio_listener_region_del(MemoryListener *listener,
|
|||
iova += int128_get64(llsize);
|
||||
}
|
||||
ret = vfio_container_dma_unmap(bcontainer, iova,
|
||||
int128_get64(llsize), NULL);
|
||||
int128_get64(llsize), NULL, false);
|
||||
if (ret) {
|
||||
error_report("vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", "
|
||||
"0x%"HWADDR_PRIx") = %d (%s)",
|
||||
|
|
|
@ -81,7 +81,7 @@ int vfio_container_dma_map(VFIOContainerBase *bcontainer,
|
|||
void *vaddr, bool readonly);
|
||||
int vfio_container_dma_unmap(VFIOContainerBase *bcontainer,
|
||||
hwaddr iova, ram_addr_t size,
|
||||
IOMMUTLBEntry *iotlb);
|
||||
IOMMUTLBEntry *iotlb, bool unmap_all);
|
||||
bool vfio_container_add_section_window(VFIOContainerBase *bcontainer,
|
||||
MemoryRegionSection *section,
|
||||
Error **errp);
|
||||
|
@ -120,9 +120,20 @@ struct VFIOIOMMUClass {
|
|||
int (*dma_map)(const VFIOContainerBase *bcontainer,
|
||||
hwaddr iova, ram_addr_t size,
|
||||
void *vaddr, bool readonly);
|
||||
/**
|
||||
* @dma_unmap
|
||||
*
|
||||
* Unmap an address range from the container.
|
||||
*
|
||||
* @bcontainer: #VFIOContainerBase to use for unmap
|
||||
* @iova: start address to unmap
|
||||
* @size: size of the range to unmap
|
||||
* @iotlb: The IOMMU TLB mapping entry (or NULL)
|
||||
* @unmap_all: if set, unmap the entire address space
|
||||
*/
|
||||
int (*dma_unmap)(const VFIOContainerBase *bcontainer,
|
||||
hwaddr iova, ram_addr_t size,
|
||||
IOMMUTLBEntry *iotlb);
|
||||
IOMMUTLBEntry *iotlb, bool unmap_all);
|
||||
bool (*attach_device)(const char *name, VFIODevice *vbasedev,
|
||||
AddressSpace *as, Error **errp);
|
||||
void (*detach_device)(VFIODevice *vbasedev);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue