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