aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/arch/cpu/interrupts.cpp29
-rw-r--r--arch/x86_64/scripts/kernel.ld2
-rw-r--r--kapi/kapi/memory/address.hpp4
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;
}