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

From: Zhangjin Wu
Date: Mon Sep 25 2023 - 18:43:48 EST


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@xxxxxxxxxxx>
---
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