From 9e87b37ec648e69f641dd83c7909a337dbd15728 Mon Sep 17 00:00:00 2001
From: Guillem Jover <guillem@hadrons.org>
Date: Wed, 14 Aug 2019 03:30:09 +0200
Subject: [PATCH libaio 03/11] harness: Add KERNEL_RW_POINTER for various
 32-bit architectures

Signed-off-by: Guillem Jover <guillem@hadrons.org>
---
 harness/main.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/harness/main.c b/harness/main.c
index 82e9c69..0eed7bd 100644
--- a/harness/main.c
+++ b/harness/main.c
@@ -12,7 +12,16 @@
 #include <libaio.h>
 
 #if __LP64__ == 0
+#if defined(__i386__) || defined(__powerpc__)
 #define KERNEL_RW_POINTER	((void *)0xc0010000)
+#elif defined(__arm__) || defined(__s390__)
+#define KERNEL_RW_POINTER	((void *)0x00010000)
+#elif defined(__sparc__)
+#define KERNEL_RW_POINTER	((void *)0xf0010000)
+#else
+#warning Not really sure where kernel memory is.  Guessing.
+#define KERNEL_RW_POINTER	((void *)0xc0010000)
+#endif
 #else
 //#warning Not really sure where kernel memory is.  Guessing.
 #define KERNEL_RW_POINTER	((void *)0xffffffff81000000)
-- 
2.26.0.292.g33ef6b2f38

From f9c8695989fea731c93d99c684482df5744b385c Mon Sep 17 00:00:00 2001
From: Guillem Jover <guillem@hadrons.org>
Date: Wed, 14 Aug 2019 03:18:50 +0200
Subject: [PATCH libaio 04/11] Fix and improve MIPS support

Fix structure padding for MIPS 64, add syscall definitions, and the
kernel R/W pointer.

Signed-off-by: Guillem Jover <guillem@hadrons.org>
---
 harness/main.c     |  2 +-
 src/libaio.h       |  6 +++++-
 src/syscall-mips.h | 54 ++++++++++++++++++++++++++++++++++++++++++++++
 src/syscall.h      |  2 ++
 4 files changed, 62 insertions(+), 2 deletions(-)
 create mode 100644 src/syscall-mips.h

diff --git a/harness/main.c b/harness/main.c
index 0eed7bd..33d8e46 100644
--- a/harness/main.c
+++ b/harness/main.c
@@ -12,7 +12,7 @@
 #include <libaio.h>
 
 #if __LP64__ == 0
-#if defined(__i386__) || defined(__powerpc__)
+#if defined(__i386__) || defined(__powerpc__) || defined(__mips__)
 #define KERNEL_RW_POINTER	((void *)0xc0010000)
 #elif defined(__arm__) || defined(__s390__)
 #define KERNEL_RW_POINTER	((void *)0x00010000)
