--- /dev/null
+From: =?utf-8?q?St=C3=A9phane_Glondu?= <glondu@debian.org>
+Date: Fri, 28 Jun 2024 07:53:21 +0200
+Subject: Detect if atomic 64-bit load from RO memory works
+
+Bug: https://github.com/ocaml/ocaml/issues/13234
+Forwarded: https://github.com/ocaml/ocaml/pull/13267
+---
+ aclocal.m4 | 21 +++++++++++++++++++++
+ configure.ac | 5 +++++
+ otherlibs/runtime_events/runtime_events_consumer.c | 11 +++++++++--
+ runtime/caml/s.h.in | 2 ++
+ 4 files changed, 37 insertions(+), 2 deletions(-)
+
+diff --git a/aclocal.m4 b/aclocal.m4
+index cb73385..6f8e119 100644
+--- a/aclocal.m4
++++ b/aclocal.m4
+@@ -573,3 +573,24 @@ AC_DEFUN([OCAML_CC_SUPPORTS_ATOMIC], [
+ AC_MSG_RESULT([no])])
+ LIBS="$saved_LIBS"
+ ])
++
++AC_DEFUN([OCAML_ATOMIC_LOAD64_RW_CHECK], [
++ AC_MSG_CHECKING([whether atomic 64-bit load from RO memory works])
++ saved_LIBS="$LIBS"
++ LIBS="$LIBS $1"
++ OCAML_RUN_IFELSE([AC_LANG_SOURCE([[
++ #include <stdlib.h>
++ #include <stdint.h>
++ #include <stdatomic.h>
++ #include <sys/mman.h>
++ int main() {
++ uint64_t *a = mmap(NULL, 64, PROT_READ, MAP_ANONYMOUS | MAP_SHARED, 0, 0);
++ uint64_t b = atomic_load_explicit(a, memory_order_acquire);
++ return 0;
++ }
++ ]])],
++ [AC_MSG_RESULT([yes])],
++ [AC_DEFINE([ATOMIC_LOAD64_RW]) AC_MSG_RESULT([no])],
++ [AC_MSG_RESULT([cross-compiling; assume yes])])
++ LIBS="$saved_LIBS"
++])
+diff --git a/configure.ac b/configure.ac
+index a8e4222..6cd9b64 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1162,6 +1162,11 @@ OCAML_CC_SUPPORTS_ATOMIC([$cclibs])
+ AS_IF([! $cc_supports_atomic],
+ [AC_MSG_FAILURE([C11 atomic support is required, use another C compiler])])
+
++# Atomic 64-bit load requires RW memory on at least Debian armel
++# See: https://github.com/ocaml/ocaml/issues/13234
++
++OCAML_ATOMIC_LOAD64_RW_CHECK([$cclibs])
++
+ # Full support for thread local storage
+ # macOS and MinGW-w64 have problems with thread local storage accessed from DLLs
+
+diff --git a/otherlibs/runtime_events/runtime_events_consumer.c b/otherlibs/runtime_events/runtime_events_consumer.c
+index 9df4eb5..c3c7aca 100644
+--- a/otherlibs/runtime_events/runtime_events_consumer.c
++++ b/otherlibs/runtime_events/runtime_events_consumer.c
+@@ -189,7 +189,14 @@ caml_runtime_events_create_cursor(const char_os* runtime_events_path, int pid,
+
+ cursor->ring_file_size_bytes = GetFileSize(cursor->ring_file_handle, NULL);
+ #else
+- ring_fd = open(runtime_events_loc, O_RDONLY, 0);
++#ifndef ATOMIC_LOAD64_RW
++ const int open_flags = O_RDONLY;
++ const int mmap_prot = PROT_READ;
++#else
++ const int open_flags = O_RDWR;
++ const int mmap_prot = PROT_READ | PROT_WRITE;
++#endif
++ ring_fd = open(runtime_events_loc, open_flags, 0);
+
+ if( ring_fd == -1 ) {
+ caml_stat_free(cursor);
+@@ -210,7 +217,7 @@ caml_runtime_events_create_cursor(const char_os* runtime_events_path, int pid,
+ /* This cast is necessary for compatibility with Illumos' non-POSIX
+ mmap/munmap */
+ cursor->metadata = (struct runtime_events_metadata_header *)
+- mmap(NULL, cursor->ring_file_size_bytes, PROT_READ,
++ mmap(NULL, cursor->ring_file_size_bytes, mmap_prot,
+ MAP_SHARED, ring_fd, 0);
+
+ if( cursor->metadata == MAP_FAILED ) {
+diff --git a/runtime/caml/s.h.in b/runtime/caml/s.h.in
+index 0dc2ed7..bf9cca0 100644
+--- a/runtime/caml/s.h.in
++++ b/runtime/caml/s.h.in
+@@ -309,3 +309,5 @@
+ #undef HAS_BSD_GETAFFINITY_NP
+
+ #undef HAS_ZSTD
++
++#undef ATOMIC_LOAD64_RW