[PATCH] vfio/type1: Cleanup remaining vaddr removal/update fragments

Alex Williamson
2022-12-07T21:46:21Z

Fix several loose ends relative to reverting support for vaddr removal
and update. Mark feature and ioctl flags as deprecated, restore local
variable scope in pin pages, remove remaining support in the mapping
code.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---

This applies on top of Steve's patch[1] to fully remove and deprecate
this feature in the short term, following the same methodology we used
for the v1 migration interface removal. The intention would be to pick
Steve's patch and this follow-on for v6.2 given that existing support
exposes vulnerabilities and no known upstream userspaces make use of
this feature.

[1]https://lore.kernel.org/all/1670363753-249738-2-git-send-email-steven.sistare@oracle.com/

drivers/vfio/vfio_iommu_type1.c | 23 ++++-------------------
include/uapi/linux/vfio.h | 7 ++++---
2 files changed, 8 insertions(+), 22 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 02c6ea3bed69..731d8d4b6524 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -790,7 +790,6 @@ static int vfio_iommu_type1_pin_pages(void *iommu_data,
unsigned long remote_vaddr;
struct vfio_dma *dma;
bool do_accounting;
- dma_addr_t iova;

if (!iommu || !pages)
return -EINVAL;
@@ -815,6 +814,7 @@ static int vfio_iommu_type1_pin_pages(void *iommu_data,
do_accounting = list_empty(&iommu->domain_list);

for (i = 0; i < npage; i++) {
+ dma_addr_t iova;
unsigned long phys_pfn;
struct vfio_pfn *vpfn;

@@ -1467,7 +1467,6 @@ static bool vfio_iommu_iova_dma_valid(struct vfio_iommu *iommu,
static int vfio_dma_do_map(struct vfio_iommu *iommu,
struct vfio_iommu_type1_dma_map *map)
{
- bool set_vaddr = map->flags & VFIO_DMA_MAP_FLAG_VADDR;
dma_addr_t iova = map->iova;
unsigned long vaddr = map->vaddr;
size_t size = map->size;
@@ -1485,16 +1484,13 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,
if (map->flags & VFIO_DMA_MAP_FLAG_READ)
prot |= IOMMU_READ;

- if ((prot && set_vaddr) || (!prot && !set_vaddr))
- return -EINVAL;
-
mutex_lock(&iommu->lock);

pgsize = (size_t)1 << __ffs(iommu->pgsize_bitmap);

WARN_ON((pgsize - 1) & PAGE_MASK);

- if (!size || (size | iova | vaddr) & (pgsize - 1)) {
+ if (!prot || !size || (size | iova | vaddr) & (pgsize - 1)) {
ret = -EINVAL;
goto out_unlock;
}
@@ -1505,17 +1501,7 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,
goto out_unlock;
}

- dma = vfio_find_dma(iommu, iova, size);
- if (set_vaddr) {
- if (!dma) {
- ret = -ENOENT;
- } else if (dma->iova != iova || dma->size != size) {
- ret = -EINVAL;
- } else {
- dma->vaddr = vaddr;
- }
- goto out_unlock;
- } else if (dma) {
+ if (vfio_find_dma(iommu, iova, size)) {
ret = -EEXIST;
goto out_unlock;
}
@@ -2727,8 +2713,7 @@ static int vfio_iommu_type1_map_dma(struct vfio_iommu *iommu,
{
struct vfio_iommu_type1_dma_map map;
unsigned long minsz;
- uint32_t mask = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE |
- VFIO_DMA_MAP_FLAG_VADDR;
+ uint32_t mask = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;

minsz = offsetofend(struct vfio_iommu_type1_dma_map, size);

diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 04d944c8941d..800ca94aafb3 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -49,8 +49,8 @@
/* Supports VFIO_DMA_UNMAP_FLAG_ALL */
#define VFIO_UNMAP_ALL 9

-/* Obsolete, not supported by any IOMMU. */
-#define VFIO_UPDATE_VADDR 10
+/* Probe for reverted vaddr removal and update support */
+#define VFIO_UPDATE_VADDR_DEPRECATED 10

/*
* The IOCTL interface is designed for extensibility by embedding the
@@ -1348,7 +1348,7 @@ struct vfio_iommu_type1_dma_map {
__u32 flags;
#define VFIO_DMA_MAP_FLAG_READ (1 << 0) /* readable from device */
#define VFIO_DMA_MAP_FLAG_WRITE (1 << 1) /* writable from device */
-#define VFIO_DMA_MAP_FLAG_VADDR (1 << 2)
+#define VFIO_DMA_MAP_FLAG_VADDR_DEPRECATED (1 << 2) /* prior vaddr remapping */
__u64 vaddr; /* Process virtual address */
__u64 iova; /* IO virtual address */
__u64 size; /* Size of mapping (bytes) */
@@ -1390,6 +1390,7 @@ struct vfio_iommu_type1_dma_unmap {
__u32 flags;
#define VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP (1 << 0)
#define VFIO_DMA_UNMAP_FLAG_ALL (1 << 1)
+#define VFIO_DMA_UNMAP_FLAG_VADDR_DEPRECATED (1 << 2) /* prior vaddr removal */
__u64 iova; /* IO virtual address */
__u64 size; /* Size of mapping (bytes) */
__u8 data[];