[PATCH v1 7/7] DCE/DSE: riscv: trim syscall tables

Zhangjin Wu falcon at tinylab.org
Mon Sep 25 15:43:32 PDT 2023


When the maximum nr of the used syscalls is smaller than __NR_syscalls
(original syscalls total). It is able to update __NR_syscalls to
(maximum nr + 1) and further trim the '>= (maximum nr + 1)' part of the
syscall tables:

For example:

    sys_call_table [143] = {
	[0 ... 143 - 1] = sys_ni_syscall,
        [64] = sys_write,
        [93] = sys_exit,
        [142] = sys_reboot,
    }

The >= 143 part of the syscall tables can be trimmed.

At the same time, the syscall >= 143 from user space must be ignored
from do_trap_ecall_u() of traps.c.

Signed-off-by: Zhangjin Wu <falcon at tinylab.org>
---
 arch/riscv/include/asm/unistd.h               |  2 ++
 arch/riscv/kernel/Makefile                    |  2 ++
 arch/riscv/kernel/syscalls/Makefile           | 22 +++++++++++++++++++
 .../kernel/syscalls/compat_syscall_table.c    |  4 ++--
 arch/riscv/kernel/syscalls/syscall_table.c    |  4 ++--
 5 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/include/asm/unistd.h b/arch/riscv/include/asm/unistd.h
index 221630bdbd07..4d8e41f446ff 100644
--- a/arch/riscv/include/asm/unistd.h
+++ b/arch/riscv/include/asm/unistd.h
@@ -23,4 +23,6 @@
 
 #include <uapi/asm/unistd.h>
 
+#ifndef NR_syscalls
 #define NR_syscalls (__NR_syscalls)
+#endif
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 40aebbf06880..e75424c10729 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -49,7 +49,9 @@ obj-y	+= signal.o
 obj-y	+= syscalls/
 obj-y	+= sys_riscv.o
 obj-y	+= time.o
+ifneq ($(CONFIG_TRIM_UNUSED_SYSCALLS),y)
 obj-y	+= traps.o
+endif
 obj-y	+= riscv_ksyms.o
 obj-y	+= stacktrace.o
 obj-y	+= cacheinfo.o
diff --git a/arch/riscv/kernel/syscalls/Makefile b/arch/riscv/kernel/syscalls/Makefile
index 3b5969aaa9e8..f1a0597c8b24 100644
--- a/arch/riscv/kernel/syscalls/Makefile
+++ b/arch/riscv/kernel/syscalls/Makefile
@@ -14,9 +14,18 @@ else # CONFIG_TRIM_UNUSED_SYSCALLS
 
 include $(srctree)/scripts/Makefile.syscalls
 
+# calculate syscalls total from $(obj)/syscall_table_used.i
+ifneq ($(used_syscalls),)
+  NR_syscalls := $$(($$(sed -E -n -e '/^\[([0-9]+|\([0-9]+ \+ [0-9]+\))\] = /{s/^\[(.*)\].*/\1/gp}' $(obj)/syscall_table_used.i | bc | sort -g | tail -1 | grep '[0-9]' || echo -1) + 1))
+else
+  NR_syscalls := 0
+endif
+
+CFLAGS_traps_used.o                += -DNR_syscalls=$(NR_syscalls)
 CFLAGS_syscall_table_used.o        += $(call cc-option,-Wno-override-init,)
 CFLAGS_compat_syscall_table_used.o += $(call cc-option,-Wno-override-init,)
 
+obj-y                += traps_used.o
 obj-y                += syscall_table_used.o
 obj-$(CONFIG_COMPAT) += compat_syscall_table_used.o
 
@@ -24,15 +33,26 @@ obj-$(CONFIG_COMPAT) += compat_syscall_table_used.o
 quiet_cmd_used = USED    $@
       cmd_used = sed -E -e '/^\[([0-9]+|\([0-9]+ \+ [0-9]+\))\] = /{/= *__riscv_(__sys_|sys_|compat_)*($(used_syscalls)),/!{s%^%/* %g;s%$$% */%g}}' -i $@;
 
