Skip to content

Add riscv64 support#19

Open
rota1001 wants to merge 1 commit intosysprog21:mainfrom
rota1001:add-rv64-support
Open

Add riscv64 support#19
rota1001 wants to merge 1 commit intosysprog21:mainfrom
rota1001:add-rv64-support

Conversation

@rota1001
Copy link
Copy Markdown
Collaborator

@rota1001 rota1001 commented Mar 23, 2026

This PR did the following things:

  • Add riscv64 support by reusing aarch64 syscall table
  • Correct aarch64 syscall name and those non-lagacy syscalls marked as lagacy
  • Disable link time relaxation to reduce link time (of riscv64) to several seconds
  • Fetch the correct rootfs in the build script
  • Successfully run kbox on alpine Linux running on the QEMU virt machine

According to the kernel document[1], syscalls are specified in arch/*/kernel/Makefile.syscalls and scripts/syscall.tbl.

It is found that all the aarch64 host syscalls used in kbox has either common, 64 or rlimit tag in scripts/syscall.tbl[2], which means riscv64 share the same host syscall table.

Also, there are two errors found in the host syscall table. (Also according to scripts/syscall.tbl[2]):

  • rt_sigalstack is not the correct syscall name, it is sigalstack instead
  • getrlimit and statfs are not lagacy syscalls

The build script of rootfs is updated, so the following command can produce a usable alpine.ext4:

$ make ARCH=riscv64 CC=riscv64-linux-gnu-gcc rootfs

For the fetch-lkl.sh script, the riscv64 support is added. However, the pre-built lkl binary has to be updated on GitHub (The github action has to be updated), so for now, it can only be compiled by explicitly assigning the LKL path in the config. The LKL build process is as follows (on x86-64 ubuntu 24.04):

$ sudo dpkg --add-architecture riscv64
$ sudo apt update
$ sudo apt install -y libfuse3-dev:riscv64 libarchive-dev:riscv64
$ git clone --depth 1 https://github.com/lkl/linux.git lkl
$ cd lkl
$ make CROSS_COMPILE=riscv64-linux-gnu- -C tools/lkl

With the LKL path set in the config, the following command can successfully build the kbox:

$ make ARCH=riscv64 CC=riscv64-linux-gnu-gcc

The compiled kbox is successfully run on QEMU and execute /bin/sh.[3]

[1] https://docs.kernel.org/process/adding-syscalls.html#since-6-11
[2] https://github.com/torvalds/linux/blob/master/scripts/syscall.tbl
[3] https://hackmd.io/@rota1001/kbox-rv64#Run-it-on-riscv64


Summary by cubic

Adds riscv64 support in seccomp mode by unifying aarch64/riscv64 onto a generic 64‑bit host syscall table and updating the build for the Alpine riscv64 rootfs. Trap and rewrite remain unsupported on riscv64.

  • New Features

    • riscv64 (seccomp only): use HOST_NRS_GENERIC; share the aarch64 BPF deny list; set audit arch 0xc00000f3; report uname -m as "riscv64"; error if trap mode is requested on non-x86_64/aarch64; add riscv64 trap stubs (no-op).
    • Build/Docs: add Alpine riscv64 SHA256; pass -Wl,--no-relax to speed riscv64 linking; list riscv64 in README.
  • Bug Fixes

    • Use sigaltstack (not rt_sigaltstack) in dispatch and host syscall tables.
    • Correct aarch64 syscall numbers: getrlimit=163, statfs=43.

Written for commit 0000846. Summary will update on new commits.

cubic-dev-ai[bot]

This comment was marked as resolved.

@rota1001 rota1001 changed the title Add rv64 support Add riscv64 support Mar 23, 2026
@jserv
Copy link
Copy Markdown
Contributor

jserv commented Mar 24, 2026

#21 concerns the system call overhead in kbox, which has been observed to be as high as 33× compared to native (bare-metal) execution. Addressing this overhead is a prerequisite for improving overall system performance.

To this end, I plan to prioritize closing #21 by exploring a solution based on binary rewriting. Given current infrastructure constraints and to ensure efficient validation, the initial implementation will focus on x86-64 and arm64 architectures, both of which are fully supported by the machines provided through GitHub Actions.

After the proposed solution has been thoroughly implemented and validated on these architectures, we can proceed to extend support to RISC-V.

@jserv jserv mentioned this pull request Apr 8, 2026
{ \
(unsigned short) (c), (unsigned char) (t), (unsigned char) (f), \
(unsigned int) (val) \
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like unrelated style changes?
Please keep the changes to a minimum.
Otherwise, this will make git blame messy.

Copy link
Copy Markdown
Collaborator Author

@rota1001 rota1001 Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change was made because the source code wasn't properly formatted with clang-format, which caused it to be blocked by the new commit-hook. Did you mean I have to separate it to another commit?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, a single patch should contain only one logical change.
However, it looks like this patch is doing two things:

  1. Fixing a pre-existing clang-format error.
  2. Adding RISC-V support.

So, yes, I would prefer splitting this into two patches.

const struct kbox_host_nrs *host_nrs = &HOST_NRS_X86_64;
#elif defined(__aarch64__)
#elif defined(__aarch64__) || (defined(__riscv) && __riscv_xlen == 64)
const struct kbox_host_nrs *host_nrs = &HOST_NRS_AARCH64;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reusing the HOST_NRS_AARCH64 struct directly for RISC-V is semantically confusing for future maintenance. Maybe consider adding a preparatory refactoring patch to rename it to something more generic before wiring up RISC-V support?

@rota1001
Copy link
Copy Markdown
Collaborator Author

rota1001 commented Apr 11, 2026

I have implemented the seccomp mode for riscv64 in this commit, and trap mode and rewrite mode are left unimplemented.

This can be build with make directly on the riscv64 machine:

make

Or using cross-compile toolchain on the x86-64 machine:

make ARCH=riscv64 CC=riscv64-linux-gnu-gcc

The seccomp mode is tested for all architectures(aarch64, x86-64, riscv64), and the result is as same as the result before this commit:

PASS: bench_test
PASS: clock_test
PASS: clone3_test
PASS: dup_test
PASS: errno_test
FAIL: jit_alias_shared_exec_mprotect_allowed
FAIL: anonymous RWX mmap should be denied (ptr == MAP_FAILED)
FAIL: resolve example.com A record
PASS: path_escape_test
PASS: process_vm_readv denied
FAIL: raise SIGUSR1

If the trap mode is specified when running on riscv64 architecture, the following error message will be shown currently:

kbox: unsupported architecture for trap mode

I am currently working on the trap and rewrite modes for riscv64. Would you prefer I include them in this PR, or should I submit them in a follow-up PR?

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants