Skip to content

Commit e7f8553

Browse files
merged aes_hil_update
2 parents 678b4bf + 8471eaa commit e7f8553

149 files changed

Lines changed: 1047 additions & 1023 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"editor.defaultFormatter": "rust-lang.rust-analyzer",
44
"editor.formatOnSave": true,
55
"rust-analyzer.server.extraEnv": {
6-
"RUSTUP_TOOLCHAIN": "nightly-2025-11-03"
6+
"RUSTUP_TOOLCHAIN": "nightly-2026-04-21"
77
},
88
"rust-analyzer.check.allTargets": false,
99
}

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,8 @@ result_unit_err = "allow"
233233
unusual-byte-groupings = "allow"
234234
# We widely use upper case acronyms for hardware registers and fields.
235235
upper_case_acronyms = "allow"
236-
236+
# Condensing match statements can make code harder to read and inconsistent.
237+
collapsible-match = "allow"
237238

238239
missing_safety_doc = "allow"
239240
doc_lazy_continuation = "allow"

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,9 +407,15 @@ ci-job-clippy:
407407
@cargo clippy -- -D warnings
408408
# Run `cargo clippy` in select boards so we run clippy with targets that
409409
# actually check the arch-specific functions.
410+
#
411+
# - nrf52840dk: cortex-m4
412+
# - raspberry_pi_pico: cortex-m0
413+
# - hifive1: riscv
414+
# - qemu_i486_q35: x86
410415
@cd boards/nordic/nrf52840dk && cargo clippy -- -D warnings
416+
@cd boards/raspberry_pi_pico && cargo clippy -- -D warnings
411417
@cd boards/hifive1 && cargo clippy -- -D warnings
412-
@cd boards/qemu_i486_q35 && cargo clippy -- -D warnings
418+
@cd boards/qemu_i486_q35 && cargo clippy -Zjson-target-spec -- -D warnings
413419

414420

415421

README.md

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,48 @@ Amit Levy, Bradford Campbell, Branden Ghena, Daniel B. Giffin, Pat Pannuto, Prab
106106
<details>
107107
<summary>Other Tock-related papers</summary>
108108

