1*4882a593SmuzhiyunFrom e5499a3cac1e823c3e0697e8667e952317b70cc8 Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Alistair Francis <alistair.francis@wdc.com> 3*4882a593SmuzhiyunDate: Thu, 4 Mar 2021 12:10:11 -0500 4*4882a593SmuzhiyunSubject: [PATCH] Fixup support for io_pgetevents_time64 syscall 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunThis is a fixup for the original commit 5b5e2985f355c8e99c196d9ce5d02c15bebadfbc 7*4882a593Smuzhiyun"Add support for io_pgetevents_time64 syscall" that didn't correctly 8*4882a593Smuzhiyunwork for 32-bit architecutres with a 64-bit time_t that aren't RISC-V. 9*4882a593Smuzhiyun 10*4882a593SmuzhiyunFor a full discussion of the issue see: 11*4882a593Smuzhiyunhttps://github.com/openssl/openssl/commit/5b5e2985f355c8e99c196d9ce5d02c15bebadfbc 12*4882a593Smuzhiyun 13*4882a593SmuzhiyunSigned-off-by: Alistair Francis <alistair.francis@wdc.com> 14*4882a593Smuzhiyun 15*4882a593SmuzhiyunReviewed-by: Tomas Mraz <tomas@openssl.org> 16*4882a593SmuzhiyunReviewed-by: Paul Dale <pauli@openssl.org> 17*4882a593Smuzhiyun(Merged from https://github.com/openssl/openssl/pull/14432) 18*4882a593Smuzhiyun--- 19*4882a593Smuzhiyun engines/e_afalg.c | 55 ++++++++++++++++++++++++++++++++++++----------- 20*4882a593Smuzhiyun 1 file changed, 42 insertions(+), 13 deletions(-) 21*4882a593Smuzhiyun 22*4882a593Smuzhiyundiff --git a/engines/e_afalg.c b/engines/e_afalg.c 23*4882a593Smuzhiyunindex 9480d7c24b..4e9d67db2d 100644 24*4882a593Smuzhiyun--- a/engines/e_afalg.c 25*4882a593Smuzhiyun+++ b/engines/e_afalg.c 26*4882a593Smuzhiyun@@ -124,27 +124,56 @@ static ossl_inline int io_read(aio_context_t ctx, long n, struct iocb **iocb) 27*4882a593Smuzhiyun return syscall(__NR_io_submit, ctx, n, iocb); 28*4882a593Smuzhiyun } 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun+/* A version of 'struct timespec' with 32-bit time_t and nanoseconds. */ 31*4882a593Smuzhiyun+struct __timespec32 32*4882a593Smuzhiyun+{ 33*4882a593Smuzhiyun+ __kernel_long_t tv_sec; 34*4882a593Smuzhiyun+ __kernel_long_t tv_nsec; 35*4882a593Smuzhiyun+}; 36*4882a593Smuzhiyun+ 37*4882a593Smuzhiyun static ossl_inline int io_getevents(aio_context_t ctx, long min, long max, 38*4882a593Smuzhiyun struct io_event *events, 39*4882a593Smuzhiyun struct timespec *timeout) 40*4882a593Smuzhiyun { 41*4882a593Smuzhiyun+#if defined(__NR_io_pgetevents_time64) 42*4882a593Smuzhiyun+ /* Check if we are a 32-bit architecture with a 64-bit time_t */ 43*4882a593Smuzhiyun+ if (sizeof(*timeout) != sizeof(struct __timespec32)) { 44*4882a593Smuzhiyun+ int ret = syscall(__NR_io_pgetevents_time64, ctx, min, max, events, 45*4882a593Smuzhiyun+ timeout, NULL); 46*4882a593Smuzhiyun+ if (ret == 0 || errno != ENOSYS) 47*4882a593Smuzhiyun+ return ret; 48*4882a593Smuzhiyun+ } 49*4882a593Smuzhiyun+#endif 50*4882a593Smuzhiyun+ 51*4882a593Smuzhiyun #if defined(__NR_io_getevents) 52*4882a593Smuzhiyun- return syscall(__NR_io_getevents, ctx, min, max, events, timeout); 53*4882a593Smuzhiyun-#elif defined(__NR_io_pgetevents_time64) 54*4882a593Smuzhiyun- /* Let's only support the 64 suffix syscalls for 64-bit time_t. 55*4882a593Smuzhiyun- * This simplifies the code for us as we don't need to use a 64-bit 56*4882a593Smuzhiyun- * version of timespec with a 32-bit time_t and handle converting 57*4882a593Smuzhiyun- * between 64-bit and 32-bit times and check for overflows. 58*4882a593Smuzhiyun- */ 59*4882a593Smuzhiyun- if (sizeof(timeout->tv_sec) == 8) 60*4882a593Smuzhiyun- return syscall(__NR_io_pgetevents_time64, ctx, min, max, events, timeout, NULL); 61*4882a593Smuzhiyun+ if (sizeof(*timeout) == sizeof(struct __timespec32)) 62*4882a593Smuzhiyun+ /* 63*4882a593Smuzhiyun+ * time_t matches our architecture length, we can just use 64*4882a593Smuzhiyun+ * __NR_io_getevents 65*4882a593Smuzhiyun+ */ 66*4882a593Smuzhiyun+ return syscall(__NR_io_getevents, ctx, min, max, events, timeout); 67*4882a593Smuzhiyun else { 68*4882a593Smuzhiyun- errno = ENOSYS; 69*4882a593Smuzhiyun- return -1; 70*4882a593Smuzhiyun+ /* 71*4882a593Smuzhiyun+ * We don't have __NR_io_pgetevents_time64, but we are using a 72*4882a593Smuzhiyun+ * 64-bit time_t on a 32-bit architecture. If we can fit the 73*4882a593Smuzhiyun+ * timeout value in a 32-bit time_t, then let's do that 74*4882a593Smuzhiyun+ * and then use the __NR_io_getevents syscall. 75*4882a593Smuzhiyun+ */ 76*4882a593Smuzhiyun+ if (timeout && timeout->tv_sec == (long)timeout->tv_sec) { 77*4882a593Smuzhiyun+ struct __timespec32 ts32; 78*4882a593Smuzhiyun+ 79*4882a593Smuzhiyun+ ts32.tv_sec = (__kernel_long_t) timeout->tv_sec; 80*4882a593Smuzhiyun+ ts32.tv_nsec = (__kernel_long_t) timeout->tv_nsec; 81*4882a593Smuzhiyun+ 82*4882a593Smuzhiyun+ return syscall(__NR_io_getevents, ctx, min, max, events, ts32); 83*4882a593Smuzhiyun+ } else { 84*4882a593Smuzhiyun+ return syscall(__NR_io_getevents, ctx, min, max, events, NULL); 85*4882a593Smuzhiyun+ } 86*4882a593Smuzhiyun } 87*4882a593Smuzhiyun-#else 88*4882a593Smuzhiyun-# error "We require either the io_getevents syscall or __NR_io_pgetevents_time64." 89*4882a593Smuzhiyun #endif 90*4882a593Smuzhiyun+ 91*4882a593Smuzhiyun+ errno = ENOSYS; 92*4882a593Smuzhiyun+ return -1; 93*4882a593Smuzhiyun } 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun static void afalg_waitfd_cleanup(ASYNC_WAIT_CTX *ctx, const void *key, 96*4882a593Smuzhiyun-- 97*4882a593Smuzhiyun2.25.1 98*4882a593Smuzhiyun 99