diff --git a/src/libaio.h b/src/libaio.h
index 8b33382..26b07f9 100644
--- a/src/libaio.h
+++ b/src/libaio.h
@@ -52,7 +52,9 @@ typedef enum io_iocb_cmd {
 
 /* little endian, 32 bits */
 #if defined(__i386__) || (defined(__arm__) && !defined(__ARMEB__)) || \
-    defined(__sh__) || defined(__bfin__) || defined(__MIPSEL__) || \
+    defined(__sh__) || \
+    defined(__bfin__) || \
+    (defined(__MIPSEL__) && !defined(__mips64)) || \
     defined(__cris__) || (defined(__riscv) && __riscv_xlen == 32) || \
     (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
          __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_LONG__ == 4)
@@ -62,6 +64,7 @@ typedef enum io_iocb_cmd {
 
 /* little endian, 64 bits */
 #elif defined(__ia64__) || defined(__x86_64__) || defined(__alpha__) || \
+      (defined(__mips64) && defined(__MIPSEL__)) || \
       (defined(__aarch64__) && defined(__AARCH64EL__)) || \
       (defined(__riscv) && __riscv_xlen == 64) || \
       (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
@@ -73,6 +76,7 @@ typedef enum io_iocb_cmd {
 /* big endian, 64 bits */
 #elif defined(__powerpc64__) || defined(__s390x__) || \
       (defined(__sparc__) && defined(__arch64__)) || \
+      (defined(__mips64) && defined(__MIPSEB__)) || \
       (defined(__aarch64__) && defined(__AARCH64EB__)) || \
       (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
            __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __SIZEOF_LONG__ == 8)
diff --git a/src/syscall-mips.h b/src/syscall-mips.h
new file mode 100644
index 0000000..2c4245e
--- /dev/null
+++ b/src/syscall-mips.h
@@ -0,0 +1,54 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 96, 97, 98, 99, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+
+#ifndef _MIPS_SIM_ABI32
+#define _MIPS_SIM_ABI32			1
+#define _MIPS_SIM_NABI32		2
+#define _MIPS_SIM_ABI64			3
+#endif
+
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+
+/*
+ * Linux o32 style syscalls are in the range from 4000 to 4999.
+ */
+#define __NR_Linux			4000
+#define __NR_io_setup			(__NR_Linux + 241)
+#define __NR_io_destroy			(__NR_Linux + 242)
+#define __NR_io_getevents		(__NR_Linux + 243)
+#define __NR_io_submit			(__NR_Linux + 244)
+#define __NR_io_cancel			(__NR_Linux + 245)
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+
+/*
+ * Linux 64-bit syscalls are in the range from 5000 to 5999.
+ */
+#define __NR_Linux			5000
+#define __NR_io_setup			(__NR_Linux + 200)
+#define __NR_io_destroy			(__NR_Linux + 201)
+#define __NR_io_getevents		(__NR_Linux + 202)
+#define __NR_io_submit			(__NR_Linux + 203)
+#define __NR_io_cancel			(__NR_Linux + 204)
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
+
+#if _MIPS_SIM == _MIPS_SIM_NABI32
+
+/*
+ * Linux N32 syscalls are in the range from 6000 to 6999.
+ */
+#define __NR_Linux			6000
+#define __NR_io_setup			(__NR_Linux + 200)
+#define __NR_io_destroy			(__NR_Linux + 201)
+#define __NR_io_getevents		(__NR_Linux + 202)
+#define __NR_io_submit			(__NR_Linux + 203)
+#define __NR_io_cancel			(__NR_Linux + 204)
+#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
diff --git a/src/syscall.h b/src/syscall.h
index b53da4c..db78e28 100644
--- a/src/syscall.h
+++ b/src/syscall.h
@@ -27,6 +27,8 @@
 #include "syscall-arm.h"
 #elif defined(__sparc__)
 #include "syscall-sparc.h"
+#elif defined(__mips__)
+#include "syscall-mips.h"
 #elif defined(__aarch64__) || defined(__riscv)
 #include "syscall-generic.h"
 #else
-- 
2.26.0.292.g33ef6b2f38

From d7f5065448efb49b2a26e728ff735e12ea05b62e Mon Sep 17 00:00:00 2001
From: Jeff Moyer <jmoyer@redhat.com>
Date: Tue, 13 Aug 2019 15:30:05 -0400
Subject: [PATCH libaio 25/28] harness: fix read into PROT_WRITE mmap test

This test has been broken forever.  Fix it up to perform an
aio_read using the result of a regular read as the expected
return code.

Reported-by: Guillem Jover <guillem@hadrons.org>
Signed-off-by: Jeff Moyer <jmoyer@redhat.com>
---
 harness/cases/5.t | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/harness/cases/5.t b/harness/cases/5.t
index 2b4b4bb..7d67562 100644
--- a/harness/cases/5.t
+++ b/harness/cases/5.t
@@ -40,14 +40,14 @@ int test_main(void)
 	buf = mmap(0, page_size, PROT_WRITE, MAP_SHARED, rwfd, 0);
 	assert(buf != (char *)-1);
 
-	status |= attempt_rw(rwfd, buf, SIZE,  0,  READ, SIZE);
-
 	/* Whether PROT_WRITE is readable is arch-dependent.  So compare
 	 * against read result. */
 	res = read(rwfd, buf, SIZE);
 	if (res < 0)
 		res = -errno;
-	status |= attempt_rw(rwfd, buf, SIZE,  0, WRITE, res);
+	status |= attempt_rw(rwfd, buf, SIZE,  0,  READ, res);
+
+	status |= attempt_rw(rwfd, buf, SIZE,  0, WRITE, SIZE);
 
 	return status;
 }
-- 
2.26.0.292.g33ef6b2f38

From 711c0381798c85f3e25ea0ab503b24857850a762 Mon Sep 17 00:00:00 2001
From: Guillem Jover <guillem@hadrons.org>
Date: Wed, 14 Aug 2019 04:42:42 +0200
Subject: [PATCH libaio 26/28] harness: Fix PROT_WRITE mmap check

This partially reverts commit d7f5065448efb49b2a26e728ff735e12ea05b62e.

The actual problem in the original code was that read() was being used
to assert whether the buffer was readable, but the kernel was instead
reading from the file descriptor and then writing into the buffer, so
no EFAULT was being generated (on architectures that do so).

We needed to use a write() so that the kernel would read from the
buffer.

Signed-off-by: Guillem Jover <guillem@hadrons.org>
Signed-off-by: Jeff Moyer <jmoyer@redhat.com>
---
 harness/cases/5.t | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/harness/cases/5.t b/harness/cases/5.t
index 7d67562..b0a7c56 100644
--- a/harness/cases/5.t
+++ b/harness/cases/5.t
@@ -41,13 +41,12 @@ int test_main(void)
 	assert(buf != (char *)-1);
 
 	/* Whether PROT_WRITE is readable is arch-dependent.  So compare
-	 * against read result. */
-	res = read(rwfd, buf, SIZE);
+	 * against write() result (to make the kernel read from buf). */
+	res = write(rwfd, buf, SIZE);
 	if (res < 0)
 		res = -errno;
-	status |= attempt_rw(rwfd, buf, SIZE,  0,  READ, res);
-
-	status |= attempt_rw(rwfd, buf, SIZE,  0, WRITE, SIZE);
+	status |= attempt_rw(rwfd, buf, SIZE,  0,  READ, SIZE);
+	status |= attempt_rw(rwfd, buf, SIZE,  0, WRITE, res);
 
 	return status;
 }
-- 
2.26.0.292.g33ef6b2f38

