summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Kobert <dennis@kobert.dev>2019-11-15 07:32:54 +0100
committerDennis Kobert <dennis@kobert.dev>2019-11-15 07:32:54 +0100
commit67df24a850b6dc070382289d09c70e369726cac4 (patch)
tree1221daf02158c4654bf5c5382bd6e888da0855d0
parent307571308b115eb737281711c780fa4cd1ed837f (diff)
Add protection fault handler
-rw-r--r--kernel/src/interrupts/exceptions.rs26
-rw-r--r--kernel/src/interrupts/idt.rs2
-rw-r--r--kernel/src/interrupts/mod.rs11
-rw-r--r--kernel/tests/int3.rs2
-rw-r--r--kernel/tests/stack_overflow.rs2
5 files changed, 30 insertions, 13 deletions
diff --git a/kernel/src/interrupts/exceptions.rs b/kernel/src/interrupts/exceptions.rs
index f6d5176..a3ecf9d 100644
--- a/kernel/src/interrupts/exceptions.rs
+++ b/kernel/src/interrupts/exceptions.rs
@@ -13,10 +13,10 @@ macro_rules! exception_default {
};
}
-static mut expected_fault: Interrupts = Interrupts::NONE;
+static mut expected_fault: Interrupts = Interrupts::None;
pub unsafe fn expect_fault(int: Interrupts) {
- if expected_fault == Interrupts::NONE {
+ if expected_fault == Interrupts::None {
expected_fault = int;
}
}
@@ -27,7 +27,7 @@ fn get_expected_fault() -> Interrupts {
pub extern "x86-interrupt" fn breakpoint_handler(stack_frame: &mut InterruptStackFrame) {
match get_expected_fault() {
- Interrupts::BREAKPOINT => qemu::exit_qemu(qemu::QemuExitCode::Success),
+ Interrupts::Breakpoint => qemu::exit_qemu(qemu::QemuExitCode::Success),
_ => panic!(
"BREAKPOINT exception thrown\n\n{}",
exception_default!(stack_frame)
@@ -35,6 +35,20 @@ pub extern "x86-interrupt" fn breakpoint_handler(stack_frame: &mut InterruptStac
}
}
+pub extern "x86-interrupt" fn general_protection_fault_handler(
+ stack_frame: &mut InterruptStackFrame,
+ error_code: u64,
+) {
+ match get_expected_fault() {
+ Interrupts::GeneralProtectionFault => qemu::exit_qemu(qemu::QemuExitCode::Success),
+ _ => panic!(
+ "GENERAL PROTECTION exception thrown\nerror code: {:x}\n{}",
+ error_code,
+ exception_default!(stack_frame)
+ ),
+ }
+}
+
pub extern "x86-interrupt" fn page_fault_handler(
stack_frame: &mut InterruptStackFrame,
error_code: PageFaultErrorCode,
@@ -42,7 +56,7 @@ pub extern "x86-interrupt" fn page_fault_handler(
use x86_64::registers::control::Cr2;
match get_expected_fault() {
- Interrupts::PAGE_FAULT => qemu::exit_qemu(qemu::QemuExitCode::Success),
+ Interrupts::PageFault => qemu::exit_qemu(qemu::QemuExitCode::Success),
_ => panic!(
"PAGE FAULT while accessing address: 0x{:08x}\nerror code: {:?}(0x{:x})\n{}",
Cr2::read().as_u64(),
@@ -58,7 +72,7 @@ pub extern "x86-interrupt" fn segment_not_present_handler(
error_code: u64,
) {
match get_expected_fault() {
- Interrupts::NOT_PRESENT => qemu::exit_qemu(qemu::QemuExitCode::Success),
+ Interrupts::NotPresent => qemu::exit_qemu(qemu::QemuExitCode::Success),
_ => panic!(
"SEGMENT NOT PRESENT exception\nerror code: 0x{:x}\n{}",
error_code,
@@ -72,7 +86,7 @@ pub extern "x86-interrupt" fn double_fault_handler(
_error_code: u64, // code is always zero
) {
match get_expected_fault() {
- Interrupts::NOT_PRESENT => qemu::exit_qemu(qemu::QemuExitCode::Success),
+ Interrupts::DoubleFault => qemu::exit_qemu(qemu::QemuExitCode::Success),
_ => panic!(
"DOUBLE FAULT\nthis is a fatal exception\n{}",
exception_default!(stack_frame)
diff --git a/kernel/src/interrupts/idt.rs b/kernel/src/interrupts/idt.rs
index 9541f22..e85ef5a 100644
--- a/kernel/src/interrupts/idt.rs
+++ b/kernel/src/interrupts/idt.rs
@@ -8,6 +8,8 @@ lazy_static! {
.set_handler_fn(super::exceptions::breakpoint_handler);
idt.segment_not_present
.set_handler_fn(super::exceptions::segment_not_present_handler);
+ idt.general_protection_fault
+ .set_handler_fn(super::exceptions::general_protection_fault_handler);
unsafe {
idt.double_fault
.set_handler_fn(super::exceptions::double_fault_handler)
diff --git a/kernel/src/interrupts/mod.rs b/kernel/src/interrupts/mod.rs
index 4ff3c4d..087a59c 100644
--- a/kernel/src/interrupts/mod.rs
+++ b/kernel/src/interrupts/mod.rs
@@ -5,9 +5,10 @@ pub mod idt;
#[repr(usize)]
#[derive(PartialEq, Clone, Copy)]
pub enum Interrupts {
- NONE,
- PAGE_FAULT,
- DOUBLE_FAULT,
- NOT_PRESENT,
- BREAKPOINT,
+ None,
+ PageFault,
+ DoubleFault,
+ NotPresent,
+ Breakpoint,
+ GeneralProtectionFault,
}
diff --git a/kernel/tests/int3.rs b/kernel/tests/int3.rs
index f4e2116..f5b5470 100644
--- a/kernel/tests/int3.rs
+++ b/kernel/tests/int3.rs
@@ -13,7 +13,7 @@ use kernel::io::qemu;
extern "C" fn _start() -> ! {
kernel::init();
unsafe {
- exceptions::expect_fault(interrupts::Interrupts::BREAKPOINT);
+ exceptions::expect_fault(interrupts::Interrupts::Breakpoint);
}
x86_64::instructions::interrupts::int3();
panic!("BREAKPOINT not caught");
diff --git a/kernel/tests/stack_overflow.rs b/kernel/tests/stack_overflow.rs
index eedb3b5..9e75f59 100644
--- a/kernel/tests/stack_overflow.rs
+++ b/kernel/tests/stack_overflow.rs
@@ -14,7 +14,7 @@ use kernel::io::qemu;
extern "C" fn _start() -> ! {
kernel::init();
unsafe {
- exceptions::expect_fault(interrupts::Interrupts::NOT_PRESENT);
+ exceptions::expect_fault(interrupts::Interrupts::PageFault);
}
_loop(0);
panic!("PAGE_FAULT not caught");