tools/testing/selftests/vfio/lib/iommu.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/vfio/lib/iommu.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/vfio/lib/iommu.c
Extension
.c
Size
10497 bytes
Lines
465
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
#include <dirent.h>
#include <fcntl.h>
#include <libgen.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/eventfd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

#include <linux/limits.h>
#include <linux/mman.h>
#include <linux/types.h>
#include <linux/vfio.h>
#include <linux/iommufd.h>

#include "../../../kselftest.h"
#include <libvfio.h>

const char *default_iommu_mode = MODE_IOMMUFD;

/* Reminder: Keep in sync with FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES(). */
static const struct iommu_mode iommu_modes[] = {
	{
		.name = MODE_VFIO_TYPE1_IOMMU,
		.container_path = "/dev/vfio/vfio",
		.iommu_type = VFIO_TYPE1_IOMMU,
	},
	{
		.name = MODE_VFIO_TYPE1V2_IOMMU,
		.container_path = "/dev/vfio/vfio",
		.iommu_type = VFIO_TYPE1v2_IOMMU,
	},
	{
		.name = MODE_IOMMUFD_COMPAT_TYPE1,
		.container_path = "/dev/iommu",
		.iommu_type = VFIO_TYPE1_IOMMU,
	},
	{
		.name = MODE_IOMMUFD_COMPAT_TYPE1V2,
		.container_path = "/dev/iommu",
		.iommu_type = VFIO_TYPE1v2_IOMMU,
	},
	{
		.name = MODE_IOMMUFD,
	},
};

static const struct iommu_mode *lookup_iommu_mode(const char *iommu_mode)
{
	int i;

	if (!iommu_mode)
		iommu_mode = default_iommu_mode;

	for (i = 0; i < ARRAY_SIZE(iommu_modes); i++) {
		if (strcmp(iommu_mode, iommu_modes[i].name))
			continue;

		return &iommu_modes[i];
	}

	VFIO_FAIL("Unrecognized IOMMU mode: %s\n", iommu_mode);
}

int __iommu_hva2iova(struct iommu *iommu, void *vaddr, iova_t *iova)
{
	struct dma_region *region;

	list_for_each_entry(region, &iommu->dma_regions, link) {
		if (vaddr < region->vaddr)
			continue;

		if (vaddr >= region->vaddr + region->size)
			continue;

		if (iova)
			*iova = region->iova + (vaddr - region->vaddr);

		return 0;
	}

	return -ENOENT;
}

iova_t iommu_hva2iova(struct iommu *iommu, void *vaddr)
{

Annotation

Implementation Notes