From 6966ec77b195ac289ae168c7c5646d59a307f33f Mon Sep 17 00:00:00 2001 From: Xiaotian Wu Date: Tue, 9 Feb 2021 15:39:13 +0800 Subject: [PATCH] arch: Add 64-bit LoongArch support Signed-off-by: Xiaotian Wu Signed-off-by: WANG Xuerui Acked-by: Tom Hromatka Signed-off-by: Paul Moore --- include/seccomp.h.in | 12 ++++++++++ src/Makefile.am | 1 + src/arch-loongarch64.c | 42 ++++++++++++++++++++++++++++++++ src/arch-loongarch64.h | 28 ++++++++++++++++++++++ src/arch-syscall-dump.c | 4 ++++ src/arch-syscall-validate | 50 +++++++++++++++++++++++++++++++++++++++ src/arch.c | 7 ++++++ src/gen_pfc.c | 2 ++ src/python/libseccomp.pxd | 1 + src/python/seccomp.pyx | 4 ++++ src/syscalls.h | 4 ++++ src/system.c | 1 + tools/scmp_arch_detect.c | 3 +++ tools/scmp_bpf_disasm.c | 2 ++ tools/scmp_bpf_sim.c | 2 ++ tools/util.c | 2 ++ tools/util.h | 11 +++++++++ 17 files changed, 176 insertions(+) create mode 100644 src/arch-loongarch64.c create mode 100644 src/arch-loongarch64.h diff --git a/include/seccomp.h.in b/include/seccomp.h.in index dfbb2671..4ab10d9c 100644 --- a/include/seccomp.h.in +++ b/include/seccomp.h.in @@ -152,6 +152,18 @@ struct scmp_arg_cmp { #endif /* AUDIT_ARCH_AARCH64 */ #define SCMP_ARCH_AARCH64 AUDIT_ARCH_AARCH64 +/** + * The LoongArch architecture tokens + */ +/* 64-bit LoongArch audit support is upstream as of 5.19-rc1 */ +#ifndef AUDIT_ARCH_LOONGARCH64 +#ifndef EM_LOONGARCH +#define EM_LOONGARCH 258 +#endif /* EM_LOONGARCH */ +#define AUDIT_ARCH_LOONGARCH64 (EM_LOONGARCH|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) +#endif /* AUDIT_ARCH_LOONGARCH64 */ +#define SCMP_ARCH_LOONGARCH64 AUDIT_ARCH_LOONGARCH64 + /** * The MIPS architecture tokens */ diff --git a/src/Makefile.am b/src/Makefile.am index 1ff0ee75..8c39d9e0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -32,6 +32,7 @@ SOURCES_ALL = \ arch-x32.h arch-x32.c \ arch-arm.h arch-arm.c \ arch-aarch64.h arch-aarch64.c \ + arch-loongarch64.h arch-loongarch64.c \ arch-mips.h arch-mips.c \ arch-mips64.h arch-mips64.c \ arch-mips64n32.h arch-mips64n32.c \ diff --git a/src/arch-loongarch64.c b/src/arch-loongarch64.c new file mode 100644 index 00000000..8268204d --- /dev/null +++ b/src/arch-loongarch64.c @@ -0,0 +1,42 @@ +/** + * Enhanced Seccomp 64-bit LoongArch Syscall Table + * + * Copyright (c) 2021 Xiaotian Wu + */ + +/* + * This library is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License as + * published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#include +#include +#include + +#include "arch.h" +#include "arch-loongarch64.h" +#include "syscalls.h" + +ARCH_DEF(loongarch64) + +const struct arch_def arch_def_loongarch64 = { + .token = SCMP_ARCH_LOONGARCH64, + .token_bpf = AUDIT_ARCH_LOONGARCH64, + .size = ARCH_SIZE_64, + .endian = ARCH_ENDIAN_LITTLE, + .syscall_resolve_name_raw = loongarch64_syscall_resolve_name, + .syscall_resolve_num_raw = loongarch64_syscall_resolve_num, + .syscall_rewrite = NULL, + .rule_add = NULL, + .syscall_name_kver = loongarch64_syscall_name_kver, + .syscall_num_kver = loongarch64_syscall_num_kver, +}; diff --git a/src/arch-loongarch64.h b/src/arch-loongarch64.h new file mode 100644 index 00000000..c3c06af7 --- /dev/null +++ b/src/arch-loongarch64.h @@ -0,0 +1,28 @@ +/** + * Enhanced Seccomp 64-bit LoongArch Syscall Table + * + * Copyright (c) 2021 Xiaotian Wu + */ + +/* + * This library is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License as + * published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#ifndef _ARCH_LOONGARCH64_H +#define _ARCH_LOONGARCH64_H + +#include "arch.h" + +ARCH_DECL(loongarch64) + +#endif diff --git a/src/arch-syscall-dump.c b/src/arch-syscall-dump.c index 843483b2..abc1680f 100644 --- a/src/arch-syscall-dump.c +++ b/src/arch-syscall-dump.c @@ -34,6 +34,7 @@ #include "arch-x86_64.h" #include "arch-x32.h" #include "arch-arm.h" +#include "arch-loongarch64.h" #include "arch-mips.h" #include "arch-mips64.h" #include "arch-mips64n32.h" @@ -107,6 +108,9 @@ int main(int argc, char *argv[]) case SCMP_ARCH_AARCH64: sys = aarch64_syscall_iterate(iter); break; + case SCMP_ARCH_LOONGARCH64: + sys = loongarch64_syscall_iterate(iter); + break; case SCMP_ARCH_MIPS: case SCMP_ARCH_MIPSEL: sys = mips_syscall_iterate(iter); diff --git a/src/arch-syscall-validate b/src/arch-syscall-validate index 0cb4d8f4..b2f62c6d 100755 --- a/src/arch-syscall-validate +++ b/src/arch-syscall-validate @@ -306,6 +306,48 @@ function dump_lib_aarch64() { dump_lib_arch aarch64 | mangle_lib_syscall aarch64 } +# +# Dump the loongarch64 syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_loongarch64() { + local sed_filter="" + + sed_filter+='s/__NR3264_fadvise64/223/;' + sed_filter+='s/__NR3264_fcntl/25/;' + sed_filter+='s/__NR3264_fstatfs/44/;' + sed_filter+='s/__NR3264_ftruncate/46/;' + sed_filter+='s/__NR3264_lseek/62/;' + sed_filter+='s/__NR3264_mmap/222/;' + sed_filter+='s/__NR3264_sendfile/71/;' + sed_filter+='s/__NR3264_statfs/43/;' + sed_filter+='s/__NR3264_truncate/45/;' + + gcc -E -dM -I$1/include/uapi \ + -D__BITS_PER_LONG=64 \ + -D__ARCH_WANT_SYS_CLONE \ + -D__ARCH_WANT_SYS_CLONE3 \ + $1/arch/loongarch/include/uapi/asm/unistd.h | \ + grep "^#define __NR_" | \ + sed '/__NR_syscalls/d' | \ + sed '/__NR_arch_specific_syscall/d' | \ + sed 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+\(.*\)/\1,\2/' | \ + sed $sed_filter | sort +} + +# +# Dump the loongarch64 library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_loongarch64() { + dump_lib_arch loongarch64 | mangle_lib_syscall loongarch64 +} + # # Dump the mips system syscall table # @@ -619,6 +661,9 @@ function dump_sys() { aarch64) dump_sys_aarch64 "$2" ;; + loongarch64) + dump_sys_loongarch64 "$2" + ;; mips) dump_sys_mips "$2" ;; @@ -686,6 +731,9 @@ function dump_lib() { aarch64) dump_lib_aarch64 ;; + loongarch64) + dump_lib_loongarch64 + ;; mips) dump_lib_mips ;; @@ -750,6 +798,7 @@ function gen_csv() { abi_list="" abi_list+=" x86 x86_64 x32" abi_list+=" arm aarch64" + abi_list+=" loongarch64" abi_list+=" mips mips64 mips64n32" abi_list+=" parisc parisc64" abi_list+=" ppc ppc64" @@ -861,6 +910,7 @@ if [[ $opt_arches == "" ]]; then opt_arches=" \ x86 x86_64 x32 \ arm aarch64 \ + loongarch64 \ mips mips64 mips64n32 \ parisc parisc64 \ ppc ppc64 \ diff --git a/src/arch.c b/src/arch.c index 921e4557..8c45fa38 100644 --- a/src/arch.c +++ b/src/arch.c @@ -35,6 +35,7 @@ #include "arch-x32.h" #include "arch-arm.h" #include "arch-aarch64.h" +#include "arch-loongarch64.h" #include "arch-mips.h" #include "arch-mips64.h" #include "arch-mips64n32.h" @@ -63,6 +64,8 @@ const struct arch_def *arch_def_native = &arch_def_x86_64; const struct arch_def *arch_def_native = &arch_def_arm; #elif __aarch64__ const struct arch_def *arch_def_native = &arch_def_aarch64; +#elif __loongarch64 +const struct arch_def *arch_def_native = &arch_def_loongarch64; #elif __mips__ && _MIPS_SIM == _MIPS_SIM_ABI32 #if __MIPSEB__ const struct arch_def *arch_def_native = &arch_def_mips; @@ -141,6 +144,8 @@ const struct arch_def *arch_def_lookup(uint32_t token) return &arch_def_arm; case SCMP_ARCH_AARCH64: return &arch_def_aarch64; + case SCMP_ARCH_LOONGARCH64: + return &arch_def_loongarch64; case SCMP_ARCH_MIPS: return &arch_def_mips; case SCMP_ARCH_MIPSEL: @@ -197,6 +202,8 @@ const struct arch_def *arch_def_lookup_name(const char *arch_name) return &arch_def_arm; else if (strcmp(arch_name, "aarch64") == 0) return &arch_def_aarch64; + else if (strcmp(arch_name, "loongarch64") == 0) + return &arch_def_loongarch64; else if (strcmp(arch_name, "mips") == 0) return &arch_def_mips; else if (strcmp(arch_name, "mipsel") == 0) diff --git a/src/gen_pfc.c b/src/gen_pfc.c index 4916055c..bb217c8e 100644 --- a/src/gen_pfc.c +++ b/src/gen_pfc.c @@ -61,6 +61,8 @@ static const char *_pfc_arch(const struct arch_def *arch) return "arm"; case SCMP_ARCH_AARCH64: return "aarch64"; + case SCMP_ARCH_LOONGARCH64: + return "loongarch64"; case SCMP_ARCH_MIPS: return "mips"; case SCMP_ARCH_MIPSEL: diff --git a/src/python/libseccomp.pxd b/src/python/libseccomp.pxd index 55f8207d..a6bd0b43 100644 --- a/src/python/libseccomp.pxd +++ b/src/python/libseccomp.pxd @@ -38,6 +38,7 @@ cdef extern from "seccomp.h": SCMP_ARCH_X32 SCMP_ARCH_ARM SCMP_ARCH_AARCH64 + SCMP_ARCH_LOONGARCH64 SCMP_ARCH_MIPS SCMP_ARCH_MIPS64 SCMP_ARCH_MIPS64N32 diff --git a/src/python/seccomp.pyx b/src/python/seccomp.pyx index 5657577f..9891d761 100644 --- a/src/python/seccomp.pyx +++ b/src/python/seccomp.pyx @@ -206,6 +206,7 @@ cdef class Arch: X32 - 64-bit x86 using the x32 ABI ARM - ARM AARCH64 - 64-bit ARM + LOONGARCH64 - 64-bit LoongArch MIPS - MIPS O32 ABI MIPS64 - MIPS 64-bit ABI MIPS64N32 - MIPS N32 ABI @@ -227,6 +228,7 @@ cdef class Arch: X32 = libseccomp.SCMP_ARCH_X32 ARM = libseccomp.SCMP_ARCH_ARM AARCH64 = libseccomp.SCMP_ARCH_AARCH64 + LOONGARCH64 = libseccomp.SCMP_ARCH_LOONGARCH64 MIPS = libseccomp.SCMP_ARCH_MIPS MIPS64 = libseccomp.SCMP_ARCH_MIPS64 MIPS64N32 = libseccomp.SCMP_ARCH_MIPS64N32 @@ -264,6 +266,8 @@ cdef class Arch: self._token = libseccomp.SCMP_ARCH_ARM elif arch == libseccomp.SCMP_ARCH_AARCH64: self._token = libseccomp.SCMP_ARCH_AARCH64 + elif arch == libseccomp.SCMP_ARCH_LOONGARCH64: + self._token = libseccomp.SCMP_ARCH_LOONGARCH64 elif arch == libseccomp.SCMP_ARCH_MIPS: self._token = libseccomp.SCMP_ARCH_MIPS elif arch == libseccomp.SCMP_ARCH_MIPS64: diff --git a/src/syscalls.h b/src/syscalls.h index 3a9e0cb5..10b2b7a2 100644 --- a/src/syscalls.h +++ b/src/syscalls.h @@ -15,6 +15,7 @@ #include "arch-aarch64.h" #include "arch-arm.h" #include "arch.h" +#include "arch-loongarch64.h" #include "arch-mips64.h" #include "arch-mips64n32.h" #include "arch-mips.h" @@ -51,6 +52,9 @@ struct arch_syscall_table { int aarch64; enum scmp_kver aarch64_kver; + int loongarch64; + enum scmp_kver loongarch64_kver; + int mips; enum scmp_kver mips_kver; int mips64; diff --git a/src/system.c b/src/system.c index 3d10e21d..e205de7a 100644 --- a/src/system.c +++ b/src/system.c @@ -128,6 +128,7 @@ int sys_chk_seccomp_syscall(void) case SCMP_ARCH_X86_64: case SCMP_ARCH_ARM: case SCMP_ARCH_AARCH64: + case SCMP_ARCH_LOONGARCH64: case SCMP_ARCH_PPC64: case SCMP_ARCH_PPC64LE: case SCMP_ARCH_S390: diff --git a/tools/scmp_arch_detect.c b/tools/scmp_arch_detect.c index b6bd2bbd..c23cf7f6 100644 --- a/tools/scmp_arch_detect.c +++ b/tools/scmp_arch_detect.c @@ -81,6 +81,9 @@ int main(int argc, char *argv[]) case SCMP_ARCH_AARCH64: printf("aarch64\n"); break; + case SCMP_ARCH_LOONGARCH64: + printf("loongarch64\n"); + break; case SCMP_ARCH_MIPS: printf("mips\n"); break; diff --git a/tools/scmp_bpf_disasm.c b/tools/scmp_bpf_disasm.c index b682de73..45726591 100644 --- a/tools/scmp_bpf_disasm.c +++ b/tools/scmp_bpf_disasm.c @@ -484,6 +484,8 @@ int main(int argc, char *argv[]) arch = AUDIT_ARCH_ARM; else if (strcmp(optarg, "aarch64") == 0) arch = AUDIT_ARCH_AARCH64; + else if (strcmp(optarg, "loongarch64") == 0) + arch = AUDIT_ARCH_LOONGARCH64; else if (strcmp(optarg, "mips") == 0) arch = AUDIT_ARCH_MIPS; else if (strcmp(optarg, "mipsel") == 0) diff --git a/tools/scmp_bpf_sim.c b/tools/scmp_bpf_sim.c index 04edfbc3..7d31d790 100644 --- a/tools/scmp_bpf_sim.c +++ b/tools/scmp_bpf_sim.c @@ -259,6 +259,8 @@ int main(int argc, char *argv[]) arch = AUDIT_ARCH_ARM; else if (strcmp(optarg, "aarch64") == 0) arch = AUDIT_ARCH_AARCH64; + else if (strcmp(optarg, "loongarch64") == 0) + arch = AUDIT_ARCH_LOONGARCH64; else if (strcmp(optarg, "mips") == 0) arch = AUDIT_ARCH_MIPS; else if (strcmp(optarg, "mipsel") == 0) diff --git a/tools/util.c b/tools/util.c index afea6c90..327fc148 100644 --- a/tools/util.c +++ b/tools/util.c @@ -44,6 +44,8 @@ #define ARCH_NATIVE AUDIT_ARCH_ARM #elif __aarch64__ #define ARCH_NATIVE AUDIT_ARCH_AARCH64 +#elif __loongarch64 +#define ARCH_NATIVE AUDIT_ARCH_LOONGARCH64 #elif __mips__ && _MIPS_SIM == _MIPS_SIM_ABI32 #if __MIPSEB__ #define ARCH_NATIVE AUDIT_ARCH_MIPS diff --git a/tools/util.h b/tools/util.h index 6c2ca33d..24b9ed6a 100644 --- a/tools/util.h +++ b/tools/util.h @@ -37,6 +37,17 @@ #define AUDIT_ARCH_AARCH64 (EM_AARCH64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) #endif /* AUDIT_ARCH_AARCH64 */ +/** + * The 64-bit LoongArch architecture tokens + */ +/* 64-bit LoongArch audit support is upstream as of 5.19-rc1 */ +#ifndef AUDIT_ARCH_LOONGARCH64 +#ifndef EM_LOONGARCH +#define EM_LOONGARCH 258 +#endif /* EM_LOONGARCH */ +#define AUDIT_ARCH_LOONGARCH64 (EM_LOONGARCH|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) +#endif /* AUDIT_ARCH_LOONGARCH64 */ + /** * The MIPS architecture tokens */