109+
<p>In SOSP'25 we reflected on 10 years of Tock development.</p>
110+
111+
<h4><a href="https://dl.acm.org/doi/10.1145/3731569.3764828">[SOSP'25] Tock: From Research To Securing 10 Million Computers</a></h4>
112+
<pre>
113+
@inproceedings{10.1145/3731569.3764828,
114+
author = {Schuermann, Leon and Campbell, Brad and Ghena, Branden and Levis, Philip and Levy, Amit and Pannuto, Pat},
115+
title = {Tock: From Research To Securing 10 Million Computers},
116+
year = {2025},
117+
isbn = {9798400718700},
118+
publisher = {Association for Computing Machinery},
119+
address = {New York, NY, USA},
120+
url = {https://doi.org/10.1145/3731569.3764828},
121+
doi = {10.1145/3731569.3764828},
122+
booktitle = {Proceedings of the ACM SIGOPS 31st Symposium on Operating Systems Principles},
123+
pages = {36–49},
124+
numpages = {14},
125+
location = {Lotte Hotel World, Seoul, Republic of Korea},
126+
series = {SOSP '25}
127+
}</pre>
128+
129+
<p>There is a paper on the Tock security model. The threat model documentation in the docs/ folder is the source of truth for the current Tock threat model, but this paper represents a snapshot of the reasoning behind the Tock threat model and details how it compares to those in similar embedded OSes.</p>
130+
<h4><a href="https://dx.doi.org/10.1145/3517208.3523752">[EuroSec'22] Tiered Trust for useful embedded systems security</a></h4>
131+
<pre>
132+
@inproceedings{10.1145/3517208.3523752,
133+
author = {Ayers, Hudson and Dutta, Prabal and Levis, Philip and Levy, Amit and Pannuto, Pat and Van Why, Johnathan and Watson, Jean-Luc},
134+
title = {Tiered Trust for Useful Embedded Systems Security},
135+
year = {2022},
136+
isbn = {9781450392556},
137+
publisher = {Association for Computing Machinery},
138+
address = {New York, NY, USA},
139+
url = {https://doi.org/10.1145/3517208.3523752},
140+
doi = {10.1145/3517208.3523752},
141+
booktitle = {Proceedings of the 15th European Workshop on Systems Security},
142+
pages = {15–21},
143+
numpages = {7},
144+
keywords = {security, embedded systems, operating systems, IoT},
145+
location = {Rennes, France},
146+
series = {EuroSec '22}
147+
}</pre>
148+
109149
<p>There are two shorter papers that look at potential limitations of the Rust language for embedded software development. The earlier PLOS paper lays out challenges and the later APSys paper lays out potential solutions. Some persons describing work on programming languages and type theory may benefit from these references, but generally, most work should cite the SOSP paper above.</p>
110-
<h4><a href="http://doi.acm.org/10.1145/3124680.3124717">APSys: The Case for Writing a Kernel in Rust</a></h4>
150+
<h4><a href="http://doi.acm.org/10.1145/3124680.3124717">[APSys'17] The Case for Writing a Kernel in Rust</a></h4>
111151
<pre>
112152
@inproceedings{levy17rustkernel,
113153
title = {The Case for Writing a Kernel in Rust},
@@ -129,7 +169,7 @@ Amit Levy, Bradford Campbell, Branden Ghena, Daniel B. Giffin, Pat Pannuto, Prab
129169
author = {Levy, Amit and Campbell, Bradford and Ghena, Branden and Pannuto, Pat and Dutta, Prabal and Levis, Philip},
130170
}</pre>
131171

132-
<h4><a href="http://dx.doi.org/10.1145/2818302.2818306">PLOS: Ownership is Theft: Experiences Building an Embedded OS in Rust</a></h4>
172+
<h4><a href="http://dx.doi.org/10.1145/2818302.2818306">[PLOS'15] Ownership is Theft: Experiences Building an Embedded OS in Rust</a></h4>
133173
<pre>
134174
@inproceedings{levy15ownership,
135175
title = {Ownership is Theft: Experiences Building an Embedded {OS} in {R}ust},
@@ -145,25 +185,6 @@ Amit Levy, Bradford Campbell, Branden Ghena, Daniel B. Giffin, Pat Pannuto, Prab
145185
address = {New York, NY, USA},
146186
conference-url = {http://plosworkshop.org/2015/},
147187
author = {Levy, Amit and Andersen, Michael P and Campbell, Bradford and Culler, David and Dutta, Prabal and Ghena, Branden and Levis, Philip and Pannuto, Pat},
148-
}</pre>
149-
<p>There is also a paper on the Tock security model. The threat model documentation in the docs/ folder is the source of truth for the current Tock threat model, but this paper represents a snapshot of the reasoning behind the Tock threat model and details how it compares to those in similar embedded OSes.</p>
150-
<h4><a href="https://dx.doi.org/10.1145/3517208.3523752">EuroSec: Tiered Trust for useful embedded systems security</a></h4>
151-
<pre>
152-
@inproceedings{10.1145/3517208.3523752,
153-
author = {Ayers, Hudson and Dutta, Prabal and Levis, Philip and Levy, Amit and Pannuto, Pat and Van Why, Johnathan and Watson, Jean-Luc},
154-
title = {Tiered Trust for Useful Embedded Systems Security},
155-
year = {2022},
156-
isbn = {9781450392556},
157-
publisher = {Association for Computing Machinery},
158-
address = {New York, NY, USA},
159-
url = {https://doi.org/10.1145/3517208.3523752},
160-
doi = {10.1145/3517208.3523752},
161-
booktitle = {Proceedings of the 15th European Workshop on Systems Security},
162-
pages = {15–21},
163-
numpages = {7},
164-
keywords = {security, embedded systems, operating systems, IoT},
165-
location = {Rennes, France},
166-
series = {EuroSec '22}
167188
}</pre>
168189
</details>
169190

arch/cortex-m/src/syscall.rs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const SVC_FRAME_SIZE: usize = 32;
5858
/// Values for encoding the stored state buffer in a binary slice.
5959
const VERSION: usize = 1;
6060
const STORED_STATE_SIZE: usize = size_of::<CortexMStoredState>();
61-
const TAG: [u8; 4] = [b'c', b't', b'x', b'm'];
61+
const TAG: [u8; 4] = *b"ctxm";
6262
const METADATA_LEN: usize = 3;
6363

6464
const VERSION_IDX: usize = 0;
@@ -181,7 +181,7 @@ impl<A: CortexMVariant> kernel::syscall::UserspaceKernelBoundary for SysCall<A>
181181
}
182182

183183
let sp = state.psp as *mut u32;
184-
let (r0, r1, r2, r3) = (sp.offset(0), sp.offset(1), sp.offset(2), sp.offset(3));
184+
let (r0, r1, r2, r3) = (sp.add(0), sp.add(1), sp.add(2), sp.add(3));
185185

186186
// These operations are only safe so long as
187187
// - the pointers are properly aligned. This is guaranteed because the
@@ -245,13 +245,13 @@ impl<A: CortexMVariant> kernel::syscall::UserspaceKernelBoundary for SysCall<A>
245245
// - Instruction addresses require `|1` to indicate thumb code
246246
// - Stack offset 4 is R12, which the syscall interface ignores
247247
let stack_bottom = state.psp as *mut usize;
248-
ptr::write(stack_bottom.offset(7), state.psr); //......... -> APSR
249-
ptr::write(stack_bottom.offset(6), callback.pc.addr() | 1); //... -> PC
250-
ptr::write(stack_bottom.offset(5), state.yield_pc | 1); // -> LR
251-
ptr::write(stack_bottom.offset(3), callback.argument3.as_usize()); // -> R3
252-
ptr::write(stack_bottom.offset(2), callback.argument2); // -> R2
253-
ptr::write(stack_bottom.offset(1), callback.argument1); // -> R1
254-
ptr::write(stack_bottom.offset(0), callback.argument0); // -> R0
248+
ptr::write(stack_bottom.add(7), state.psr); //......... -> APSR
249+
ptr::write(stack_bottom.add(6), callback.pc.addr() | 1); //... -> PC
250+
ptr::write(stack_bottom.add(5), state.yield_pc | 1); // -> LR
251+
ptr::write(stack_bottom.add(3), callback.argument3.as_usize()); // -> R3
252+
ptr::write(stack_bottom.add(2), callback.argument2); // -> R2
253+
ptr::write(stack_bottom.add(1), callback.argument1); // -> R1
254+
ptr::write(stack_bottom.add(0), callback.argument0); // -> R0
255255

256256
Ok(())
257257
}
@@ -296,26 +296,26 @@ impl<A: CortexMVariant> kernel::syscall::UserspaceKernelBoundary for SysCall<A>
296296
// syscall (i.e. we return a value to the app immediately) then this
297297
// will have no effect. If we are doing something like `yield()`,
298298
// however, then we need to have this state.
299-
state.yield_pc = ptr::read(new_stack_pointer.offset(6));
300-
state.psr = ptr::read(new_stack_pointer.offset(7));
299+
state.yield_pc = ptr::read(new_stack_pointer.add(6));
300+
state.psr = ptr::read(new_stack_pointer.add(7));
301301

302302
// Get the syscall arguments and return them along with the syscall.
303303
// It's possible the app did something invalid, in which case we put
304304
// the app in the fault state.
305-
let r0 = ptr::read(new_stack_pointer.offset(0));
306-
let r1 = ptr::read(new_stack_pointer.offset(1));
307-
let r2 = ptr::read(new_stack_pointer.offset(2));
308-
let r3 = ptr::read(new_stack_pointer.offset(3));
305+
let r0 = ptr::read(new_stack_pointer.add(0));
306+
let r1 = ptr::read(new_stack_pointer.add(1));
307+
let r2 = ptr::read(new_stack_pointer.add(2));
308+
let r3 = ptr::read(new_stack_pointer.add(3));
309309

310310
// Get the actual SVC number.
311311
// Read the PC from the stack as a *const u16 (i.e. we're treating instructions as
312312
// u16).
313313
let pcptr_ptr: *const usize = new_stack_pointer;
314314
let pcptr_ptr: *const *const u16 = pcptr_ptr.cast();
315-
let pcptr = ptr::read(pcptr_ptr.offset(6));
315+
let pcptr = ptr::read(pcptr_ptr.add(6));
316316
// The svc instruction is the last instruction before the PC, and should be 16 bits.
317317
// Read it by offsetting the PC.
318-
let svc_instr = ptr::read(pcptr.offset(-1));
318+
let svc_instr = ptr::read(pcptr.sub(1));
319319
let svc_num = (svc_instr & 0xff) as u8;
320320

321321
// Use the helper function to convert these raw values into a Tock
@@ -367,14 +367,14 @@ impl<A: CortexMVariant> kernel::syscall::UserspaceKernelBoundary for SysCall<A>
367367
0xBAD00BAD,
368368
)
369369
} else {
370-
let r0 = ptr::read(stack_pointer.offset(0));
371-
let r1 = ptr::read(stack_pointer.offset(1));
372-
let r2 = ptr::read(stack_pointer.offset(2));
373-
let r3 = ptr::read(stack_pointer.offset(3));
374-
let r12 = ptr::read(stack_pointer.offset(4));
375-
let lr = ptr::read(stack_pointer.offset(5));
376-
let pc = ptr::read(stack_pointer.offset(6));
377-
let xpsr = ptr::read(stack_pointer.offset(7));
370+
let r0 = ptr::read(stack_pointer.add(0));
371+
let r1 = ptr::read(stack_pointer.add(1));
372+
let r2 = ptr::read(stack_pointer.add(2));
373+
let r3 = ptr::read(stack_pointer.add(3));
374+
let r12 = ptr::read(stack_pointer.add(4));
375+
let lr = ptr::read(stack_pointer.add(5));
376+
let pc = ptr::read(stack_pointer.add(6));
377+
let xpsr = ptr::read(stack_pointer.add(7));
378378
(r0, r1, r2, r3, r12, lr, pc, xpsr)
379379
};
380380

arch/cortex-m0/src/lib.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ struct HardFaultStackedRegisters {
3333
/// by the naked hard_fault_handler function.
3434
unsafe extern "C" fn hard_fault_handler_kernel(faulting_stack: *mut u32) -> ! {
3535
let hardfault_stacked_registers = HardFaultStackedRegisters {
36-
r0: *faulting_stack.offset(0),
37-
r1: *faulting_stack.offset(1),
38-
r2: *faulting_stack.offset(2),
39-
r3: *faulting_stack.offset(3),
40-
r12: *faulting_stack.offset(4),
41-
lr: *faulting_stack.offset(5),
42-
pc: *faulting_stack.offset(6),
43-
xpsr: *faulting_stack.offset(7),
36+
r0: *faulting_stack.add(0),
37+
r1: *faulting_stack.add(1),
38+
r2: *faulting_stack.add(2),
39+
r3: *faulting_stack.add(3),
40+
r12: *faulting_stack.add(4),
41+
lr: *faulting_stack.add(5),
42+
pc: *faulting_stack.add(6),
43+
xpsr: *faulting_stack.add(7),
4444
};
4545

4646
panic!(

arch/cortex-v7m/src/lib.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -288,14 +288,14 @@ unsafe extern "C" fn hard_fault_handler_arm_v7m_kernel(
288288
panic!("kernel stack overflow");
289289
} else {
290290
// Show the normal kernel hardfault message.
291-
let stacked_r0: u32 = *faulting_stack.offset(0);
292-
let stacked_r1: u32 = *faulting_stack.offset(1);
293-
let stacked_r2: u32 = *faulting_stack.offset(2);
294-
let stacked_r3: u32 = *faulting_stack.offset(3);
295-
let stacked_r12: u32 = *faulting_stack.offset(4);
296-
let stacked_lr: u32 = *faulting_stack.offset(5);
297-
let stacked_pc: u32 = *faulting_stack.offset(6);
298-
let stacked_xpsr: u32 = *faulting_stack.offset(7);
291+
let stacked_r0: u32 = *faulting_stack.add(0);
292+
let stacked_r1: u32 = *faulting_stack.add(1);
293+
let stacked_r2: u32 = *faulting_stack.add(2);
294+
let stacked_r3: u32 = *faulting_stack.add(3);
295+
let stacked_r12: u32 = *faulting_stack.add(4);
296+
let stacked_lr: u32 = *faulting_stack.add(5);
297+
let stacked_pc: u32 = *faulting_stack.add(6);
298+
let stacked_xpsr: u32 = *faulting_stack.add(7);
299299

300300
let mode_str = "Kernel";
301301

arch/riscv/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,18 +173,18 @@ pub unsafe fn configure_trap_handler() {
173173
// Indicate to the trap handler that we are executing kernel code.
174174
csr::CSR.mscratch.set(0);
175175

176-
// Set the machine-mode trap handler. By not configuing an S-mode or U-mode
176+
// Set the machine-mode trap handler. By not configuring an S-mode or U-mode
177177
// trap handler, this should ensure that all traps are handled by the M-mode
178178
// handler.
179179
csr::CSR.mtvec.write(
180-
csr::mtvec::mtvec::trap_addr.val(_start_trap as usize >> 2)
180+
csr::mtvec::mtvec::trap_addr.val(_start_trap as extern "C" fn() -> ! as usize >> 2)
181181
+ csr::mtvec::mtvec::mode::CLEAR,
182182
);
183183
}
184184

185185
// Mock implementation for tests on Travis-CI.
186186
#[cfg(not(any(doc, all(target_arch = "riscv32", target_os = "none"))))]
187-
pub extern "C" fn _start_trap() {
187+
pub extern "C" fn _start_trap() -> ! {
188188
unimplemented!()
189189
}
190190

@@ -291,7 +291,7 @@ pub extern "C" fn _start_trap() {
291291
// symbol name.
292292
#[export_name = "_start_trap"]
293293
#[unsafe(naked)]
294-
pub extern "C" fn _start_trap() {
294+
pub extern "C" fn _start_trap() -> ! {
295295
use core::arch::naked_asm;
296296
naked_asm!(
297297
"

arch/riscv/src/syscall.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const R_A4: usize = 13;
4949
/// Values for encoding the stored state buffer in a binary slice.
5050
const VERSION: u32 = 1;
5151
const STORED_STATE_SIZE: u32 = size_of::<Riscv32iStoredState>() as u32;
52-
const TAG: [u8; 4] = [b'r', b'v', b'5', b'i'];
52+
const TAG: [u8; 4] = *b"rv5i";
5353
const METADATA_LEN: usize = 3;
5454

5555
const VERSION_IDX: usize = 0;

arch/rv32i/src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ pub mod machine_timer;
1111

1212
// Re-export shared libraries so that dependent crates do not have to have
1313
// both rv32i and riscv as dependencies.
14+
pub use riscv::_start_trap;
15+
pub use riscv::configure_trap_handler;
1416
pub use riscv::csr;
17+
pub use riscv::dma_fence;
1518
pub use riscv::initialize_ram_jump_to_main;
1619
pub use riscv::pmp;
20+
pub use riscv::print_mcause;
1721
pub use riscv::print_riscv_state;
22+
pub use riscv::semihost_command;
1823
pub use riscv::support;
1924
pub use riscv::syscall;
2025
pub use riscv::thread_id;
2126
pub use riscv::PermissionMode;
22-
pub use riscv::_start_trap;
23-
pub use riscv::configure_trap_handler;
24-
pub use riscv::dma_fence;
25-
pub use riscv::print_mcause;
26-
pub use riscv::semihost_command;

0 commit comments

Comments
 (0)