[kernel] Use IST for kernel stacks for NMI, #DF, #PF

We started actually running up against the page boundary for kernel
stacks and thus double-faulting on page faults from kernel space. So I
finally added IST stacks. Note that we currently just
increment/decrement the IST entry by a page when we enter the handler to
avoid clobbering on re-entry, but this means:

* these handlers need to be able to operate with only a page of stack
* kernel stacks always have to be >1 pages
* the amount of nesting possible is tied to the kernel stack size.

These seem fine for now, but we should maybe find a way to use something
besides g_kernel_stacks to set up the IST stacks if/when this becomes an
issue.
This commit is contained in:
Justin C. Miller
2021-02-02 18:27:37 -08:00
parent 8575939b20
commit 68a2250886
8 changed files with 166 additions and 87 deletions

View File

@@ -17,17 +17,42 @@ void idt_set_entry(uint8_t i, uint64_t addr, uint16_t selector, uint8_t flags);
/// Set the stack pointer for a given ring in the TSS
/// \arg ring Ring to set for (0-2)
/// \arg rsp Stack pointer to set
void tss_set_stack(int ring, uintptr_t rsp);
void tss_set_stack(unsigned ring, uintptr_t rsp);
/// Get the stack pointer for a given ring in the TSS
/// \arg ring Ring to get (0-2)
/// \returns Stack pointers for that ring
uintptr_t tss_get_stack(int ring);
uintptr_t tss_get_stack(unsigned ring);
/// Set the given IDT entry to use the given IST entry
/// \arg i Which IDT entry to set
/// \arg ist Which IST entry to set (1-7)
void idt_set_ist(unsigned i, unsigned ist);
/// Set the stack pointer for a given IST in the TSS
/// \arg ist Which IST entry to set (1-7)
/// \arg rsp Stack pointer to set
void tss_set_ist(unsigned ist, uintptr_t rsp);
/// Increment the stack pointer for the given vector,
/// if it's using an IST entry
/// \arg i Which IDT entry to use
void ist_increment(unsigned i);
/// Decrement the stack pointer for the given vector,
/// if it's using an IST entry
/// \arg i Which IDT entry to use
void ist_decrement(unsigned i);
/// Get the stack pointer for a given IST in the TSS
/// \arg ring Which IST entry to get (1-7)
/// \returns Stack pointers for that IST entry
uintptr_t tss_get_ist(unsigned ist);
/// Dump information about the current GDT to the screen
/// \arg index Which entry to print, or -1 for all entries
void gdt_dump(int index = -1);
void gdt_dump(unsigned index = -1);
/// Dump information about the current IDT to the screen
/// \arg index Which entry to print, or -1 for all entries
void idt_dump(int index = -1);
void idt_dump(unsigned index = -1);