perlindgren / hippomenes

In love with Atalanta
10 stars 4 forks source link

RISC-V RT-SEC #21

Open perlindgren opened 5 months ago

perlindgren commented 5 months ago

The RT-SEC should be an opt-in extension to the RISC-V RT specification.

Problem/Motivation:

Rust RTIC fuses static guarantees provided by the Rust language with properties of Stack Resource Based scheduling, the former brings memory safety, and freedom from undefined behavior, while the latter ensures race- and deadlock-free execution, single stack sharing, bounded priority inversion. RTIC produces an efficient binary leveraging on the underling hardware (Hippomenes in this case), to perform accelerated scheduling:

To ensure memory safety, the Rust compiler performs lifetime analysis and asserts freedom from mutable aliasing. In cases analysis is out of reach, the compiler injects code performing run-time verification that panics in favor of running into undefined behavior. Thus at run-time the generated code either runs under defined (memory safe) behavior or halts with a panic (indicating the type of violation and source code location).

Great, we now have what we all been waiting for, or ....

Not really, the Rust memory safety guarantees may be violated by introducing explicit unsafe code. Luckily, the need for such unsafe code is limited to cases:

Proposed solution:

Hardware support to mitigate safety issues in case of unsafe Rust. (As a complement to static/formal verification of unsafe Rust code.)

Due the RTIC modelling framework, system state is represented by means of typed resources managed by the framework. Thus by static analysis of resources, the range of underlying or referred addresses can be computed Static and Dynamic Memory Protection using Type-Based Memory Layout in Rust.

Thus, the per-task set of reachable regions can be collected and used for both static and run-time (dynamic) validation. This issue will cover both:

Implementation:

Hippomenes has the goal to ensure singly cycle execution, with zero cycle latency of interrupt (task) dispatch. Thus the implementation must be able to validate memory accesses with zero-latency. A reasonable approach is to introduce a task id, and let the MPU resolve address validity accordingly. (Similar techniques are found in TLBs). In the aforementioned publication, a two stage lookup approach is presented, where region matching is done in parallel, followed by a selection process. For FPGA solutions, the MPU configuration can be synthesized, while for ASIC, MPU tables need to dynamic (static ram). In case of extreme safety requirements, MPU configuration should be synthesized. (But then resources are fixed in location and size, thus only business logic around may be changed.)

Workflow in suggested order:

  1. The implementation of A). A can be implemented without prior passes.
  2. Static ram based MPU. Proof of concept with manual configuration through a set of CSR registers.
  3. Integration with RTIC as a pass for generating setup information for the init task to populate MPU tables.
  4. Integration with RTIC as a pass for generating application specific MPU configuration.
  5. Stretch goal: CSR space protection (this is green field research).

This tracking issue will be used as a basis for an upcoming Master's thesis at LTU.