summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Kobert <dennis@kobert.dev>2019-11-11 18:42:59 +0100
committerDennis Kobert <dennis@kobert.dev>2019-11-11 18:42:59 +0100
commitec22f3464c87b3d1b1688898053a569bc4839404 (patch)
tree7332136eb3c3cb08dea32cbd89ee3254b55466bb
parent26a7561196674b39f9adadcb374f36c503361adb (diff)
Add expect fault handling
-rw-r--r--kernel/Cargo.toml9
-rw-r--r--kernel/src/interrupts/exceptions.rs66
-rw-r--r--kernel/src/interrupts/idt.rs (renamed from kernel/src/interrupts/table.rs)0
-rw-r--r--kernel/src/interrupts/mod.rs14
-rw-r--r--kernel/src/lib.rs2
-rw-r--r--kernel/tests/int3.rs16
-rw-r--r--kernel/tests/stack_overflow.rs11
7 files changed, 80 insertions, 38 deletions
diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml
index a2ce08c..1baefdb 100644
--- a/kernel/Cargo.toml
+++ b/kernel/Cargo.toml
@@ -5,8 +5,13 @@ authors = ["Dennis Kobert <dennis@kobert.dev>",
"Jan Zwerschke"]
edition = "2018"
-# [lib]
-# crate-type = ["staticlib"]
+[[test]]
+name = "int3"
+harness = false
+
+[[test]]
+name = "stack_overflow"
+harness = false
[package.metadata.cargo-xbuild]
sysroot_path = "target/sysroot"
diff --git a/kernel/src/interrupts/exceptions.rs b/kernel/src/interrupts/exceptions.rs
index 1e7680a..f6d5176 100644
--- a/kernel/src/interrupts/exceptions.rs
+++ b/kernel/src/interrupts/exceptions.rs
@@ -1,3 +1,5 @@
+use super::Interrupts;
+use crate::io::qemu;
use x86_64::structures::idt::{InterruptStackFrame, PageFaultErrorCode};
macro_rules! exception_default {
@@ -11,11 +13,26 @@ macro_rules! exception_default {
};
}
+static mut expected_fault: Interrupts = Interrupts::NONE;
+
+pub unsafe fn expect_fault(int: Interrupts) {
+ if expected_fault == Interrupts::NONE {
+ expected_fault = int;
+ }
+}
+
+fn get_expected_fault() -> Interrupts {
+ unsafe { expected_fault }
+}
+
pub extern "x86-interrupt" fn breakpoint_handler(stack_frame: &mut InterruptStackFrame) {
- panic!(
- "BREAKPOINT exception thrown\n\n{}",
- exception_default!(stack_frame)
- );
+ match get_expected_fault() {
+ Interrupts::BREAKPOINT => qemu::exit_qemu(qemu::QemuExitCode::Success),
+ _ => panic!(
+ "BREAKPOINT exception thrown\n\n{}",
+ exception_default!(stack_frame)
+ ),
+ }
}
pub extern "x86-interrupt" fn page_fault_handler(
@@ -24,32 +41,41 @@ pub extern "x86-interrupt" fn page_fault_handler(
) {
use x86_64::registers::control::Cr2;
- panic!(
- "PAGE FAULT while accessing address: 0x{:08x}\nerror code: {:?}(0x{:x})\n{}",
- Cr2::read().as_u64(),
- error_code,
- error_code.bits(),
- exception_default!(stack_frame)
- );
+ match get_expected_fault() {
+ Interrupts::PAGE_FAULT => qemu::exit_qemu(qemu::QemuExitCode::Success),
+ _ => panic!(
+ "PAGE FAULT while accessing address: 0x{:08x}\nerror code: {:?}(0x{:x})\n{}",
+ Cr2::read().as_u64(),
+ error_code,
+ error_code.bits(),
+ exception_default!(stack_frame)
+ ),
+ }
}
pub extern "x86-interrupt" fn segment_not_present_handler(
stack_frame: &mut InterruptStackFrame,
error_code: u64,
) {
- panic!(
- "SEGMENT NOT PRESENT exception\nerror code: 0x{:x}\n{}",
- error_code,
- exception_default!(stack_frame)
- );
+ match get_expected_fault() {
+ Interrupts::NOT_PRESENT => qemu::exit_qemu(qemu::QemuExitCode::Success),
+ _ => panic!(
+ "SEGMENT NOT PRESENT exception\nerror code: 0x{:x}\n{}",
+ error_code,
+ exception_default!(stack_frame)
+ ),
+ }
}
pub extern "x86-interrupt" fn double_fault_handler(
stack_frame: &mut InterruptStackFrame,
_error_code: u64, // code is always zero
) {
- panic!(
- "DOUBLE FAULT\nthis is a fatal exception\n{}",
- exception_default!(stack_frame)
- );
+ match get_expected_fault() {
+ Interrupts::NOT_PRESENT => 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/table.rs b/kernel/src/interrupts/idt.rs
index 9541f22..9541f22 100644
--- a/kernel/src/interrupts/table.rs
+++ b/kernel/src/interrupts/idt.rs
diff --git a/kernel/src/interrupts/mod.rs b/kernel/src/interrupts/mod.rs
index 14de3f2..4ff3c4d 100644
--- a/kernel/src/interrupts/mod.rs
+++ b/kernel/src/interrupts/mod.rs
@@ -1,3 +1,13 @@
-mod exceptions;
+pub mod exceptions;
pub mod gdt;
-pub mod table;
+pub mod idt;
+
+#[repr(usize)]
+#[derive(PartialEq, Clone, Copy)]
+pub enum Interrupts {
+ NONE,
+ PAGE_FAULT,
+ DOUBLE_FAULT,
+ NOT_PRESENT,
+ BREAKPOINT,
+}
diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs
index 52d41ed..8ab660d 100644
--- a/kernel/src/lib.rs
+++ b/kernel/src/lib.rs
@@ -32,5 +32,5 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
pub fn init() {
interrupts::gdt::init();
- interrupts::table::init();
+ interrupts::idt::init();
}
diff --git a/kernel/tests/int3.rs b/kernel/tests/int3.rs
index 771c17d..f4e2116 100644
--- a/kernel/tests/int3.rs
+++ b/kernel/tests/int3.rs
@@ -1,28 +1,26 @@
#![no_main]
#![feature(compiler_builtins_lib)]
-#![feature(custom_test_frameworks)]
#![feature(abi_x86_interrupt)]
#![feature(panic_info_message)]
-#![test_runner(kernel::testing::serial_test_runner)]
-#![reexport_test_harness_main = "test_main"]
#![no_std]
use kernel;
+use kernel::interrupts;
+use kernel::interrupts::exceptions;
use kernel::io::qemu;
#[no_mangle]
extern "C" fn _start() -> ! {
kernel::init();
- test_main();
+ unsafe {
+ exceptions::expect_fault(interrupts::Interrupts::BREAKPOINT);
+ }
+ x86_64::instructions::interrupts::int3();
+ panic!("BREAKPOINT not caught");
loop {}
}
-#[test_case]
-fn breakpoint() {
- x86_64::instructions::interrupts::int3();
-}
-
#[cfg(test)]
#[panic_handler]
#[no_mangle]
diff --git a/kernel/tests/stack_overflow.rs b/kernel/tests/stack_overflow.rs
index 677a9e1..dc53537 100644
--- a/kernel/tests/stack_overflow.rs
+++ b/kernel/tests/stack_overflow.rs
@@ -1,25 +1,28 @@
#![no_main]
#![feature(compiler_builtins_lib)]
-#![feature(custom_test_frameworks)]
#![feature(abi_x86_interrupt)]
#![feature(panic_info_message)]
-#![test_runner(kernel::testing::serial_test_runner_panic)]
#![no_std]
use core::fmt::Write;
use kernel;
+use kernel::interrupts;
+use kernel::interrupts::exceptions;
use kernel::io::qemu;
#[no_mangle]
extern "C" fn _start() -> ! {
kernel::init();
+ unsafe {
+ exceptions::expect_fault(interrupts::Interrupts::PAGE_FAULT);
+ }
_loop(0);
-
+ panic!("PAGE_FAULT not caught");
loop {}
}
fn _loop(i: u128) -> u128 {
- if i > 1u128 << 83 {
+ if i > 1u128 << 120 {
return i;
}
let n = i;