LoongArch 32-bit UAPI will be using generic syscall table,
mostly identical with 64-bit one. It will follow the convention
set by RISC-V, being the second 32 bit architecture without
time32.
Generate unisted_32.h and syscall_table_32.h as necessary,
expose united_32.h in unisted.h UAPI, and implement mmap2
which is a part of 32 bit syscalls.
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
arch/loongarch/include/asm/Kbuild | 1 +
arch/loongarch/include/uapi/asm/Kbuild | 1 +
arch/loongarch/include/uapi/asm/unistd.h | 6 ++++++
arch/loongarch/kernel/syscall.c | 21 +++++++++++++++++++++
4 files changed, 29 insertions(+)
diff --git a/arch/loongarch/include/asm/Kbuild b/arch/loongarch/include/asm/Kbuild
index 80ddb5edb8455ce206fe1c67c3156c486c07b892..39c6c45e2a759cf90015619776464af0a52a5b9a 100644
--- a/arch/loongarch/include/asm/Kbuild
+++ b/arch/loongarch/include/asm/Kbuild
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscall_table_32.h
syscall-y += syscall_table_64.h
generated-y += orc_hash.h
diff --git a/arch/loongarch/include/uapi/asm/Kbuild b/arch/loongarch/include/uapi/asm/Kbuild
index 517761419999a898ab3d73b2568eea160795faec..89ac01faa5aef5f35837b8c4acc583082c30db53 100644
--- a/arch/loongarch/include/uapi/asm/Kbuild
+++ b/arch/loongarch/include/uapi/asm/Kbuild
@@ -1,2 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
+syscall-y += unistd_32.h
syscall-y += unistd_64.h
diff --git a/arch/loongarch/include/uapi/asm/unistd.h b/arch/loongarch/include/uapi/asm/unistd.h
index 1f01980f9c94826957c9729c09c550cd090e4850..38c8bce307450f37b9cc72193c6999664a34b152 100644
--- a/arch/loongarch/include/uapi/asm/unistd.h
+++ b/arch/loongarch/include/uapi/asm/unistd.h
@@ -1,3 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
#include <asm/unistd_64.h>
+#else
+#include <asm/unistd_32.h>
+#endif
diff --git a/arch/loongarch/kernel/syscall.c b/arch/loongarch/kernel/syscall.c
index 168bd97540f8cfc9be26d75843c5066c6630a0d2..b267db6ed79c20199504247c181cc245ef86abfd 100644
--- a/arch/loongarch/kernel/syscall.c
+++ b/arch/loongarch/kernel/syscall.c
@@ -34,9 +34,30 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, unsigned long,
return ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
}
+#ifdef CONFIG_32BIT
+SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, unsigned long,
+ prot, unsigned long, flags, unsigned long, fd, unsigned long, offset)
+{
+ /*
+ * Note that the shift for mmap2 is constant (12),
+ * regardless of PAGE_SIZE
+ */
+
+ if (offset & (~PAGE_MASK >> 12))
+ return -EINVAL;
+
+ return ksys_mmap_pgoff(addr, len, prot, flags, fd,
+ offset >> (PAGE_SHIFT - 12));
+}
+#endif
+
void *sys_call_table[__NR_syscalls] = {
[0 ... __NR_syscalls - 1] = sys_ni_syscall,
+#ifdef CONFIG_64BIT
#include <asm/syscall_table_64.h>
+#else
+#include <asm/syscall_table_32.h>
+#endif
};
typedef long (*sys_call_fn)(unsigned long, unsigned long,
--
2.43.0
On Thu, Jan 2, 2025, at 19:34, Jiaxun Yang wrote:
>
> +#ifdef CONFIG_32BIT
> +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, unsigned long,
> + prot, unsigned long, flags, unsigned long, fd, unsigned long, offset)
> +{
> + /*
> + * Note that the shift for mmap2 is constant (12),
> + * regardless of PAGE_SIZE
> + */
> +
> + if (offset & (~PAGE_MASK >> 12))
> + return -EINVAL;
> +
> + return ksys_mmap_pgoff(addr, len, prot, flags, fd,
> + offset >> (PAGE_SHIFT - 12));
> +}
> +#endif
I think it's time we move this into mm/mmap.c and agree on the calling
conventions across architectures. I'm currently travelling, but I can
dig out a patch I made a while ago to convert most 32-bit
architectures over to a common mmap2() implementation.
As far as I can tell, the only architectures that actually want
mmap_pgoff() are m68k, arc and hexagon. Everything else either has
a fixed 4KB page size (so mmap_pgoff and mmap2 are the same), or
they already enforce the mmap2 semantics.
There are some smaller differences between architectures at the
moment that I think shouldn't really exist: sparc32/m68k/arm32/parisc
skips the alignment check, sparc64 and alpha add an overflow check (on
sys_mmap) and powerpc adds a pgprot argument check. I think the
version you have is fine for common code (including the ones that
don't check alignment today), not sure about the additional checks.
Arnd
© 2016 - 2026 Red Hat, Inc.