1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org> 4 * 5 * Description: 6 * Basic io_pgetevents() test to check various failures. 7 */ 8#include "time64_variants.h" 9#include "tst_test.h" 10#include "tst_timer.h" 11#include "lapi/io_pgetevents.h" 12 13#ifdef HAVE_LIBAIO 14static sigset_t sigmask; 15static struct io_event events[1]; 16static io_context_t ctx, invalid_ctx = 0; 17static int fd, ctx_initialized; 18 19static struct tst_ts to; 20static void *bad_addr; 21 22static struct tcase { 23 char *name; 24 io_context_t *ctx; 25 long min_nr; 26 long max_nr; 27 struct io_event *events; 28 struct tst_ts *timeout; 29 sigset_t *sigmask; 30 int exp_errno; 31} tcases[] = { 32 {"invalid ctx", &invalid_ctx, 1, 1, events, &to, &sigmask, EINVAL}, 33 {"invalid min_nr", &ctx, -1, 1, events, &to, &sigmask, EINVAL}, 34 {"invalid max_nr", &ctx, 1, -1, events, &to, &sigmask, EINVAL}, 35 {"invalid events", &ctx, 1, 1, NULL, &to, &sigmask, EFAULT}, 36 {"invalid timeout", &ctx, 1, 1, events, NULL, &sigmask, EFAULT}, 37 {"invalid sigmask", &ctx, 1, 1, events, &to, NULL, EFAULT}, 38}; 39 40static struct time64_variants variants[] = { 41#if (__NR_io_pgetevents != __LTP__NR_INVALID_SYSCALL) 42 { .io_pgetevents = sys_io_pgetevents, .ts_type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with old kernel spec"}, 43#endif 44 45#if (__NR_io_pgetevents_time64 != __LTP__NR_INVALID_SYSCALL) 46 { .io_pgetevents = sys_io_pgetevents_time64, .ts_type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec"}, 47#endif 48}; 49 50static void setup(void) 51{ 52 struct time64_variants *tv = &variants[tst_variant]; 53 struct iocb cb, *cbs[1]; 54 char data[4096]; 55 int ret; 56 57 tst_res(TINFO, "Testing variant: %s", tv->desc); 58 bad_addr = tst_get_bad_addr(NULL); 59 to = tst_ts_from_ns(tv->ts_type, 10000); 60 61 cbs[0] = &cb; 62 63 sigemptyset(&sigmask); 64 65 fd = SAFE_OPEN("io_pgetevents_file", O_RDWR | O_CREAT, 0644); 66 io_prep_pwrite(&cb, fd, data, 4096, 0); 67 68 TEST(io_setup(1, &ctx)); 69 if (TST_RET == -ENOSYS) 70 tst_brk(TCONF | TRERRNO, "io_setup(): AIO not supported by kernel"); 71 if (TST_RET < 0) 72 tst_brk(TBROK | TRERRNO, "io_setup() failed"); 73 74 ctx_initialized = 1; 75 76 ret = io_submit(ctx, 1, cbs); 77 if (ret != 1) 78 tst_brk(TBROK | TERRNO, "io_submit() failed"); 79} 80 81static void cleanup(void) 82{ 83 if (ctx_initialized) { 84 if (io_destroy(ctx) < 0) 85 tst_res(TWARN | TERRNO, "io_destroy() failed"); 86 } 87 88 if (fd > 0) 89 SAFE_CLOSE(fd); 90} 91 92static void run(unsigned int n) 93{ 94 struct time64_variants *tv = &variants[tst_variant]; 95 struct tcase *tc = &tcases[n]; 96 void *const to = tc->timeout ? tst_ts_get(tc->timeout) : bad_addr; 97 sigset_t *const sigmask = tc->sigmask ? tc->sigmask : bad_addr; 98 99 TEST(tv->io_pgetevents(*tc->ctx, tc->min_nr, tc->max_nr, tc->events, to, 100 sigmask)); 101 102 if (TST_RET == 1) { 103 tst_res(TFAIL, "%s: io_pgetevents() passed unexpectedly", 104 tc->name); 105 return; 106 } 107 108 if (tc->exp_errno != TST_ERR) { 109 tst_res(TFAIL | TTERRNO, "%s: io_pgetevents() should fail with %s", 110 tc->name, tst_strerrno(tc->exp_errno)); 111 return; 112 } 113 114 tst_res(TPASS | TTERRNO, "%s: io_pgetevents() failed as expected", 115 tc->name); 116} 117 118static struct tst_test test = { 119 .min_kver = "4.18", 120 .needs_tmpdir = 1, 121 .tcnt = ARRAY_SIZE(tcases), 122 .test = run, 123 .test_variants = ARRAY_SIZE(variants), 124 .setup = setup, 125 .cleanup = cleanup, 126}; 127 128#else 129TST_TEST_TCONF("test requires libaio and it's development packages"); 130#endif 131