VFIO fixes for v5.12-rc4

- Fix 32-bit issue with new unmap-all flag (Steve Sistare)
 
  - Various Kconfig changes for better coverage (Jason Gunthorpe)
 
  - Fix to batch pinning support (Daniel Jordan)
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.14 (GNU/Linux)
 
 iQIcBAABAgAGBQJgU6PRAAoJECObm247sIsixAQP/RQCvHD4W7jmgrb7ksucE7Hz
 KaJaJzbonayUCdI5e1W4x4j8BhiclIAJXz+kMbjltN4AqASkKVIBzIlBmDt4nsJ/
 AMCN7A1EOmPpG1xX6TpTXxfdw/7VjSRtFk/S8mv0N0NIRdZwue4SBbZd/oXkk7NF
 vBSsJkVn/nCGrEu1+vb/Ld5T8fecni99slyTaN/WYlEVqIJtTDEZhvPwMrIqNOcu
 n2UDMrifuUqXmbOKtCRhwPIwpOzEx8E1vNHAWHu3S8KOhdj7g6QXyWij2EmBD0hs
 rKU+uVnH/KImNVGHnwVqbPrlCxUcBV/RXKAA2XxN6VQiiLYAvhbHISVTtVHt21rQ
 pwJGcOyOeBmt+FrVw3cLwtkn3y87Nrg6gpQlrw3k3dyuYIUVThlUlBADzpmX0ZM5
 40BYpWPsrqdvPQxZzY6ccAvkn838ZTNPDSPac5nnQOJgeYnxR+cWKzKeL4bggJxm
 kYhoIIQETnbJeUZQYOP4FT8ltJPJkhaMTHYSdKrCvkYhN2Eq3+Wi+gLiMbeEpM+d
 6IUH+ZwHfH8DGQGUBfpt6AuKNu5vnUppHAu/xpoXJxl2ITyKHDoXypuEHsD+DRro
 4CmS74+ma932WHYc+wwqnKRjyUFlwaDbqmIV7vv54dHRkhMSfGDVbWybCosGNodL
 NJNR1uFmuVgcyKpcWinq
 =C+4w
 -----END PGP SIGNATURE-----

Merge tag 'vfio-v5.12-rc4' of git://github.com/awilliam/linux-vfio

Pull VFIO fixes from Alex Williamson:

 - Fix 32-bit issue with new unmap-all flag (Steve Sistare)

 - Various Kconfig changes for better coverage (Jason Gunthorpe)

 - Fix to batch pinning support (Daniel Jordan)

* tag 'vfio-v5.12-rc4' of git://github.com/awilliam/linux-vfio:
  vfio/type1: fix vaddr_get_pfns() return in vfio_pin_page_external()
  vfio: Depend on MMU
  ARM: amba: Allow some ARM_AMBA users to compile with COMPILE_TEST
  vfio-platform: Add COMPILE_TEST to VFIO_PLATFORM
  vfio: IOMMU_API should be selected
  vfio/type1: fix unmap all on ILP32
This commit is contained in:
Linus Torvalds 2021-03-18 12:37:05 -07:00
commit dc0337999d
4 changed files with 27 additions and 12 deletions

View File

@ -21,8 +21,8 @@ config VFIO_VIRQFD
menuconfig VFIO menuconfig VFIO
tristate "VFIO Non-Privileged userspace driver framework" tristate "VFIO Non-Privileged userspace driver framework"
depends on IOMMU_API select IOMMU_API
select VFIO_IOMMU_TYPE1 if (X86 || S390 || ARM || ARM64) select VFIO_IOMMU_TYPE1 if MMU && (X86 || S390 || ARM || ARM64)
help help
VFIO provides a framework for secure userspace device drivers. VFIO provides a framework for secure userspace device drivers.
See Documentation/driver-api/vfio.rst for more details. See Documentation/driver-api/vfio.rst for more details.

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
config VFIO_PLATFORM config VFIO_PLATFORM
tristate "VFIO support for platform devices" tristate "VFIO support for platform devices"
depends on VFIO && EVENTFD && (ARM || ARM64) depends on VFIO && EVENTFD && (ARM || ARM64 || COMPILE_TEST)
select VFIO_VIRQFD select VFIO_VIRQFD
help help
Support for platform devices with VFIO. This is required to make Support for platform devices with VFIO. This is required to make
@ -12,7 +12,7 @@ config VFIO_PLATFORM
config VFIO_AMBA config VFIO_AMBA
tristate "VFIO support for AMBA devices" tristate "VFIO support for AMBA devices"
depends on VFIO_PLATFORM && ARM_AMBA depends on VFIO_PLATFORM && (ARM_AMBA || COMPILE_TEST)
help help
Support for ARM AMBA devices with VFIO. This is required to make Support for ARM AMBA devices with VFIO. This is required to make
use of ARM AMBA devices present on the system using the VFIO use of ARM AMBA devices present on the system using the VFIO

View File

@ -189,7 +189,7 @@ static struct vfio_dma *vfio_find_dma(struct vfio_iommu *iommu,
} }
static struct rb_node *vfio_find_dma_first_node(struct vfio_iommu *iommu, static struct rb_node *vfio_find_dma_first_node(struct vfio_iommu *iommu,
dma_addr_t start, size_t size) dma_addr_t start, u64 size)
{ {
struct rb_node *res = NULL; struct rb_node *res = NULL;
struct rb_node *node = iommu->dma_list.rb_node; struct rb_node *node = iommu->dma_list.rb_node;
@ -785,7 +785,12 @@ static int vfio_pin_page_external(struct vfio_dma *dma, unsigned long vaddr,
return -ENODEV; return -ENODEV;
ret = vaddr_get_pfns(mm, vaddr, 1, dma->prot, pfn_base, pages); ret = vaddr_get_pfns(mm, vaddr, 1, dma->prot, pfn_base, pages);
if (ret == 1 && do_accounting && !is_invalid_reserved_pfn(*pfn_base)) { if (ret != 1)
goto out;
ret = 0;
if (do_accounting && !is_invalid_reserved_pfn(*pfn_base)) {
ret = vfio_lock_acct(dma, 1, true); ret = vfio_lock_acct(dma, 1, true);
if (ret) { if (ret) {
put_pfn(*pfn_base, dma->prot); put_pfn(*pfn_base, dma->prot);
@ -797,6 +802,7 @@ static int vfio_pin_page_external(struct vfio_dma *dma, unsigned long vaddr,
} }
} }
out:
mmput(mm); mmput(mm);
return ret; return ret;
} }
@ -1288,7 +1294,7 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
int ret = -EINVAL, retries = 0; int ret = -EINVAL, retries = 0;
unsigned long pgshift; unsigned long pgshift;
dma_addr_t iova = unmap->iova; dma_addr_t iova = unmap->iova;
unsigned long size = unmap->size; u64 size = unmap->size;
bool unmap_all = unmap->flags & VFIO_DMA_UNMAP_FLAG_ALL; bool unmap_all = unmap->flags & VFIO_DMA_UNMAP_FLAG_ALL;
bool invalidate_vaddr = unmap->flags & VFIO_DMA_UNMAP_FLAG_VADDR; bool invalidate_vaddr = unmap->flags & VFIO_DMA_UNMAP_FLAG_VADDR;
struct rb_node *n, *first_n; struct rb_node *n, *first_n;
@ -1304,14 +1310,12 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
if (unmap_all) { if (unmap_all) {
if (iova || size) if (iova || size)
goto unlock; goto unlock;
size = SIZE_MAX; size = U64_MAX;
} else if (!size || size & (pgsize - 1)) { } else if (!size || size & (pgsize - 1) ||
iova + size - 1 < iova || size > SIZE_MAX) {
goto unlock; goto unlock;
} }
if (iova + size - 1 < iova || size > SIZE_MAX)
goto unlock;
/* When dirty tracking is enabled, allow only min supported pgsize */ /* When dirty tracking is enabled, allow only min supported pgsize */
if ((unmap->flags & VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP) && if ((unmap->flags & VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP) &&
(!iommu->dirty_page_tracking || (bitmap->pgsize != pgsize))) { (!iommu->dirty_page_tracking || (bitmap->pgsize != pgsize))) {

View File

@ -105,8 +105,19 @@ extern struct bus_type amba_bustype;
#define amba_get_drvdata(d) dev_get_drvdata(&d->dev) #define amba_get_drvdata(d) dev_get_drvdata(&d->dev)
#define amba_set_drvdata(d,p) dev_set_drvdata(&d->dev, p) #define amba_set_drvdata(d,p) dev_set_drvdata(&d->dev, p)
#ifdef CONFIG_ARM_AMBA
int amba_driver_register(struct amba_driver *); int amba_driver_register(struct amba_driver *);
void amba_driver_unregister(struct amba_driver *); void amba_driver_unregister(struct amba_driver *);
#else
static inline int amba_driver_register(struct amba_driver *drv)
{
return -EINVAL;
}
static inline void amba_driver_unregister(struct amba_driver *drv)
{
}
#endif
struct amba_device *amba_device_alloc(const char *, resource_size_t, size_t); struct amba_device *amba_device_alloc(const char *, resource_size_t, size_t);
void amba_device_put(struct amba_device *); void amba_device_put(struct amba_device *);
int amba_device_add(struct amba_device *, struct resource *); int amba_device_add(struct amba_device *, struct resource *);