riscv / riscv-cheri

This repository contains the CHERI extension specification, adding hardware capabilities to RISC-V ISA to enable fine-grained memory protection and scalable compartmentalization.
https://jira.riscv.org/browse/RVG-148
Creative Commons Attribution 4.0 International
57 stars 30 forks source link

Add GCTOP instruction? #400

Open nwf opened 2 months ago

nwf commented 2 months ago

CHERIoT-RTOS has recently started taking advantage of our ISA's CGetTop instruction, the counterpart to CGetBase / GCBASE, as it is particularly useful for accessing near the top of our bounded stacks for per-compartment-invocation storage.[^cheriot-rtos] I believe it'd be no more complex in terms of gateware than GCBASE and it replaces a three-instruction GCBASE; GCLEN; ADD sequence.

So, could we add GCTOP to Zcheripurecap?

[^cheriot-rtos]: The curious reader should see the RTOS's intra-compartment unwinding implementation (https://github.com/CHERIoT-Platform/cheriot-rtos/pull/297) and in particular the uses of CGetTop at https://github.com/CHERIoT-Platform/cheriot-rtos/blob/069e20a55e218c8869de0daf4c5a0007c6d47731/sdk/include/unwind.h#L27 and https://github.com/CHERIoT-Platform/cheriot-rtos/blob/069e20a55e218c8869de0daf4c5a0007c6d47731/sdk/lib/unwind_error_handler/unwind.S#L7

andresag01 commented 2 months ago

We considered this instruction a long time ago, but decided to leave it out because it can be emulated with the sequence you pointed out and its reasonably infrequent that it would not affect performance in any meaningful way.

How frequent is GCTOP used in your case?

davidchisnall commented 2 months ago

It varies a bit. Our allocator uses it quite a bit on some hot paths.

We also, in the CHERIoT cross-compartment calling convention, reserve 16 bytes of space at the top of the truncated stack for each compartment, which we can use for compartment-invocation-local storage (similar to TLS, but you get a fresh one on reentrant invocation of compartments). We find this by doing cgettop + csetaddr. This is used every time we enter an error handling block (roughly analogous to a try block), which will happen quite a lot. This is quite specific to the CHERIoT model though.

If it's not useful for other people, it's fine to keep it in a separate extension (Zcheritop or Xcheriot, or a future Zcheriot).