CHERIoT RTOS
A compartmentalised RTOS for CHERIoT hardware
Loading...
Searching...
No Matches
hardware_revoker.hh
1#pragma once
2
3#include <cheri.hh>
4#include <concepts>
5
6struct Timeout;
7
8namespace Revocation
9{
10 /**
11 * Concept for a revoker. Boards can provide their own definition
12 * of this, which must be found in `<platform-hardware_revoker.hh>` in a
13 * path provided by the board include directories.
14 */
15 template<typename T>
17 requires(T v) {
18 { T::IsAsynchronous } -> std::same_as<const bool &>;
19
20 { v.init() } -> std::same_as<void>;
21
22 { v.system_epoch_get() } -> std::same_as<uint32_t>;
23
24 { v.system_bg_revoker_kick() } -> std::same_as<void>;
25 } &&
26 requires(T v, uint32_t epoch) {
27 {
28 v.template has_revocation_finished_for_epoch<true>(epoch)
29 } -> std::same_as<uint32_t>;
30 {
31 v.template has_revocation_finished_for_epoch<false>(epoch)
32 } -> std::same_as<uint32_t>;
33 } &&
34 requires(T v,
35 ptraddr_t addr,
36 ptraddr_t endAddr,
37 CHERI::Capability<void> *cap) {
38 // Read the revocation state of a particular address
39 { v.mark_get(addr) } -> std::same_as<bool>;
40
41 /*
42 * Mark cap.address as revoked.
43 *
44 * Marks created with this method do not need immediate enforcement:
45 * the allocator uses this only to mark the locations of its in-band
46 * headers and will ensure that capabilities to these addresses do not
47 * leak out of its compartment. That is, these marks must be visible
48 * to subequent `mark_get` and mark manipulation after this function
49 * returns, but the allocator's object state machine intends that
50 * there are no pointers in the system that will be impacted by this
51 * mark.
52 */
53 { v.mark_set_one(cap) } -> std::same_as<void>;
54
55 { v.mark_clear_one(addr) } -> std::same_as<void>;
56
57 /*
58 * Set a range of addresses, [cap.base(), cap.top()), as revoked.
59 *
60 * This is invoked for each object the allocator frees for reuse. The
61 * allocator's object lifecycle state machine ensures that these marks
62 * will remain at least through the next epoch opening and closing.
63 *
64 * Marks created by this method must be immediately enforced
65 * everywhere, except on the calling core, for which the requirement
66 * is merely that the core, and in particular its load barrier,
67 * percieve these marks. Subsequent `mark_get` and mark manipulation
68 * must also percieve these marks after this function returns.
69 *
70 * That is, unlike with `mark_set_one`, there may be pointers in the
71 * system that will be impacted by these marks, and locations holding
72 * capabilities, other than main memory and the current core's
73 * register file (see below), must ensure that copies of any such will
74 * be found and invalidated before the sooner of...
75 *
76 * 1. the next attempt use or propagate such a capability or
77 *
78 * 2. the closing of the first epoch opened after this call returns
79 * (at which point, the allocator is free to clear these marks).
80 *
81 * Main memory is allowed relaxed percepton because the load barrier
82 * serves to prevent propagaition (and use) of capabilities affected
83 * by these marks and because the latter deadline will necessarily be
84 * met by the revoker's scan of memory.
85 *
86 * The calling core is allowed relaxed perception because it is, by
87 * virtue of calling this function, presumed to be exeucing
88 * `heap_free()` within the allocator compartment and so will exit via
89 * the switcher's cross-call return path. The net effect is that the
90 * register file will be sufficiently refreshed by reads from memory
91 * during that return -- if not already done by preemption -- that
92 * there is no need to forcibly do so now.
93 */
94 { v.mark_set_range(cap) } -> std::same_as<void>;
95
96 { v.mark_clear_range(addr, endAddr) } -> std::same_as<void>;
97 };
98
99 /**
100 * If this revoker supports an interrupt to notify of completion then it
101 * must have a method that blocks waiting for the interrupt to fire. This
102 * method should return true if the epoch has been reached or false if the
103 * timeout expired.
104 */
105 template<typename T>
107 requires(T v, Timeout *timeout, uint32_t epoch) {
108 { v.wait_for_completion(timeout, epoch) } -> std::same_as<bool>;
109 };
110} // namespace Revocation
C++ helpers for operating on capabilities.
Concept for a revoker.
If this revoker supports an interrupt to notify of completion then it must have a method that blocks ...
Structure representing a timeout.
Definition timeout.h:47