Skip to content

Commit 8017f99

Browse files
authored
Merge pull request #389 from 00xc/cpu/tss
cpu/tss: fix TSS layout
2 parents 4e48ccb + 089bc9b commit 8017f99

File tree

3 files changed

+34
-12
lines changed

3 files changed

+34
-12
lines changed

kernel/src/cpu/idt/svsm.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,7 @@ extern "C" {
5757
}
5858

5959
fn init_ist_vectors() {
60-
idt_mut().set_entry(
61-
DF_VECTOR,
62-
IdtEntry::ist_entry(asm_entry_df, IST_DF.try_into().unwrap()),
63-
);
60+
idt_mut().set_entry(DF_VECTOR, IdtEntry::ist_entry(asm_entry_df, IST_DF.get()));
6461
}
6562

6663
pub fn early_idt_init() {

kernel/src/cpu/percpu.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ impl PerCpu {
499499
fn setup_tss(&self) {
500500
let double_fault_stack = self.get_top_of_df_stack();
501501
let mut tss = self.tss.get();
502-
tss.ist_stacks[IST_DF] = double_fault_stack;
502+
tss.set_ist_stack(IST_DF, double_fault_stack);
503503
self.tss.set(tss);
504504
}
505505

kernel/src/cpu/tss.rs

+32-7
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@
66

77
use super::gdt::GDTEntry;
88
use crate::address::VirtAddr;
9+
use core::num::NonZeroU8;
910

1011
// IST offsets
11-
pub const _IST_INVALID: usize = 0;
12-
pub const IST_DF: usize = 1;
12+
pub const IST_DF: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(1) };
1313

1414
#[derive(Debug, Default, Clone, Copy)]
15-
#[repr(C, packed)]
15+
#[repr(C, packed(4))]
1616
pub struct X86Tss {
17-
reserved1: u32,
17+
reserved0: u32,
1818
pub stacks: [VirtAddr; 3],
19-
pub ist_stacks: [VirtAddr; 8],
19+
reserved1: u64,
20+
ist_stacks: [VirtAddr; 7],
2021
reserved2: u64,
2122
reserved3: u16,
2223
io_bmp_base: u16,
@@ -27,15 +28,22 @@ pub const TSS_LIMIT: u64 = core::mem::size_of::<X86Tss>() as u64;
2728
impl X86Tss {
2829
pub const fn new() -> Self {
2930
X86Tss {
30-
reserved1: 0,
31+
reserved0: 0,
3132
stacks: [VirtAddr::null(); 3],
32-
ist_stacks: [VirtAddr::null(); 8],
33+
reserved1: 0,
34+
ist_stacks: [VirtAddr::null(); 7],
3335
reserved2: 0,
3436
reserved3: 0,
3537
io_bmp_base: (TSS_LIMIT + 1) as u16,
3638
}
3739
}
3840

41+
pub fn set_ist_stack(&mut self, index: NonZeroU8, addr: VirtAddr) {
42+
// IST entries start at index 1
43+
let index = usize::from(index.get() - 1);
44+
self.ist_stacks[index] = addr;
45+
}
46+
3947
pub fn to_gdt_entry(&self) -> (GDTEntry, GDTEntry) {
4048
let addr = (self as *const X86Tss) as u64;
4149

@@ -60,3 +68,20 @@ impl X86Tss {
6068
(GDTEntry::from_raw(desc0), GDTEntry::from_raw(desc1))
6169
}
6270
}
71+
72+
#[cfg(test)]
73+
mod test {
74+
use super::*;
75+
use core::mem::offset_of;
76+
77+
#[test]
78+
fn test_tss_offsets() {
79+
assert_eq!(offset_of!(X86Tss, reserved0), 0x0);
80+
assert_eq!(offset_of!(X86Tss, stacks), 0x4);
81+
assert_eq!(offset_of!(X86Tss, reserved1), 0x1c);
82+
assert_eq!(offset_of!(X86Tss, ist_stacks), 0x24);
83+
assert_eq!(offset_of!(X86Tss, reserved2), 0x5c);
84+
assert_eq!(offset_of!(X86Tss, reserved3), 0x64);
85+
assert_eq!(offset_of!(X86Tss, io_bmp_base), 0x66);
86+
}
87+
}

0 commit comments

Comments
 (0)