18
18
*/
19
19
#define CSR_MSHWMB 0xbc2
20
20
21
+ /**
22
+ * The special capability register for the fast zeroing control.
23
+ * Writing a capability here starts zeroing from the address of this register
24
+ * down to the base.
25
+ *
26
+ * TODO: This is a made up number, it might need to be a different one.
27
+ */
28
+ #define SCR_ZTOP 0x1c
29
+
21
30
#define MAX_FAULTS_PER_COMPARTMENT_CALL 1024
22
31
23
32
#define SPILL_SLOT_cs0 0
@@ -126,6 +135,46 @@ switcher_scheduler_entry_csp:
126
135
* and integer register. All three registers are clobbered.
127
136
*/
128
137
.macro zero_stack base top scratch
138
+ #ifdef CHERIOT_HAS_ZTOP
139
+ // Derive the capability to the range that should be zeroed.
140
+ // This is stored in base, leaving top as a second scratch register to use
141
+ csub \top, c\top, c\base
142
+ csetboundsexact c\base, c\base, \top
143
+
144
+ // Wait for any prior zeroing to finish.
145
+ cspecialr c\scratch, SCR_ZTOP
146
+ // If ztop is untagged, no zeroing is happening and our attempt to store
147
+ // relative to ztop will trap.
148
+ cgettag \top, c\scratch
149
+ beqz \top, 2f
150
+ // If we've already reached the bottom then do nothing.
151
+ // NOTE: This can be deleted if ZTOP's tag is cleared when zeroing finishes.
152
+ cgetbase \top, c\scratch
153
+ beq \top, \scratch, 2f
154
+ // If the current zeroing range is a subset of range that we're about to
155
+ // zero, don't bother waiting, just zero from the start.
156
+ ctestsubset \top, c\base, c\scratch
157
+ bnez \top, 2f
158
+ // If the requested range is a subset of the previous requested range,
159
+ // restart zeroing that instead
160
+ // NOTE: This may result in zeroing things too many times, we're trading
161
+ // some throughput for latency here. This might be the wrong choice.
162
+ ctestsubset \top, c\scratch, c\base
163
+ bnez \top, 1f
164
+ // Store a byte at the bottom of the zeroed region. This will block until
165
+ // we've finished the zeroing.
166
+ cgetbase \top, c\scratch
167
+ csetaddr c\top, c\scratch, \top
168
+ csb zero, 0 (c\top)
169
+ j 2f
170
+ 1:
171
+ cmove c\base, c\scratch
172
+ 2:
173
+ // Set the new value
174
+ cspecialw SCR_ZTOP, c\base
175
+
176
+ #else
177
+
129
178
addi \scratch, \top, -32
130
179
addi \top, \top, -16
131
180
bgt \base, \scratch, 1f
@@ -143,6 +192,8 @@ switcher_scheduler_entry_csp:
143
192
csc cnull, 0 (c\base)
144
193
csc cnull, 8 (c\base)
145
194
2:
195
+
196
+ #endif
146
197
.endm
147
198
148
199
.section .text , "ax" , @progbits
@@ -200,7 +251,7 @@ compartment_switcher_entry:
200
251
sub s1, s0, s1
201
252
csetboundsexact ct2, csp, s1
202
253
csetaddr csp, ct2, s0
203
- #ifdef CONFIG_MSHWM
254
+ #ifdef CHERIOT_HAS_MSHWM
204
255
// Read and align the stack high water mark
205
256
csrr gp, CSR_MSHWM
206
257
and gp, gp, ~0xf
@@ -213,7 +264,7 @@ compartment_switcher_entry:
213
264
#endif
214
265
zero_stack t2, s0, gp
215
266
after_zero:
216
- #ifdef CONFIG_MSHWM
267
+ #ifdef CHERIOT_HAS_MSHWM
217
268
// store new stack top as stack high water mark
218
269
csrw CSR_MSHWM, sp
219
270
#endif
@@ -347,11 +398,20 @@ exception_entry_asm:
347
398
csc ct0, TrustedStack_offset_mepcc(csp)
348
399
csrr t1, mstatus
349
400
csw t1, TrustedStack_offset_mstatus(csp)
350
- #ifdef CONFIG_MSHWM
401
+ #ifdef CHERIOT_HAS_MSHWM
351
402
csrr t1, CSR_MSHWM
352
403
csw t1, TrustedStack_offset_mshwm(csp)
353
404
csrr t1, CSR_MSHWMB
354
405
csw t1, TrustedStack_offset_mshwmb(csp)
406
+ #endif
407
+ #ifdef CHERIOT_HAS_ZTOP
408
+ // Stop zeroing and capture the current zeroing value. Note: cspecialr is
409
+ // encoded as cspecialrw and so we can't just use cnull as the source. We
410
+ // probably could use the current ct1 value, since it's guaranteed to be
411
+ // untagged at this point in the code.
412
+ cmove ct1, cnull
413
+ cspecialrw ct1, SCR_ZTOP, ct1
414
+ csc ct1, TrustedStack_offset_ztop(csp)
355
415
#endif
356
416
csrr t1, mcause
357
417
csw t1, TrustedStack_offset_mcause(csp)
@@ -432,11 +492,15 @@ exception_entry_asm:
432
492
.Linstall_context:
433
493
clw x1, TrustedStack_offset_mstatus(csp)
434
494
csrw mstatus, x1
435
- #ifdef CONFIG_MSHWM
495
+ #ifdef CHERIOT_HAS_MSHWM
436
496
clw x1, TrustedStack_offset_mshwm(csp)
437
497
csrw CSR_MSHWM, x1
438
498
clw x1, TrustedStack_offset_mshwmb(csp)
439
499
csrw CSR_MSHWMB, x1
500
+ #endif
501
+ #ifdef CHERIOT_HAS_ZTOP
502
+ clc c1, TrustedStack_offset_ztop(csp)
503
+ cspecialw SCR_ZTOP, c1
440
504
#endif
441
505
cspecialw mepcc, ct2
442
506
csb zero, TrustedStack_offset_inForcedUnwind(csp)
@@ -657,7 +721,7 @@ exception_entry_asm:
657
721
658
722
// Load the trusted stack pointer to ct1
659
723
cspecialr ct1, mtdc
660
- #ifdef CONFIG_MSHWM
724
+ #ifdef CHERIOT_HAS_MSHWM
661
725
// Update the spilled copy of the stack high water mark to ensure that we
662
726
// will clear all of the stack used by the error handler and the spilled
663
727
// context.
@@ -761,7 +825,7 @@ exception_entry_asm:
761
825
clc cgp, SPILL_SLOT_cgp(csp)
762
826
cincoffset csp, csp, SPILL_SLOT_SIZE
763
827
#ifndef CONFIG_NO_SWITCHER_SAFETY
764
- #ifdef CONFIG_MSHWM
828
+ #ifdef CHERIOT_HAS_MSHWM
765
829
// read and align the stack high water mark
766
830
// we will use this as base address for stack clearing
767
831
// note that it cannot be greater than stack top as we
@@ -774,7 +838,7 @@ exception_entry_asm:
774
838
cgetaddr t1, csp
775
839
csetaddr ct2, csp, tp
776
840
zero_stack t2, t1, tp
777
- #ifdef CONFIG_MSHWM
841
+ #ifdef CHERIOT_HAS_MSHWM
778
842
csrw CSR_MSHWM, sp
779
843
#endif
780
844
#endif // CONFIG_NO_SWITCHER_SAFETY
0 commit comments