From 0000846cf5ca52268e4f372f8d6a4c9728120f20 Mon Sep 17 00:00:00 2001 From: Chisheng Chen Date: Sat, 11 Apr 2026 15:56:52 +0800 Subject: [PATCH 1/4] Add seccomp mode support for riscv64 This introduces the riscv64 architecture to kbox and just implements seccomp mode first. The trap mode and the rewrite mode are left unimplemented at this moment. Change-Id: Ie95e7d74dbef45a05df8c81c37362b9d119520c4 --- README.md | 1 + mk/toolchain.mk | 5 +++++ scripts/alpine-sha256.txt | 1 + src/dispatch-misc.c | 2 ++ src/image.c | 14 +++++++++++-- src/rewrite.c | 6 +++--- src/seccomp-bpf.c | 2 +- src/seccomp-defs.h | 2 ++ src/seccomp-supervisor.c | 4 ++-- src/syscall-nr.c | 2 +- src/syscall-nr.h | 2 +- src/syscall-trap.c | 37 ++++++++++++++++++++++++++++++++++ tests/unit/test-syscall-nr.c | 8 ++++---- tests/unit/test-syscall-trap.c | 16 +++++++-------- 14 files changed, 80 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 44d8bc4..dc13962 100644 --- a/README.md +++ b/README.md @@ -267,6 +267,7 @@ with - x86_64 - aarch64 +- riscv64 ## License diff --git a/mk/toolchain.mk b/mk/toolchain.mk index 2d4297d..bac91a2 100644 --- a/mk/toolchain.mk +++ b/mk/toolchain.mk @@ -29,6 +29,11 @@ CFLAGS += -Wno-unused-parameter CFLAGS += -Iinclude -Isrc LDFLAGS += -Wl,-z,noexecstack -Wl,-z,separate-code +# Disable link relaxation of riscv64 architecture to prevent long link time +ifeq ($(ARCH),riscv64) + LDFLAGS += -Wl,--no-relax +endif + # Build mode from Kconfig (fallback to BUILD= for unconfigured builds) ifeq ($(CONFIG_BUILD_RELEASE),y) CFLAGS += -O2 -DNDEBUG diff --git a/scripts/alpine-sha256.txt b/scripts/alpine-sha256.txt index 6259d19..346dec3 100644 --- a/scripts/alpine-sha256.txt +++ b/scripts/alpine-sha256.txt @@ -1,2 +1,3 @@ 55ea3e5a7c2c35e6268c5dcbb8e45a9cd5b0e372e7b4e798499a526834f7ed90 alpine-minirootfs-3.21.0-x86_64.tar.gz f31202c4070c4ef7de9e157e1bd01cb4da3a2150035d74ea5372c5e86f1efac1 alpine-minirootfs-3.21.0-aarch64.tar.gz +b2c5ed2be586aebd2da5dd13dbc96bc8cc41b72e517d0726dfbbb0a9810e66d6 alpine-minirootfs-3.21.0-riscv64.tar.gz diff --git a/src/dispatch-misc.c b/src/dispatch-misc.c index e6b4478..ffcac95 100644 --- a/src/dispatch-misc.c +++ b/src/dispatch-misc.c @@ -239,6 +239,8 @@ struct kbox_dispatch forward_uname(const struct kbox_syscall_request *req, snprintf(uts.machine, sizeof(uts.machine), "x86_64"); #elif defined(__aarch64__) snprintf(uts.machine, sizeof(uts.machine), "aarch64"); +#elif (defined(__riscv) && __riscv_xlen == 64) + snprintf(uts.machine, sizeof(uts.machine), "riscv64"); #else snprintf(uts.machine, sizeof(uts.machine), "unknown"); #endif diff --git a/src/image.c b/src/image.c index 635945e..7840881 100644 --- a/src/image.c +++ b/src/image.c @@ -490,8 +490,8 @@ static const struct kbox_host_nrs *select_host_nrs(void) { #if defined(__x86_64__) return &HOST_NRS_X86_64; -#elif defined(__aarch64__) - return &HOST_NRS_AARCH64; +#elif defined(__aarch64__) || (defined(__riscv) && (__riscv_xlen == 64)) + return &HOST_NRS_GENERIC; #else return NULL; #endif @@ -1318,6 +1318,16 @@ int kbox_run_image(const struct kbox_image_args *args) * all children share one LKL instance. */ { +#if !defined(__x86_64__) && !defined(__aarch64__) + if (args->syscall_mode == KBOX_SYSCALL_MODE_TRAP) { + fprintf(stderr, + "kbox: unsupported architecture for trap mode\n"); + close(exec_memfd); + if (interp_memfd >= 0) + close(interp_memfd); + goto err_net; + } +#endif int use_trap = (args->syscall_mode == KBOX_SYSCALL_MODE_TRAP); if (args->syscall_mode == KBOX_SYSCALL_MODE_AUTO) { if (!is_shell_command(command)) { diff --git a/src/rewrite.c b/src/rewrite.c index 25b852a..77c276b 100644 --- a/src/rewrite.c +++ b/src/rewrite.c @@ -608,10 +608,10 @@ static int encode_aarch64_virtual_procinfo_patch( if (aarch64_prev_insn_syscall_nr(image, image_len, site_off, &nr) < 0) return -1; - if (nr == (uint32_t) HOST_NRS_AARCH64.getpid || - nr == (uint32_t) HOST_NRS_AARCH64.gettid) { + if (nr == (uint32_t) HOST_NRS_GENERIC.getpid || + nr == (uint32_t) HOST_NRS_GENERIC.gettid) { value = 1; - } else if (nr == (uint32_t) HOST_NRS_AARCH64.getppid) { + } else if (nr == (uint32_t) HOST_NRS_GENERIC.getppid) { value = 0; } else { return -1; diff --git a/src/seccomp-bpf.c b/src/seccomp-bpf.c index ad86b1d..8481eff 100644 --- a/src/seccomp-bpf.c +++ b/src/seccomp-bpf.c @@ -142,7 +142,7 @@ static const int deny_nrs[] = { 153, /* vhangup */ }; -#elif defined(__aarch64__) +#elif defined(__aarch64__) || (defined(__riscv) && __riscv_xlen == 64) static const int deny_nrs[] = { /* Seccomp manipulation */ 277, /* seccomp */ diff --git a/src/seccomp-defs.h b/src/seccomp-defs.h index 68a8874..948526f 100644 --- a/src/seccomp-defs.h +++ b/src/seccomp-defs.h @@ -34,6 +34,8 @@ #define KBOX_AUDIT_ARCH_CURRENT 0xc000003eU #elif defined(__aarch64__) #define KBOX_AUDIT_ARCH_CURRENT 0xc00000b7U +#elif defined(__riscv) && __riscv_xlen == 64 +#define KBOX_AUDIT_ARCH_CURRENT 0xc00000f3U #else #error "unsupported architecture" #endif diff --git a/src/seccomp-supervisor.c b/src/seccomp-supervisor.c index e506443..08ba24c 100644 --- a/src/seccomp-supervisor.c +++ b/src/seccomp-supervisor.c @@ -482,8 +482,8 @@ int kbox_run_supervisor(const struct kbox_sysnrs *sysnrs, /* Architecture-specific host syscall numbers for the BPF filter. */ #if defined(__x86_64__) const struct kbox_host_nrs *host_nrs = &HOST_NRS_X86_64; -#elif defined(__aarch64__) - const struct kbox_host_nrs *host_nrs = &HOST_NRS_AARCH64; +#elif defined(__aarch64__) || (defined(__riscv) && __riscv_xlen == 64) + const struct kbox_host_nrs *host_nrs = &HOST_NRS_GENERIC; #else #error "Unsupported architecture" #endif diff --git a/src/syscall-nr.c b/src/syscall-nr.c index 3368637..bfad4da 100644 --- a/src/syscall-nr.c +++ b/src/syscall-nr.c @@ -353,7 +353,7 @@ const struct kbox_host_nrs HOST_NRS_X86_64 = { .readlink = 89, }; -const struct kbox_host_nrs HOST_NRS_AARCH64 = { +const struct kbox_host_nrs HOST_NRS_GENERIC = { .openat = 56, .openat2 = 437, .open = -1, diff --git a/src/syscall-nr.h b/src/syscall-nr.h index ec7e902..d3dd90f 100644 --- a/src/syscall-nr.h +++ b/src/syscall-nr.h @@ -220,7 +220,7 @@ struct kbox_host_nrs { }; extern const struct kbox_host_nrs HOST_NRS_X86_64; -extern const struct kbox_host_nrs HOST_NRS_AARCH64; +extern const struct kbox_host_nrs HOST_NRS_GENERIC; const struct kbox_sysnrs *detect_sysnrs(void); const char *syscall_name_from_nr(const struct kbox_host_nrs *h, int nr); diff --git a/src/syscall-trap.c b/src/syscall-trap.c index c67710d..663fb14 100644 --- a/src/syscall-trap.c +++ b/src/syscall-trap.c @@ -579,6 +579,43 @@ extern int64_t kbox_syscall_trap_host_clone3_now(const void *uargs, extern int64_t kbox_syscall_trap_host_rt_sigprocmask_unblock( const uint64_t *mask, size_t sigset_size); +#elif (defined(__riscv) && __riscv_xlen == 64) +int64_t kbox_syscall_trap_host_syscall6(long nr, + uint64_t a0, + uint64_t a1, + uint64_t a2, + uint64_t a3, + uint64_t a4, + uint64_t a5) +{ +} +int64_t kbox_syscall_trap_host_futex_wait_private(int *addr, int expected) {} +int64_t kbox_syscall_trap_host_futex_wake_private(int *addr, int count) {} +int64_t kbox_syscall_trap_host_exit_group_now(int status) {} +int64_t kbox_syscall_trap_host_execve_now(const char *pathname, + char *const argv[], + char *const envp[]) +{ +} +int64_t kbox_syscall_trap_host_execveat_now(int dirfd, + const char *pathname, + char *const argv[], + char *const envp[], + int flags) +{ +} +int64_t kbox_syscall_trap_host_clone_now(uint64_t a0, + uint64_t a1, + uint64_t a2, + uint64_t a3, + uint64_t a4) +{ +} +int64_t kbox_syscall_trap_host_clone3_now(const void *uargs, size_t size) {} +int64_t kbox_syscall_trap_host_rt_sigprocmask_unblock(const uint64_t *mask, + size_t sigset_size) +{ +} #endif static int direct_trap_execute(struct kbox_syscall_trap_runtime *runtime, diff --git a/tests/unit/test-syscall-nr.c b/tests/unit/test-syscall-nr.c index 7bd5c12..8c2da54 100644 --- a/tests/unit/test-syscall-nr.c +++ b/tests/unit/test-syscall-nr.c @@ -72,15 +72,15 @@ static void test_host_x86_64_sendmsg(void) static void test_host_aarch64_gettimeofday(void) { - ASSERT_EQ(HOST_NRS_AARCH64.gettimeofday, 169); + ASSERT_EQ(HOST_NRS_GENERIC.gettimeofday, 169); } static void test_host_aarch64_no_open(void) { /* aarch64 has no legacy open syscall */ - ASSERT_EQ(HOST_NRS_AARCH64.open, -1); - ASSERT_EQ(HOST_NRS_AARCH64.stat, -1); - ASSERT_EQ(HOST_NRS_AARCH64.lstat, -1); + ASSERT_EQ(HOST_NRS_GENERIC.open, -1); + ASSERT_EQ(HOST_NRS_GENERIC.stat, -1); + ASSERT_EQ(HOST_NRS_GENERIC.lstat, -1); } static void test_at_fdcwd(void) diff --git a/tests/unit/test-syscall-trap.c b/tests/unit/test-syscall-trap.c index 88a893c..0a39ae5 100644 --- a/tests/unit/test-syscall-trap.c +++ b/tests/unit/test-syscall-trap.c @@ -259,7 +259,7 @@ static void test_sigsys_continue_executes_host_syscall(void) uc.uc_mcontext.gregs[REG_RAX] = HOST_NRS_X86_64.getpid; expected_rc = 0; #elif defined(__aarch64__) - uc.uc_mcontext.regs[8] = HOST_NRS_AARCH64.getpid; + uc.uc_mcontext.regs[8] = HOST_NRS_GENERIC.getpid; expected_rc = 0; #endif @@ -280,7 +280,7 @@ static void test_sigsys_runtime_install_uninstall(void) #if defined(__x86_64__) ctx.host_nrs = &HOST_NRS_X86_64; #elif defined(__aarch64__) - ctx.host_nrs = &HOST_NRS_AARCH64; + ctx.host_nrs = &HOST_NRS_GENERIC; #endif ASSERT_EQ(kbox_syscall_trap_runtime_install(&runtime, &ctx), 0); @@ -301,7 +301,7 @@ static void test_sigsys_runtime_install_preserves_sqpoll(void) #if defined(__x86_64__) ctx.host_nrs = &HOST_NRS_X86_64; #elif defined(__aarch64__) - ctx.host_nrs = &HOST_NRS_AARCH64; + ctx.host_nrs = &HOST_NRS_GENERIC; #endif runtime.sqpoll = 1; @@ -372,7 +372,7 @@ static void test_sigsys_dispatch_helper(void) uc.uc_mcontext.gregs[REG_RIP] = 0x7000; expected_rc = 0; #elif defined(__aarch64__) - ctx.host_nrs = &HOST_NRS_AARCH64; + ctx.host_nrs = &HOST_NRS_GENERIC; init_sigsys(&info, 172); uc.uc_mcontext.pc = 0x7000; expected_rc = 0; @@ -406,7 +406,7 @@ static void test_trap_runtime_capture_and_dispatch_pending(void) uc.uc_mcontext.gregs[REG_RIP] = 0x7200; expected_rc = 0; #elif defined(__aarch64__) - ctx.host_nrs = &HOST_NRS_AARCH64; + ctx.host_nrs = &HOST_NRS_GENERIC; init_sigsys(&info, 172); uc.uc_mcontext.pc = 0x7200; expected_rc = 0; @@ -467,7 +467,7 @@ static void test_trap_runtime_service_thread_dispatches(void) memset(&ctx, 0, sizeof(ctx)); #if defined(__aarch64__) - ctx.host_nrs = &HOST_NRS_AARCH64; + ctx.host_nrs = &HOST_NRS_GENERIC; #else ctx.host_nrs = &HOST_NRS_X86_64; #endif @@ -505,7 +505,7 @@ static void test_trap_active_dispatch_uses_service_thread(void) #if defined(__x86_64__) ctx.host_nrs = &HOST_NRS_X86_64; #elif defined(__aarch64__) - ctx.host_nrs = &HOST_NRS_AARCH64; + ctx.host_nrs = &HOST_NRS_GENERIC; #endif req.nr = 88; @@ -533,7 +533,7 @@ static void test_trap_active_dispatch_fails_cleanly_during_sqpoll_stop(void) #if defined(__x86_64__) ctx.host_nrs = &HOST_NRS_X86_64; #elif defined(__aarch64__) - ctx.host_nrs = &HOST_NRS_AARCH64; + ctx.host_nrs = &HOST_NRS_GENERIC; #endif req.nr = 99; From 0000cfd976a7506f6e64f00570ba82fbf11af390 Mon Sep 17 00:00:00 2001 From: Chisheng Chen Date: Sat, 11 Apr 2026 23:07:37 +0800 Subject: [PATCH 2/4] Add trap mode support for riscv64 This implements the trap mode for riscv64 architecture. The rewrite mode is left unimplemented at this moment. Change-Id: I3509e98008c4f7831c086d387d139d4dbab056f3 --- src/elf.c | 2 +- src/image.c | 10 -- src/loader-entry.c | 3 + src/loader-entry.h | 1 + src/loader-transfer.c | 18 +++ src/seccomp-dispatch.c | 8 +- src/syscall-trap.c | 282 ++++++++++++++++++++++++++++++++--------- 7 files changed, 249 insertions(+), 75 deletions(-) diff --git a/src/elf.c b/src/elf.c index 5baebe5..0f1162e 100644 --- a/src/elf.c +++ b/src/elf.c @@ -417,7 +417,7 @@ int kbox_build_elf_load_plan(const unsigned char *buf, p_memsz = read_le64(buf + off + P_MEMSZ_OFF); p_align = read_le64(buf + off + P_ALIGN_OFF); - if (p_filesz > p_memsz) + if (p_memsz && p_filesz > p_memsz) return -1; /* Validate that p_offset + p_filesz does not overflow. We do diff --git a/src/image.c b/src/image.c index 7840881..e2cd277 100644 --- a/src/image.c +++ b/src/image.c @@ -1318,16 +1318,6 @@ int kbox_run_image(const struct kbox_image_args *args) * all children share one LKL instance. */ { -#if !defined(__x86_64__) && !defined(__aarch64__) - if (args->syscall_mode == KBOX_SYSCALL_MODE_TRAP) { - fprintf(stderr, - "kbox: unsupported architecture for trap mode\n"); - close(exec_memfd); - if (interp_memfd >= 0) - close(interp_memfd); - goto err_net; - } -#endif int use_trap = (args->syscall_mode == KBOX_SYSCALL_MODE_TRAP); if (args->syscall_mode == KBOX_SYSCALL_MODE_AUTO) { if (!is_shell_command(command)) { diff --git a/src/loader-entry.c b/src/loader-entry.c index faf77f1..171d453 100644 --- a/src/loader-entry.c +++ b/src/loader-entry.c @@ -17,6 +17,9 @@ static int machine_to_entry_arch(uint16_t machine, case 0xb7: *arch_out = KBOX_LOADER_ENTRY_ARCH_AARCH64; return 0; + case 0xf3: + *arch_out = KBOX_LOADER_ENTRY_ARCH_RISCV64; + return 0; default: return -1; } diff --git a/src/loader-entry.h b/src/loader-entry.h index 6747d59..e3cd7bb 100644 --- a/src/loader-entry.h +++ b/src/loader-entry.h @@ -9,6 +9,7 @@ enum kbox_loader_entry_arch { KBOX_LOADER_ENTRY_ARCH_X86_64, KBOX_LOADER_ENTRY_ARCH_AARCH64, + KBOX_LOADER_ENTRY_ARCH_RISCV64 }; struct kbox_loader_entry_state { diff --git a/src/loader-transfer.c b/src/loader-transfer.c index 192051d..0408706 100644 --- a/src/loader-transfer.c +++ b/src/loader-transfer.c @@ -89,6 +89,24 @@ kbox_loader_transfer_to_guest(const struct kbox_loader_transfer_state *state) : "r"(sp), "r"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4), "r"(x5), "r"(x16) : "memory"); +#elif defined(__riscv) && (__riscv_xlen == 64) + if (state->arch != KBOX_LOADER_ENTRY_ARCH_RISCV64) + __builtin_trap(); + register uint64_t a0 __asm__("a0") = state->regs[0]; + register uint64_t a1 __asm__("a1") = state->regs[1]; + register uint64_t a2 __asm__("a2") = state->regs[2]; + register uint64_t a3 __asm__("a3") = state->regs[3]; + register uint64_t a4 __asm__("a4") = state->regs[4]; + register uint64_t a5 __asm__("a5") = state->regs[5]; + register uint64_t t0 __asm__("t0") = state->pc; + uint64_t sp = state->sp; + + __asm__ volatile( + "mv sp, %0\n\t" + "jr t0\n\t" + : + : "r"(sp), "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5), "r"(t0) + : "memory"); #else (void) state; __builtin_trap(); diff --git a/src/seccomp-dispatch.c b/src/seccomp-dispatch.c index 3894750..1a5f3f9 100644 --- a/src/seccomp-dispatch.c +++ b/src/seccomp-dispatch.c @@ -33,28 +33,28 @@ #ifndef __NR_pidfd_open #if defined(__x86_64__) #define __NR_pidfd_open 434 -#elif defined(__aarch64__) +#elif defined(__aarch64__) || (defined(__riscv) && (__riscv_xlen == 64)) #define __NR_pidfd_open 434 #endif #endif #ifndef __NR_pidfd_getfd #if defined(__x86_64__) #define __NR_pidfd_getfd 438 -#elif defined(__aarch64__) +#elif defined(__aarch64__) || (defined(__riscv) && (__riscv_xlen == 64)) #define __NR_pidfd_getfd 438 #endif #endif #ifndef __NR_faccessat2 #if defined(__x86_64__) #define __NR_faccessat2 439 -#elif defined(__aarch64__) +#elif defined(__aarch64__) || (defined(__riscv) && (__riscv_xlen == 64)) #define __NR_faccessat2 439 #endif #endif #ifndef __NR_statx #if defined(__x86_64__) #define __NR_statx 332 -#elif defined(__aarch64__) +#elif defined(__aarch64__) || (defined(__riscv) && (__riscv_xlen == 64)) #define __NR_statx 291 #endif #endif diff --git a/src/syscall-trap.c b/src/syscall-trap.c index 663fb14..639c9d1 100644 --- a/src/syscall-trap.c +++ b/src/syscall-trap.c @@ -387,26 +387,6 @@ extern int64_t kbox_syscall_trap_host_rt_sigprocmask_unblock( const uint64_t *mask, size_t sigset_size); #elif defined(__aarch64__) -extern char kbox_syscall_trap_host_syscall_start[]; -extern char kbox_syscall_trap_host_syscall_ip_label[]; -extern char kbox_syscall_trap_host_syscall_end[]; -extern char kbox_syscall_trap_host_futex_wait_start[]; -extern char kbox_syscall_trap_host_futex_wait_end[]; -extern char kbox_syscall_trap_host_futex_wake_start[]; -extern char kbox_syscall_trap_host_futex_wake_end[]; -extern char kbox_syscall_trap_host_exit_group_start[]; -extern char kbox_syscall_trap_host_exit_group_end[]; -extern char kbox_syscall_trap_host_execve_start[]; -extern char kbox_syscall_trap_host_execve_end[]; -extern char kbox_syscall_trap_host_execveat_start[]; -extern char kbox_syscall_trap_host_execveat_end[]; -extern char kbox_syscall_trap_host_clone_start[]; -extern char kbox_syscall_trap_host_clone_end[]; -extern char kbox_syscall_trap_host_clone3_start[]; -extern char kbox_syscall_trap_host_clone3_end[]; -extern char kbox_syscall_trap_host_rt_sigprocmask_unblock_start[]; -extern char kbox_syscall_trap_host_rt_sigprocmask_unblock_end[]; - __asm__( ".text\n" ".globl kbox_syscall_trap_host_syscall6\n" @@ -549,6 +529,172 @@ __asm__( "ret\n" ".size kbox_syscall_trap_host_rt_sigprocmask_unblock, " ".-kbox_syscall_trap_host_rt_sigprocmask_unblock\n"); +#elif (defined(__riscv) && __riscv_xlen == 64) +__asm__( + ".text\n" + ".globl kbox_syscall_trap_host_syscall6\n" + ".type kbox_syscall_trap_host_syscall6,%function\n" + ".globl kbox_syscall_trap_host_syscall_start\n" + "kbox_syscall_trap_host_syscall_start:\n" + "kbox_syscall_trap_host_syscall6:\n" + "mv a7, a0\n" + "mv a0, a1\n" + "mv a1, a2\n" + "mv a2, a3\n" + "mv a3, a4\n" + "mv a4, a5\n" + "mv a5, a6\n" + ".globl kbox_syscall_trap_host_syscall_ip_label\n" + "kbox_syscall_trap_host_syscall_ip_label:\n" + "ecall\n" + ".globl kbox_syscall_trap_host_syscall_end\n" + "kbox_syscall_trap_host_syscall_end:\n" + "ret\n" + ".size kbox_syscall_trap_host_syscall6, " + ".-kbox_syscall_trap_host_syscall6\n" + + ".globl kbox_syscall_trap_host_futex_wait_private\n" + ".type kbox_syscall_trap_host_futex_wait_private,%function\n" + ".globl kbox_syscall_trap_host_futex_wait_start\n" + "kbox_syscall_trap_host_futex_wait_private:\n" + "kbox_syscall_trap_host_futex_wait_start:" + "li a7, " XSTR(__NR_futex) "\n" + "mv a2, a1\n" + "li a1, " XSTR(FUTEX_WAIT_PRIVATE) "\n" + "li a3, 0\n" + "li a4, 0\n" + "li a5, 0\n" + "ecall\n" + ".globl kbox_syscall_trap_host_futex_wait_end\n" + "kbox_syscall_trap_host_futex_wait_end:\n" + "ret\n" + ".size kbox_syscall_trap_host_futex_wait_private, " + ".-kbox_syscall_trap_host_futex_wait_private\n" + + ".globl kbox_syscall_trap_host_futex_wake_private\n" + ".type kbox_syscall_trap_host_futex_wake_private,%function\n" + ".globl kbox_syscall_trap_host_futex_wake_start\n" + "kbox_syscall_trap_host_futex_wake_start:\n" + "kbox_syscall_trap_host_futex_wake_private:\n" + "li a7, " XSTR(__NR_futex) "\n" + "mv a2, a1\n" + "li a1, " XSTR(FUTEX_WAKE_PRIVATE) "\n" + "li a3, 0\n" + "li a4, 0\n" + "li a5, 0\n" + "ecall\n" + ".globl kbox_syscall_trap_host_futex_wake_end\n" + "kbox_syscall_trap_host_futex_wake_end:\n" + "ret\n" + ".size kbox_syscall_trap_host_futex_wake_private, " + ".-kbox_syscall_trap_host_futex_wake_private\n" + + ".globl kbox_syscall_trap_host_exit_group_now\n" + ".type kbox_syscall_trap_host_exit_group_now,%function\n" + ".globl kbox_syscall_trap_host_exit_group_start\n" + "kbox_syscall_trap_host_exit_group_start:\n" + "kbox_syscall_trap_host_exit_group_now:\n" + "li a7, " XSTR(__NR_exit_group) "\n" + "ecall\n" + ".globl kbox_syscall_trap_host_exit_group_end\n" + "kbox_syscall_trap_host_exit_group_end:\n" + "ret\n" + ".size kbox_syscall_trap_host_exit_group_now, " + ".-kbox_syscall_trap_host_exit_group_now\n" + + ".globl kbox_syscall_trap_host_execve_now\n" + ".type kbox_syscall_trap_host_execve_now,%function\n" + ".globl kbox_syscall_trap_host_execve_start\n" + "kbox_syscall_trap_host_execve_start:\n" + "kbox_syscall_trap_host_execve_now:\n" + "li a7, " XSTR(__NR_execve) "\n" + "ecall\n" + ".globl kbox_syscall_trap_host_execve_end\n" + "kbox_syscall_trap_host_execve_end:\n" + "ret\n" + ".size kbox_syscall_trap_host_execve_now, " + ".-kbox_syscall_trap_host_execve_now\n" + + ".globl kbox_syscall_trap_host_execveat_now\n" + ".type kbox_syscall_trap_host_execveat_now,%function\n" + ".globl kbox_syscall_trap_host_execveat_start\n" + "kbox_syscall_trap_host_execveat_start:\n" + "kbox_syscall_trap_host_execveat_now:\n" + "li a7, " XSTR(__NR_execveat) "\n" + "ecall\n" + ".globl kbox_syscall_trap_host_execveat_end\n" + "kbox_syscall_trap_host_execveat_end:\n" + "ret\n" + ".size kbox_syscall_trap_host_execveat_now, " + ".-kbox_syscall_trap_host_execveat_now\n" + + ".globl kbox_syscall_trap_host_clone_now\n" + ".type kbox_syscall_trap_host_clone_now,%function\n" + ".globl kbox_syscall_trap_host_clone_start\n" + "kbox_syscall_trap_host_clone_start:\n" + "kbox_syscall_trap_host_clone_now:\n" + "li a7, " XSTR(__NR_clone) "\n" + "ecall\n" + ".globl kbox_syscall_trap_host_clone_end\n" + "kbox_syscall_trap_host_clone_end:\n" + "ret\n" + ".size kbox_syscall_trap_host_clone_now, " + ".-kbox_syscall_trap_host_clone_now\n" + + ".globl kbox_syscall_trap_host_clone3_now\n" + ".type kbox_syscall_trap_host_clone3_now,%function\n" + ".globl kbox_syscall_trap_host_clone3_start\n" + "kbox_syscall_trap_host_clone3_start:\n" + "kbox_syscall_trap_host_clone3_now:\n" + "li a7, " XSTR(__NR_clone3) "\n" + "ecall\n" + ".globl kbox_syscall_trap_host_clone3_end\n" + "kbox_syscall_trap_host_clone3_end:\n" + "ret\n" + ".size kbox_syscall_trap_host_clone3_now, " + ".-kbox_syscall_trap_host_clone3_now\n" + + ".globl kbox_syscall_trap_host_rt_sigprocmask_unblock\n" + ".type kbox_syscall_trap_host_rt_sigprocmask_unblock,%function\n" + ".globl kbox_syscall_trap_host_rt_sigprocmask_unblock_start\n" + "kbox_syscall_trap_host_rt_sigprocmask_unblock_start:\n" + "kbox_syscall_trap_host_rt_sigprocmask_unblock:\n" + "li a7, " XSTR(__NR_rt_sigprocmask) "\n" + "mv a3, a1\n" + "mv a1, a0\n" + "li a0, " XSTR(SIG_UNBLOCK) "\n" + "li a2, 0\n" + "li a4, 0\n" + "li a5, 0\n" + "ecall\n" + ".globl kbox_syscall_trap_host_rt_sigprocmask_unblock_end\n" + "kbox_syscall_trap_host_rt_sigprocmask_unblock_end:\n" + "ret\n" + ".size kbox_syscall_trap_host_rt_sigprocmask_unblock, " + ".-kbox_syscall_trap_host_rt_sigprocmask_unblock\n"); +#endif + +#if defined(__aarch64__) || (defined(__riscv) && __riscv_xlen == 64) +extern char kbox_syscall_trap_host_syscall_start[]; +extern char kbox_syscall_trap_host_syscall_ip_label[]; +extern char kbox_syscall_trap_host_syscall_end[]; +extern char kbox_syscall_trap_host_futex_wait_start[]; +extern char kbox_syscall_trap_host_futex_wait_end[]; +extern char kbox_syscall_trap_host_futex_wake_start[]; +extern char kbox_syscall_trap_host_futex_wake_end[]; +extern char kbox_syscall_trap_host_exit_group_start[]; +extern char kbox_syscall_trap_host_exit_group_end[]; +extern char kbox_syscall_trap_host_execve_start[]; +extern char kbox_syscall_trap_host_execve_end[]; +extern char kbox_syscall_trap_host_execveat_start[]; +extern char kbox_syscall_trap_host_execveat_end[]; +extern char kbox_syscall_trap_host_clone_start[]; +extern char kbox_syscall_trap_host_clone_end[]; +extern char kbox_syscall_trap_host_clone3_start[]; +extern char kbox_syscall_trap_host_clone3_end[]; +extern char kbox_syscall_trap_host_rt_sigprocmask_unblock_start[]; +extern char kbox_syscall_trap_host_rt_sigprocmask_unblock_end[]; + extern int64_t kbox_syscall_trap_host_syscall6(long nr, uint64_t a0, @@ -579,43 +725,6 @@ extern int64_t kbox_syscall_trap_host_clone3_now(const void *uargs, extern int64_t kbox_syscall_trap_host_rt_sigprocmask_unblock( const uint64_t *mask, size_t sigset_size); -#elif (defined(__riscv) && __riscv_xlen == 64) -int64_t kbox_syscall_trap_host_syscall6(long nr, - uint64_t a0, - uint64_t a1, - uint64_t a2, - uint64_t a3, - uint64_t a4, - uint64_t a5) -{ -} -int64_t kbox_syscall_trap_host_futex_wait_private(int *addr, int expected) {} -int64_t kbox_syscall_trap_host_futex_wake_private(int *addr, int count) {} -int64_t kbox_syscall_trap_host_exit_group_now(int status) {} -int64_t kbox_syscall_trap_host_execve_now(const char *pathname, - char *const argv[], - char *const envp[]) -{ -} -int64_t kbox_syscall_trap_host_execveat_now(int dirfd, - const char *pathname, - char *const argv[], - char *const envp[], - int flags) -{ -} -int64_t kbox_syscall_trap_host_clone_now(uint64_t a0, - uint64_t a1, - uint64_t a2, - uint64_t a3, - uint64_t a4) -{ -} -int64_t kbox_syscall_trap_host_clone3_now(const void *uargs, size_t size) {} -int64_t kbox_syscall_trap_host_rt_sigprocmask_unblock(const uint64_t *mask, - size_t sigset_size) -{ -} #endif static int direct_trap_execute(struct kbox_syscall_trap_runtime *runtime, @@ -771,7 +880,8 @@ int kbox_syscall_trap_sigset_blocks_reserved(const void *mask, size_t len) uintptr_t kbox_syscall_trap_host_syscall_ip(void) { -#if defined(__x86_64__) || defined(__aarch64__) +#if defined(__x86_64__) || defined(__aarch64__) || \ + (defined(__riscv) && __riscv_xlen == 64) return (uintptr_t) kbox_syscall_trap_host_syscall_ip_label; #else return 0; @@ -780,7 +890,8 @@ uintptr_t kbox_syscall_trap_host_syscall_ip(void) int kbox_syscall_trap_host_syscall_range(struct kbox_syscall_trap_ip_range *out) { -#if defined(__x86_64__) || defined(__aarch64__) +#if defined(__x86_64__) || defined(__aarch64__) || \ + (defined(__riscv) && __riscv_xlen == 64) uintptr_t start = (uintptr_t) kbox_syscall_trap_host_syscall_start; uintptr_t end = (uintptr_t) kbox_syscall_trap_host_syscall_end; @@ -875,7 +986,7 @@ int kbox_syscall_trap_internal_ip_ranges(struct kbox_syscall_trap_ip_range *out, (uintptr_t) kbox_syscall_trap_host_rt_sigprocmask_unblock_start, (uintptr_t) kbox_syscall_trap_host_rt_sigprocmask_unblock_end) < 0) return -1; -#elif defined(__aarch64__) +#elif defined(__aarch64__) || (defined(__riscv) && __riscv_xlen == 64) if (append_ip_range(out, cap, &n, (uintptr_t) kbox_syscall_trap_host_futex_wait_start, (uintptr_t) kbox_syscall_trap_host_futex_wait_end) < 0) @@ -952,6 +1063,17 @@ int kbox_syscall_regs_from_sigsys(const siginfo_t *info, out->args[4] = (uint64_t) uc->uc_mcontext.regs[4]; out->args[5] = (uint64_t) uc->uc_mcontext.regs[5]; return 0; +#elif defined(__riscv) && __riscv_xlen == 64 + out->nr = (info->si_syscall != 0) ? info->si_syscall + : (int) uc->uc_mcontext.__gregs[17]; + out->instruction_pointer = (uint64_t) uc->uc_mcontext.__gregs[0]; + out->args[0] = (uint64_t) uc->uc_mcontext.__gregs[10]; + out->args[1] = (uint64_t) uc->uc_mcontext.__gregs[11]; + out->args[2] = (uint64_t) uc->uc_mcontext.__gregs[12]; + out->args[3] = (uint64_t) uc->uc_mcontext.__gregs[13]; + out->args[4] = (uint64_t) uc->uc_mcontext.__gregs[14]; + out->args[5] = (uint64_t) uc->uc_mcontext.__gregs[15]; + return 0; #else (void) uc; return -1; @@ -1427,6 +1549,43 @@ static int64_t host_syscall(const ucontext_t *uc) (uint64_t) uc->uc_mcontext.regs[1], (uint64_t) uc->uc_mcontext.regs[2], (uint64_t) uc->uc_mcontext.regs[3], (uint64_t) uc->uc_mcontext.regs[4], (uint64_t) uc->uc_mcontext.regs[5]); +#elif defined(__riscv) && (__riscv_xlen == 64) + long nr = (long) uc->uc_mcontext.__gregs[17]; + + if (nr == __NR_exit || nr == __NR_exit_group) + return kbox_syscall_trap_host_exit_group_now( + (int) uc->uc_mcontext.__gregs[10]); + if (nr == __NR_execve) + return kbox_syscall_trap_host_execve_now( + (const char *) (uintptr_t) uc->uc_mcontext.__gregs[10], + (char *const *) (uintptr_t) uc->uc_mcontext.__gregs[11], + (char *const *) (uintptr_t) uc->uc_mcontext.__gregs[12]); + if (nr == __NR_execveat) + return kbox_syscall_trap_host_execveat_now( + (int) uc->uc_mcontext.__gregs[10], + (const char *) (uintptr_t) uc->uc_mcontext.__gregs[11], + (char *const *) (uintptr_t) uc->uc_mcontext.__gregs[12], + (char *const *) (uintptr_t) uc->uc_mcontext.__gregs[13], + (int) uc->uc_mcontext.__gregs[14]); + if (nr == __NR_clone) + return kbox_syscall_trap_host_clone_now( + (uint64_t) uc->uc_mcontext.__gregs[10], + (uint64_t) uc->uc_mcontext.__gregs[11], + (uint64_t) uc->uc_mcontext.__gregs[12], + (uint64_t) uc->uc_mcontext.__gregs[13], + (uint64_t) uc->uc_mcontext.__gregs[14]); + if (nr == __NR_clone3) + return kbox_syscall_trap_host_clone3_now( + (const void *) (uintptr_t) uc->uc_mcontext.__gregs[10], + (size_t) uc->uc_mcontext.__gregs[11]); + + return kbox_syscall_trap_host_syscall6( + nr, (uint64_t) uc->uc_mcontext.__gregs[10], + (uint64_t) uc->uc_mcontext.__gregs[11], + (uint64_t) uc->uc_mcontext.__gregs[12], + (uint64_t) uc->uc_mcontext.__gregs[13], + (uint64_t) uc->uc_mcontext.__gregs[14], + (uint64_t) uc->uc_mcontext.__gregs[15]); #else (void) uc; return -ENOSYS; @@ -1462,6 +1621,9 @@ int kbox_syscall_result_to_sigsys(void *ucontext_ptr, #elif defined(__aarch64__) uc->uc_mcontext.regs[0] = (uint64_t) ret; return 0; +#elif defined(__riscv) && (__riscv_xlen == 64) + uc->uc_mcontext.__gregs[10] = (uint64_t) ret; + return 0; #else return -1; #endif From 000023a1f8e855724f72cabd1bdbead0bc03a451 Mon Sep 17 00:00:00 2001 From: Chisheng Chen Date: Sat, 11 Apr 2026 23:10:11 +0800 Subject: [PATCH 3/4] Update unit test for riscv64 The are some arch-related implementations in the unit test. This updates them. Change-Id: Ic97b0639aa70f4499d6f5e4b95ff6b512baf0db1 --- tests/unit/test-syscall-trap.c | 89 +++++++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 11 deletions(-) diff --git a/tests/unit/test-syscall-trap.c b/tests/unit/test-syscall-trap.c index 0a39ae5..36a418b 100644 --- a/tests/unit/test-syscall-trap.c +++ b/tests/unit/test-syscall-trap.c @@ -91,7 +91,8 @@ static void test_host_syscall_range_contains_ip(void) struct kbox_syscall_trap_ip_range range; uintptr_t ip = kbox_syscall_trap_host_syscall_ip(); -#if defined(__x86_64__) || defined(__aarch64__) +#if defined(__x86_64__) || defined(__aarch64__) || \ + (defined(__riscv) && (__riscv_xlen == 64)) ASSERT_EQ(kbox_syscall_trap_host_syscall_range(&range), 0); ASSERT_TRUE(range.start < range.end); ASSERT_TRUE(ip >= range.start); @@ -150,6 +151,30 @@ static void test_sigsys_decode_aarch64_registers(void) ASSERT_EQ(regs.args[0], 101); ASSERT_EQ(regs.args[5], 606); } +#elif defined(__riscv) && (__riscv_xlen == 64) +static void test_sigsys_decode_riscv64_registers(void) +{ + siginfo_t info; + ucontext_t uc; + struct kbox_syscall_regs regs; + + memset(&uc, 0, sizeof(uc)); + init_sigsys(&info, 56); + uc.uc_mcontext.__gregs[0] = 0x4000; + uc.uc_mcontext.__gregs[10] = 101; + uc.uc_mcontext.__gregs[11] = 202; + uc.uc_mcontext.__gregs[12] = 303; + uc.uc_mcontext.__gregs[13] = 404; + uc.uc_mcontext.__gregs[14] = 505; + uc.uc_mcontext.__gregs[15] = 606; + uc.uc_mcontext.__gregs[16] = 999; + + ASSERT_EQ(kbox_syscall_regs_from_sigsys(&info, &uc, ®s), 0); + ASSERT_EQ(regs.nr, 56); + ASSERT_EQ(regs.instruction_pointer, 0x4000); + ASSERT_EQ(regs.args[0], 101); + ASSERT_EQ(regs.args[5], 606); +} #endif static void test_sigsys_request_builder_uses_trap_source(void) @@ -174,6 +199,11 @@ static void test_sigsys_request_builder_uses_trap_source(void) uc.uc_mcontext.pc = 0x5000; uc.uc_mcontext.regs[0] = 7; expected_rc = 0; +#elif defined(__riscv) && (__riscv_xlen == 64) + init_sigsys(&info, 93); + uc.uc_mcontext.__gregs[0] = 0x5000; + uc.uc_mcontext.__gregs[10] = 7; + expected_rc = 0; #else memset(&info, 0, sizeof(info)); info.si_signo = SIGSYS; @@ -182,7 +212,8 @@ static void test_sigsys_request_builder_uses_trap_source(void) ASSERT_EQ( kbox_syscall_request_from_sigsys(&req, 777, &info, &uc, &guest_mem), expected_rc); -#if defined(__x86_64__) || defined(__aarch64__) +#if defined(__x86_64__) || defined(__aarch64__) || \ + (defined(__riscv) && (__riscv_xlen == 64)) ASSERT_EQ(req.source, KBOX_SYSCALL_SOURCE_TRAP); ASSERT_EQ(req.pid, 777); ASSERT_EQ(req.cookie, 0); @@ -209,6 +240,10 @@ static void test_sigsys_request_builder_defaults_current_guest_mem(void) init_sigsys(&info, 172); uc.uc_mcontext.pc = 0x6000; expected_rc = 0; +#elif defined(__riscv) && (__riscv_xlen == 64) + init_sigsys(&info, 172); + uc.uc_mcontext.__gregs[0] = 0x6000; + expected_rc = 0; #else memset(&info, 0, sizeof(info)); info.si_signo = SIGSYS; @@ -216,7 +251,8 @@ static void test_sigsys_request_builder_defaults_current_guest_mem(void) ASSERT_EQ(kbox_syscall_request_from_sigsys(&req, 123, &info, &uc, NULL), expected_rc); -#if defined(__x86_64__) || defined(__aarch64__) +#if defined(__x86_64__) || defined(__aarch64__) || \ + (defined(__riscv) && (__riscv_xlen == 64)) ASSERT_EQ(req.guest_mem.ops, &kbox_current_guest_mem_ops); ASSERT_EQ(req.guest_mem.opaque, 0); #endif @@ -233,7 +269,8 @@ static void test_sigsys_result_writer(void) dispatch.val = 1234; dispatch.error = 0; -#if defined(__x86_64__) || defined(__aarch64__) +#if defined(__x86_64__) || defined(__aarch64__) || \ + (defined(__riscv) && (__riscv_xlen == 64)) expected_rc = 0; #endif ASSERT_EQ(kbox_syscall_result_to_sigsys(&uc, &dispatch), expected_rc); @@ -241,6 +278,8 @@ static void test_sigsys_result_writer(void) ASSERT_EQ(uc.uc_mcontext.gregs[REG_RAX], 1234); #elif defined(__aarch64__) ASSERT_EQ(uc.uc_mcontext.regs[0], 1234); +#elif defined(__riscv) && (__riscv_xlen == 64) + ASSERT_EQ(uc.uc_mcontext.__gregs[10], 1234); #endif } @@ -261,6 +300,9 @@ static void test_sigsys_continue_executes_host_syscall(void) #elif defined(__aarch64__) uc.uc_mcontext.regs[8] = HOST_NRS_GENERIC.getpid; expected_rc = 0; +#elif defined(__riscv) && (__riscv_xlen == 64) + uc.uc_mcontext.__gregs[17] = HOST_NRS_GENERIC.getpid; + expected_rc = 0; #endif ASSERT_EQ(kbox_syscall_result_to_sigsys(&uc, &dispatch), expected_rc); @@ -268,6 +310,8 @@ static void test_sigsys_continue_executes_host_syscall(void) ASSERT_EQ(uc.uc_mcontext.gregs[REG_RAX], getpid()); #elif defined(__aarch64__) ASSERT_EQ(uc.uc_mcontext.regs[0], (uint64_t) getpid()); +#elif defined(__riscv) && (__riscv_xlen == 64) + ASSERT_EQ(uc.uc_mcontext.__gregs[10], (uint64_t) getpid()); #endif } @@ -279,7 +323,7 @@ static void test_sigsys_runtime_install_uninstall(void) memset(&ctx, 0, sizeof(ctx)); #if defined(__x86_64__) ctx.host_nrs = &HOST_NRS_X86_64; -#elif defined(__aarch64__) +#elif defined(__aarch64__) || (defined(__riscv) && (__riscv_xlen == 64)) ctx.host_nrs = &HOST_NRS_GENERIC; #endif @@ -302,10 +346,13 @@ static void test_sigsys_runtime_install_preserves_sqpoll(void) ctx.host_nrs = &HOST_NRS_X86_64; #elif defined(__aarch64__) ctx.host_nrs = &HOST_NRS_GENERIC; +#elif defined(__riscv) && (__riscv_xlen == 64) + ctx.host_nrs = &HOST_NRS_GENERIC; #endif runtime.sqpoll = 1; -#if defined(__x86_64__) || defined(__aarch64__) +#if defined(__x86_64__) || defined(__aarch64__) || \ + (defined(__riscv) && (__riscv_xlen == 64)) ASSERT_EQ(kbox_syscall_trap_runtime_install(&runtime, &ctx), 0); ASSERT_EQ(runtime.sqpoll, 1); kbox_syscall_trap_runtime_uninstall(&runtime); @@ -336,6 +383,10 @@ static void test_sigsys_trap_handle_uses_runtime_executor(void) init_sigsys(&info, 172); uc.uc_mcontext.pc = 0x7100; expected_rc = 0; +#elif defined(__riscv) && (__riscv_xlen == 64) + init_sigsys(&info, 172); + uc.uc_mcontext.__gregs[0] = 0x7100; + expected_rc = 0; #else memset(&info, 0, sizeof(info)); info.si_signo = SIGSYS; @@ -348,6 +399,8 @@ static void test_sigsys_trap_handle_uses_runtime_executor(void) ASSERT_EQ(uc.uc_mcontext.gregs[REG_RAX], info.si_syscall + 10); #elif defined(__aarch64__) ASSERT_EQ(uc.uc_mcontext.regs[0], (uint64_t) info.si_syscall + 10); +#elif defined(__riscv) && (__riscv_xlen == 64) + ASSERT_EQ(uc.uc_mcontext.__gregs[10], (uint64_t) info.si_syscall + 10); #endif ASSERT_EQ(custom_execute_calls, 1); ASSERT_EQ(custom_execute_last_nr, info.si_syscall); @@ -376,6 +429,11 @@ static void test_sigsys_dispatch_helper(void) init_sigsys(&info, 172); uc.uc_mcontext.pc = 0x7000; expected_rc = 0; +#elif defined(__riscv) && (__riscv_xlen == 64) + ctx.host_nrs = &HOST_NRS_GENERIC; + init_sigsys(&info, 172); + uc.uc_mcontext.__gregs[0] = 0x7000; + expected_rc = 0; #else memset(&info, 0, sizeof(info)); info.si_signo = SIGSYS; @@ -410,6 +468,11 @@ static void test_trap_runtime_capture_and_dispatch_pending(void) init_sigsys(&info, 172); uc.uc_mcontext.pc = 0x7200; expected_rc = 0; +#elif defined(__riscv) && (__riscv_xlen == 64) + ctx.host_nrs = &HOST_NRS_GENERIC; + init_sigsys(&info, 172); + uc.uc_mcontext.__gregs[0] = 0x7200; + expected_rc = 0; #else memset(&info, 0, sizeof(info)); info.si_signo = SIGSYS; @@ -466,7 +529,7 @@ static void test_trap_runtime_service_thread_dispatches(void) int i; memset(&ctx, 0, sizeof(ctx)); -#if defined(__aarch64__) +#if defined(__aarch64__) || (defined(__riscv) && (__riscv_xlen == 64)) ctx.host_nrs = &HOST_NRS_GENERIC; #else ctx.host_nrs = &HOST_NRS_X86_64; @@ -504,12 +567,13 @@ static void test_trap_active_dispatch_uses_service_thread(void) memset(&req, 0, sizeof(req)); #if defined(__x86_64__) ctx.host_nrs = &HOST_NRS_X86_64; -#elif defined(__aarch64__) +#elif defined(__aarch64__) || (defined(__riscv) && (__riscv_xlen == 64)) ctx.host_nrs = &HOST_NRS_GENERIC; #endif req.nr = 88; -#if defined(__x86_64__) || defined(__aarch64__) +#if defined(__x86_64__) || defined(__aarch64__) || \ + (defined(__riscv) && (__riscv_xlen == 64)) ASSERT_EQ(kbox_syscall_trap_runtime_install(&runtime, &ctx), 0); ASSERT_EQ(kbox_syscall_trap_active_pid(), runtime.pid); ASSERT_EQ(kbox_syscall_trap_active_dispatch(&req, &dispatch), 0); @@ -532,12 +596,13 @@ static void test_trap_active_dispatch_fails_cleanly_during_sqpoll_stop(void) memset(&req, 0, sizeof(req)); #if defined(__x86_64__) ctx.host_nrs = &HOST_NRS_X86_64; -#elif defined(__aarch64__) +#elif defined(__aarch64__) || (defined(__riscv) && (__riscv_xlen == 64)) ctx.host_nrs = &HOST_NRS_GENERIC; #endif req.nr = 99; -#if defined(__x86_64__) || defined(__aarch64__) +#if defined(__x86_64__) || defined(__aarch64__) || \ + (defined(__riscv) && (__riscv_xlen == 64)) ASSERT_EQ(kbox_syscall_trap_runtime_install(&runtime, &ctx), 0); runtime.sqpoll = 1; __atomic_store_n(&runtime.service_stop, 1, __ATOMIC_RELEASE); @@ -557,6 +622,8 @@ void test_syscall_trap_init(void) TEST_REGISTER(test_sigsys_decode_x86_64_registers); #elif defined(__aarch64__) TEST_REGISTER(test_sigsys_decode_aarch64_registers); +#elif defined(__riscv) && (__riscv_xlen == 64) + TEST_REGISTER(test_sigsys_decode_riscv64_registers); #endif TEST_REGISTER(test_sigsys_request_builder_uses_trap_source); TEST_REGISTER(test_sigsys_request_builder_defaults_current_guest_mem); From 00007bec630d62ebbffce682d71feb8e73555f49 Mon Sep 17 00:00:00 2001 From: Chisheng Chen Date: Sun, 12 Apr 2026 15:36:14 +0800 Subject: [PATCH 4/4] Note the riscv64 rewrite mode limitation The rewrite mode of riscv64 is currently not supported. This commit updates the README and the document to state this limitation. Change-Id: I7cf2ef5dc7e6a01547b9a8a31a25dba600db74fc --- README.md | 2 +- docs/architecture.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dc13962..47eeecf 100644 --- a/README.md +++ b/README.md @@ -267,7 +267,7 @@ with - x86_64 - aarch64 -- riscv64 +- riscv64 (Only the trap mode and the seccomp mode are available) ## License diff --git a/docs/architecture.md b/docs/architecture.md index 4583c3b..1221d0e 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -174,6 +174,8 @@ host-kernel calls. `mmap` and `epoll_*` are deliberately excluded because they need W^X enforcement, shadow validation, or FD-table gating that the fast-path cannot perform. +On **riscv64**, the rewrite mode is not available now. + Each site is classified as WRAPPER (simple `syscall; ret` pattern, eligible for inline virtualized return: getpid=1, gettid=1, getppid=0) or COMPLEX (result consumed internally by helpers like `raise()` that