mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
vfio/container: Support unmap all in one ioctl()
VFIO type1 kernel uAPI supports unmapping whole address space in one call
since commit c19650995374 ("vfio/type1: implement unmap all"). Use the
unmap_all variant whenever it's supported in kernel.
Opportunistically pass VFIOLegacyContainer pointer in low level function
vfio_legacy_dma_unmap_one().
Co-developed-by: John Levon <levon@movementarian.org>
Signed-off-by: John Levon <levon@movementarian.org>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Link: https://lore.kernel.org/qemu-devel/20251009040134.334251-2-zhenzhong.duan@intel.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
committed by
Cédric Le Goater
parent
725ec89803
commit
962bcf0911
+21
-15
@@ -121,14 +121,14 @@ unmap_exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vfio_legacy_dma_unmap_one(const VFIOContainer *bcontainer,
|
||||
static int vfio_legacy_dma_unmap_one(const VFIOLegacyContainer *container,
|
||||
hwaddr iova, uint64_t size,
|
||||
IOMMUTLBEntry *iotlb)
|
||||
uint32_t flags, IOMMUTLBEntry *iotlb)
|
||||
{
|
||||
const VFIOLegacyContainer *container = VFIO_IOMMU_LEGACY(bcontainer);
|
||||
const VFIOContainer *bcontainer = VFIO_IOMMU(container);
|
||||
struct vfio_iommu_type1_dma_unmap unmap = {
|
||||
.argsz = sizeof(unmap),
|
||||
.flags = 0,
|
||||
.flags = flags,
|
||||
.iova = iova,
|
||||
.size = size,
|
||||
};
|
||||
@@ -170,25 +170,28 @@ static int vfio_legacy_dma_unmap(const VFIOContainer *bcontainer,
|
||||
hwaddr iova, uint64_t size,
|
||||
IOMMUTLBEntry *iotlb, bool unmap_all)
|
||||
{
|
||||
const VFIOLegacyContainer *container = VFIO_IOMMU_LEGACY(bcontainer);
|
||||
uint32_t flags = 0;
|
||||
int ret;
|
||||
|
||||
if (unmap_all) {
|
||||
/* The unmap ioctl doesn't accept a full 64-bit span. */
|
||||
Int128 llsize = int128_rshift(int128_2_64(), 1);
|
||||
if (container->unmap_all_supported) {
|
||||
flags = VFIO_DMA_UNMAP_FLAG_ALL;
|
||||
} else {
|
||||
/* The unmap ioctl doesn't accept a full 64-bit span. */
|
||||
Int128 llsize = int128_rshift(int128_2_64(), 1);
|
||||
size = int128_get64(llsize);
|
||||
|
||||
ret = vfio_legacy_dma_unmap_one(bcontainer, 0, int128_get64(llsize),
|
||||
iotlb);
|
||||
ret = vfio_legacy_dma_unmap_one(container, 0, size, flags, iotlb);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = vfio_legacy_dma_unmap_one(bcontainer, int128_get64(llsize),
|
||||
int128_get64(llsize), iotlb);
|
||||
iova = size;
|
||||
}
|
||||
|
||||
} else {
|
||||
ret = vfio_legacy_dma_unmap_one(bcontainer, iova, size, iotlb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return vfio_legacy_dma_unmap_one(container, iova, size, flags, iotlb);
|
||||
}
|
||||
|
||||
static int vfio_legacy_dma_map(const VFIOContainer *bcontainer, hwaddr iova,
|
||||
@@ -519,6 +522,9 @@ static bool vfio_legacy_setup(VFIOContainer *bcontainer, Error **errp)
|
||||
|
||||
vfio_get_info_iova_range(info, bcontainer);
|
||||
|
||||
ret = ioctl(container->fd, VFIO_CHECK_EXTENSION, VFIO_UNMAP_ALL);
|
||||
container->unmap_all_supported = !!ret;
|
||||
|
||||
vfio_get_iommu_info_migration(container, info);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ struct VFIOLegacyContainer {
|
||||
|
||||
int fd; /* /dev/vfio/vfio, empowered by the attached groups */
|
||||
unsigned iommu_type;
|
||||
bool unmap_all_supported;
|
||||
QLIST_HEAD(, VFIOGroup) group_list;
|
||||
VFIOContainerCPR cpr;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user