[PATCH v2 3/4] posix_fadvise: handle 2 variants for SYSCALL_ALIGN_64BIT

Vineet Gupta <[email protected]>
Newsgroups gmane.comp.lib.uclibc.general
Message-ID <[email protected]>
arm/powerpc/xtensa pass @advice as 2nd arg to syscall (vs. canonical 4th)

Current code however does this for UCLIBC_SYSCALL_ALIGN_64BIT which
powerpc/xtensa also happen to define.

This is not true for ARCv2 ISA and possibly other arch of future with
64-bit even register requirement, which uses the standard syscall
handler in kernel.

Fix that by providing 2 variants of SYSCALL_ALIGN_64BIT

Signed-off-by: Vineet Gupta <[email protected]>
Cc: Baruch Siach <[email protected]>
Cc: Max Filippov <[email protected]>
---
 libc/sysdeps/linux/common/posix_fadvise.c   | 10 +++++++++-
 libc/sysdeps/linux/common/posix_fadvise64.c | 11 ++++++++++-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/libc/sysdeps/linux/common/posix_fadvise.c b/libc/sysdeps/linux/common/posix_fadvise.c
index 14bbeeea13bc..74d8409c01c5 100644
--- a/libc/sysdeps/linux/common/posix_fadvise.c
+++ b/libc/sysdeps/linux/common/posix_fadvise.c
@@ -41,9 +41,17 @@ int posix_fadvise(int fd, off_t offset, off_t len, int advice)
 #  if __WORDSIZE == 64
 	ret = INTERNAL_SYSCALL(fadvise64_64, err, 4, fd, offset, len, advice);
 #  else
-#   if defined(__UCLIBC_SYSCALL_ALIGN_64BIT__) || defined(__arm__)
+#   if defined (__arm__) || \
+      (defined(__UCLIBC_SYSCALL_ALIGN_64BIT__) && (defined(__powerpc__) || defined(__xtensa__)))
+	/* arch with 64-bit data in even reg alignment #1: [powerpc/xtensa]
+	 * custom syscall handler (rearranges @advice to avoid register hole punch) */
 	ret = INTERNAL_SYSCALL(fadvise64_64, err, 6, fd, advice,
 			OFF_HI_LO (offset), OFF_HI_LO (len));
+#   elif defined(__UCLIBC_SYSCALL_ALIGN_64BIT__)
+	/* arch with 64-bit data in even reg alignment #2: [arcv2/others-in-future]
+	 * stock syscall handler in kernel (reg hole punched) */
+	ret = INTERNAL_SYSCALL(fadvise64_64, err, 7, fd, 0,
+			OFF_HI_LO (offset), OFF_HI_LO (len), advice);
 #   else
 	ret = INTERNAL_SYSCALL(fadvise64_64, err, 6, fd,
 			OFF_HI_LO (offset), OFF_HI_LO (len), advice);
diff --git a/libc/sysdeps/linux/common/posix_fadvise64.c b/libc/sysdeps/linux/common/posix_fadvise64.c
index 5d8989121871..37fb269ca8dc 100644
--- a/libc/sysdeps/linux/common/posix_fadvise64.c
+++ b/libc/sysdeps/linux/common/posix_fadvise64.c
@@ -24,9 +24,18 @@ int posix_fadvise64(int fd, off64_t offset, off64_t len, int advice)
 {
 	INTERNAL_SYSCALL_DECL (err);
 	/* ARM has always been funky. */
-# if defined(__UCLIBC_SYSCALL_ALIGN_64BIT__) || defined(__arm__)
+#if defined (__arm__) || \
+    (defined(__UCLIBC_SYSCALL_ALIGN_64BIT__) && (defined(__powerpc__) || defined(__xtensa__)))
+	/* arch with 64-bit data in even reg alignment #1: [powerpc/xtensa]
+	 * custom syscall handler (rearranges @advice to avoid register hole punch) */
 	int ret = INTERNAL_SYSCALL (fadvise64_64, err, 6, fd, advice,
 			OFF64_HI_LO (offset), OFF64_HI_LO (len));
+#elif defined(__UCLIBC_SYSCALL_ALIGN_64BIT__)
+	/* arch with 64-bit data in even reg alignment #2: [arcv2/others-in-future]
+	 * stock syscall handler in kernel (reg hole punched) */
+	int ret = INTERNAL_SYSCALL (fadvise64_64, err, 7, fd, 0,
+			OFF64_HI_LO (offset), OFF64_HI_LO (len),
+			advice);
 # else
 	int ret = INTERNAL_SYSCALL (fadvise64_64, err, 6, fd,
 			OFF64_HI_LO (offset), OFF64_HI_LO (len),
-- 
1.9.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.