+# update the syscalls total
+quiet_cmd_snr = SNR     $@
+      cmd_snr = snr=$(NR_syscalls); if [ $$snr -ne 0 ]; then \
+		sed -i -e "s/sys_call_table\[.*\] =/sys_call_table[($$snr)] =/g;s/\[0 ... (.*) - 1\] = __riscv_sys_ni_syscall/[0 ... ($$snr) - 1] = __riscv_sys_ni_syscall/g" $@; \
+		fi;
+
+$(obj)/traps_used.c: $(src)/../traps.c $(obj)/syscall_table_used.i FORCE
+	$(Q)cp $< $@
+
 $(obj)/syscall_table_used.c: $(src)/syscall_table.c
 	$(Q)cp $< $@
 
 $(obj)/syscall_table_used.i: $(src)/syscall_table_used.c $(used_syscalls_deps) FORCE
 	$(call if_changed_dep,cpp_i_c)
 	$(call cmd,used)
+	$(call cmd,snr)
 
 $(obj)/syscall_table_used.o: $(obj)/syscall_table_used.i FORCE
 	$(call if_changed,cc_o_c)
+	$(call cmd,force_checksrc)
 
 $(obj)/compat_syscall_table_used.c: $(src)/compat_syscall_table.c
 	$(Q)cp $< $@
@@ -40,8 +60,10 @@ $(obj)/compat_syscall_table_used.c: $(src)/compat_syscall_table.c
 $(obj)/compat_syscall_table_used.i: $(src)/compat_syscall_table_used.c $(used_syscalls_deps) FORCE
 	$(call if_changed_dep,cpp_i_c)
 	$(call cmd,used)
+	$(call cmd,snr)
 
 $(obj)/compat_syscall_table_used.o: $(obj)/compat_syscall_table_used.i FORCE
 	$(call if_changed,cc_o_c)
+	$(call cmd,force_checksrc)
 
 endif # CONFIG_TRIM_UNUSED_SYSCALLS
diff --git a/arch/riscv/kernel/syscalls/compat_syscall_table.c b/arch/riscv/kernel/syscalls/compat_syscall_table.c
index ad7f2d712f5f..4756b6858eac 100644
--- a/arch/riscv/kernel/syscalls/compat_syscall_table.c
+++ b/arch/riscv/kernel/syscalls/compat_syscall_table.c
@@ -17,7 +17,7 @@
 
 asmlinkage long compat_sys_rt_sigreturn(void);
 
-void * const compat_sys_call_table[__NR_syscalls] = {
-	[0 ... __NR_syscalls - 1] = __riscv_sys_ni_syscall,
+void * const compat_sys_call_table[NR_syscalls] = {
+	[0 ... NR_syscalls - 1] = __riscv_sys_ni_syscall,
 #include <asm/unistd.h>
 };
diff --git a/arch/riscv/kernel/syscalls/syscall_table.c b/arch/riscv/kernel/syscalls/syscall_table.c
index dda913764903..d2b3233ae5d4 100644
--- a/arch/riscv/kernel/syscalls/syscall_table.c
+++ b/arch/riscv/kernel/syscalls/syscall_table.c
@@ -16,7 +16,7 @@
 #undef __SYSCALL
 #define __SYSCALL(nr, call)	[nr] = __riscv_##call,
 
-void * const sys_call_table[__NR_syscalls] = {
-	[0 ... __NR_syscalls - 1] = __riscv_sys_ni_syscall,
+void * const sys_call_table[NR_syscalls] = {
+	[0 ... NR_syscalls - 1] = __riscv_sys_ni_syscall,
 #include <asm/unistd.h>
 };
-- 
2.25.1




More information about the linux-riscv mailing list