0007-Fixup-support-for-io_pgetevents_time64-syscall.patch 3.7 KB

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