Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce new diverging handler functions for exceptions classified as "abort" #109

Merged
merged 4 commits into from Dec 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions Changelog.md
@@ -1,6 +1,7 @@
- **Breaking:** Replace `ux` dependency with custom wrapper structs ([#91](https://github.com/rust-osdev/x86_64/pull/91))
- **Breaking:** Add new UnsafePhysFrame type and use it in Mapper::map_to ([#89](https://github.com/rust-osdev/x86_64/pull/89))
- **Breaking:** Rename divide_by_zero field of interrupt descriptor table to divide_error ([#108](https://github.com/rust-osdev/x86_64/pull/108))
- **Breaking:** Introduce new diverging handler functions for double faults and machine check exceptions ([#109](https://github.com/rust-osdev/x86_64/pull/109))
- _Possibly Breaking:_ Make Mapper trait object safe by adding `Self: Sized` bounds on generic functions ([#84](https://github.com/rust-osdev/x86_64/pull/84))


Expand Down
15 changes: 11 additions & 4 deletions src/structures/idt.rs
Expand Up @@ -198,7 +198,7 @@ pub struct InterruptDescriptorTable {
/// and the program cannot be restarted.
///
/// The vector number of the `#DF` exception is 8.
pub double_fault: Entry<HandlerFuncWithErrCode>,
pub double_fault: Entry<DivergingHandlerFuncWithErrCode>,

/// This interrupt vector is reserved. It is for a discontinued exception originally used
/// by processors that supported external x87-instruction coprocessors. On those processors,
Expand Down Expand Up @@ -308,7 +308,7 @@ pub struct InterruptDescriptorTable {
/// There is no reliable way to restart the program.
///
/// The vector number of the `#MC` exception is 18.
pub machine_check: Entry<HandlerFunc>,
pub machine_check: Entry<DivergingHandlerFunc>,

/// The SIMD Floating-Point Exception (`#XF`) is used to handle unmasked SSE
/// floating-point exceptions. The SSE floating-point exceptions reported by
Expand Down Expand Up @@ -507,14 +507,14 @@ impl Index<usize> for InterruptDescriptorTable {
7 => &self.device_not_available,
9 => &self.coprocessor_segment_overrun,
16 => &self.x87_floating_point,
18 => &self.machine_check,
19 => &self.simd_floating_point,
20 => &self.virtualization,
i @ 32..=255 => &self.interrupts[i - 32],
i @ 15 | i @ 31 | i @ 21..=29 => panic!("entry {} is reserved", i),
i @ 8 | i @ 10..=14 | i @ 17 | i @ 30 => {
panic!("entry {} is an exception with error code", i)
}
i @ 18 => panic!("entry {} is an diverging exception (must not return)", i),
i => panic!("no entry with index {}", i),
}
}
Expand All @@ -537,14 +537,14 @@ impl IndexMut<usize> for InterruptDescriptorTable {
7 => &mut self.device_not_available,
9 => &mut self.coprocessor_segment_overrun,
16 => &mut self.x87_floating_point,
18 => &mut self.machine_check,
19 => &mut self.simd_floating_point,
20 => &mut self.virtualization,
i @ 32..=255 => &mut self.interrupts[i - 32],
i @ 15 | i @ 31 | i @ 21..=29 => panic!("entry {} is reserved", i),
i @ 8 | i @ 10..=14 | i @ 17 | i @ 30 => {
panic!("entry {} is an exception with error code", i)
}
i @ 18 => panic!("entry {} is an diverging exception (must not return)", i),
i => panic!("no entry with index {}", i),
}
}
Expand Down Expand Up @@ -574,6 +574,11 @@ pub type HandlerFuncWithErrCode =
/// A page fault handler function that pushes a page fault error code.
pub type PageFaultHandlerFunc =
extern "x86-interrupt" fn(&mut InterruptStackFrame, error_code: PageFaultErrorCode);
/// A handler function that must not return, e.g. for a machine check exception.
pub type DivergingHandlerFunc = extern "x86-interrupt" fn(&mut InterruptStackFrame) -> !;
/// A handler function with an error code that must not return, e.g. for a double fault exception.
pub type DivergingHandlerFuncWithErrCode =
extern "x86-interrupt" fn(&mut InterruptStackFrame, error_code: u64) -> !;

impl<F> Entry<F> {
/// Creates a non-present IDT entry (but sets the must-be-one bits).
Expand Down Expand Up @@ -632,6 +637,8 @@ macro_rules! impl_set_handler_fn {
impl_set_handler_fn!(HandlerFunc);
impl_set_handler_fn!(HandlerFuncWithErrCode);
impl_set_handler_fn!(PageFaultHandlerFunc);
impl_set_handler_fn!(DivergingHandlerFunc);
impl_set_handler_fn!(DivergingHandlerFuncWithErrCode);

/// Represents the options field of an IDT entry.
#[repr(transparent)]
Expand Down
2 changes: 1 addition & 1 deletion testing/tests/double_fault_stack_overflow.rs
Expand Up @@ -54,7 +54,7 @@ pub fn init_test_idt() {
extern "x86-interrupt" fn double_fault_handler(
_stack_frame: &mut InterruptStackFrame,
_error_code: u64,
) {
) -> ! {
serial_println!("[ok]");
exit_qemu(QemuExitCode::Success);
loop {}
Expand Down