tools/testing/selftests/iommu/iommufd.c

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/iommu/iommufd.c
Extension
.c
Size
105166 bytes
Lines
3617
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_test_hw_info_buffer_larger {
		struct iommu_test_hw_info info;
		uint64_t trailing_bytes;
	} buffer_larger;

	if (self->device_id) {
		uint8_t max_pasid = 0;

		/* Provide a zero-size user_buffer */
		test_cmd_get_hw_info(self->device_id,
				     IOMMU_HW_INFO_TYPE_DEFAULT, NULL, 0);
		/* Provide a user_buffer with exact size */
		test_cmd_get_hw_info(self->device_id,
				     IOMMU_HW_INFO_TYPE_DEFAULT, &buffer_exact,
				     sizeof(buffer_exact));

		/* Request for a wrong data_type, and a correct one */
		test_err_get_hw_info(EOPNOTSUPP, self->device_id,
				     IOMMU_HW_INFO_TYPE_SELFTEST + 1,
				     &buffer_exact, sizeof(buffer_exact));
		test_cmd_get_hw_info(self->device_id,
				     IOMMU_HW_INFO_TYPE_SELFTEST, &buffer_exact,
				     sizeof(buffer_exact));
		/*
		 * Provide a user_buffer with size larger than the exact size to check if
		 * kernel zero the trailing bytes.
		 */
		test_cmd_get_hw_info(self->device_id,
				     IOMMU_HW_INFO_TYPE_DEFAULT, &buffer_larger,
				     sizeof(buffer_larger));
		/*
		 * Provide a user_buffer with size smaller than the exact size to check if
		 * the fields within the size range still gets updated.
		 */
		test_cmd_get_hw_info(self->device_id,
				     IOMMU_HW_INFO_TYPE_DEFAULT, &buffer_exact,
				     offsetofend(struct iommu_test_hw_info,
						 flags));
		test_cmd_get_hw_info_pasid(self->device_id, &max_pasid);
		ASSERT_EQ(0, max_pasid);
		if (variant->pasid_capable) {
			test_cmd_get_hw_info_pasid(self->device_pasid_id,
						   &max_pasid);
			ASSERT_EQ(MOCK_PASID_WIDTH, max_pasid);
		}
	} else {
		test_err_get_hw_info(ENOENT, self->device_id,
				     IOMMU_HW_INFO_TYPE_DEFAULT, &buffer_exact,
				     sizeof(buffer_exact));
		test_err_get_hw_info(ENOENT, self->device_id,
				     IOMMU_HW_INFO_TYPE_DEFAULT, &buffer_larger,
				     sizeof(buffer_larger));
	}
}

TEST_F(iommufd_ioas, area)
{
	int i;

	/* Unmap fails if nothing is mapped */
	for (i = 0; i != 10; i++)
		test_err_ioctl_ioas_unmap(ENOENT, i * PAGE_SIZE, PAGE_SIZE);

	/* Unmap works */
	for (i = 0; i != 10; i++)
		test_ioctl_ioas_map_fixed(buffer, PAGE_SIZE,
					  self->base_iova + i * PAGE_SIZE);
	for (i = 0; i != 10; i++)
		test_ioctl_ioas_unmap(self->base_iova + i * PAGE_SIZE,
				      PAGE_SIZE);

	/* Split fails */
	test_ioctl_ioas_map_fixed(buffer, PAGE_SIZE * 2,
				  self->base_iova + 16 * PAGE_SIZE);
	test_err_ioctl_ioas_unmap(ENOENT, self->base_iova + 16 * PAGE_SIZE,
				  PAGE_SIZE);
	test_err_ioctl_ioas_unmap(ENOENT, self->base_iova + 17 * PAGE_SIZE,
				  PAGE_SIZE);

	/* Over map fails */
	test_err_ioctl_ioas_map_fixed(EEXIST, buffer, PAGE_SIZE * 2,
				      self->base_iova + 16 * PAGE_SIZE);
	test_err_ioctl_ioas_map_fixed(EEXIST, buffer, PAGE_SIZE,
				      self->base_iova + 16 * PAGE_SIZE);
	test_err_ioctl_ioas_map_fixed(EEXIST, buffer, PAGE_SIZE,
				      self->base_iova + 17 * PAGE_SIZE);
	test_err_ioctl_ioas_map_fixed(EEXIST, buffer, PAGE_SIZE * 2,
				      self->base_iova + 15 * PAGE_SIZE);
	test_err_ioctl_ioas_map_fixed(EEXIST, buffer, PAGE_SIZE * 3,
				      self->base_iova + 15 * PAGE_SIZE);

Annotation

Implementation Notes