Skip to content

Daniel-A-W/riscv-extensions

Repository files navigation

A set of extensions to the Sail RISC-V model for demonstrating transient execution vulnerabilities. Files generated from the original RISC-V model include their respective copyright header, and the license for the RISC-V model can be found in RISCV-LICENSE or in the sail-riscv submodule.

MAKE TARGETS: sim : Generate and compile the executable simulator using a subset of the available RISC-V modules. The reduced simulator can still demonstrate transient execution vulnerabilities and has a significantly shorter build time.

fullsim : Generate and compile the executable simulator using all available RISC-V modules.

tests : Assemble all files in the tests subdirectory (not including subfolders) and link to the htif.s runtime.

spec-tests : Assemble and link the speculation tests in tests/spectre.

get-riscv-tests : Download the pre-compiled RISC-V test suite provided by the model's maintainers.

riscv-tests : Run the pre-compiled RISC-V test suite.

ADDING CUSTOM TESTS: Any *.s file placed in "tests" (not including subdirectories) will be assembled and linked with the htif.s runtime when the make target "tests" is called. To terminate a program using the htif.s runtime, load the desired return code into register a0 and jump to htif_exit. A more mature runtime is provided by the RISC-V model and can be found in sail-riscv/test/first_party/src/common/.

IMPLEMENTATION DETAILS: The extensions operate in four passes:

  1. Decode compressed instructions into their non-compressed equivalent
  2. Translate instructions into cache-aware instructions
  3. Translate cache-aware instructions into speculation-aware instructions
  4. Inflate the wall-clock timer when executing a (speculation-aware) load and missing the cache

The cache uses the simplest possible placement and replacement mechanisms. Any physical address is split into an offset of cache_line_size_exp bits and a base, and bases are always cache_line_size-aligned. If the cache is full and a new entry is requested, the eldest line is evicted and a full line is loaded in, beginning at the requested base address. New entries will be requested upon performing a load or store using an address which is cacheable, not currently cached, and not split across multiple cache lines. Misaligned loads bypass the cache entirely, and misaligned stores invalidate the cache line (or lines) containing any written bits.

Transient execution is triggered by any conditional jump instruction. The current state of all (non-vector) registers are saved before beginning transient execution, and transient stores may only write to the cache. Transient execution will be terminated by any raised exception, fence, or subsequent branch instruction. Attempting a transient store while the cache is full will lead to an exception and terminate transient execution. If mis-speculation occurred, all transiently modified cache lines are marked invalid and the register state is restored. Otherwise, all modified cache lines are written to memory and execution proceeds as though the previous transient steps had all occurred normally.

Author: Daniel Wright, 2025

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages