RVVM: a RISC-V virtual machine built around a tracing JIT
The RISC-V Virtual Machine
At a glance
- What is it?
- RVVM is a virtual machine and emulator for RISC-V guests that emphasises performance, lean code and portability, with a tracing JIT that has x86_64, ARM64 and RISC-V backends and claims to be faster than QEMU TCG, and it already boots Linux, Haiku, FreeBSD and OpenBSD. It suits anyone who wants RISC-V on a machine that is not RISC-V, and it ships a library so the emulator can be embedded in other programs.
- Who is it for?
- Adopt RVVM if you need to run RISC-V binaries on a machine with a different architecture, or if you are building a tool that needs to emulate RISC-V, because the library API lets you embed the emulator rather than shelling out to a virtual machine. Do not adopt it if you need a stable, long lived release line, because the tagged versions stop in 2024 while the default branch is a staging branch that moves constantly.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 10 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What RVVM is and how it is different
RVVM is a virtual machine and emulator for RISC-V guests, and the README lists the priorities in one line: it emphasises performance, security, lean code and portability.
The interesting technical decision is the tracing JIT, and the feature list is explicit about it. RVVM has a tracing JIT with x86_64, ARM64 and RISC-V backends, and the README states that it is faster than QEMU TCG.
The difference in approach is worth spelling out, because it is the same difference that separates a JIT from any translator. A tracing JIT watches a block of guest code as it executes, compiles that block into native code for the host, and runs it directly. The overhead moves to compilation rather than to every instruction, and the price is that you need a compiler backend for each host architecture you care about.
RVVM has three of them, and the RISC-V one means the emulator can run on a RISC-V host and still be fast, which is the case a portable interpreter handles worst.
The instruction set support is specific too. It is fully spec compliant for the rv64imafdcb instruction set, with the Zkr, Zicbom, Zicboz and Sstc extensions, and the default is 64-bit with a switch for 32-bit guests.
The code is C, the primary language of the repository, and the project is licensed under GPL-3.0 with the library under MPL.
The guest operating systems that actually boot
The claim about guests is concrete, and it is the part that tells you whether the emulator is a research prototype or a usable tool.
RVVM already runs a lot of guest operating systems, including Linux, Haiku, FreeBSD and OpenBSD. The main features list repeats it with the firmware layer included: working OpenSBI and U-Boot, and Linux, FreeBSD, OpenBSD and Haiku guests.
OpenSBI and U-Boot is the pair that matters most for a RISC-V system, because that is where the privilege levels start. RISC-V machines boot in machine mode, and OpenSBI is the firmware that sets up the next stage and drops into the supervisor mode the operating system expects. A guest that boots under both of those is booting the way real RISC-V hardware boots, not taking a shortcut.
The device set supports that. There is a framebuffer display, HID mouse and keyboard, and a UART terminal, which is the minimum for a graphical guest and for a serial console. Storage is NVMe with TRIM support, described as deallocating space on the host, and fast multi-threaded IO. The networking userland stack works on any host OS, which is an interesting choice, because it moves the network stack out of the guest and into the host process rather than emulating a network card.
The other notable device is VFIO PCIe passthrough, for GPUs and similar hardware, which is the feature that turns an emulator into something you can put a real accelerator into.
The project also maintains a WASM demo, linked from the README, which is a small sign of how portable the core has been made.
The library API, and userland emulation
The most interesting architectural decision in the project is the split between the emulator library and the binaries.
There is a library API, librvvm, for machine and userland emulation, including the ability to implement new devices. That is what makes the emulator embeddable. You can put a RISC-V machine inside your own program, give it your own devices, and drive it, rather than running it as a separate process and talking to it over a socket.
The userland emulation side is the other half of the idea, and it is the part that changes the use case. The README says RVVM also aims to run RISC-V applications on a foreign architecture host without a full OS guest and without isolation, which is userland emulation. Instead of booting Linux and running the program inside it, the program itself is translated and run in the host's address space.
That is much lighter than a full virtual machine, and it is the shape you want when the goal is to run one RISC-V binary on a developer machine rather than to test an operating system. The userland emulation is marked as work in progress, and so is the shadow page table acceleration.
Security is handled at the kernel level, with the feature list describing isolation to prevent and contain vulnerability exploitation, which is the right layer to do it at for a machine that runs hostile code. The security posture is part of the design rather than an afterthought.
Building it, and the build system as a project spec
The build is deliberately plain, and the README recommends GNU Make with CMake as an alternative.
git clone https://github.com/LekKit/RVVM
cd RVVM
make
cd release.linux.x86_64
./rvvm_x86_64 -hgit clone https://github.com/LekKit/RVVM
cd RVVM
cmake -S. -Bbuild
cmake --build build --target all
cd build
./rvvm -hThe Makefile is described as a build system in itself atop GNU Make, aiming at simplicity and easy cross-compilation, and the design is that the project specification lives in a separate file, project.mk, containing the name, the sources, the feature use flags and the binary and library targets. The Makefile holds the machinery and the variables.
Those variables are the interface, and they are worth a look because they explain what the project expects from a build environment. There is the build directory, which defaults to a name like release.windows.x86_64, the usual compiler and flag variables, and pkg-config. Then there are the informational ones, the compiler brand, version and target triplet, the target and host architecture and operating system, and the project version taken from git describe.
And then the switches that matter for a project like this: link time optimisation, building dynamic libraries, static libraries, shared project libraries, an intermediate object file build step, an optimised build with debug info, a full debug build without optimisations, and the UndefinedBehaviorSanitizer and AddressSanitizer options, with the sanitizer builds implying the debug configuration. For an emulator, having the sanitizers as first class build options rather than something you patch in is a good sign about how the code is tested.
Nightly build artifacts and an Arch package are available for people who do not want to build.
Running a machine
The example command is a good summary of the interface, because it shows the whole model of a machine in one line.
rvvm fw_payload.bin -i drive.img -m 2G -smp 2 -res 1280x720 -portfwd tcp/127.0.0.1:2022=22That launches a dual-core virtual machine with 2 GiB of RAM and a 1280 by 720 display, runs the OpenSBI and U-Boot firmware, boots an EFI guest from the disk image, and forwards host port 2022 into the guest SSH port.
The argument list is short and each one maps to a piece of the machine model.
[fw_payload.bin] Initial M-mode firmware, OpenSBI + U-Boot in this case
-i drive.img Attach preferred storage image (Currently as NVMe)
-m 2G Memory amount (may be suffixed by k/M/G), default 256M
-smp 2 Amount of cores, single-core machine by default
-res 1280x720 Set display(s) resolution
-portfwd 8080=80 Port forwarding (Extended: tcp/127.0.0.1:8080=80)
-rv32 Enable 32-bit RISC-V, 64-bit by default
-v Verbose mode
-h Extended helpNote the defaults, since they are the ones you will hit if you leave an argument out. Memory defaults to 256 megabytes, a single core by default, and 64-bit RISC-V unless you pass the 32-bit switch. The port forwarding syntax is the extended form with the protocol and the host address, so the same flag covers a plain port and a specific interface.
The wiki pages are where the recommended guest firmware and images are listed, and the running page has the full argument explanation.
The licence split, the contributors and the state of the project
The licensing is two-tier, and the reasoning is stated.
The librvvm library is licensed under the non-viral MPL 2.0 licence. If you wish to use librvvm as a component of a larger project that is not GPL compliant, you are free to do so in any form, static linkage, binary distribution or modules, as long as you comply with MPL 2.0. The MPL terms also apply to Java JNI bindings.
The RVVM Manager and the Linux userland emulator binaries, rvvm and rvvm-user, are under the copyleft GPL 3.0, since they are intended for end users. The stated reason is that all the heavy lifting is done by librvvm anyway, so the library is the part worth keeping permissively licensed for people embedding it.
That is a sensible arrangement for an emulator, and it matters for anyone who wants to embed the machine model inside a commercial product, since the library can be linked without dragging the copyleft into the host project.
The contributor table in the README shows the shape of the project. LekKit does the API and infrastructure, the interpreter for rv64imafdc, the MMU, interrupts and privilege handling, the JIT compiler with the x86 and RISC-V backends, and the devices including NVMe, the RTL8169 network card and VFIO. Other contributors cover the ARM and ARM64 JIT backends, the initial C, M and Zicsr extensions, the initial UART and the VM debugger, the userspace network work, the Haiku GUI and I2C HID, the OpenBSD and PLIC fixes, and the relative input mode. The project also asks for hardware donations, specifically a Milk-V Megrez for KVM work.
On the state of it, the tagged releases are v0.6 from March 2024 and v0.5 from April 2023, the version badge reads 0.7-git, and the default branch is staging rather than main, with the README asking contributors to check the staging branch when reporting issues. The last push was on 2026-10-12, so the work is active even though the releases are old.
Editorial conclusion
Adopt RVVM if you need to run RISC-V binaries on a machine with a different architecture, or if you are building a tool that needs to emulate RISC-V, because the library API lets you embed the emulator rather than shelling out to a virtual machine. Do not adopt it if you need a stable, long lived release line, because the tagged versions stop in 2024 while the default branch is a staging branch that moves constantly. Before you build, check which host backends your machine needs and whether the release you pick has them, and read the licence split, since the library and the binaries are under different terms.
Frequently asked questions
What is RVVM?
It is a virtual machine and emulator for RISC-V guests that emphasises performance, security, lean code and portability. It has a tracing JIT with x86_64, ARM64 and RISC-V backends, which the README states is faster than QEMU TCG, and it runs Linux, Haiku, FreeBSD and OpenBSD guests.
How do I build RVVM?
With GNU Make, which is the recommended path, by cloning the repository and running make, then running the binary from the release directory, or with CMake using cmake -S. -Bbuild followed by cmake --build build --target all. The project specification lives in project.mk, and the Makefile exposes options for link time optimisation, debug builds and the sanitizers.
How do I run a RISC-V Linux guest with RVVM?
The documented example is rvvm fw_payload.bin -i drive.img -m 2G -smp 2 -res 1280x720 -portfwd tcp/127.0.0.1:2022=22, where the first argument is the machine mode firmware such as OpenSBI and U-Boot, the -i flag attaches the storage image, -m sets memory, -smp the core count, -res the display resolution and -portfwd forwards a host port into the guest.
Can I use librvvm in a project that is not GPL licensed?
Yes. The librvvm library is under the non-viral MPL 2.0 licence, and the README states you may use it as a component of a larger non-GPL compliant project in any form, static linkage, binary distribution or modules, as long as you comply with MPL 2.0. The rvvm and rvvm-user binaries themselves are GPL 3.0.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/lekkit-rvvm)