drivers/iommu/iommufd/vfio_compat.c

Source file repositories/reference/linux-study-clean/drivers/iommu/iommufd/vfio_compat.c

File Facts

System
Linux kernel
Corpus path
drivers/iommu/iommufd/vfio_compat.c
Extension
.c
Size
14472 bytes
Lines
537
Domain
Driver Families
Bucket
drivers/iommu
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (unmap.iova != 0 || unmap.size != 0) {
			rc = -EINVAL;
			goto err_put;
		}
		rc = iopt_unmap_all(&ioas->iopt, &unmapped);
	} else {
		if (READ_ONCE(ioas->iopt.disable_large_pages)) {
			/*
			 * Create cuts at the start and last of the requested
			 * range. If the start IOVA is 0 then it doesn't need to
			 * be cut.
			 */
			unsigned long iovas[] = { unmap.iova + unmap.size - 1,
						  unmap.iova - 1 };

			rc = iopt_cut_iova(&ioas->iopt, iovas,
					   unmap.iova ? 2 : 1);
			if (rc)
				goto err_put;
		}
		rc = iopt_unmap_iova(&ioas->iopt, unmap.iova, unmap.size,
				     &unmapped);
	}
	unmap.size = unmapped;
	if (copy_to_user(arg, &unmap, minsz))
		rc = -EFAULT;

err_put:
	iommufd_put_object(ictx, &ioas->obj);
	return rc;
}

static int iommufd_vfio_cc_iommu(struct iommufd_ctx *ictx)
{
	struct iommufd_hwpt_paging *hwpt_paging;
	struct iommufd_ioas *ioas;
	int rc = 1;

	ioas = get_compat_ioas(ictx);
	if (IS_ERR(ioas))
		return PTR_ERR(ioas);

	mutex_lock(&ioas->mutex);
	list_for_each_entry(hwpt_paging, &ioas->hwpt_list, hwpt_item) {
		if (!hwpt_paging->enforce_cache_coherency) {
			rc = 0;
			break;
		}
	}
	mutex_unlock(&ioas->mutex);

	iommufd_put_object(ictx, &ioas->obj);
	return rc;
}

static int iommufd_vfio_check_extension(struct iommufd_ctx *ictx,
					unsigned long type)
{
	switch (type) {
	case VFIO_TYPE1_IOMMU:
	case VFIO_TYPE1v2_IOMMU:
	case VFIO_UNMAP_ALL:
		return !ictx->no_iommu_mode;

	case VFIO_NOIOMMU_IOMMU:
		return IS_ENABLED(CONFIG_VFIO_NOIOMMU);

	case VFIO_DMA_CC_IOMMU:
		return iommufd_vfio_cc_iommu(ictx);

	case __VFIO_RESERVED_TYPE1_NESTING_IOMMU:
		return 0;

	/*
	 * VFIO_DMA_MAP_FLAG_VADDR
	 * https://lore.kernel.org/kvm/1611939252-7240-1-git-send-email-steven.sistare@oracle.com/
	 * https://lore.kernel.org/all/Yz777bJZjTyLrHEQ@nvidia.com/
	 *
	 * It is hard to see how this could be implemented safely.
	 */
	case VFIO_UPDATE_VADDR:
	default:
		return 0;
	}
}

static int iommufd_vfio_set_iommu(struct iommufd_ctx *ictx, unsigned long type)
{
	bool no_iommu_mode = READ_ONCE(ictx->no_iommu_mode);
	struct iommufd_ioas *ioas = NULL;

Annotation

Implementation Notes