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

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/iommu/iommufd_fail_nth.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  *
  4  * These tests are "kernel integrity" tests. They are looking for kernel
  5  * WARN/OOPS/kasn/etc splats triggered by kernel sanitizers & debugging
  6  * features. It does not attempt to verify that the system calls are doing what
  7  * they are supposed to do.
  8  *
  9  * The basic philosophy is to run a sequence of calls that will succeed and then
 10  * sweep every failure injection point on that call chain to look for
 11  * interesting things in error handling.
 12  *
 13  * This test is best run with:
 14  *  echo 1 > /proc/sys/kernel/panic_on_warn
 15  * If something is actually going wrong.
 16  */
 17 #include <fcntl.h>
 18 #include <dirent.h>
 19 
 20 #define __EXPORTED_HEADERS__
 21 #include <linux/vfio.h>
 22 
 23 #include "iommufd_utils.h"
 24 
 25 static bool have_fault_injection;
 26 
 27 static int writeat(int dfd, const char *fn, const char *val)
 28 {
 29         size_t val_len = strlen(val);
 30         ssize_t res;
 31         int fd;
 32 
 33         fd = openat(dfd, fn, O_WRONLY);
 34         if (fd == -1)
 35                 return -1;
 36         res = write(fd, val, val_len);
 37         assert(res == val_len);
 38         close(fd);
 39         return 0;
 40 }
 41 
 42 static __attribute__((constructor)) void setup_buffer(void)
 43 {
 44         PAGE_SIZE = sysconf(_SC_PAGE_SIZE);
 45 
 46         BUFFER_SIZE = 2*1024*1024;
 47 
 48         buffer = mmap(0, BUFFER_SIZE, PROT_READ | PROT_WRITE,
 49                       MAP_SHARED | MAP_ANONYMOUS, -1, 0);
 50 }
 51 
 52 /*
 53  * This sets up fail_injection in a way that is useful for this test.
 54  * It does not attempt to restore things back to how they were.
 55  */
 56 static __attribute__((constructor)) void setup_fault_injection(void)
 57 {
 58         DIR *debugfs = opendir("/sys/kernel/debug/");
 59         struct dirent *dent;
 60 
 61         if (!debugfs)
 62                 return;
 63 
 64         /* Allow any allocation call to be fault injected */
 65         if (writeat(dirfd(debugfs), "failslab/ignore-gfp-wait", "N"))
 66                 return;
 67         writeat(dirfd(debugfs), "fail_page_alloc/ignore-gfp-wait", "N");
 68         writeat(dirfd(debugfs), "fail_page_alloc/ignore-gfp-highmem", "N");
 69 
 70         while ((dent = readdir(debugfs))) {
 71                 char fn[300];
 72 
 73                 if (strncmp(dent->d_name, "fail", 4) != 0)
 74                         continue;
 75 
 76                 /* We are looking for kernel splats, quiet down the log */
 77                 snprintf(fn, sizeof(fn), "%s/verbose", dent->d_name);
 78                 writeat(dirfd(debugfs), fn, "");
 79         }
 80         closedir(debugfs);
 81         have_fault_injection = true;
 82 }
 83 
 84 struct fail_nth_state {
 85         int proc_fd;
 86         unsigned int iteration;
 87 };
 88 
 89 static void fail_nth_first(struct __test_metadata *_metadata,
 90                            struct fail_nth_state *nth_state)
 91 {
 92         char buf[300];
 93 
 94         snprintf(buf, sizeof(buf), "/proc/self/task/%u/fail-nth", getpid());
 95         nth_state->proc_fd = open(buf, O_RDWR);
 96         ASSERT_NE(-1, nth_state->proc_fd);
 97 }
 98 
 99 static bool fail_nth_next(struct __test_metadata *_metadata,
100                           struct fail_nth_state *nth_state,
101                           int test_result)
102 {
103         static const char disable_nth[] = "";
104         char buf[300];
105 
106         /*
107          * This is just an arbitrary limit based on the current kernel
108          * situation. Changes in the kernel can dramatically change the number of
109          * required fault injection sites, so if this hits it doesn't
110          * necessarily mean a test failure, just that the limit has to be made
111          * bigger.
112          */
113         ASSERT_GT(400, nth_state->iteration);
114         if (nth_state->iteration != 0) {
115                 ssize_t res;
116                 ssize_t res2;
117 
118                 buf[0] = 0;
119                 /*
120                  * Annoyingly disabling the nth can also fail. This means
121                  * the test passed without triggering failure
122                  */
123                 res = pread(nth_state->proc_fd, buf, sizeof(buf), 0);
124                 if (res == -1 && errno == EFAULT) {
125                         buf[0] = '1';
126                         buf[1] = '\n';
127                         res = 2;
128                 }
129 
130                 res2 = pwrite(nth_state->proc_fd, disable_nth,
131                               ARRAY_SIZE(disable_nth) - 1, 0);
132                 if (res2 == -1 && errno == EFAULT) {
133                         res2 = pwrite(nth_state->proc_fd, disable_nth,
134                                       ARRAY_SIZE(disable_nth) - 1, 0);
135                         buf[0] = '1';
136                         buf[1] = '\n';
137                 }
138                 ASSERT_EQ(ARRAY_SIZE(disable_nth) - 1, res2);
139 
140                 /* printf("  nth %u result=%d nth=%u\n", nth_state->iteration,
141                        test_result, atoi(buf)); */
142                 fflush(stdout);
143                 ASSERT_LT(1, res);
144                 if (res != 2 || buf[0] != '' || buf[1] != '\n')
145                         return false;
146         } else {
147                 /* printf("  nth %u result=%d\n", nth_state->iteration,
148                        test_result); */
149         }
150         nth_state->iteration++;
151         return true;
152 }
153 
154 /*
155  * This is called during the test to start failure injection. It allows the test
156  * to do some setup that has already been swept and thus reduce the required
157  * iterations.
158  */
159 void __fail_nth_enable(struct __test_metadata *_metadata,
160                        struct fail_nth_state *nth_state)
161 {
162         char buf[300];
163         size_t len;
164 
165         if (!nth_state->iteration)
166                 return;
167 
168         len = snprintf(buf, sizeof(buf), "%u", nth_state->iteration);
169         ASSERT_EQ(len, pwrite(nth_state->proc_fd, buf, len, 0));
170 }
171 #define fail_nth_enable() __fail_nth_enable(_metadata, _nth_state)
172 
173 #define TEST_FAIL_NTH(fixture_name, name)                                           \
174         static int test_nth_##name(struct __test_metadata *_metadata,               \
175                                    FIXTURE_DATA(fixture_name) *self,                \
176                                    const FIXTURE_VARIANT(fixture_name)              \
177                                            *variant,                                \
178                                    struct fail_nth_state *_nth_state);              \
179         TEST_F(fixture_name, name)                                                  \
180         {                                                                           \
181                 struct fail_nth_state nth_state = {};                               \
182                 int test_result = 0;                                                \
183                                                                                     \
184                 if (!have_fault_injection)                                          \
185                         SKIP(return,                                                \
186                                    "fault injection is not enabled in the kernel"); \
187                 fail_nth_first(_metadata, &nth_state);                              \
188                 ASSERT_EQ(0, test_nth_##name(_metadata, self, variant,              \
189                                              &nth_state));                          \
190                 while (fail_nth_next(_metadata, &nth_state, test_result)) {         \
191                         fixture_name##_teardown(_metadata, self, variant);          \
192                         fixture_name##_setup(_metadata, self, variant);             \
193                         test_result = test_nth_##name(_metadata, self,              \
194                                                       variant, &nth_state);         \
195                 };                                                                  \
196                 ASSERT_EQ(0, test_result);                                          \
197         }                                                                           \
198         static int test_nth_##name(                                                 \
199                 struct __test_metadata __attribute__((unused)) *_metadata,          \
200                 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self,           \
201                 const FIXTURE_VARIANT(fixture_name) __attribute__((unused))         \
202                         *variant,                                                   \
203                 struct fail_nth_state *_nth_state)
204 
205 FIXTURE(basic_fail_nth)
206 {
207         int fd;
208         uint32_t access_id;
209 };
210 
211 FIXTURE_SETUP(basic_fail_nth)
212 {
213         self->fd = -1;
214         self->access_id = 0;
215 }
216 
217 FIXTURE_TEARDOWN(basic_fail_nth)
218 {
219         int rc;
220 
221         if (self->access_id) {
222                 /* The access FD holds the iommufd open until it closes */
223                 rc = _test_cmd_destroy_access(self->access_id);
224                 assert(rc == 0);
225         }
226         teardown_iommufd(self->fd, _metadata);
227 }
228 
229 /* Cover ioas.c */
230 TEST_FAIL_NTH(basic_fail_nth, basic)
231 {
232         struct iommu_iova_range ranges[10];
233         uint32_t ioas_id;
234         __u64 iova;
235 
236         fail_nth_enable();
237 
238         self->fd = open("/dev/iommu", O_RDWR);
239         if (self->fd == -1)
240                 return -1;
241 
242         if (_test_ioctl_ioas_alloc(self->fd, &ioas_id))
243                 return -1;
244 
245         {
246                 struct iommu_ioas_iova_ranges ranges_cmd = {
247                         .size = sizeof(ranges_cmd),
248                         .num_iovas = ARRAY_SIZE(ranges),
249                         .ioas_id = ioas_id,
250                         .allowed_iovas = (uintptr_t)ranges,
251                 };
252                 if (ioctl(self->fd, IOMMU_IOAS_IOVA_RANGES, &ranges_cmd))
253                         return -1;
254         }
255 
256         {
257                 struct iommu_ioas_allow_iovas allow_cmd = {
258                         .size = sizeof(allow_cmd),
259                         .ioas_id = ioas_id,
260                         .num_iovas = 1,
261                         .allowed_iovas = (uintptr_t)ranges,
262                 };
263 
264                 ranges[0].start = 16*1024;
265                 ranges[0].last = BUFFER_SIZE + 16 * 1024 * 600 - 1;
266                 if (ioctl(self->fd, IOMMU_IOAS_ALLOW_IOVAS, &allow_cmd))
267                         return -1;
268         }
269 
270         if (_test_ioctl_ioas_map(self->fd, ioas_id, buffer, BUFFER_SIZE, &iova,
271                                  IOMMU_IOAS_MAP_WRITEABLE |
272                                          IOMMU_IOAS_MAP_READABLE))
273                 return -1;
274 
275         {
276                 struct iommu_ioas_copy copy_cmd = {
277                         .size = sizeof(copy_cmd),
278                         .flags = IOMMU_IOAS_MAP_WRITEABLE |
279                                  IOMMU_IOAS_MAP_READABLE,
280                         .dst_ioas_id = ioas_id,
281                         .src_ioas_id = ioas_id,
282                         .src_iova = iova,
283                         .length = sizeof(ranges),
284                 };
285 
286                 if (ioctl(self->fd, IOMMU_IOAS_COPY, &copy_cmd))
287                         return -1;
288         }
289 
290         if (_test_ioctl_ioas_unmap(self->fd, ioas_id, iova, BUFFER_SIZE,
291                                    NULL))
292                 return -1;
293         /* Failure path of no IOVA to unmap */
294         _test_ioctl_ioas_unmap(self->fd, ioas_id, iova, BUFFER_SIZE, NULL);
295         return 0;
296 }
297 
298 /* iopt_area_fill_domains() and iopt_area_fill_domain() */
299 TEST_FAIL_NTH(basic_fail_nth, map_domain)
300 {
301         uint32_t ioas_id;
302         __u32 stdev_id;
303         __u32 hwpt_id;
304         __u64 iova;
305 
306         self->fd = open("/dev/iommu", O_RDWR);
307         if (self->fd == -1)
308                 return -1;
309 
310         if (_test_ioctl_ioas_alloc(self->fd, &ioas_id))
311                 return -1;
312 
313         if (_test_ioctl_set_temp_memory_limit(self->fd, 32))
314                 return -1;
315 
316         fail_nth_enable();
317 
318         if (_test_cmd_mock_domain(self->fd, ioas_id, &stdev_id, &hwpt_id, NULL))
319                 return -1;
320 
321         if (_test_ioctl_ioas_map(self->fd, ioas_id, buffer, 262144, &iova,
322                                  IOMMU_IOAS_MAP_WRITEABLE |
323                                          IOMMU_IOAS_MAP_READABLE))
324                 return -1;
325 
326         if (_test_ioctl_destroy(self->fd, stdev_id))
327                 return -1;
328 
329         if (_test_cmd_mock_domain(self->fd, ioas_id, &stdev_id, &hwpt_id, NULL))
330                 return -1;
331         return 0;
332 }
333 
334 TEST_FAIL_NTH(basic_fail_nth, map_two_domains)
335 {
336         uint32_t ioas_id;
337         __u32 stdev_id2;
338         __u32 stdev_id;
339         __u32 hwpt_id2;
340         __u32 hwpt_id;
341         __u64 iova;
342 
343         self->fd = open("/dev/iommu", O_RDWR);
344         if (self->fd == -1)
345                 return -1;
346 
347         if (_test_ioctl_ioas_alloc(self->fd, &ioas_id))
348                 return -1;
349 
350         if (_test_ioctl_set_temp_memory_limit(self->fd, 32))
351                 return -1;
352 
353         if (_test_cmd_mock_domain(self->fd, ioas_id, &stdev_id, &hwpt_id, NULL))
354                 return -1;
355 
356         fail_nth_enable();
357 
358         if (_test_cmd_mock_domain(self->fd, ioas_id, &stdev_id2, &hwpt_id2,
359                                   NULL))
360                 return -1;
361 
362         if (_test_ioctl_ioas_map(self->fd, ioas_id, buffer, 262144, &iova,
363                                  IOMMU_IOAS_MAP_WRITEABLE |
364                                          IOMMU_IOAS_MAP_READABLE))
365                 return -1;
366 
367         if (_test_ioctl_destroy(self->fd, stdev_id))
368                 return -1;
369 
370         if (_test_ioctl_destroy(self->fd, stdev_id2))
371                 return -1;
372 
373         if (_test_cmd_mock_domain(self->fd, ioas_id, &stdev_id, &hwpt_id, NULL))
374                 return -1;
375         if (_test_cmd_mock_domain(self->fd, ioas_id, &stdev_id2, &hwpt_id2,
376                                   NULL))
377                 return -1;
378         return 0;
379 }
380 
381 TEST_FAIL_NTH(basic_fail_nth, access_rw)
382 {
383         uint64_t tmp_big[4096];
384         uint32_t ioas_id;
385         uint16_t tmp[32];
386         __u64 iova;
387 
388         self->fd = open("/dev/iommu", O_RDWR);
389         if (self->fd == -1)
390                 return -1;
391 
392         if (_test_ioctl_ioas_alloc(self->fd, &ioas_id))
393                 return -1;
394 
395         if (_test_ioctl_set_temp_memory_limit(self->fd, 32))
396                 return -1;
397 
398         if (_test_ioctl_ioas_map(self->fd, ioas_id, buffer, 262144, &iova,
399                                  IOMMU_IOAS_MAP_WRITEABLE |
400                                          IOMMU_IOAS_MAP_READABLE))
401                 return -1;
402 
403         fail_nth_enable();
404 
405         if (_test_cmd_create_access(self->fd, ioas_id, &self->access_id, 0))
406                 return -1;
407 
408         {
409                 struct iommu_test_cmd access_cmd = {
410                         .size = sizeof(access_cmd),
411                         .op = IOMMU_TEST_OP_ACCESS_RW,
412                         .id = self->access_id,
413                         .access_rw = { .iova = iova,
414                                        .length = sizeof(tmp),
415                                        .uptr = (uintptr_t)tmp },
416                 };
417 
418                 // READ
419                 if (ioctl(self->fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_RW),
420                           &access_cmd))
421                         return -1;
422 
423                 access_cmd.access_rw.flags = MOCK_ACCESS_RW_WRITE;
424                 if (ioctl(self->fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_RW),
425                           &access_cmd))
426                         return -1;
427 
428                 access_cmd.access_rw.flags = MOCK_ACCESS_RW_SLOW_PATH;
429                 if (ioctl(self->fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_RW),
430                           &access_cmd))
431                         return -1;
432                 access_cmd.access_rw.flags = MOCK_ACCESS_RW_SLOW_PATH |
433                                              MOCK_ACCESS_RW_WRITE;
434                 if (ioctl(self->fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_RW),
435                           &access_cmd))
436                         return -1;
437         }
438 
439         {
440                 struct iommu_test_cmd access_cmd = {
441                         .size = sizeof(access_cmd),
442                         .op = IOMMU_TEST_OP_ACCESS_RW,
443                         .id = self->access_id,
444                         .access_rw = { .iova = iova,
445                                        .flags = MOCK_ACCESS_RW_SLOW_PATH,
446                                        .length = sizeof(tmp_big),
447                                        .uptr = (uintptr_t)tmp_big },
448                 };
449 
450                 if (ioctl(self->fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_RW),
451                           &access_cmd))
452                         return -1;
453         }
454         if (_test_cmd_destroy_access(self->access_id))
455                 return -1;
456         self->access_id = 0;
457         return 0;
458 }
459 
460 /* pages.c access functions */
461 TEST_FAIL_NTH(basic_fail_nth, access_pin)
462 {
463         uint32_t access_pages_id;
464         uint32_t ioas_id;
465         __u64 iova;
466 
467         self->fd = open("/dev/iommu", O_RDWR);
468         if (self->fd == -1)
469                 return -1;
470 
471         if (_test_ioctl_ioas_alloc(self->fd, &ioas_id))
472                 return -1;
473 
474         if (_test_ioctl_set_temp_memory_limit(self->fd, 32))
475                 return -1;
476 
477         if (_test_ioctl_ioas_map(self->fd, ioas_id, buffer, BUFFER_SIZE, &iova,
478                                  IOMMU_IOAS_MAP_WRITEABLE |
479                                          IOMMU_IOAS_MAP_READABLE))
480                 return -1;
481 
482         if (_test_cmd_create_access(self->fd, ioas_id, &self->access_id,
483                                     MOCK_FLAGS_ACCESS_CREATE_NEEDS_PIN_PAGES))
484                 return -1;
485 
486         fail_nth_enable();
487 
488         {
489                 struct iommu_test_cmd access_cmd = {
490                         .size = sizeof(access_cmd),
491                         .op = IOMMU_TEST_OP_ACCESS_PAGES,
492                         .id = self->access_id,
493                         .access_pages = { .iova = iova,
494                                           .length = BUFFER_SIZE,
495                                           .uptr = (uintptr_t)buffer },
496                 };
497 
498                 if (ioctl(self->fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_RW),
499                           &access_cmd))
500                         return -1;
501                 access_pages_id = access_cmd.access_pages.out_access_pages_id;
502         }
503 
504         if (_test_cmd_destroy_access_pages(self->fd, self->access_id,
505                                            access_pages_id))
506                 return -1;
507 
508         if (_test_cmd_destroy_access(self->access_id))
509                 return -1;
510         self->access_id = 0;
511         return 0;
512 }
513 
514 /* iopt_pages_fill_xarray() */
515 TEST_FAIL_NTH(basic_fail_nth, access_pin_domain)
516 {
517         uint32_t access_pages_id;
518         uint32_t ioas_id;
519         __u32 stdev_id;
520         __u32 hwpt_id;
521         __u64 iova;
522 
523         self->fd = open("/dev/iommu", O_RDWR);
524         if (self->fd == -1)
525                 return -1;
526 
527         if (_test_ioctl_ioas_alloc(self->fd, &ioas_id))
528                 return -1;
529 
530         if (_test_ioctl_set_temp_memory_limit(self->fd, 32))
531                 return -1;
532 
533         if (_test_cmd_mock_domain(self->fd, ioas_id, &stdev_id, &hwpt_id, NULL))
534                 return -1;
535 
536         if (_test_ioctl_ioas_map(self->fd, ioas_id, buffer, BUFFER_SIZE, &iova,
537                                  IOMMU_IOAS_MAP_WRITEABLE |
538                                          IOMMU_IOAS_MAP_READABLE))
539                 return -1;
540 
541         if (_test_cmd_create_access(self->fd, ioas_id, &self->access_id,
542                                     MOCK_FLAGS_ACCESS_CREATE_NEEDS_PIN_PAGES))
543                 return -1;
544 
545         fail_nth_enable();
546 
547         {
548                 struct iommu_test_cmd access_cmd = {
549                         .size = sizeof(access_cmd),
550                         .op = IOMMU_TEST_OP_ACCESS_PAGES,
551                         .id = self->access_id,
552                         .access_pages = { .iova = iova,
553                                           .length = BUFFER_SIZE,
554                                           .uptr = (uintptr_t)buffer },
555                 };
556 
557                 if (ioctl(self->fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_RW),
558                           &access_cmd))
559                         return -1;
560                 access_pages_id = access_cmd.access_pages.out_access_pages_id;
561         }
562 
563         if (_test_cmd_destroy_access_pages(self->fd, self->access_id,
564                                            access_pages_id))
565                 return -1;
566 
567         if (_test_cmd_destroy_access(self->access_id))
568                 return -1;
569         self->access_id = 0;
570 
571         if (_test_ioctl_destroy(self->fd, stdev_id))
572                 return -1;
573         return 0;
574 }
575 
576 /* device.c */
577 TEST_FAIL_NTH(basic_fail_nth, device)
578 {
579         struct iommu_test_hw_info info;
580         uint32_t ioas_id;
581         uint32_t ioas_id2;
582         uint32_t stdev_id;
583         uint32_t idev_id;
584         uint32_t hwpt_id;
585         __u64 iova;
586 
587         self->fd = open("/dev/iommu", O_RDWR);
588         if (self->fd == -1)
589                 return -1;
590 
591         if (_test_ioctl_ioas_alloc(self->fd, &ioas_id))
592                 return -1;
593 
594         if (_test_ioctl_ioas_alloc(self->fd, &ioas_id2))
595                 return -1;
596 
597         iova = MOCK_APERTURE_START;
598         if (_test_ioctl_ioas_map(self->fd, ioas_id, buffer, PAGE_SIZE, &iova,
599                                  IOMMU_IOAS_MAP_FIXED_IOVA |
600                                          IOMMU_IOAS_MAP_WRITEABLE |
601                                          IOMMU_IOAS_MAP_READABLE))
602                 return -1;
603         if (_test_ioctl_ioas_map(self->fd, ioas_id2, buffer, PAGE_SIZE, &iova,
604                                  IOMMU_IOAS_MAP_FIXED_IOVA |
605                                          IOMMU_IOAS_MAP_WRITEABLE |
606                                          IOMMU_IOAS_MAP_READABLE))
607                 return -1;
608 
609         fail_nth_enable();
610 
611         if (_test_cmd_mock_domain(self->fd, ioas_id, &stdev_id, NULL,
612                                   &idev_id))
613                 return -1;
614 
615         if (_test_cmd_get_hw_info(self->fd, idev_id, &info, sizeof(info), NULL))
616                 return -1;
617 
618         if (_test_cmd_hwpt_alloc(self->fd, idev_id, ioas_id, 0, 0, &hwpt_id,
619                                  IOMMU_HWPT_DATA_NONE, 0, 0))
620                 return -1;
621 
622         if (_test_cmd_mock_domain_replace(self->fd, stdev_id, ioas_id2, NULL))
623                 return -1;
624 
625         if (_test_cmd_mock_domain_replace(self->fd, stdev_id, hwpt_id, NULL))
626                 return -1;
627         return 0;
628 }
629 
630 TEST_HARNESS_MAIN
631 

~ [ 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