tools/testing/selftests/vfio/vfio_dma_mapping_test.c

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/vfio/vfio_dma_mapping_test.c
Extension
.c
Size
7756 bytes
Lines
308
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

struct iommu_mapping {
	u64 pgd;
	u64 p4d;
	u64 pud;
	u64 pmd;
	u64 pte;
};

static void parse_next_value(char **line, u64 *value)
{
	char *token;

	token = strtok_r(*line, " \t|\n", line);
	if (!token)
		return;

	/* Caller verifies `value`. No need to check return value. */
	sscanf(token, "0x%lx", value);
}

static int intel_iommu_mapping_get(const char *bdf, u64 iova,
				   struct iommu_mapping *mapping)
{
	char iommu_mapping_path[PATH_MAX], line[PATH_MAX];
	u64 line_iova = -1;
	int ret = -ENOENT;
	FILE *file;
	char *rest;

	snprintf_assert(iommu_mapping_path, sizeof(iommu_mapping_path),
			"/sys/kernel/debug/iommu/intel/%s/domain_translation_struct",
			bdf);

	printf("Searching for IOVA 0x%lx in %s\n", iova, iommu_mapping_path);

	file = fopen(iommu_mapping_path, "r");
	VFIO_ASSERT_NOT_NULL(file, "fopen(%s) failed", iommu_mapping_path);

	while (fgets(line, sizeof(line), file)) {
		rest = line;

		parse_next_value(&rest, &line_iova);
		if (line_iova != (iova / getpagesize()))
			continue;

		/*
		 * Ensure each struct field is initialized in case of empty
		 * page table values.
		 */
		memset(mapping, 0, sizeof(*mapping));
		parse_next_value(&rest, &mapping->pgd);
		parse_next_value(&rest, &mapping->p4d);
		parse_next_value(&rest, &mapping->pud);
		parse_next_value(&rest, &mapping->pmd);
		parse_next_value(&rest, &mapping->pte);

		ret = 0;
		break;
	}

	fclose(file);

	if (ret)
		printf("IOVA not found\n");

	return ret;
}

static int iommu_mapping_get(const char *bdf, u64 iova,
			     struct iommu_mapping *mapping)
{
	if (!access("/sys/kernel/debug/iommu/intel", F_OK))
		return intel_iommu_mapping_get(bdf, iova, mapping);

	return -EOPNOTSUPP;
}

FIXTURE(vfio_dma_mapping_test) {
	struct iommu *iommu;
	struct vfio_pci_device *device;
	struct iova_allocator *iova_allocator;
};

FIXTURE_VARIANT(vfio_dma_mapping_test) {
	const char *iommu_mode;
	u64 size;
	int mmap_flags;
};

#define FIXTURE_VARIANT_ADD_IOMMU_MODE(_iommu_mode, _name, _size, _mmap_flags) \

Annotation

Implementation Notes