xref: /linux/tools/testing/selftests/iommu/iommufd.c (revision 7255fcc80d4b525cc10cfaaf7f485830d4ed2000)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES */
3 #include <stdlib.h>
4 #include <sys/mman.h>
5 #include <sys/eventfd.h>
6 
7 #define __EXPORTED_HEADERS__
8 #include <linux/vfio.h>
9 
10 #include "iommufd_utils.h"
11 
12 static unsigned long HUGEPAGE_SIZE;
13 
14 #define MOCK_PAGE_SIZE (PAGE_SIZE / 2)
15 #define MOCK_HUGE_PAGE_SIZE (512 * MOCK_PAGE_SIZE)
16 
17 static unsigned long get_huge_page_size(void)
18 {
19 	char buf[80];
20 	int ret;
21 	int fd;
22 
23 	fd = open("/sys/kernel/mm/transparent_hugepage/hpage_pmd_size",
24 		  O_RDONLY);
25 	if (fd < 0)
26 		return 2 * 1024 * 1024;
27 
28 	ret = read(fd, buf, sizeof(buf));
29 	close(fd);
30 	if (ret <= 0 || ret == sizeof(buf))
31 		return 2 * 1024 * 1024;
32 	buf[ret] = 0;
33 	return strtoul(buf, NULL, 10);
34 }
35 
36 static __attribute__((constructor)) void setup_sizes(void)
37 {
38 	void *vrc;
39 	int rc;
40 
41 	PAGE_SIZE = sysconf(_SC_PAGE_SIZE);
42 	HUGEPAGE_SIZE = get_huge_page_size();
43 
44 	BUFFER_SIZE = PAGE_SIZE * 16;
45 	rc = posix_memalign(&buffer, HUGEPAGE_SIZE, BUFFER_SIZE);
46 	assert(!rc);
47 	assert(buffer);
48 	assert((uintptr_t)buffer % HUGEPAGE_SIZE == 0);
49 	vrc = mmap(buffer, BUFFER_SIZE, PROT_READ | PROT_WRITE,
50 		   MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
51 	assert(vrc == buffer);
52 }
53 
54 FIXTURE(iommufd)
55 {
56 	int fd;
57 };
58 
59 FIXTURE_SETUP(iommufd)
60 {
61 	self->fd = open("/dev/iommu", O_RDWR);
62 	ASSERT_NE(-1, self->fd);
63 }
64 
65 FIXTURE_TEARDOWN(iommufd)
66 {
67 	teardown_iommufd(self->fd, _metadata);
68 }
69 
70 TEST_F(iommufd, simple_close)
71 {
72 }
73 
74 TEST_F(iommufd, cmd_fail)
75 {
76 	struct iommu_destroy cmd = { .size = sizeof(cmd), .id = 0 };
77 
78 	/* object id is invalid */
79 	EXPECT_ERRNO(ENOENT, _test_ioctl_destroy(self->fd, 0));
80 	/* Bad pointer */
81 	EXPECT_ERRNO(EFAULT, ioctl(self->fd, IOMMU_DESTROY, NULL));
82 	/* Unknown ioctl */
83 	EXPECT_ERRNO(ENOTTY,
84 		     ioctl(self->fd, _IO(IOMMUFD_TYPE, IOMMUFD_CMD_BASE - 1),
85 			   &cmd));
86 }
87 
88 TEST_F(iommufd, cmd_length)
89 {
90 #define TEST_LENGTH(_struct, _ioctl, _last)                              \
91 	{                                                                \
92 		size_t min_size = offsetofend(struct _struct, _last);    \
93 		struct {                                                 \
94 			struct _struct cmd;                              \
95 			uint8_t extra;                                   \
96 		} cmd = { .cmd = { .size = min_size - 1 },               \
97 			  .extra = UINT8_MAX };                          \
98 		int old_errno;                                           \
99 		int rc;                                                  \
100 									 \
101 		EXPECT_ERRNO(EINVAL, ioctl(self->fd, _ioctl, &cmd));     \
102 		cmd.cmd.size = sizeof(struct _struct) + 1;               \
103 		EXPECT_ERRNO(E2BIG, ioctl(self->fd, _ioctl, &cmd));      \
104 		cmd.cmd.size = sizeof(struct _struct);                   \
105 		rc = ioctl(self->fd, _ioctl, &cmd);                      \
106 		old_errno = errno;                                       \
107 		cmd.cmd.size = sizeof(struct _struct) + 1;               \
108 		cmd.extra = 0;                                           \
109 		if (rc) {                                                \
110 			EXPECT_ERRNO(old_errno,                          \
111 				     ioctl(self->fd, _ioctl, &cmd));     \
112 		} else {                                                 \
113 			ASSERT_EQ(0, ioctl(self->fd, _ioctl, &cmd));     \
114 		}                                                        \
115 	}
116 
117 	TEST_LENGTH(iommu_destroy, IOMMU_DESTROY, id);
118 	TEST_LENGTH(iommu_hw_info, IOMMU_GET_HW_INFO, __reserved);
119 	TEST_LENGTH(iommu_hwpt_alloc, IOMMU_HWPT_ALLOC, __reserved);
120 	TEST_LENGTH(iommu_hwpt_invalidate, IOMMU_HWPT_INVALIDATE, __reserved);
121 	TEST_LENGTH(iommu_ioas_alloc, IOMMU_IOAS_ALLOC, out_ioas_id);
122 	TEST_LENGTH(iommu_ioas_iova_ranges, IOMMU_IOAS_IOVA_RANGES,
123 		    out_iova_alignment);
124 	TEST_LENGTH(iommu_ioas_allow_iovas, IOMMU_IOAS_ALLOW_IOVAS,
125 		    allowed_iovas);
126 	TEST_LENGTH(iommu_ioas_map, IOMMU_IOAS_MAP, iova);
127 	TEST_LENGTH(iommu_ioas_copy, IOMMU_IOAS_COPY, src_iova);
128 	TEST_LENGTH(iommu_ioas_unmap, IOMMU_IOAS_UNMAP, length);
129 	TEST_LENGTH(iommu_option, IOMMU_OPTION, val64);
130 	TEST_LENGTH(iommu_vfio_ioas, IOMMU_VFIO_IOAS, __reserved);
131 #undef TEST_LENGTH
132 }
133 
134 TEST_F(iommufd, cmd_ex_fail)
135 {
136 	struct {
137 		struct iommu_destroy cmd;
138 		__u64 future;
139 	} cmd = { .cmd = { .size = sizeof(cmd), .id = 0 } };
140 
141 	/* object id is invalid and command is longer */
142 	EXPECT_ERRNO(ENOENT, ioctl(self->fd, IOMMU_DESTROY, &cmd));
143 	/* future area is non-zero */
144 	cmd.future = 1;
145 	EXPECT_ERRNO(E2BIG, ioctl(self->fd, IOMMU_DESTROY, &cmd));
146 	/* Original command "works" */
147 	cmd.cmd.size = sizeof(cmd.cmd);
148 	EXPECT_ERRNO(ENOENT, ioctl(self->fd, IOMMU_DESTROY, &cmd));
149 	/* Short command fails */
150 	cmd.cmd.size = sizeof(cmd.cmd) - 1;
151 	EXPECT_ERRNO(EINVAL, ioctl(self->fd, IOMMU_DESTROY, &cmd));
152 }
153 
154 TEST_F(iommufd, global_options)
155 {
156 	struct iommu_option cmd = {
157 		.size = sizeof(cmd),
158 		.option_id = IOMMU_OPTION_RLIMIT_MODE,
159 		.op = IOMMU_OPTION_OP_GET,
160 		.val64 = 1,
161 	};
162 
163 	cmd.option_id = IOMMU_OPTION_RLIMIT_MODE;
164 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_OPTION, &cmd));
165 	ASSERT_EQ(0, cmd.val64);
166 
167 	/* This requires root */
168 	cmd.op = IOMMU_OPTION_OP_SET;
169 	cmd.val64 = 1;
170 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_OPTION, &cmd));
171 	cmd.val64 = 2;
172 	EXPECT_ERRNO(EINVAL, ioctl(self->fd, IOMMU_OPTION, &cmd));
173 
174 	cmd.op = IOMMU_OPTION_OP_GET;
175 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_OPTION, &cmd));
176 	ASSERT_EQ(1, cmd.val64);
177 
178 	cmd.op = IOMMU_OPTION_OP_SET;
179 	cmd.val64 = 0;
180 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_OPTION, &cmd));
181 
182 	cmd.op = IOMMU_OPTION_OP_GET;
183 	cmd.option_id = IOMMU_OPTION_HUGE_PAGES;
184 	EXPECT_ERRNO(ENOENT, ioctl(self->fd, IOMMU_OPTION, &cmd));
185 	cmd.op = IOMMU_OPTION_OP_SET;
186 	EXPECT_ERRNO(ENOENT, ioctl(self->fd, IOMMU_OPTION, &cmd));
187 }
188 
189 FIXTURE(iommufd_ioas)
190 {
191 	int fd;
192 	uint32_t ioas_id;
193 	uint32_t stdev_id;
194 	uint32_t hwpt_id;
195 	uint32_t device_id;
196 	uint64_t base_iova;
197 };
198 
199 FIXTURE_VARIANT(iommufd_ioas)
200 {
201 	unsigned int mock_domains;
202 	unsigned int memory_limit;
203 };
204 
205 FIXTURE_SETUP(iommufd_ioas)
206 {
207 	unsigned int i;
208 
209 
210 	self->fd = open("/dev/iommu", O_RDWR);
211 	ASSERT_NE(-1, self->fd);
212 	test_ioctl_ioas_alloc(&self->ioas_id);
213 
214 	if (!variant->memory_limit) {
215 		test_ioctl_set_default_memory_limit();
216 	} else {
217 		test_ioctl_set_temp_memory_limit(variant->memory_limit);
218 	}
219 
220 	for (i = 0; i != variant->mock_domains; i++) {
221 		test_cmd_mock_domain(self->ioas_id, &self->stdev_id,
222 				     &self->hwpt_id, &self->device_id);
223 		self->base_iova = MOCK_APERTURE_START;
224 	}
225 }
226 
227 FIXTURE_TEARDOWN(iommufd_ioas)
228 {
229 	test_ioctl_set_default_memory_limit();
230 	teardown_iommufd(self->fd, _metadata);
231 }
232 
233 FIXTURE_VARIANT_ADD(iommufd_ioas, no_domain)
234 {
235 };
236 
237 FIXTURE_VARIANT_ADD(iommufd_ioas, mock_domain)
238 {
239 	.mock_domains = 1,
240 };
241 
242 FIXTURE_VARIANT_ADD(iommufd_ioas, two_mock_domain)
243 {
244 	.mock_domains = 2,
245 };
246 
247 FIXTURE_VARIANT_ADD(iommufd_ioas, mock_domain_limit)
248 {
249 	.mock_domains = 1,
250 	.memory_limit = 16,
251 };
252 
253 TEST_F(iommufd_ioas, ioas_auto_destroy)
254 {
255 }
256 
257 TEST_F(iommufd_ioas, ioas_destroy)
258 {
259 	if (self->stdev_id) {
260 		/* IOAS cannot be freed while a device has a HWPT using it */
261 		EXPECT_ERRNO(EBUSY,
262 			     _test_ioctl_destroy(self->fd, self->ioas_id));
263 	} else {
264 		/* Can allocate and manually free an IOAS table */
265 		test_ioctl_destroy(self->ioas_id);
266 	}
267 }
268 
269 TEST_F(iommufd_ioas, alloc_hwpt_nested)
270 {
271 	const uint32_t min_data_len =
272 		offsetofend(struct iommu_hwpt_selftest, iotlb);
273 	struct iommu_hwpt_selftest data = {
274 		.iotlb = IOMMU_TEST_IOTLB_DEFAULT,
275 	};
276 	struct iommu_hwpt_invalidate_selftest inv_reqs[2] = {};
277 	uint32_t nested_hwpt_id[2] = {};
278 	uint32_t num_inv;
279 	uint32_t parent_hwpt_id = 0;
280 	uint32_t parent_hwpt_id_not_work = 0;
281 	uint32_t test_hwpt_id = 0;
282 
283 	if (self->device_id) {
284 		/* Negative tests */
285 		test_err_hwpt_alloc(ENOENT, self->ioas_id, self->device_id, 0,
286 				    &test_hwpt_id);
287 		test_err_hwpt_alloc(EINVAL, self->device_id, self->device_id, 0,
288 				    &test_hwpt_id);
289 
290 		test_cmd_hwpt_alloc(self->device_id, self->ioas_id,
291 				    IOMMU_HWPT_ALLOC_NEST_PARENT,
292 				    &parent_hwpt_id);
293 
294 		test_cmd_hwpt_alloc(self->device_id, self->ioas_id, 0,
295 				    &parent_hwpt_id_not_work);
296 
297 		/* Negative nested tests */
298 		test_err_hwpt_alloc_nested(EINVAL, self->device_id,
299 					   parent_hwpt_id, 0,
300 					   &nested_hwpt_id[0],
301 					   IOMMU_HWPT_DATA_NONE, &data,
302 					   sizeof(data));
303 		test_err_hwpt_alloc_nested(EOPNOTSUPP, self->device_id,
304 					   parent_hwpt_id, 0,
305 					   &nested_hwpt_id[0],
306 					   IOMMU_HWPT_DATA_SELFTEST + 1, &data,
307 					   sizeof(data));
308 		test_err_hwpt_alloc_nested(EINVAL, self->device_id,
309 					   parent_hwpt_id, 0,
310 					   &nested_hwpt_id[0],
311 					   IOMMU_HWPT_DATA_SELFTEST, &data,
312 					   min_data_len - 1);
313 		test_err_hwpt_alloc_nested(EFAULT, self->device_id,
314 					   parent_hwpt_id, 0,
315 					   &nested_hwpt_id[0],
316 					   IOMMU_HWPT_DATA_SELFTEST, NULL,
317 					   sizeof(data));
318 		test_err_hwpt_alloc_nested(
319 			EOPNOTSUPP, self->device_id, parent_hwpt_id,
320 			IOMMU_HWPT_ALLOC_NEST_PARENT, &nested_hwpt_id[0],
321 			IOMMU_HWPT_DATA_SELFTEST, &data, sizeof(data));
322 		test_err_hwpt_alloc_nested(EINVAL, self->device_id,
323 					   parent_hwpt_id_not_work, 0,
324 					   &nested_hwpt_id[0],
325 					   IOMMU_HWPT_DATA_SELFTEST, &data,
326 					   sizeof(data));
327 
328 		/* Allocate two nested hwpts sharing one common parent hwpt */
329 		test_cmd_hwpt_alloc_nested(self->device_id, parent_hwpt_id, 0,
330 					   &nested_hwpt_id[0],
331 					   IOMMU_HWPT_DATA_SELFTEST, &data,
332 					   sizeof(data));
333 		test_cmd_hwpt_alloc_nested(self->device_id, parent_hwpt_id, 0,
334 					   &nested_hwpt_id[1],
335 					   IOMMU_HWPT_DATA_SELFTEST, &data,
336 					   sizeof(data));
337 		test_cmd_hwpt_check_iotlb_all(nested_hwpt_id[0],
338 					      IOMMU_TEST_IOTLB_DEFAULT);
339 		test_cmd_hwpt_check_iotlb_all(nested_hwpt_id[1],
340 					      IOMMU_TEST_IOTLB_DEFAULT);
341 
342 		/* Negative test: a nested hwpt on top of a nested hwpt */
343 		test_err_hwpt_alloc_nested(EINVAL, self->device_id,
344 					   nested_hwpt_id[0], 0, &test_hwpt_id,
345 					   IOMMU_HWPT_DATA_SELFTEST, &data,
346 					   sizeof(data));
347 		/* Negative test: parent hwpt now cannot be freed */
348 		EXPECT_ERRNO(EBUSY,
349 			     _test_ioctl_destroy(self->fd, parent_hwpt_id));
350 
351 		/* hwpt_invalidate only supports a user-managed hwpt (nested) */
352 		num_inv = 1;
353 		test_err_hwpt_invalidate(ENOENT, parent_hwpt_id, inv_reqs,
354 					 IOMMU_HWPT_INVALIDATE_DATA_SELFTEST,
355 					 sizeof(*inv_reqs), &num_inv);
356 		assert(!num_inv);
357 
358 		/* Check data_type by passing zero-length array */
359 		num_inv = 0;
360 		test_cmd_hwpt_invalidate(nested_hwpt_id[0], inv_reqs,
361 					 IOMMU_HWPT_INVALIDATE_DATA_SELFTEST,
362 					 sizeof(*inv_reqs), &num_inv);
363 		assert(!num_inv);
364 
365 		/* Negative test: Invalid data_type */
366 		num_inv = 1;
367 		test_err_hwpt_invalidate(EINVAL, nested_hwpt_id[0], inv_reqs,
368 					 IOMMU_HWPT_INVALIDATE_DATA_SELFTEST_INVALID,
369 					 sizeof(*inv_reqs), &num_inv);
370 		assert(!num_inv);
371 
372 		/* Negative test: structure size sanity */
373 		num_inv = 1;
374 		test_err_hwpt_invalidate(EINVAL, nested_hwpt_id[0], inv_reqs,
375 					 IOMMU_HWPT_INVALIDATE_DATA_SELFTEST,
376 					 sizeof(*inv_reqs) + 1, &num_inv);
377 		assert(!num_inv);
378 
379 		num_inv = 1;
380 		test_err_hwpt_invalidate(EINVAL, nested_hwpt_id[0], inv_reqs,
381 					 IOMMU_HWPT_INVALIDATE_DATA_SELFTEST,
382 					 1, &num_inv);
383 		assert(!num_inv);
384 
385 		/* Negative test: invalid flag is passed */
386 		num_inv = 1;
387 		inv_reqs[0].flags = 0xffffffff;
388 		test_err_hwpt_invalidate(EOPNOTSUPP, nested_hwpt_id[0], inv_reqs,
389 					 IOMMU_HWPT_INVALIDATE_DATA_SELFTEST,
390 					 sizeof(*inv_reqs), &num_inv);
391 		assert(!num_inv);
392 
393 		/* Negative test: invalid data_uptr when array is not empty */
394 		num_inv = 1;
395 		inv_reqs[0].flags = 0;
396 		test_err_hwpt_invalidate(EINVAL, nested_hwpt_id[0], NULL,
397 					 IOMMU_HWPT_INVALIDATE_DATA_SELFTEST,
398 					 sizeof(*inv_reqs), &num_inv);
399 		assert(!num_inv);
400 
401 		/* Negative test: invalid entry_len when array is not empty */
402 		num_inv = 1;
403 		inv_reqs[0].flags = 0;
404 		test_err_hwpt_invalidate(EINVAL, nested_hwpt_id[0], inv_reqs,
405 					 IOMMU_HWPT_INVALIDATE_DATA_SELFTEST,
406 					 0, &num_inv);
407 		assert(!num_inv);
408 
409 		/* Negative test: invalid iotlb_id */
410 		num_inv = 1;
411 		inv_reqs[0].flags = 0;
412 		inv_reqs[0].iotlb_id = MOCK_NESTED_DOMAIN_IOTLB_ID_MAX + 1;
413 		test_err_hwpt_invalidate(EINVAL, nested_hwpt_id[0], inv_reqs,
414 					 IOMMU_HWPT_INVALIDATE_DATA_SELFTEST,
415 					 sizeof(*inv_reqs), &num_inv);
416 		assert(!num_inv);
417 
418 		/*
419 		 * Invalidate the 1st iotlb entry but fail the 2nd request
420 		 * due to invalid flags configuration in the 2nd request.
421 		 */
422 		num_inv = 2;
423 		inv_reqs[0].flags = 0;
424 		inv_reqs[0].iotlb_id = 0;
425 		inv_reqs[1].flags = 0xffffffff;
426 		inv_reqs[1].iotlb_id = 1;
427 		test_err_hwpt_invalidate(EOPNOTSUPP, nested_hwpt_id[0], inv_reqs,
428 					 IOMMU_HWPT_INVALIDATE_DATA_SELFTEST,
429 					 sizeof(*inv_reqs), &num_inv);
430 		assert(num_inv == 1);
431 		test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 0, 0);
432 		test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 1,
433 					  IOMMU_TEST_IOTLB_DEFAULT);
434 		test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 2,
435 					  IOMMU_TEST_IOTLB_DEFAULT);
436 		test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 3,
437 					  IOMMU_TEST_IOTLB_DEFAULT);
438 
439 		/*
440 		 * Invalidate the 1st iotlb entry but fail the 2nd request
441 		 * due to invalid iotlb_id configuration in the 2nd request.
442 		 */
443 		num_inv = 2;
444 		inv_reqs[0].flags = 0;
445 		inv_reqs[0].iotlb_id = 0;
446 		inv_reqs[1].flags = 0;
447 		inv_reqs[1].iotlb_id = MOCK_NESTED_DOMAIN_IOTLB_ID_MAX + 1;
448 		test_err_hwpt_invalidate(EINVAL, nested_hwpt_id[0], inv_reqs,
449 					 IOMMU_HWPT_INVALIDATE_DATA_SELFTEST,
450 					 sizeof(*inv_reqs), &num_inv);
451 		assert(num_inv == 1);
452 		test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 0, 0);
453 		test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 1,
454 					  IOMMU_TEST_IOTLB_DEFAULT);
455 		test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 2,
456 					  IOMMU_TEST_IOTLB_DEFAULT);
457 		test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 3,
458 					  IOMMU_TEST_IOTLB_DEFAULT);
459 
460 		/* Invalidate the 2nd iotlb entry and verify */
461 		num_inv = 1;
462 		inv_reqs[0].flags = 0;
463 		inv_reqs[0].iotlb_id = 1;
464 		test_cmd_hwpt_invalidate(nested_hwpt_id[0], inv_reqs,
465 					 IOMMU_HWPT_INVALIDATE_DATA_SELFTEST,
466 					 sizeof(*inv_reqs), &num_inv);
467 		assert(num_inv == 1);
468 		test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 0, 0);
469 		test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 1, 0);
470 		test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 2,
471 					  IOMMU_TEST_IOTLB_DEFAULT);
472 		test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 3,
473 					  IOMMU_TEST_IOTLB_DEFAULT);
474 
475 		/* Invalidate the 3rd and 4th iotlb entries and verify */
476 		num_inv = 2;
477 		inv_reqs[0].flags = 0;
478 		inv_reqs[0].iotlb_id = 2;
479 		inv_reqs[1].flags = 0;
480 		inv_reqs[1].iotlb_id = 3;
481 		test_cmd_hwpt_invalidate(nested_hwpt_id[0], inv_reqs,
482 					 IOMMU_HWPT_INVALIDATE_DATA_SELFTEST,
483 					 sizeof(*inv_reqs), &num_inv);
484 		assert(num_inv == 2);
485 		test_cmd_hwpt_check_iotlb_all(nested_hwpt_id[0], 0);
486 
487 		/* Invalidate all iotlb entries for nested_hwpt_id[1] and verify */
488 		num_inv = 1;
489 		inv_reqs[0].flags = IOMMU_TEST_INVALIDATE_FLAG_ALL;
490 		test_cmd_hwpt_invalidate(nested_hwpt_id[1], inv_reqs,
491 					 IOMMU_HWPT_INVALIDATE_DATA_SELFTEST,
492 					 sizeof(*inv_reqs), &num_inv);
493 		assert(num_inv == 1);
494 		test_cmd_hwpt_check_iotlb_all(nested_hwpt_id[1], 0);
495 
496 		/* Attach device to nested_hwpt_id[0] that then will be busy */
497 		test_cmd_mock_domain_replace(self->stdev_id, nested_hwpt_id[0]);
498 		EXPECT_ERRNO(EBUSY,
499 			     _test_ioctl_destroy(self->fd, nested_hwpt_id[0]));
500 
501 		/* Switch from nested_hwpt_id[0] to nested_hwpt_id[1] */
502 		test_cmd_mock_domain_replace(self->stdev_id, nested_hwpt_id[1]);
503 		EXPECT_ERRNO(EBUSY,
504 			     _test_ioctl_destroy(self->fd, nested_hwpt_id[1]));
505 		test_ioctl_destroy(nested_hwpt_id[0]);
506 
507 		/* Detach from nested_hwpt_id[1] and destroy it */
508 		test_cmd_mock_domain_replace(self->stdev_id, parent_hwpt_id);
509 		test_ioctl_destroy(nested_hwpt_id[1]);
510 
511 		/* Detach from the parent hw_pagetable and destroy it */
512 		test_cmd_mock_domain_replace(self->stdev_id, self->ioas_id);
513 		test_ioctl_destroy(parent_hwpt_id);
514 		test_ioctl_destroy(parent_hwpt_id_not_work);
515 	} else {
516 		test_err_hwpt_alloc(ENOENT, self->device_id, self->ioas_id, 0,
517 				    &parent_hwpt_id);
518 		test_err_hwpt_alloc_nested(ENOENT, self->device_id,
519 					   parent_hwpt_id, 0,
520 					   &nested_hwpt_id[0],
521 					   IOMMU_HWPT_DATA_SELFTEST, &data,
522 					   sizeof(data));
523 		test_err_hwpt_alloc_nested(ENOENT, self->device_id,
524 					   parent_hwpt_id, 0,
525 					   &nested_hwpt_id[1],
526 					   IOMMU_HWPT_DATA_SELFTEST, &data,
527 					   sizeof(data));
528 		test_err_mock_domain_replace(ENOENT, self->stdev_id,
529 					     nested_hwpt_id[0]);
530 		test_err_mock_domain_replace(ENOENT, self->stdev_id,
531 					     nested_hwpt_id[1]);
532 	}
533 }
534 
535 TEST_F(iommufd_ioas, hwpt_attach)
536 {
537 	/* Create a device attached directly to a hwpt */
538 	if (self->stdev_id) {
539 		test_cmd_mock_domain(self->hwpt_id, NULL, NULL, NULL);
540 	} else {
541 		test_err_mock_domain(ENOENT, self->hwpt_id, NULL, NULL);
542 	}
543 }
544 
545 TEST_F(iommufd_ioas, ioas_area_destroy)
546 {
547 	/* Adding an area does not change ability to destroy */
548 	test_ioctl_ioas_map_fixed(buffer, PAGE_SIZE, self->base_iova);
549 	if (self->stdev_id)
550 		EXPECT_ERRNO(EBUSY,
551 			     _test_ioctl_destroy(self->fd, self->ioas_id));
552 	else
553 		test_ioctl_destroy(self->ioas_id);
554 }
555 
556 TEST_F(iommufd_ioas, ioas_area_auto_destroy)
557 {
558 	int i;
559 
560 	/* Can allocate and automatically free an IOAS table with many areas */
561 	for (i = 0; i != 10; i++) {
562 		test_ioctl_ioas_map_fixed(buffer, PAGE_SIZE,
563 					  self->base_iova + i * PAGE_SIZE);
564 	}
565 }
566 
567 TEST_F(iommufd_ioas, get_hw_info)
568 {
569 	struct iommu_test_hw_info buffer_exact;
570 	struct iommu_test_hw_info_buffer_larger {
571 		struct iommu_test_hw_info info;
572 		uint64_t trailing_bytes;
573 	} buffer_larger;
574 	struct iommu_test_hw_info_buffer_smaller {
575 		__u32 flags;
576 	} buffer_smaller;
577 
578 	if (self->device_id) {
579 		/* Provide a zero-size user_buffer */
580 		test_cmd_get_hw_info(self->device_id, NULL, 0);
581 		/* Provide a user_buffer with exact size */
582 		test_cmd_get_hw_info(self->device_id, &buffer_exact, sizeof(buffer_exact));
583 		/*
584 		 * Provide a user_buffer with size larger than the exact size to check if
585 		 * kernel zero the trailing bytes.
586 		 */
587 		test_cmd_get_hw_info(self->device_id, &buffer_larger, sizeof(buffer_larger));
588 		/*
589 		 * Provide a user_buffer with size smaller than the exact size to check if
590 		 * the fields within the size range still gets updated.
591 		 */
592 		test_cmd_get_hw_info(self->device_id, &buffer_smaller, sizeof(buffer_smaller));
593 	} else {
594 		test_err_get_hw_info(ENOENT, self->device_id,
595 				     &buffer_exact, sizeof(buffer_exact));
596 		test_err_get_hw_info(ENOENT, self->device_id,
597 				     &buffer_larger, sizeof(buffer_larger));
598 	}
599 }
600 
601 TEST_F(iommufd_ioas, area)
602 {
603 	int i;
604 
605 	/* Unmap fails if nothing is mapped */
606 	for (i = 0; i != 10; i++)
607 		test_err_ioctl_ioas_unmap(ENOENT, i * PAGE_SIZE, PAGE_SIZE);
608 
609 	/* Unmap works */
610 	for (i = 0; i != 10; i++)
611 		test_ioctl_ioas_map_fixed(buffer, PAGE_SIZE,
612 					  self->base_iova + i * PAGE_SIZE);
613 	for (i = 0; i != 10; i++)
614 		test_ioctl_ioas_unmap(self->base_iova + i * PAGE_SIZE,
615 				      PAGE_SIZE);
616 
617 	/* Split fails */
618 	test_ioctl_ioas_map_fixed(buffer, PAGE_SIZE * 2,
619 				  self->base_iova + 16 * PAGE_SIZE);
620 	test_err_ioctl_ioas_unmap(ENOENT, self->base_iova + 16 * PAGE_SIZE,
621 				  PAGE_SIZE);
622 	test_err_ioctl_ioas_unmap(ENOENT, self->base_iova + 17 * PAGE_SIZE,
623 				  PAGE_SIZE);
624 
625 	/* Over map fails */
626 	test_err_ioctl_ioas_map_fixed(EEXIST, buffer, PAGE_SIZE * 2,
627 				      self->base_iova + 16 * PAGE_SIZE);
628 	test_err_ioctl_ioas_map_fixed(EEXIST, buffer, PAGE_SIZE,
629 				      self->base_iova + 16 * PAGE_SIZE);
630 	test_err_ioctl_ioas_map_fixed(EEXIST, buffer, PAGE_SIZE,
631 				      self->base_iova + 17 * PAGE_SIZE);
632 	test_err_ioctl_ioas_map_fixed(EEXIST, buffer, PAGE_SIZE * 2,
633 				      self->base_iova + 15 * PAGE_SIZE);
634 	test_err_ioctl_ioas_map_fixed(EEXIST, buffer, PAGE_SIZE * 3,
635 				      self->base_iova + 15 * PAGE_SIZE);
636 
637 	/* unmap all works */
638 	test_ioctl_ioas_unmap(0, UINT64_MAX);
639 
640 	/* Unmap all succeeds on an empty IOAS */
641 	test_ioctl_ioas_unmap(0, UINT64_MAX);
642 }
643 
644 TEST_F(iommufd_ioas, unmap_fully_contained_areas)
645 {
646 	uint64_t unmap_len;
647 	int i;
648 
649 	/* Give no_domain some space to rewind base_iova */
650 	self->base_iova += 4 * PAGE_SIZE;
651 
652 	for (i = 0; i != 4; i++)
653 		test_ioctl_ioas_map_fixed(buffer, 8 * PAGE_SIZE,
654 					  self->base_iova + i * 16 * PAGE_SIZE);
655 
656 	/* Unmap not fully contained area doesn't work */
657 	test_err_ioctl_ioas_unmap(ENOENT, self->base_iova - 4 * PAGE_SIZE,
658 				  8 * PAGE_SIZE);
659 	test_err_ioctl_ioas_unmap(ENOENT,
660 				  self->base_iova + 3 * 16 * PAGE_SIZE +
661 					  8 * PAGE_SIZE - 4 * PAGE_SIZE,
662 				  8 * PAGE_SIZE);
663 
664 	/* Unmap fully contained areas works */
665 	ASSERT_EQ(0, _test_ioctl_ioas_unmap(self->fd, self->ioas_id,
666 					    self->base_iova - 4 * PAGE_SIZE,
667 					    3 * 16 * PAGE_SIZE + 8 * PAGE_SIZE +
668 						    4 * PAGE_SIZE,
669 					    &unmap_len));
670 	ASSERT_EQ(32 * PAGE_SIZE, unmap_len);
671 }
672 
673 TEST_F(iommufd_ioas, area_auto_iova)
674 {
675 	struct iommu_test_cmd test_cmd = {
676 		.size = sizeof(test_cmd),
677 		.op = IOMMU_TEST_OP_ADD_RESERVED,
678 		.id = self->ioas_id,
679 		.add_reserved = { .start = PAGE_SIZE * 4,
680 				  .length = PAGE_SIZE * 100 },
681 	};
682 	struct iommu_iova_range ranges[1] = {};
683 	struct iommu_ioas_allow_iovas allow_cmd = {
684 		.size = sizeof(allow_cmd),
685 		.ioas_id = self->ioas_id,
686 		.num_iovas = 1,
687 		.allowed_iovas = (uintptr_t)ranges,
688 	};
689 	__u64 iovas[10];
690 	int i;
691 
692 	/* Simple 4k pages */
693 	for (i = 0; i != 10; i++)
694 		test_ioctl_ioas_map(buffer, PAGE_SIZE, &iovas[i]);
695 	for (i = 0; i != 10; i++)
696 		test_ioctl_ioas_unmap(iovas[i], PAGE_SIZE);
697 
698 	/* Kernel automatically aligns IOVAs properly */
699 	for (i = 0; i != 10; i++) {
700 		size_t length = PAGE_SIZE * (i + 1);
701 
702 		if (self->stdev_id) {
703 			test_ioctl_ioas_map(buffer, length, &iovas[i]);
704 		} else {
705 			test_ioctl_ioas_map((void *)(1UL << 31), length,
706 					    &iovas[i]);
707 		}
708 		EXPECT_EQ(0, iovas[i] % (1UL << (ffs(length) - 1)));
709 	}
710 	for (i = 0; i != 10; i++)
711 		test_ioctl_ioas_unmap(iovas[i], PAGE_SIZE * (i + 1));
712 
713 	/* Avoids a reserved region */
714 	ASSERT_EQ(0,
715 		  ioctl(self->fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ADD_RESERVED),
716 			&test_cmd));
717 	for (i = 0; i != 10; i++) {
718 		size_t length = PAGE_SIZE * (i + 1);
719 
720 		test_ioctl_ioas_map(buffer, length, &iovas[i]);
721 		EXPECT_EQ(0, iovas[i] % (1UL << (ffs(length) - 1)));
722 		EXPECT_EQ(false,
723 			  iovas[i] > test_cmd.add_reserved.start &&
724 				  iovas[i] <
725 					  test_cmd.add_reserved.start +
726 						  test_cmd.add_reserved.length);
727 	}
728 	for (i = 0; i != 10; i++)
729 		test_ioctl_ioas_unmap(iovas[i], PAGE_SIZE * (i + 1));
730 
731 	/* Allowed region intersects with a reserved region */
732 	ranges[0].start = PAGE_SIZE;
733 	ranges[0].last = PAGE_SIZE * 600;
734 	EXPECT_ERRNO(EADDRINUSE,
735 		     ioctl(self->fd, IOMMU_IOAS_ALLOW_IOVAS, &allow_cmd));
736 
737 	/* Allocate from an allowed region */
738 	if (self->stdev_id) {
739 		ranges[0].start = MOCK_APERTURE_START + PAGE_SIZE;
740 		ranges[0].last = MOCK_APERTURE_START + PAGE_SIZE * 600 - 1;
741 	} else {
742 		ranges[0].start = PAGE_SIZE * 200;
743 		ranges[0].last = PAGE_SIZE * 600 - 1;
744 	}
745 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_IOAS_ALLOW_IOVAS, &allow_cmd));
746 	for (i = 0; i != 10; i++) {
747 		size_t length = PAGE_SIZE * (i + 1);
748 
749 		test_ioctl_ioas_map(buffer, length, &iovas[i]);
750 		EXPECT_EQ(0, iovas[i] % (1UL << (ffs(length) - 1)));
751 		EXPECT_EQ(true, iovas[i] >= ranges[0].start);
752 		EXPECT_EQ(true, iovas[i] <= ranges[0].last);
753 		EXPECT_EQ(true, iovas[i] + length > ranges[0].start);
754 		EXPECT_EQ(true, iovas[i] + length <= ranges[0].last + 1);
755 	}
756 	for (i = 0; i != 10; i++)
757 		test_ioctl_ioas_unmap(iovas[i], PAGE_SIZE * (i + 1));
758 }
759 
760 TEST_F(iommufd_ioas, area_allowed)
761 {
762 	struct iommu_test_cmd test_cmd = {
763 		.size = sizeof(test_cmd),
764 		.op = IOMMU_TEST_OP_ADD_RESERVED,
765 		.id = self->ioas_id,
766 		.add_reserved = { .start = PAGE_SIZE * 4,
767 				  .length = PAGE_SIZE * 100 },
768 	};
769 	struct iommu_iova_range ranges[1] = {};
770 	struct iommu_ioas_allow_iovas allow_cmd = {
771 		.size = sizeof(allow_cmd),
772 		.ioas_id = self->ioas_id,
773 		.num_iovas = 1,
774 		.allowed_iovas = (uintptr_t)ranges,
775 	};
776 
777 	/* Reserved intersects an allowed */
778 	allow_cmd.num_iovas = 1;
779 	ranges[0].start = self->base_iova;
780 	ranges[0].last = ranges[0].start + PAGE_SIZE * 600;
781 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_IOAS_ALLOW_IOVAS, &allow_cmd));
782 	test_cmd.add_reserved.start = ranges[0].start + PAGE_SIZE;
783 	test_cmd.add_reserved.length = PAGE_SIZE;
784 	EXPECT_ERRNO(EADDRINUSE,
785 		     ioctl(self->fd,
786 			   _IOMMU_TEST_CMD(IOMMU_TEST_OP_ADD_RESERVED),
787 			   &test_cmd));
788 	allow_cmd.num_iovas = 0;
789 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_IOAS_ALLOW_IOVAS, &allow_cmd));
790 
791 	/* Allowed intersects a reserved */
792 	ASSERT_EQ(0,
793 		  ioctl(self->fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ADD_RESERVED),
794 			&test_cmd));
795 	allow_cmd.num_iovas = 1;
796 	ranges[0].start = self->base_iova;
797 	ranges[0].last = ranges[0].start + PAGE_SIZE * 600;
798 	EXPECT_ERRNO(EADDRINUSE,
799 		     ioctl(self->fd, IOMMU_IOAS_ALLOW_IOVAS, &allow_cmd));
800 }
801 
802 TEST_F(iommufd_ioas, copy_area)
803 {
804 	struct iommu_ioas_copy copy_cmd = {
805 		.size = sizeof(copy_cmd),
806 		.flags = IOMMU_IOAS_MAP_FIXED_IOVA,
807 		.dst_ioas_id = self->ioas_id,
808 		.src_ioas_id = self->ioas_id,
809 		.length = PAGE_SIZE,
810 	};
811 
812 	test_ioctl_ioas_map_fixed(buffer, PAGE_SIZE, self->base_iova);
813 
814 	/* Copy inside a single IOAS */
815 	copy_cmd.src_iova = self->base_iova;
816 	copy_cmd.dst_iova = self->base_iova + PAGE_SIZE;
817 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_IOAS_COPY, &copy_cmd));
818 
819 	/* Copy between IOAS's */
820 	copy_cmd.src_iova = self->base_iova;
821 	copy_cmd.dst_iova = 0;
822 	test_ioctl_ioas_alloc(&copy_cmd.dst_ioas_id);
823 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_IOAS_COPY, &copy_cmd));
824 }
825 
826 TEST_F(iommufd_ioas, iova_ranges)
827 {
828 	struct iommu_test_cmd test_cmd = {
829 		.size = sizeof(test_cmd),
830 		.op = IOMMU_TEST_OP_ADD_RESERVED,
831 		.id = self->ioas_id,
832 		.add_reserved = { .start = PAGE_SIZE, .length = PAGE_SIZE },
833 	};
834 	struct iommu_iova_range *ranges = buffer;
835 	struct iommu_ioas_iova_ranges ranges_cmd = {
836 		.size = sizeof(ranges_cmd),
837 		.ioas_id = self->ioas_id,
838 		.num_iovas = BUFFER_SIZE / sizeof(*ranges),
839 		.allowed_iovas = (uintptr_t)ranges,
840 	};
841 
842 	/* Range can be read */
843 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_IOAS_IOVA_RANGES, &ranges_cmd));
844 	EXPECT_EQ(1, ranges_cmd.num_iovas);
845 	if (!self->stdev_id) {
846 		EXPECT_EQ(0, ranges[0].start);
847 		EXPECT_EQ(SIZE_MAX, ranges[0].last);
848 		EXPECT_EQ(1, ranges_cmd.out_iova_alignment);
849 	} else {
850 		EXPECT_EQ(MOCK_APERTURE_START, ranges[0].start);
851 		EXPECT_EQ(MOCK_APERTURE_LAST, ranges[0].last);
852 		EXPECT_EQ(MOCK_PAGE_SIZE, ranges_cmd.out_iova_alignment);
853 	}
854 
855 	/* Buffer too small */
856 	memset(ranges, 0, BUFFER_SIZE);
857 	ranges_cmd.num_iovas = 0;
858 	EXPECT_ERRNO(EMSGSIZE,
859 		     ioctl(self->fd, IOMMU_IOAS_IOVA_RANGES, &ranges_cmd));
860 	EXPECT_EQ(1, ranges_cmd.num_iovas);
861 	EXPECT_EQ(0, ranges[0].start);
862 	EXPECT_EQ(0, ranges[0].last);
863 
864 	/* 2 ranges */
865 	ASSERT_EQ(0,
866 		  ioctl(self->fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ADD_RESERVED),
867 			&test_cmd));
868 	ranges_cmd.num_iovas = BUFFER_SIZE / sizeof(*ranges);
869 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_IOAS_IOVA_RANGES, &ranges_cmd));
870 	if (!self->stdev_id) {
871 		EXPECT_EQ(2, ranges_cmd.num_iovas);
872 		EXPECT_EQ(0, ranges[0].start);
873 		EXPECT_EQ(PAGE_SIZE - 1, ranges[0].last);
874 		EXPECT_EQ(PAGE_SIZE * 2, ranges[1].start);
875 		EXPECT_EQ(SIZE_MAX, ranges[1].last);
876 	} else {
877 		EXPECT_EQ(1, ranges_cmd.num_iovas);
878 		EXPECT_EQ(MOCK_APERTURE_START, ranges[0].start);
879 		EXPECT_EQ(MOCK_APERTURE_LAST, ranges[0].last);
880 	}
881 
882 	/* Buffer too small */
883 	memset(ranges, 0, BUFFER_SIZE);
884 	ranges_cmd.num_iovas = 1;
885 	if (!self->stdev_id) {
886 		EXPECT_ERRNO(EMSGSIZE, ioctl(self->fd, IOMMU_IOAS_IOVA_RANGES,
887 					     &ranges_cmd));
888 		EXPECT_EQ(2, ranges_cmd.num_iovas);
889 		EXPECT_EQ(0, ranges[0].start);
890 		EXPECT_EQ(PAGE_SIZE - 1, ranges[0].last);
891 	} else {
892 		ASSERT_EQ(0,
893 			  ioctl(self->fd, IOMMU_IOAS_IOVA_RANGES, &ranges_cmd));
894 		EXPECT_EQ(1, ranges_cmd.num_iovas);
895 		EXPECT_EQ(MOCK_APERTURE_START, ranges[0].start);
896 		EXPECT_EQ(MOCK_APERTURE_LAST, ranges[0].last);
897 	}
898 	EXPECT_EQ(0, ranges[1].start);
899 	EXPECT_EQ(0, ranges[1].last);
900 }
901 
902 TEST_F(iommufd_ioas, access_domain_destory)
903 {
904 	struct iommu_test_cmd access_cmd = {
905 		.size = sizeof(access_cmd),
906 		.op = IOMMU_TEST_OP_ACCESS_PAGES,
907 		.access_pages = { .iova = self->base_iova + PAGE_SIZE,
908 				  .length = PAGE_SIZE},
909 	};
910 	size_t buf_size = 2 * HUGEPAGE_SIZE;
911 	uint8_t *buf;
912 
913 	buf = mmap(0, buf_size, PROT_READ | PROT_WRITE,
914 		   MAP_SHARED | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, -1,
915 		   0);
916 	ASSERT_NE(MAP_FAILED, buf);
917 	test_ioctl_ioas_map_fixed(buf, buf_size, self->base_iova);
918 
919 	test_cmd_create_access(self->ioas_id, &access_cmd.id,
920 			       MOCK_FLAGS_ACCESS_CREATE_NEEDS_PIN_PAGES);
921 	access_cmd.access_pages.uptr = (uintptr_t)buf + PAGE_SIZE;
922 	ASSERT_EQ(0,
923 		  ioctl(self->fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_PAGES),
924 			&access_cmd));
925 
926 	/* Causes a complicated unpin across a huge page boundary */
927 	if (self->stdev_id)
928 		test_ioctl_destroy(self->stdev_id);
929 
930 	test_cmd_destroy_access_pages(
931 		access_cmd.id, access_cmd.access_pages.out_access_pages_id);
932 	test_cmd_destroy_access(access_cmd.id);
933 	ASSERT_EQ(0, munmap(buf, buf_size));
934 }
935 
936 TEST_F(iommufd_ioas, access_pin)
937 {
938 	struct iommu_test_cmd access_cmd = {
939 		.size = sizeof(access_cmd),
940 		.op = IOMMU_TEST_OP_ACCESS_PAGES,
941 		.access_pages = { .iova = MOCK_APERTURE_START,
942 				  .length = BUFFER_SIZE,
943 				  .uptr = (uintptr_t)buffer },
944 	};
945 	struct iommu_test_cmd check_map_cmd = {
946 		.size = sizeof(check_map_cmd),
947 		.op = IOMMU_TEST_OP_MD_CHECK_MAP,
948 		.check_map = { .iova = MOCK_APERTURE_START,
949 			       .length = BUFFER_SIZE,
950 			       .uptr = (uintptr_t)buffer },
951 	};
952 	uint32_t access_pages_id;
953 	unsigned int npages;
954 
955 	test_cmd_create_access(self->ioas_id, &access_cmd.id,
956 			       MOCK_FLAGS_ACCESS_CREATE_NEEDS_PIN_PAGES);
957 
958 	for (npages = 1; npages < BUFFER_SIZE / PAGE_SIZE; npages++) {
959 		uint32_t mock_stdev_id;
960 		uint32_t mock_hwpt_id;
961 
962 		access_cmd.access_pages.length = npages * PAGE_SIZE;
963 
964 		/* Single map/unmap */
965 		test_ioctl_ioas_map_fixed(buffer, BUFFER_SIZE,
966 					  MOCK_APERTURE_START);
967 		ASSERT_EQ(0, ioctl(self->fd,
968 				   _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_PAGES),
969 				   &access_cmd));
970 		test_cmd_destroy_access_pages(
971 			access_cmd.id,
972 			access_cmd.access_pages.out_access_pages_id);
973 
974 		/* Double user */
975 		ASSERT_EQ(0, ioctl(self->fd,
976 				   _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_PAGES),
977 				   &access_cmd));
978 		access_pages_id = access_cmd.access_pages.out_access_pages_id;
979 		ASSERT_EQ(0, ioctl(self->fd,
980 				   _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_PAGES),
981 				   &access_cmd));
982 		test_cmd_destroy_access_pages(
983 			access_cmd.id,
984 			access_cmd.access_pages.out_access_pages_id);
985 		test_cmd_destroy_access_pages(access_cmd.id, access_pages_id);
986 
987 		/* Add/remove a domain with a user */
988 		ASSERT_EQ(0, ioctl(self->fd,
989 				   _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_PAGES),
990 				   &access_cmd));
991 		test_cmd_mock_domain(self->ioas_id, &mock_stdev_id,
992 				     &mock_hwpt_id, NULL);
993 		check_map_cmd.id = mock_hwpt_id;
994 		ASSERT_EQ(0, ioctl(self->fd,
995 				   _IOMMU_TEST_CMD(IOMMU_TEST_OP_MD_CHECK_MAP),
996 				   &check_map_cmd));
997 
998 		test_ioctl_destroy(mock_stdev_id);
999 		test_cmd_destroy_access_pages(
1000 			access_cmd.id,
1001 			access_cmd.access_pages.out_access_pages_id);
1002 
1003 		test_ioctl_ioas_unmap(MOCK_APERTURE_START, BUFFER_SIZE);
1004 	}
1005 	test_cmd_destroy_access(access_cmd.id);
1006 }
1007 
1008 TEST_F(iommufd_ioas, access_pin_unmap)
1009 {
1010 	struct iommu_test_cmd access_pages_cmd = {
1011 		.size = sizeof(access_pages_cmd),
1012 		.op = IOMMU_TEST_OP_ACCESS_PAGES,
1013 		.access_pages = { .iova = MOCK_APERTURE_START,
1014 				  .length = BUFFER_SIZE,
1015 				  .uptr = (uintptr_t)buffer },
1016 	};
1017 
1018 	test_cmd_create_access(self->ioas_id, &access_pages_cmd.id,
1019 			       MOCK_FLAGS_ACCESS_CREATE_NEEDS_PIN_PAGES);
1020 	test_ioctl_ioas_map_fixed(buffer, BUFFER_SIZE, MOCK_APERTURE_START);
1021 	ASSERT_EQ(0,
1022 		  ioctl(self->fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_PAGES),
1023 			&access_pages_cmd));
1024 
1025 	/* Trigger the unmap op */
1026 	test_ioctl_ioas_unmap(MOCK_APERTURE_START, BUFFER_SIZE);
1027 
1028 	/* kernel removed the item for us */
1029 	test_err_destroy_access_pages(
1030 		ENOENT, access_pages_cmd.id,
1031 		access_pages_cmd.access_pages.out_access_pages_id);
1032 }
1033 
1034 static void check_access_rw(struct __test_metadata *_metadata, int fd,
1035 			    unsigned int access_id, uint64_t iova,
1036 			    unsigned int def_flags)
1037 {
1038 	uint16_t tmp[32];
1039 	struct iommu_test_cmd access_cmd = {
1040 		.size = sizeof(access_cmd),
1041 		.op = IOMMU_TEST_OP_ACCESS_RW,
1042 		.id = access_id,
1043 		.access_rw = { .uptr = (uintptr_t)tmp },
1044 	};
1045 	uint16_t *buffer16 = buffer;
1046 	unsigned int i;
1047 	void *tmp2;
1048 
1049 	for (i = 0; i != BUFFER_SIZE / sizeof(*buffer16); i++)
1050 		buffer16[i] = rand();
1051 
1052 	for (access_cmd.access_rw.iova = iova + PAGE_SIZE - 50;
1053 	     access_cmd.access_rw.iova < iova + PAGE_SIZE + 50;
1054 	     access_cmd.access_rw.iova++) {
1055 		for (access_cmd.access_rw.length = 1;
1056 		     access_cmd.access_rw.length < sizeof(tmp);
1057 		     access_cmd.access_rw.length++) {
1058 			access_cmd.access_rw.flags = def_flags;
1059 			ASSERT_EQ(0, ioctl(fd,
1060 					   _IOMMU_TEST_CMD(
1061 						   IOMMU_TEST_OP_ACCESS_RW),
1062 					   &access_cmd));
1063 			ASSERT_EQ(0,
1064 				  memcmp(buffer + (access_cmd.access_rw.iova -
1065 						   iova),
1066 					 tmp, access_cmd.access_rw.length));
1067 
1068 			for (i = 0; i != ARRAY_SIZE(tmp); i++)
1069 				tmp[i] = rand();
1070 			access_cmd.access_rw.flags = def_flags |
1071 						     MOCK_ACCESS_RW_WRITE;
1072 			ASSERT_EQ(0, ioctl(fd,
1073 					   _IOMMU_TEST_CMD(
1074 						   IOMMU_TEST_OP_ACCESS_RW),
1075 					   &access_cmd));
1076 			ASSERT_EQ(0,
1077 				  memcmp(buffer + (access_cmd.access_rw.iova -
1078 						   iova),
1079 					 tmp, access_cmd.access_rw.length));
1080 		}
1081 	}
1082 
1083 	/* Multi-page test */
1084 	tmp2 = malloc(BUFFER_SIZE);
1085 	ASSERT_NE(NULL, tmp2);
1086 	access_cmd.access_rw.iova = iova;
1087 	access_cmd.access_rw.length = BUFFER_SIZE;
1088 	access_cmd.access_rw.flags = def_flags;
1089 	access_cmd.access_rw.uptr = (uintptr_t)tmp2;
1090 	ASSERT_EQ(0, ioctl(fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_RW),
1091 			   &access_cmd));
1092 	ASSERT_EQ(0, memcmp(buffer, tmp2, access_cmd.access_rw.length));
1093 	free(tmp2);
1094 }
1095 
1096 TEST_F(iommufd_ioas, access_rw)
1097 {
1098 	__u32 access_id;
1099 	__u64 iova;
1100 
1101 	test_cmd_create_access(self->ioas_id, &access_id, 0);
1102 	test_ioctl_ioas_map(buffer, BUFFER_SIZE, &iova);
1103 	check_access_rw(_metadata, self->fd, access_id, iova, 0);
1104 	check_access_rw(_metadata, self->fd, access_id, iova,
1105 			MOCK_ACCESS_RW_SLOW_PATH);
1106 	test_ioctl_ioas_unmap(iova, BUFFER_SIZE);
1107 	test_cmd_destroy_access(access_id);
1108 }
1109 
1110 TEST_F(iommufd_ioas, access_rw_unaligned)
1111 {
1112 	__u32 access_id;
1113 	__u64 iova;
1114 
1115 	test_cmd_create_access(self->ioas_id, &access_id, 0);
1116 
1117 	/* Unaligned pages */
1118 	iova = self->base_iova + MOCK_PAGE_SIZE;
1119 	test_ioctl_ioas_map_fixed(buffer, BUFFER_SIZE, iova);
1120 	check_access_rw(_metadata, self->fd, access_id, iova, 0);
1121 	test_ioctl_ioas_unmap(iova, BUFFER_SIZE);
1122 	test_cmd_destroy_access(access_id);
1123 }
1124 
1125 TEST_F(iommufd_ioas, fork_gone)
1126 {
1127 	__u32 access_id;
1128 	pid_t child;
1129 
1130 	test_cmd_create_access(self->ioas_id, &access_id, 0);
1131 
1132 	/* Create a mapping with a different mm */
1133 	child = fork();
1134 	if (!child) {
1135 		test_ioctl_ioas_map_fixed(buffer, BUFFER_SIZE,
1136 					  MOCK_APERTURE_START);
1137 		exit(0);
1138 	}
1139 	ASSERT_NE(-1, child);
1140 	ASSERT_EQ(child, waitpid(child, NULL, 0));
1141 
1142 	if (self->stdev_id) {
1143 		/*
1144 		 * If a domain already existed then everything was pinned within
1145 		 * the fork, so this copies from one domain to another.
1146 		 */
1147 		test_cmd_mock_domain(self->ioas_id, NULL, NULL, NULL);
1148 		check_access_rw(_metadata, self->fd, access_id,
1149 				MOCK_APERTURE_START, 0);
1150 
1151 	} else {
1152 		/*
1153 		 * Otherwise we need to actually pin pages which can't happen
1154 		 * since the fork is gone.
1155 		 */
1156 		test_err_mock_domain(EFAULT, self->ioas_id, NULL, NULL);
1157 	}
1158 
1159 	test_cmd_destroy_access(access_id);
1160 }
1161 
1162 TEST_F(iommufd_ioas, fork_present)
1163 {
1164 	__u32 access_id;
1165 	int pipefds[2];
1166 	uint64_t tmp;
1167 	pid_t child;
1168 	int efd;
1169 
1170 	test_cmd_create_access(self->ioas_id, &access_id, 0);
1171 
1172 	ASSERT_EQ(0, pipe2(pipefds, O_CLOEXEC));
1173 	efd = eventfd(0, EFD_CLOEXEC);
1174 	ASSERT_NE(-1, efd);
1175 
1176 	/* Create a mapping with a different mm */
1177 	child = fork();
1178 	if (!child) {
1179 		__u64 iova;
1180 		uint64_t one = 1;
1181 
1182 		close(pipefds[1]);
1183 		test_ioctl_ioas_map_fixed(buffer, BUFFER_SIZE,
1184 					  MOCK_APERTURE_START);
1185 		if (write(efd, &one, sizeof(one)) != sizeof(one))
1186 			exit(100);
1187 		if (read(pipefds[0], &iova, 1) != 1)
1188 			exit(100);
1189 		exit(0);
1190 	}
1191 	close(pipefds[0]);
1192 	ASSERT_NE(-1, child);
1193 	ASSERT_EQ(8, read(efd, &tmp, sizeof(tmp)));
1194 
1195 	/* Read pages from the remote process */
1196 	test_cmd_mock_domain(self->ioas_id, NULL, NULL, NULL);
1197 	check_access_rw(_metadata, self->fd, access_id, MOCK_APERTURE_START, 0);
1198 
1199 	ASSERT_EQ(0, close(pipefds[1]));
1200 	ASSERT_EQ(child, waitpid(child, NULL, 0));
1201 
1202 	test_cmd_destroy_access(access_id);
1203 }
1204 
1205 TEST_F(iommufd_ioas, ioas_option_huge_pages)
1206 {
1207 	struct iommu_option cmd = {
1208 		.size = sizeof(cmd),
1209 		.option_id = IOMMU_OPTION_HUGE_PAGES,
1210 		.op = IOMMU_OPTION_OP_GET,
1211 		.val64 = 3,
1212 		.object_id = self->ioas_id,
1213 	};
1214 
1215 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_OPTION, &cmd));
1216 	ASSERT_EQ(1, cmd.val64);
1217 
1218 	cmd.op = IOMMU_OPTION_OP_SET;
1219 	cmd.val64 = 0;
1220 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_OPTION, &cmd));
1221 
1222 	cmd.op = IOMMU_OPTION_OP_GET;
1223 	cmd.val64 = 3;
1224 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_OPTION, &cmd));
1225 	ASSERT_EQ(0, cmd.val64);
1226 
1227 	cmd.op = IOMMU_OPTION_OP_SET;
1228 	cmd.val64 = 2;
1229 	EXPECT_ERRNO(EINVAL, ioctl(self->fd, IOMMU_OPTION, &cmd));
1230 
1231 	cmd.op = IOMMU_OPTION_OP_SET;
1232 	cmd.val64 = 1;
1233 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_OPTION, &cmd));
1234 }
1235 
1236 TEST_F(iommufd_ioas, ioas_iova_alloc)
1237 {
1238 	unsigned int length;
1239 	__u64 iova;
1240 
1241 	for (length = 1; length != PAGE_SIZE * 2; length++) {
1242 		if (variant->mock_domains && (length % MOCK_PAGE_SIZE)) {
1243 			test_err_ioctl_ioas_map(EINVAL, buffer, length, &iova);
1244 		} else {
1245 			test_ioctl_ioas_map(buffer, length, &iova);
1246 			test_ioctl_ioas_unmap(iova, length);
1247 		}
1248 	}
1249 }
1250 
1251 TEST_F(iommufd_ioas, ioas_align_change)
1252 {
1253 	struct iommu_option cmd = {
1254 		.size = sizeof(cmd),
1255 		.option_id = IOMMU_OPTION_HUGE_PAGES,
1256 		.op = IOMMU_OPTION_OP_SET,
1257 		.object_id = self->ioas_id,
1258 		/* 0 means everything must be aligned to PAGE_SIZE */
1259 		.val64 = 0,
1260 	};
1261 
1262 	/*
1263 	 * We cannot upgrade the alignment using OPTION_HUGE_PAGES when a domain
1264 	 * and map are present.
1265 	 */
1266 	if (variant->mock_domains)
1267 		return;
1268 
1269 	/*
1270 	 * We can upgrade to PAGE_SIZE alignment when things are aligned right
1271 	 */
1272 	test_ioctl_ioas_map_fixed(buffer, PAGE_SIZE, MOCK_APERTURE_START);
1273 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_OPTION, &cmd));
1274 
1275 	/* Misalignment is rejected at map time */
1276 	test_err_ioctl_ioas_map_fixed(EINVAL, buffer + MOCK_PAGE_SIZE,
1277 				      PAGE_SIZE,
1278 				      MOCK_APERTURE_START + PAGE_SIZE);
1279 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_OPTION, &cmd));
1280 
1281 	/* Reduce alignment */
1282 	cmd.val64 = 1;
1283 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_OPTION, &cmd));
1284 
1285 	/* Confirm misalignment is rejected during alignment upgrade */
1286 	test_ioctl_ioas_map_fixed(buffer + MOCK_PAGE_SIZE, PAGE_SIZE,
1287 				  MOCK_APERTURE_START + PAGE_SIZE);
1288 	cmd.val64 = 0;
1289 	EXPECT_ERRNO(EADDRINUSE, ioctl(self->fd, IOMMU_OPTION, &cmd));
1290 
1291 	test_ioctl_ioas_unmap(MOCK_APERTURE_START + PAGE_SIZE, PAGE_SIZE);
1292 	test_ioctl_ioas_unmap(MOCK_APERTURE_START, PAGE_SIZE);
1293 }
1294 
1295 TEST_F(iommufd_ioas, copy_sweep)
1296 {
1297 	struct iommu_ioas_copy copy_cmd = {
1298 		.size = sizeof(copy_cmd),
1299 		.flags = IOMMU_IOAS_MAP_FIXED_IOVA,
1300 		.src_ioas_id = self->ioas_id,
1301 		.dst_iova = MOCK_APERTURE_START,
1302 		.length = MOCK_PAGE_SIZE,
1303 	};
1304 	unsigned int dst_ioas_id;
1305 	uint64_t last_iova;
1306 	uint64_t iova;
1307 
1308 	test_ioctl_ioas_alloc(&dst_ioas_id);
1309 	copy_cmd.dst_ioas_id = dst_ioas_id;
1310 
1311 	if (variant->mock_domains)
1312 		last_iova = MOCK_APERTURE_START + BUFFER_SIZE - 1;
1313 	else
1314 		last_iova = MOCK_APERTURE_START + BUFFER_SIZE - 2;
1315 
1316 	test_ioctl_ioas_map_fixed(buffer, last_iova - MOCK_APERTURE_START + 1,
1317 				  MOCK_APERTURE_START);
1318 
1319 	for (iova = MOCK_APERTURE_START - PAGE_SIZE; iova <= last_iova;
1320 	     iova += 511) {
1321 		copy_cmd.src_iova = iova;
1322 		if (iova < MOCK_APERTURE_START ||
1323 		    iova + copy_cmd.length - 1 > last_iova) {
1324 			EXPECT_ERRNO(ENOENT, ioctl(self->fd, IOMMU_IOAS_COPY,
1325 						   &copy_cmd));
1326 		} else {
1327 			ASSERT_EQ(0,
1328 				  ioctl(self->fd, IOMMU_IOAS_COPY, &copy_cmd));
1329 			test_ioctl_ioas_unmap_id(dst_ioas_id, copy_cmd.dst_iova,
1330 						 copy_cmd.length);
1331 		}
1332 	}
1333 
1334 	test_ioctl_destroy(dst_ioas_id);
1335 }
1336 
1337 FIXTURE(iommufd_mock_domain)
1338 {
1339 	int fd;
1340 	uint32_t ioas_id;
1341 	uint32_t hwpt_id;
1342 	uint32_t hwpt_ids[2];
1343 	uint32_t stdev_ids[2];
1344 	uint32_t idev_ids[2];
1345 	int mmap_flags;
1346 	size_t mmap_buf_size;
1347 };
1348 
1349 FIXTURE_VARIANT(iommufd_mock_domain)
1350 {
1351 	unsigned int mock_domains;
1352 	bool hugepages;
1353 };
1354 
1355 FIXTURE_SETUP(iommufd_mock_domain)
1356 {
1357 	unsigned int i;
1358 
1359 	self->fd = open("/dev/iommu", O_RDWR);
1360 	ASSERT_NE(-1, self->fd);
1361 	test_ioctl_ioas_alloc(&self->ioas_id);
1362 
1363 	ASSERT_GE(ARRAY_SIZE(self->hwpt_ids), variant->mock_domains);
1364 
1365 	for (i = 0; i != variant->mock_domains; i++)
1366 		test_cmd_mock_domain(self->ioas_id, &self->stdev_ids[i],
1367 				     &self->hwpt_ids[i], &self->idev_ids[i]);
1368 	self->hwpt_id = self->hwpt_ids[0];
1369 
1370 	self->mmap_flags = MAP_SHARED | MAP_ANONYMOUS;
1371 	self->mmap_buf_size = PAGE_SIZE * 8;
1372 	if (variant->hugepages) {
1373 		/*
1374 		 * MAP_POPULATE will cause the kernel to fail mmap if THPs are
1375 		 * not available.
1376 		 */
1377 		self->mmap_flags |= MAP_HUGETLB | MAP_POPULATE;
1378 		self->mmap_buf_size = HUGEPAGE_SIZE * 2;
1379 	}
1380 }
1381 
1382 FIXTURE_TEARDOWN(iommufd_mock_domain)
1383 {
1384 	teardown_iommufd(self->fd, _metadata);
1385 }
1386 
1387 FIXTURE_VARIANT_ADD(iommufd_mock_domain, one_domain)
1388 {
1389 	.mock_domains = 1,
1390 	.hugepages = false,
1391 };
1392 
1393 FIXTURE_VARIANT_ADD(iommufd_mock_domain, two_domains)
1394 {
1395 	.mock_domains = 2,
1396 	.hugepages = false,
1397 };
1398 
1399 FIXTURE_VARIANT_ADD(iommufd_mock_domain, one_domain_hugepage)
1400 {
1401 	.mock_domains = 1,
1402 	.hugepages = true,
1403 };
1404 
1405 FIXTURE_VARIANT_ADD(iommufd_mock_domain, two_domains_hugepage)
1406 {
1407 	.mock_domains = 2,
1408 	.hugepages = true,
1409 };
1410 
1411 /* Have the kernel check that the user pages made it to the iommu_domain */
1412 #define check_mock_iova(_ptr, _iova, _length)                                \
1413 	({                                                                   \
1414 		struct iommu_test_cmd check_map_cmd = {                      \
1415 			.size = sizeof(check_map_cmd),                       \
1416 			.op = IOMMU_TEST_OP_MD_CHECK_MAP,                    \
1417 			.id = self->hwpt_id,                                 \
1418 			.check_map = { .iova = _iova,                        \
1419 				       .length = _length,                    \
1420 				       .uptr = (uintptr_t)(_ptr) },          \
1421 		};                                                           \
1422 		ASSERT_EQ(0,                                                 \
1423 			  ioctl(self->fd,                                    \
1424 				_IOMMU_TEST_CMD(IOMMU_TEST_OP_MD_CHECK_MAP), \
1425 				&check_map_cmd));                            \
1426 		if (self->hwpt_ids[1]) {                                     \
1427 			check_map_cmd.id = self->hwpt_ids[1];                \
1428 			ASSERT_EQ(0,                                         \
1429 				  ioctl(self->fd,                            \
1430 					_IOMMU_TEST_CMD(                     \
1431 						IOMMU_TEST_OP_MD_CHECK_MAP), \
1432 					&check_map_cmd));                    \
1433 		}                                                            \
1434 	})
1435 
1436 TEST_F(iommufd_mock_domain, basic)
1437 {
1438 	size_t buf_size = self->mmap_buf_size;
1439 	uint8_t *buf;
1440 	__u64 iova;
1441 
1442 	/* Simple one page map */
1443 	test_ioctl_ioas_map(buffer, PAGE_SIZE, &iova);
1444 	check_mock_iova(buffer, iova, PAGE_SIZE);
1445 
1446 	buf = mmap(0, buf_size, PROT_READ | PROT_WRITE, self->mmap_flags, -1,
1447 		   0);
1448 	ASSERT_NE(MAP_FAILED, buf);
1449 
1450 	/* EFAULT half way through mapping */
1451 	ASSERT_EQ(0, munmap(buf + buf_size / 2, buf_size / 2));
1452 	test_err_ioctl_ioas_map(EFAULT, buf, buf_size, &iova);
1453 
1454 	/* EFAULT on first page */
1455 	ASSERT_EQ(0, munmap(buf, buf_size / 2));
1456 	test_err_ioctl_ioas_map(EFAULT, buf, buf_size, &iova);
1457 }
1458 
1459 TEST_F(iommufd_mock_domain, ro_unshare)
1460 {
1461 	uint8_t *buf;
1462 	__u64 iova;
1463 	int fd;
1464 
1465 	fd = open("/proc/self/exe", O_RDONLY);
1466 	ASSERT_NE(-1, fd);
1467 
1468 	buf = mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
1469 	ASSERT_NE(MAP_FAILED, buf);
1470 	close(fd);
1471 
1472 	/*
1473 	 * There have been lots of changes to the "unshare" mechanism in
1474 	 * get_user_pages(), make sure it works right. The write to the page
1475 	 * after we map it for reading should not change the assigned PFN.
1476 	 */
1477 	ASSERT_EQ(0,
1478 		  _test_ioctl_ioas_map(self->fd, self->ioas_id, buf, PAGE_SIZE,
1479 				       &iova, IOMMU_IOAS_MAP_READABLE));
1480 	check_mock_iova(buf, iova, PAGE_SIZE);
1481 	memset(buf, 1, PAGE_SIZE);
1482 	check_mock_iova(buf, iova, PAGE_SIZE);
1483 	ASSERT_EQ(0, munmap(buf, PAGE_SIZE));
1484 }
1485 
1486 TEST_F(iommufd_mock_domain, all_aligns)
1487 {
1488 	size_t test_step = variant->hugepages ? (self->mmap_buf_size / 16) :
1489 						MOCK_PAGE_SIZE;
1490 	size_t buf_size = self->mmap_buf_size;
1491 	unsigned int start;
1492 	unsigned int end;
1493 	uint8_t *buf;
1494 
1495 	buf = mmap(0, buf_size, PROT_READ | PROT_WRITE, self->mmap_flags, -1,
1496 		   0);
1497 	ASSERT_NE(MAP_FAILED, buf);
1498 	check_refs(buf, buf_size, 0);
1499 
1500 	/*
1501 	 * Map every combination of page size and alignment within a big region,
1502 	 * less for hugepage case as it takes so long to finish.
1503 	 */
1504 	for (start = 0; start < buf_size; start += test_step) {
1505 		if (variant->hugepages)
1506 			end = buf_size;
1507 		else
1508 			end = start + MOCK_PAGE_SIZE;
1509 		for (; end < buf_size; end += MOCK_PAGE_SIZE) {
1510 			size_t length = end - start;
1511 			__u64 iova;
1512 
1513 			test_ioctl_ioas_map(buf + start, length, &iova);
1514 			check_mock_iova(buf + start, iova, length);
1515 			check_refs(buf + start / PAGE_SIZE * PAGE_SIZE,
1516 				   end / PAGE_SIZE * PAGE_SIZE -
1517 					   start / PAGE_SIZE * PAGE_SIZE,
1518 				   1);
1519 
1520 			test_ioctl_ioas_unmap(iova, length);
1521 		}
1522 	}
1523 	check_refs(buf, buf_size, 0);
1524 	ASSERT_EQ(0, munmap(buf, buf_size));
1525 }
1526 
1527 TEST_F(iommufd_mock_domain, all_aligns_copy)
1528 {
1529 	size_t test_step = variant->hugepages ? self->mmap_buf_size / 16 :
1530 						MOCK_PAGE_SIZE;
1531 	size_t buf_size = self->mmap_buf_size;
1532 	unsigned int start;
1533 	unsigned int end;
1534 	uint8_t *buf;
1535 
1536 	buf = mmap(0, buf_size, PROT_READ | PROT_WRITE, self->mmap_flags, -1,
1537 		   0);
1538 	ASSERT_NE(MAP_FAILED, buf);
1539 	check_refs(buf, buf_size, 0);
1540 
1541 	/*
1542 	 * Map every combination of page size and alignment within a big region,
1543 	 * less for hugepage case as it takes so long to finish.
1544 	 */
1545 	for (start = 0; start < buf_size; start += test_step) {
1546 		if (variant->hugepages)
1547 			end = buf_size;
1548 		else
1549 			end = start + MOCK_PAGE_SIZE;
1550 		for (; end < buf_size; end += MOCK_PAGE_SIZE) {
1551 			size_t length = end - start;
1552 			unsigned int old_id;
1553 			uint32_t mock_stdev_id;
1554 			__u64 iova;
1555 
1556 			test_ioctl_ioas_map(buf + start, length, &iova);
1557 
1558 			/* Add and destroy a domain while the area exists */
1559 			old_id = self->hwpt_ids[1];
1560 			test_cmd_mock_domain(self->ioas_id, &mock_stdev_id,
1561 					     &self->hwpt_ids[1], NULL);
1562 
1563 			check_mock_iova(buf + start, iova, length);
1564 			check_refs(buf + start / PAGE_SIZE * PAGE_SIZE,
1565 				   end / PAGE_SIZE * PAGE_SIZE -
1566 					   start / PAGE_SIZE * PAGE_SIZE,
1567 				   1);
1568 
1569 			test_ioctl_destroy(mock_stdev_id);
1570 			self->hwpt_ids[1] = old_id;
1571 
1572 			test_ioctl_ioas_unmap(iova, length);
1573 		}
1574 	}
1575 	check_refs(buf, buf_size, 0);
1576 	ASSERT_EQ(0, munmap(buf, buf_size));
1577 }
1578 
1579 TEST_F(iommufd_mock_domain, user_copy)
1580 {
1581 	struct iommu_test_cmd access_cmd = {
1582 		.size = sizeof(access_cmd),
1583 		.op = IOMMU_TEST_OP_ACCESS_PAGES,
1584 		.access_pages = { .length = BUFFER_SIZE,
1585 				  .uptr = (uintptr_t)buffer },
1586 	};
1587 	struct iommu_ioas_copy copy_cmd = {
1588 		.size = sizeof(copy_cmd),
1589 		.flags = IOMMU_IOAS_MAP_FIXED_IOVA,
1590 		.dst_ioas_id = self->ioas_id,
1591 		.dst_iova = MOCK_APERTURE_START,
1592 		.length = BUFFER_SIZE,
1593 	};
1594 	struct iommu_ioas_unmap unmap_cmd = {
1595 		.size = sizeof(unmap_cmd),
1596 		.ioas_id = self->ioas_id,
1597 		.iova = MOCK_APERTURE_START,
1598 		.length = BUFFER_SIZE,
1599 	};
1600 	unsigned int new_ioas_id, ioas_id;
1601 
1602 	/* Pin the pages in an IOAS with no domains then copy to an IOAS with domains */
1603 	test_ioctl_ioas_alloc(&ioas_id);
1604 	test_ioctl_ioas_map_id(ioas_id, buffer, BUFFER_SIZE,
1605 			       &copy_cmd.src_iova);
1606 
1607 	test_cmd_create_access(ioas_id, &access_cmd.id,
1608 			       MOCK_FLAGS_ACCESS_CREATE_NEEDS_PIN_PAGES);
1609 
1610 	access_cmd.access_pages.iova = copy_cmd.src_iova;
1611 	ASSERT_EQ(0,
1612 		  ioctl(self->fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_PAGES),
1613 			&access_cmd));
1614 	copy_cmd.src_ioas_id = ioas_id;
1615 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_IOAS_COPY, &copy_cmd));
1616 	check_mock_iova(buffer, MOCK_APERTURE_START, BUFFER_SIZE);
1617 
1618 	/* Now replace the ioas with a new one */
1619 	test_ioctl_ioas_alloc(&new_ioas_id);
1620 	test_ioctl_ioas_map_id(new_ioas_id, buffer, BUFFER_SIZE,
1621 			       &copy_cmd.src_iova);
1622 	test_cmd_access_replace_ioas(access_cmd.id, new_ioas_id);
1623 
1624 	/* Destroy the old ioas and cleanup copied mapping */
1625 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_IOAS_UNMAP, &unmap_cmd));
1626 	test_ioctl_destroy(ioas_id);
1627 
1628 	/* Then run the same test again with the new ioas */
1629 	access_cmd.access_pages.iova = copy_cmd.src_iova;
1630 	ASSERT_EQ(0,
1631 		  ioctl(self->fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_PAGES),
1632 			&access_cmd));
1633 	copy_cmd.src_ioas_id = new_ioas_id;
1634 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_IOAS_COPY, &copy_cmd));
1635 	check_mock_iova(buffer, MOCK_APERTURE_START, BUFFER_SIZE);
1636 
1637 	test_cmd_destroy_access_pages(
1638 		access_cmd.id, access_cmd.access_pages.out_access_pages_id);
1639 	test_cmd_destroy_access(access_cmd.id);
1640 
1641 	test_ioctl_destroy(new_ioas_id);
1642 }
1643 
1644 TEST_F(iommufd_mock_domain, replace)
1645 {
1646 	uint32_t ioas_id;
1647 
1648 	test_ioctl_ioas_alloc(&ioas_id);
1649 
1650 	test_cmd_mock_domain_replace(self->stdev_ids[0], ioas_id);
1651 
1652 	/*
1653 	 * Replacing the IOAS causes the prior HWPT to be deallocated, thus we
1654 	 * should get enoent when we try to use it.
1655 	 */
1656 	if (variant->mock_domains == 1)
1657 		test_err_mock_domain_replace(ENOENT, self->stdev_ids[0],
1658 					     self->hwpt_ids[0]);
1659 
1660 	test_cmd_mock_domain_replace(self->stdev_ids[0], ioas_id);
1661 	if (variant->mock_domains >= 2) {
1662 		test_cmd_mock_domain_replace(self->stdev_ids[0],
1663 					     self->hwpt_ids[1]);
1664 		test_cmd_mock_domain_replace(self->stdev_ids[0],
1665 					     self->hwpt_ids[1]);
1666 		test_cmd_mock_domain_replace(self->stdev_ids[0],
1667 					     self->hwpt_ids[0]);
1668 	}
1669 
1670 	test_cmd_mock_domain_replace(self->stdev_ids[0], self->ioas_id);
1671 	test_ioctl_destroy(ioas_id);
1672 }
1673 
1674 TEST_F(iommufd_mock_domain, alloc_hwpt)
1675 {
1676 	int i;
1677 
1678 	for (i = 0; i != variant->mock_domains; i++) {
1679 		uint32_t hwpt_id[2];
1680 		uint32_t stddev_id;
1681 
1682 		test_err_hwpt_alloc(EOPNOTSUPP,
1683 				    self->idev_ids[i], self->ioas_id,
1684 				    ~IOMMU_HWPT_ALLOC_NEST_PARENT, &hwpt_id[0]);
1685 		test_cmd_hwpt_alloc(self->idev_ids[i], self->ioas_id,
1686 				    0, &hwpt_id[0]);
1687 		test_cmd_hwpt_alloc(self->idev_ids[i], self->ioas_id,
1688 				    IOMMU_HWPT_ALLOC_NEST_PARENT, &hwpt_id[1]);
1689 
1690 		/* Do a hw_pagetable rotation test */
1691 		test_cmd_mock_domain_replace(self->stdev_ids[i], hwpt_id[0]);
1692 		EXPECT_ERRNO(EBUSY, _test_ioctl_destroy(self->fd, hwpt_id[0]));
1693 		test_cmd_mock_domain_replace(self->stdev_ids[i], hwpt_id[1]);
1694 		EXPECT_ERRNO(EBUSY, _test_ioctl_destroy(self->fd, hwpt_id[1]));
1695 		test_cmd_mock_domain_replace(self->stdev_ids[i], self->ioas_id);
1696 		test_ioctl_destroy(hwpt_id[1]);
1697 
1698 		test_cmd_mock_domain(hwpt_id[0], &stddev_id, NULL, NULL);
1699 		test_ioctl_destroy(stddev_id);
1700 		test_ioctl_destroy(hwpt_id[0]);
1701 	}
1702 }
1703 
1704 FIXTURE(iommufd_dirty_tracking)
1705 {
1706 	int fd;
1707 	uint32_t ioas_id;
1708 	uint32_t hwpt_id;
1709 	uint32_t stdev_id;
1710 	uint32_t idev_id;
1711 	unsigned long page_size;
1712 	unsigned long bitmap_size;
1713 	void *bitmap;
1714 	void *buffer;
1715 };
1716 
1717 FIXTURE_VARIANT(iommufd_dirty_tracking)
1718 {
1719 	unsigned long buffer_size;
1720 	bool hugepages;
1721 };
1722 
1723 FIXTURE_SETUP(iommufd_dirty_tracking)
1724 {
1725 	int mmap_flags;
1726 	void *vrc;
1727 	int rc;
1728 
1729 	self->fd = open("/dev/iommu", O_RDWR);
1730 	ASSERT_NE(-1, self->fd);
1731 
1732 	rc = posix_memalign(&self->buffer, HUGEPAGE_SIZE, variant->buffer_size);
1733 	if (rc || !self->buffer) {
1734 		SKIP(return, "Skipping buffer_size=%lu due to errno=%d",
1735 			   variant->buffer_size, rc);
1736 	}
1737 
1738 	mmap_flags = MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED;
1739 	if (variant->hugepages) {
1740 		/*
1741 		 * MAP_POPULATE will cause the kernel to fail mmap if THPs are
1742 		 * not available.
1743 		 */
1744 		mmap_flags |= MAP_HUGETLB | MAP_POPULATE;
1745 	}
1746 	assert((uintptr_t)self->buffer % HUGEPAGE_SIZE == 0);
1747 	vrc = mmap(self->buffer, variant->buffer_size, PROT_READ | PROT_WRITE,
1748 		   mmap_flags, -1, 0);
1749 	assert(vrc == self->buffer);
1750 
1751 	self->page_size = MOCK_PAGE_SIZE;
1752 	self->bitmap_size =
1753 		variant->buffer_size / self->page_size / BITS_PER_BYTE;
1754 
1755 	/* Provision with an extra (PAGE_SIZE) for the unaligned case */
1756 	rc = posix_memalign(&self->bitmap, PAGE_SIZE,
1757 			    self->bitmap_size + PAGE_SIZE);
1758 	assert(!rc);
1759 	assert(self->bitmap);
1760 	assert((uintptr_t)self->bitmap % PAGE_SIZE == 0);
1761 
1762 	test_ioctl_ioas_alloc(&self->ioas_id);
1763 	/* Enable 1M mock IOMMU hugepages */
1764 	if (variant->hugepages) {
1765 		test_cmd_mock_domain_flags(self->ioas_id,
1766 					   MOCK_FLAGS_DEVICE_HUGE_IOVA,
1767 					   &self->stdev_id, &self->hwpt_id,
1768 					   &self->idev_id);
1769 	} else {
1770 		test_cmd_mock_domain(self->ioas_id, &self->stdev_id,
1771 				     &self->hwpt_id, &self->idev_id);
1772 	}
1773 }
1774 
1775 FIXTURE_TEARDOWN(iommufd_dirty_tracking)
1776 {
1777 	munmap(self->buffer, variant->buffer_size);
1778 	munmap(self->bitmap, self->bitmap_size);
1779 	teardown_iommufd(self->fd, _metadata);
1780 }
1781 
1782 FIXTURE_VARIANT_ADD(iommufd_dirty_tracking, domain_dirty128k)
1783 {
1784 	/* one u32 index bitmap */
1785 	.buffer_size = 128UL * 1024UL,
1786 };
1787 
1788 FIXTURE_VARIANT_ADD(iommufd_dirty_tracking, domain_dirty256k)
1789 {
1790 	/* one u64 index bitmap */
1791 	.buffer_size = 256UL * 1024UL,
1792 };
1793 
1794 FIXTURE_VARIANT_ADD(iommufd_dirty_tracking, domain_dirty640k)
1795 {
1796 	/* two u64 index and trailing end bitmap */
1797 	.buffer_size = 640UL * 1024UL,
1798 };
1799 
1800 FIXTURE_VARIANT_ADD(iommufd_dirty_tracking, domain_dirty128M)
1801 {
1802 	/* 4K bitmap (128M IOVA range) */
1803 	.buffer_size = 128UL * 1024UL * 1024UL,
1804 };
1805 
1806 FIXTURE_VARIANT_ADD(iommufd_dirty_tracking, domain_dirty128M_huge)
1807 {
1808 	/* 4K bitmap (128M IOVA range) */
1809 	.buffer_size = 128UL * 1024UL * 1024UL,
1810 	.hugepages = true,
1811 };
1812 
1813 FIXTURE_VARIANT_ADD(iommufd_dirty_tracking, domain_dirty256M)
1814 {
1815 	/* 8K bitmap (256M IOVA range) */
1816 	.buffer_size = 256UL * 1024UL * 1024UL,
1817 };
1818 
1819 FIXTURE_VARIANT_ADD(iommufd_dirty_tracking, domain_dirty256M_huge)
1820 {
1821 	/* 8K bitmap (256M IOVA range) */
1822 	.buffer_size = 256UL * 1024UL * 1024UL,
1823 	.hugepages = true,
1824 };
1825 
1826 TEST_F(iommufd_dirty_tracking, enforce_dirty)
1827 {
1828 	uint32_t ioas_id, stddev_id, idev_id;
1829 	uint32_t hwpt_id, _hwpt_id;
1830 	uint32_t dev_flags;
1831 
1832 	/* Regular case */
1833 	dev_flags = MOCK_FLAGS_DEVICE_NO_DIRTY;
1834 	test_cmd_hwpt_alloc(self->idev_id, self->ioas_id,
1835 			    IOMMU_HWPT_ALLOC_DIRTY_TRACKING, &hwpt_id);
1836 	test_cmd_mock_domain(hwpt_id, &stddev_id, NULL, NULL);
1837 	test_err_mock_domain_flags(EINVAL, hwpt_id, dev_flags, &stddev_id,
1838 				   NULL);
1839 	test_ioctl_destroy(stddev_id);
1840 	test_ioctl_destroy(hwpt_id);
1841 
1842 	/* IOMMU device does not support dirty tracking */
1843 	test_ioctl_ioas_alloc(&ioas_id);
1844 	test_cmd_mock_domain_flags(ioas_id, dev_flags, &stddev_id, &_hwpt_id,
1845 				   &idev_id);
1846 	test_err_hwpt_alloc(EOPNOTSUPP, idev_id, ioas_id,
1847 			    IOMMU_HWPT_ALLOC_DIRTY_TRACKING, &hwpt_id);
1848 	test_ioctl_destroy(stddev_id);
1849 }
1850 
1851 TEST_F(iommufd_dirty_tracking, set_dirty_tracking)
1852 {
1853 	uint32_t stddev_id;
1854 	uint32_t hwpt_id;
1855 
1856 	test_cmd_hwpt_alloc(self->idev_id, self->ioas_id,
1857 			    IOMMU_HWPT_ALLOC_DIRTY_TRACKING, &hwpt_id);
1858 	test_cmd_mock_domain(hwpt_id, &stddev_id, NULL, NULL);
1859 	test_cmd_set_dirty_tracking(hwpt_id, true);
1860 	test_cmd_set_dirty_tracking(hwpt_id, false);
1861 
1862 	test_ioctl_destroy(stddev_id);
1863 	test_ioctl_destroy(hwpt_id);
1864 }
1865 
1866 TEST_F(iommufd_dirty_tracking, device_dirty_capability)
1867 {
1868 	uint32_t caps = 0;
1869 	uint32_t stddev_id;
1870 	uint32_t hwpt_id;
1871 
1872 	test_cmd_hwpt_alloc(self->idev_id, self->ioas_id, 0, &hwpt_id);
1873 	test_cmd_mock_domain(hwpt_id, &stddev_id, NULL, NULL);
1874 	test_cmd_get_hw_capabilities(self->idev_id, caps,
1875 				     IOMMU_HW_CAP_DIRTY_TRACKING);
1876 	ASSERT_EQ(IOMMU_HW_CAP_DIRTY_TRACKING,
1877 		  caps & IOMMU_HW_CAP_DIRTY_TRACKING);
1878 
1879 	test_ioctl_destroy(stddev_id);
1880 	test_ioctl_destroy(hwpt_id);
1881 }
1882 
1883 TEST_F(iommufd_dirty_tracking, get_dirty_bitmap)
1884 {
1885 	uint32_t page_size = MOCK_PAGE_SIZE;
1886 	uint32_t hwpt_id;
1887 	uint32_t ioas_id;
1888 
1889 	if (variant->hugepages)
1890 		page_size = MOCK_HUGE_PAGE_SIZE;
1891 
1892 	test_ioctl_ioas_alloc(&ioas_id);
1893 	test_ioctl_ioas_map_fixed_id(ioas_id, self->buffer,
1894 				     variant->buffer_size, MOCK_APERTURE_START);
1895 
1896 	test_cmd_hwpt_alloc(self->idev_id, ioas_id,
1897 			    IOMMU_HWPT_ALLOC_DIRTY_TRACKING, &hwpt_id);
1898 
1899 	test_cmd_set_dirty_tracking(hwpt_id, true);
1900 
1901 	test_mock_dirty_bitmaps(hwpt_id, variant->buffer_size,
1902 				MOCK_APERTURE_START, self->page_size, page_size,
1903 				self->bitmap, self->bitmap_size, 0, _metadata);
1904 
1905 	/* PAGE_SIZE unaligned bitmap */
1906 	test_mock_dirty_bitmaps(hwpt_id, variant->buffer_size,
1907 				MOCK_APERTURE_START, self->page_size, page_size,
1908 				self->bitmap + MOCK_PAGE_SIZE,
1909 				self->bitmap_size, 0, _metadata);
1910 
1911 	/* u64 unaligned bitmap */
1912 	test_mock_dirty_bitmaps(hwpt_id, variant->buffer_size,
1913 				MOCK_APERTURE_START, self->page_size, page_size,
1914 				self->bitmap + 0xff1, self->bitmap_size, 0,
1915 				_metadata);
1916 
1917 	test_ioctl_destroy(hwpt_id);
1918 }
1919 
1920 TEST_F(iommufd_dirty_tracking, get_dirty_bitmap_no_clear)
1921 {
1922 	uint32_t page_size = MOCK_PAGE_SIZE;
1923 	uint32_t hwpt_id;
1924 	uint32_t ioas_id;
1925 
1926 	if (variant->hugepages)
1927 		page_size = MOCK_HUGE_PAGE_SIZE;
1928 
1929 	test_ioctl_ioas_alloc(&ioas_id);
1930 	test_ioctl_ioas_map_fixed_id(ioas_id, self->buffer,
1931 				     variant->buffer_size, MOCK_APERTURE_START);
1932 
1933 	test_cmd_hwpt_alloc(self->idev_id, ioas_id,
1934 			    IOMMU_HWPT_ALLOC_DIRTY_TRACKING, &hwpt_id);
1935 
1936 	test_cmd_set_dirty_tracking(hwpt_id, true);
1937 
1938 	test_mock_dirty_bitmaps(hwpt_id, variant->buffer_size,
1939 				MOCK_APERTURE_START, self->page_size, page_size,
1940 				self->bitmap, self->bitmap_size,
1941 				IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR,
1942 				_metadata);
1943 
1944 	/* Unaligned bitmap */
1945 	test_mock_dirty_bitmaps(hwpt_id, variant->buffer_size,
1946 				MOCK_APERTURE_START, self->page_size, page_size,
1947 				self->bitmap + MOCK_PAGE_SIZE,
1948 				self->bitmap_size,
1949 				IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR,
1950 				_metadata);
1951 
1952 	/* u64 unaligned bitmap */
1953 	test_mock_dirty_bitmaps(hwpt_id, variant->buffer_size,
1954 				MOCK_APERTURE_START, self->page_size, page_size,
1955 				self->bitmap + 0xff1, self->bitmap_size,
1956 				IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR,
1957 				_metadata);
1958 
1959 	test_ioctl_destroy(hwpt_id);
1960 }
1961 
1962 /* VFIO compatibility IOCTLs */
1963 
1964 TEST_F(iommufd, simple_ioctls)
1965 {
1966 	ASSERT_EQ(VFIO_API_VERSION, ioctl(self->fd, VFIO_GET_API_VERSION));
1967 	ASSERT_EQ(1, ioctl(self->fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU));
1968 }
1969 
1970 TEST_F(iommufd, unmap_cmd)
1971 {
1972 	struct vfio_iommu_type1_dma_unmap unmap_cmd = {
1973 		.iova = MOCK_APERTURE_START,
1974 		.size = PAGE_SIZE,
1975 	};
1976 
1977 	unmap_cmd.argsz = 1;
1978 	EXPECT_ERRNO(EINVAL, ioctl(self->fd, VFIO_IOMMU_UNMAP_DMA, &unmap_cmd));
1979 
1980 	unmap_cmd.argsz = sizeof(unmap_cmd);
1981 	unmap_cmd.flags = 1 << 31;
1982 	EXPECT_ERRNO(EINVAL, ioctl(self->fd, VFIO_IOMMU_UNMAP_DMA, &unmap_cmd));
1983 
1984 	unmap_cmd.flags = 0;
1985 	EXPECT_ERRNO(ENODEV, ioctl(self->fd, VFIO_IOMMU_UNMAP_DMA, &unmap_cmd));
1986 }
1987 
1988 TEST_F(iommufd, map_cmd)
1989 {
1990 	struct vfio_iommu_type1_dma_map map_cmd = {
1991 		.iova = MOCK_APERTURE_START,
1992 		.size = PAGE_SIZE,
1993 		.vaddr = (__u64)buffer,
1994 	};
1995 
1996 	map_cmd.argsz = 1;
1997 	EXPECT_ERRNO(EINVAL, ioctl(self->fd, VFIO_IOMMU_MAP_DMA, &map_cmd));
1998 
1999 	map_cmd.argsz = sizeof(map_cmd);
2000 	map_cmd.flags = 1 << 31;
2001 	EXPECT_ERRNO(EINVAL, ioctl(self->fd, VFIO_IOMMU_MAP_DMA, &map_cmd));
2002 
2003 	/* Requires a domain to be attached */
2004 	map_cmd.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;
2005 	EXPECT_ERRNO(ENODEV, ioctl(self->fd, VFIO_IOMMU_MAP_DMA, &map_cmd));
2006 }
2007 
2008 TEST_F(iommufd, info_cmd)
2009 {
2010 	struct vfio_iommu_type1_info info_cmd = {};
2011 
2012 	/* Invalid argsz */
2013 	info_cmd.argsz = 1;
2014 	EXPECT_ERRNO(EINVAL, ioctl(self->fd, VFIO_IOMMU_GET_INFO, &info_cmd));
2015 
2016 	info_cmd.argsz = sizeof(info_cmd);
2017 	EXPECT_ERRNO(ENODEV, ioctl(self->fd, VFIO_IOMMU_GET_INFO, &info_cmd));
2018 }
2019 
2020 TEST_F(iommufd, set_iommu_cmd)
2021 {
2022 	/* Requires a domain to be attached */
2023 	EXPECT_ERRNO(ENODEV,
2024 		     ioctl(self->fd, VFIO_SET_IOMMU, VFIO_TYPE1v2_IOMMU));
2025 	EXPECT_ERRNO(ENODEV, ioctl(self->fd, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU));
2026 }
2027 
2028 TEST_F(iommufd, vfio_ioas)
2029 {
2030 	struct iommu_vfio_ioas vfio_ioas_cmd = {
2031 		.size = sizeof(vfio_ioas_cmd),
2032 		.op = IOMMU_VFIO_IOAS_GET,
2033 	};
2034 	__u32 ioas_id;
2035 
2036 	/* ENODEV if there is no compat ioas */
2037 	EXPECT_ERRNO(ENODEV, ioctl(self->fd, IOMMU_VFIO_IOAS, &vfio_ioas_cmd));
2038 
2039 	/* Invalid id for set */
2040 	vfio_ioas_cmd.op = IOMMU_VFIO_IOAS_SET;
2041 	EXPECT_ERRNO(ENOENT, ioctl(self->fd, IOMMU_VFIO_IOAS, &vfio_ioas_cmd));
2042 
2043 	/* Valid id for set*/
2044 	test_ioctl_ioas_alloc(&ioas_id);
2045 	vfio_ioas_cmd.ioas_id = ioas_id;
2046 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_VFIO_IOAS, &vfio_ioas_cmd));
2047 
2048 	/* Same id comes back from get */
2049 	vfio_ioas_cmd.op = IOMMU_VFIO_IOAS_GET;
2050 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_VFIO_IOAS, &vfio_ioas_cmd));
2051 	ASSERT_EQ(ioas_id, vfio_ioas_cmd.ioas_id);
2052 
2053 	/* Clear works */
2054 	vfio_ioas_cmd.op = IOMMU_VFIO_IOAS_CLEAR;
2055 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_VFIO_IOAS, &vfio_ioas_cmd));
2056 	vfio_ioas_cmd.op = IOMMU_VFIO_IOAS_GET;
2057 	EXPECT_ERRNO(ENODEV, ioctl(self->fd, IOMMU_VFIO_IOAS, &vfio_ioas_cmd));
2058 }
2059 
2060 FIXTURE(vfio_compat_mock_domain)
2061 {
2062 	int fd;
2063 	uint32_t ioas_id;
2064 };
2065 
2066 FIXTURE_VARIANT(vfio_compat_mock_domain)
2067 {
2068 	unsigned int version;
2069 };
2070 
2071 FIXTURE_SETUP(vfio_compat_mock_domain)
2072 {
2073 	struct iommu_vfio_ioas vfio_ioas_cmd = {
2074 		.size = sizeof(vfio_ioas_cmd),
2075 		.op = IOMMU_VFIO_IOAS_SET,
2076 	};
2077 
2078 	self->fd = open("/dev/iommu", O_RDWR);
2079 	ASSERT_NE(-1, self->fd);
2080 
2081 	/* Create what VFIO would consider a group */
2082 	test_ioctl_ioas_alloc(&self->ioas_id);
2083 	test_cmd_mock_domain(self->ioas_id, NULL, NULL, NULL);
2084 
2085 	/* Attach it to the vfio compat */
2086 	vfio_ioas_cmd.ioas_id = self->ioas_id;
2087 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_VFIO_IOAS, &vfio_ioas_cmd));
2088 	ASSERT_EQ(0, ioctl(self->fd, VFIO_SET_IOMMU, variant->version));
2089 }
2090 
2091 FIXTURE_TEARDOWN(vfio_compat_mock_domain)
2092 {
2093 	teardown_iommufd(self->fd, _metadata);
2094 }
2095 
2096 FIXTURE_VARIANT_ADD(vfio_compat_mock_domain, Ver1v2)
2097 {
2098 	.version = VFIO_TYPE1v2_IOMMU,
2099 };
2100 
2101 FIXTURE_VARIANT_ADD(vfio_compat_mock_domain, Ver1v0)
2102 {
2103 	.version = VFIO_TYPE1_IOMMU,
2104 };
2105 
2106 TEST_F(vfio_compat_mock_domain, simple_close)
2107 {
2108 }
2109 
2110 TEST_F(vfio_compat_mock_domain, option_huge_pages)
2111 {
2112 	struct iommu_option cmd = {
2113 		.size = sizeof(cmd),
2114 		.option_id = IOMMU_OPTION_HUGE_PAGES,
2115 		.op = IOMMU_OPTION_OP_GET,
2116 		.val64 = 3,
2117 		.object_id = self->ioas_id,
2118 	};
2119 
2120 	ASSERT_EQ(0, ioctl(self->fd, IOMMU_OPTION, &cmd));
2121 	if (variant->version == VFIO_TYPE1_IOMMU) {
2122 		ASSERT_EQ(0, cmd.val64);
2123 	} else {
2124 		ASSERT_EQ(1, cmd.val64);
2125 	}
2126 }
2127 
2128 /*
2129  * Execute an ioctl command stored in buffer and check that the result does not
2130  * overflow memory.
2131  */
2132 static bool is_filled(const void *buf, uint8_t c, size_t len)
2133 {
2134 	const uint8_t *cbuf = buf;
2135 
2136 	for (; len; cbuf++, len--)
2137 		if (*cbuf != c)
2138 			return false;
2139 	return true;
2140 }
2141 
2142 #define ioctl_check_buf(fd, cmd)                                         \
2143 	({                                                               \
2144 		size_t _cmd_len = *(__u32 *)buffer;                      \
2145 									 \
2146 		memset(buffer + _cmd_len, 0xAA, BUFFER_SIZE - _cmd_len); \
2147 		ASSERT_EQ(0, ioctl(fd, cmd, buffer));                    \
2148 		ASSERT_EQ(true, is_filled(buffer + _cmd_len, 0xAA,       \
2149 					  BUFFER_SIZE - _cmd_len));      \
2150 	})
2151 
2152 static void check_vfio_info_cap_chain(struct __test_metadata *_metadata,
2153 				      struct vfio_iommu_type1_info *info_cmd)
2154 {
2155 	const struct vfio_info_cap_header *cap;
2156 
2157 	ASSERT_GE(info_cmd->argsz, info_cmd->cap_offset + sizeof(*cap));
2158 	cap = buffer + info_cmd->cap_offset;
2159 	while (true) {
2160 		size_t cap_size;
2161 
2162 		if (cap->next)
2163 			cap_size = (buffer + cap->next) - (void *)cap;
2164 		else
2165 			cap_size = (buffer + info_cmd->argsz) - (void *)cap;
2166 
2167 		switch (cap->id) {
2168 		case VFIO_IOMMU_TYPE1_INFO_CAP_IOVA_RANGE: {
2169 			struct vfio_iommu_type1_info_cap_iova_range *data =
2170 				(void *)cap;
2171 
2172 			ASSERT_EQ(1, data->header.version);
2173 			ASSERT_EQ(1, data->nr_iovas);
2174 			EXPECT_EQ(MOCK_APERTURE_START,
2175 				  data->iova_ranges[0].start);
2176 			EXPECT_EQ(MOCK_APERTURE_LAST, data->iova_ranges[0].end);
2177 			break;
2178 		}
2179 		case VFIO_IOMMU_TYPE1_INFO_DMA_AVAIL: {
2180 			struct vfio_iommu_type1_info_dma_avail *data =
2181 				(void *)cap;
2182 
2183 			ASSERT_EQ(1, data->header.version);
2184 			ASSERT_EQ(sizeof(*data), cap_size);
2185 			break;
2186 		}
2187 		default:
2188 			ASSERT_EQ(false, true);
2189 			break;
2190 		}
2191 		if (!cap->next)
2192 			break;
2193 
2194 		ASSERT_GE(info_cmd->argsz, cap->next + sizeof(*cap));
2195 		ASSERT_GE(buffer + cap->next, (void *)cap);
2196 		cap = buffer + cap->next;
2197 	}
2198 }
2199 
2200 TEST_F(vfio_compat_mock_domain, get_info)
2201 {
2202 	struct vfio_iommu_type1_info *info_cmd = buffer;
2203 	unsigned int i;
2204 	size_t caplen;
2205 
2206 	/* Pre-cap ABI */
2207 	*info_cmd = (struct vfio_iommu_type1_info){
2208 		.argsz = offsetof(struct vfio_iommu_type1_info, cap_offset),
2209 	};
2210 	ioctl_check_buf(self->fd, VFIO_IOMMU_GET_INFO);
2211 	ASSERT_NE(0, info_cmd->iova_pgsizes);
2212 	ASSERT_EQ(VFIO_IOMMU_INFO_PGSIZES | VFIO_IOMMU_INFO_CAPS,
2213 		  info_cmd->flags);
2214 
2215 	/* Read the cap chain size */
2216 	*info_cmd = (struct vfio_iommu_type1_info){
2217 		.argsz = sizeof(*info_cmd),
2218 	};
2219 	ioctl_check_buf(self->fd, VFIO_IOMMU_GET_INFO);
2220 	ASSERT_NE(0, info_cmd->iova_pgsizes);
2221 	ASSERT_EQ(VFIO_IOMMU_INFO_PGSIZES | VFIO_IOMMU_INFO_CAPS,
2222 		  info_cmd->flags);
2223 	ASSERT_EQ(0, info_cmd->cap_offset);
2224 	ASSERT_LT(sizeof(*info_cmd), info_cmd->argsz);
2225 
2226 	/* Read the caps, kernel should never create a corrupted caps */
2227 	caplen = info_cmd->argsz;
2228 	for (i = sizeof(*info_cmd); i < caplen; i++) {
2229 		*info_cmd = (struct vfio_iommu_type1_info){
2230 			.argsz = i,
2231 		};
2232 		ioctl_check_buf(self->fd, VFIO_IOMMU_GET_INFO);
2233 		ASSERT_EQ(VFIO_IOMMU_INFO_PGSIZES | VFIO_IOMMU_INFO_CAPS,
2234 			  info_cmd->flags);
2235 		if (!info_cmd->cap_offset)
2236 			continue;
2237 		check_vfio_info_cap_chain(_metadata, info_cmd);
2238 	}
2239 }
2240 
2241 static void shuffle_array(unsigned long *array, size_t nelms)
2242 {
2243 	unsigned int i;
2244 
2245 	/* Shuffle */
2246 	for (i = 0; i != nelms; i++) {
2247 		unsigned long tmp = array[i];
2248 		unsigned int other = rand() % (nelms - i);
2249 
2250 		array[i] = array[other];
2251 		array[other] = tmp;
2252 	}
2253 }
2254 
2255 TEST_F(vfio_compat_mock_domain, map)
2256 {
2257 	struct vfio_iommu_type1_dma_map map_cmd = {
2258 		.argsz = sizeof(map_cmd),
2259 		.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE,
2260 		.vaddr = (uintptr_t)buffer,
2261 		.size = BUFFER_SIZE,
2262 		.iova = MOCK_APERTURE_START,
2263 	};
2264 	struct vfio_iommu_type1_dma_unmap unmap_cmd = {
2265 		.argsz = sizeof(unmap_cmd),
2266 		.size = BUFFER_SIZE,
2267 		.iova = MOCK_APERTURE_START,
2268 	};
2269 	unsigned long pages_iova[BUFFER_SIZE / PAGE_SIZE];
2270 	unsigned int i;
2271 
2272 	/* Simple map/unmap */
2273 	ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_MAP_DMA, &map_cmd));
2274 	ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_UNMAP_DMA, &unmap_cmd));
2275 	ASSERT_EQ(BUFFER_SIZE, unmap_cmd.size);
2276 
2277 	/* UNMAP_FLAG_ALL requires 0 iova/size */
2278 	ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_MAP_DMA, &map_cmd));
2279 	unmap_cmd.flags = VFIO_DMA_UNMAP_FLAG_ALL;
2280 	EXPECT_ERRNO(EINVAL, ioctl(self->fd, VFIO_IOMMU_UNMAP_DMA, &unmap_cmd));
2281 
2282 	unmap_cmd.iova = 0;
2283 	unmap_cmd.size = 0;
2284 	ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_UNMAP_DMA, &unmap_cmd));
2285 	ASSERT_EQ(BUFFER_SIZE, unmap_cmd.size);
2286 
2287 	/* Small pages */
2288 	for (i = 0; i != ARRAY_SIZE(pages_iova); i++) {
2289 		map_cmd.iova = pages_iova[i] =
2290 			MOCK_APERTURE_START + i * PAGE_SIZE;
2291 		map_cmd.vaddr = (uintptr_t)buffer + i * PAGE_SIZE;
2292 		map_cmd.size = PAGE_SIZE;
2293 		ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_MAP_DMA, &map_cmd));
2294 	}
2295 	shuffle_array(pages_iova, ARRAY_SIZE(pages_iova));
2296 
2297 	unmap_cmd.flags = 0;
2298 	unmap_cmd.size = PAGE_SIZE;
2299 	for (i = 0; i != ARRAY_SIZE(pages_iova); i++) {
2300 		unmap_cmd.iova = pages_iova[i];
2301 		ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_UNMAP_DMA, &unmap_cmd));
2302 	}
2303 }
2304 
2305 TEST_F(vfio_compat_mock_domain, huge_map)
2306 {
2307 	size_t buf_size = HUGEPAGE_SIZE * 2;
2308 	struct vfio_iommu_type1_dma_map map_cmd = {
2309 		.argsz = sizeof(map_cmd),
2310 		.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE,
2311 		.size = buf_size,
2312 		.iova = MOCK_APERTURE_START,
2313 	};
2314 	struct vfio_iommu_type1_dma_unmap unmap_cmd = {
2315 		.argsz = sizeof(unmap_cmd),
2316 	};
2317 	unsigned long pages_iova[16];
2318 	unsigned int i;
2319 	void *buf;
2320 
2321 	/* Test huge pages and splitting */
2322 	buf = mmap(0, buf_size, PROT_READ | PROT_WRITE,
2323 		   MAP_SHARED | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, -1,
2324 		   0);
2325 	ASSERT_NE(MAP_FAILED, buf);
2326 	map_cmd.vaddr = (uintptr_t)buf;
2327 	ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_MAP_DMA, &map_cmd));
2328 
2329 	unmap_cmd.size = buf_size / ARRAY_SIZE(pages_iova);
2330 	for (i = 0; i != ARRAY_SIZE(pages_iova); i++)
2331 		pages_iova[i] = MOCK_APERTURE_START + (i * unmap_cmd.size);
2332 	shuffle_array(pages_iova, ARRAY_SIZE(pages_iova));
2333 
2334 	/* type1 mode can cut up larger mappings, type1v2 always fails */
2335 	for (i = 0; i != ARRAY_SIZE(pages_iova); i++) {
2336 		unmap_cmd.iova = pages_iova[i];
2337 		unmap_cmd.size = buf_size / ARRAY_SIZE(pages_iova);
2338 		if (variant->version == VFIO_TYPE1_IOMMU) {
2339 			ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_UNMAP_DMA,
2340 					   &unmap_cmd));
2341 		} else {
2342 			EXPECT_ERRNO(ENOENT,
2343 				     ioctl(self->fd, VFIO_IOMMU_UNMAP_DMA,
2344 					   &unmap_cmd));
2345 		}
2346 	}
2347 }
2348 
2349 TEST_HARNESS_MAIN
2350