diff options
| -rw-r--r-- | arch/x86_64/arch/cpu/interrupts.cpp | 29 | ||||
| -rw-r--r-- | arch/x86_64/scripts/kernel.ld | 2 | ||||
| -rw-r--r-- | kapi/kapi/memory/address.hpp | 4 |
3 files changed, 31 insertions, 4 deletions
diff --git a/arch/x86_64/arch/cpu/interrupts.cpp b/arch/x86_64/arch/cpu/interrupts.cpp index 94806621..f27c3a2e 100644 --- a/arch/x86_64/arch/cpu/interrupts.cpp +++ b/arch/x86_64/arch/cpu/interrupts.cpp @@ -9,7 +9,9 @@ #include <kapi/system.hpp> #include <kstd/print.hpp> +#include <kstd/units.hpp> +#include <cstddef> #include <cstdint> namespace arch::cpu @@ -17,6 +19,9 @@ namespace arch::cpu namespace { + extern "C" std::byte __kernel_stack_bottom[]; // NOLINT(readability-identifier-naming) + extern "C" std::byte __ist1_stack_bottom[]; // NOLINT(readability-identifier-naming) + enum struct exception { divide_error, @@ -128,8 +133,28 @@ namespace arch::cpu auto handle_double_fault(interrupt_frame * frame) -> void { - kapi::system::panic("[ARCH:CPU] Double fault! Possible kernel stack corruption! rsp was {}", - frame->cpu_saved.rsp); + auto const rsp = frame->cpu_saved.rsp; + auto const rip = frame->cpu_saved.rip; + auto const kernel_stack_bottom = kapi::memory::linear_address{__kernel_stack_bottom}; + auto const ist1_stack_bottom = kapi::memory::linear_address{__ist1_stack_bottom}; + + auto const overflowed_kernel = rsp < kernel_stack_bottom && rsp >= kernel_stack_bottom - kapi::memory::page::size; + auto const overflowed_ist1 = rsp < ist1_stack_bottom && rsp >= ist1_stack_bottom - kapi::memory::page::size; + + if (overflowed_kernel || overflowed_ist1) + { + auto const overflowed_what = overflowed_kernel ? "kernel" : "ist1"; + auto const overflowed_by = + kstd::bytes{static_cast<std::size_t>((overflowed_kernel ? kernel_stack_bottom : ist1_stack_bottom) - rsp)}; + + kapi::system::panic("[ARCH:CPU] Suspected {} stack overflow: \n" // + "\toverflowed by: {:#}\n" // + "\trsp: {}\n" // + "\trip: {}\n", // + overflowed_what, overflowed_by, rsp, rip); + } + + kapi::system::panic("[ARCH:CPU] Double fault at {}", rip); } } // namespace diff --git a/arch/x86_64/scripts/kernel.ld b/arch/x86_64/scripts/kernel.ld index 8cd6c1c3..f96152d7 100644 --- a/arch/x86_64/scripts/kernel.ld +++ b/arch/x86_64/scripts/kernel.ld @@ -100,6 +100,7 @@ SECTIONS .kernel_stack ALIGN(4K) : AT (ADDR (.kernel_stack) - TEACHOS_VMA) { + PROVIDE_HIDDEN(__kernel_stack_bottom = .); *(.stack) } :kernel_data @@ -107,6 +108,7 @@ SECTIONS .kernel_ist1_stack ALIGN(4K) : AT (ADDR (.kernel_ist1_stack) - TEACHOS_VMA) { + PROVIDE_HIDDEN(__ist1_stack_bottom = .); *(.ist1_stack) } :kernel_data diff --git a/kapi/kapi/memory/address.hpp b/kapi/kapi/memory/address.hpp index a7f5ac92..5b84a381 100644 --- a/kapi/kapi/memory/address.hpp +++ b/kapi/kapi/memory/address.hpp @@ -102,7 +102,7 @@ namespace kapi::memory //! //! @param n The amount to subtract from this address //! @return A nre address, @p n ahead of this one - [[nodiscard]] constexpr auto operator-(std::ptrdiff_t n) noexcept -> address + [[nodiscard]] constexpr auto operator-(std::ptrdiff_t n) const noexcept -> address { return address{m_value - n}; } @@ -139,7 +139,7 @@ namespace kapi::memory //! //! @param other The address to calculate the distance to. //! @return The distance between this address and the given one. - [[nodiscard]] constexpr auto operator-(address const & other) noexcept -> std::ptrdiff_t + [[nodiscard]] constexpr auto operator-(address const & other) const noexcept -> std::ptrdiff_t { return m_value - other.m_value; } |
