summaryrefslogtreecommitdiffstats
path: root/rsnix/src/gdt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rsnix/src/gdt.rs')
-rw-r--r--rsnix/src/gdt.rs24
1 files changed, 17 insertions, 7 deletions
diff --git a/rsnix/src/gdt.rs b/rsnix/src/gdt.rs
index 514ed2e..f3d8b9a 100644
--- a/rsnix/src/gdt.rs
+++ b/rsnix/src/gdt.rs
@@ -116,12 +116,14 @@ impl Tss {
116 } 116 }
117} 117}
118 118
119/// 4 KiB page-aligned block for the IST stacks. 119/// IST stack size: the fault path (fault dump + best-effort crash-log
120#[repr(align(4096))] 120/// FAT write) is deep, so each IST stack is 32 KiB, allocated from the
121struct Page([u8; 4096]); 121/// heap at init. They must NOT live in .bss: a 4 KiB .bss stack placed
122/// next to kernel statics silently overwrites them on overflow (the FAT
123/// ACTIVE_VOL was clobbered this way — a "no volume at slot 8" crash in
124/// the fault path). The heap region is far from the kernel image.
125const IST_STACK_SIZE: usize = 32 * 1024;
122 126
123static mut PF_STACK: Page = Page([0; 4096]);
124static mut DF_STACK: Page = Page([0; 4096]);
125static mut TSS: Tss = Tss::zero(); 127static mut TSS: Tss = Tss::zero();
126// GDT slots are 8 bytes except the TSS descriptor at index 63, which is 128// GDT slots are 8 bytes except the TSS descriptor at index 63, which is
127// 16 bytes — total 64*8 + 16. 129// 16 bytes — total 64*8 + 16.
@@ -193,8 +195,16 @@ pub fn init() -> bool {
193 195
194 // TSS descriptor (16 bytes) at index 63. 196 // TSS descriptor (16 bytes) at index 63.
195 let tss_base = core::ptr::addr_of_mut!(TSS) as usize as u64; 197 let tss_base = core::ptr::addr_of_mut!(TSS) as usize as u64;
196 TSS.ist1 = core::ptr::addr_of_mut!(PF_STACK.0[0]) as usize as u64 + 4096; 198 // IST stacks come from the heap (see IST_STACK_SIZE): 32 KiB each,
197 TSS.ist2 = core::ptr::addr_of_mut!(DF_STACK.0[0]) as usize as u64 + 4096; 199 // well away from the kernel image/.bss so an overflowing fault
200 // path can't silently overwrite statics.
201 let pf = crate::memory::allocate(IST_STACK_SIZE);
202 let df = crate::memory::allocate(IST_STACK_SIZE);
203 if pf.is_null() || df.is_null() {
204 return false;
205 }
206 TSS.ist1 = pf as u64 + IST_STACK_SIZE as u64;
207 TSS.ist2 = df as u64 + IST_STACK_SIZE as u64;
198 TSS.iomap_base = TSS_SIZE as u16; // no I/O bitmap 208 TSS.iomap_base = TSS_SIZE as u16; // no I/O bitmap
199 209
200 let mut td = [0u8; 16]; 210 let mut td = [0u8; 16];