~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/iommu/iommufd.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php