Skip to content

Commit 27b3917

Browse files
authored
Merge pull request #242 from rust-osdev/x86-interrupt-cc
Fixes for `x86-interrupt` calling convention
2 parents 9cda08b + 1490f1b commit 27b3917

File tree

5 files changed

+23
-11
lines changed

5 files changed

+23
-11
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ license = "MIT/Apache-2.0"
2222
name = "x86_64"
2323
readme = "README.md"
2424
repository = "https://github.com/rust-osdev/x86_64"
25-
version = "0.13.5"
25+
version = "0.14.0"
2626
edition = "2018"
2727

2828
[dependencies]
2929
bit_field = "0.9.0"
3030
bitflags = "1.0.4"
31+
volatile = "0.4.4"
3132

3233
[build-dependencies]
3334
cc = { version = "1.0.37", optional = true }

Changelog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Unreleased
22

3+
# 0.14.0 – 2021-04-11
4+
5+
- **Breaking:** Take the interrupt stack frame by value (not by reference) [#242](https://github.com/rust-osdev/x86_64/pull/242)
6+
- **Breaking:** Change `InterruptStackFrame::as_mut` to return a `Volatile<_>` wrapper [#242](https://github.com/rust-osdev/x86_64/pull/242)
7+
38
# 0.13.5 – 2021-04-01
49

510
- Add support for `XCR0` register ([#239](https://github.com/rust-osdev/x86_64/pull/239))

src/structures/idt.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use core::fmt;
1616
use core::marker::PhantomData;
1717
use core::ops::Bound::{Excluded, Included, Unbounded};
1818
use core::ops::{Deref, Index, IndexMut, RangeBounds};
19+
use volatile::Volatile;
1920

2021
/// An Interrupt Descriptor Table with 256 entries.
2122
///
@@ -572,18 +573,17 @@ pub struct Entry<F> {
572573
}
573574

574575
/// A handler function for an interrupt or an exception without error code.
575-
pub type HandlerFunc = extern "x86-interrupt" fn(&mut InterruptStackFrame);
576+
pub type HandlerFunc = extern "x86-interrupt" fn(InterruptStackFrame);
576577
/// A handler function for an exception that pushes an error code.
577-
pub type HandlerFuncWithErrCode =
578-
extern "x86-interrupt" fn(&mut InterruptStackFrame, error_code: u64);
578+
pub type HandlerFuncWithErrCode = extern "x86-interrupt" fn(InterruptStackFrame, error_code: u64);
579579
/// A page fault handler function that pushes a page fault error code.
580580
pub type PageFaultHandlerFunc =
581-
extern "x86-interrupt" fn(&mut InterruptStackFrame, error_code: PageFaultErrorCode);
581+
extern "x86-interrupt" fn(InterruptStackFrame, error_code: PageFaultErrorCode);
582582
/// A handler function that must not return, e.g. for a machine check exception.
583-
pub type DivergingHandlerFunc = extern "x86-interrupt" fn(&mut InterruptStackFrame) -> !;
583+
pub type DivergingHandlerFunc = extern "x86-interrupt" fn(InterruptStackFrame) -> !;
584584
/// A handler function with an error code that must not return, e.g. for a double fault exception.
585585
pub type DivergingHandlerFuncWithErrCode =
586-
extern "x86-interrupt" fn(&mut InterruptStackFrame, error_code: u64) -> !;
586+
extern "x86-interrupt" fn(InterruptStackFrame, error_code: u64) -> !;
587587

588588
impl<F> Entry<F> {
589589
/// Creates a non-present IDT entry (but sets the must-be-one bits).
@@ -721,16 +721,22 @@ pub struct InterruptStackFrame {
721721
impl InterruptStackFrame {
722722
/// Gives mutable access to the contents of the interrupt stack frame.
723723
///
724+
/// The `Volatile` wrapper is used because LLVM optimizations remove non-volatile
725+
/// modifications of the interrupt stack frame.
726+
///
724727
/// ## Safety
725728
///
726729
/// This function is unsafe since modifying the content of the interrupt stack frame
727730
/// can easily lead to undefined behavior. For example, by writing an invalid value to
728731
/// the instruction pointer field, the CPU can jump to arbitrary code at the end of the
729732
/// interrupt.
733+
///
734+
/// Also, it is not fully clear yet whether modifications of the interrupt stack frame are
735+
/// officially supported by LLVM's x86 interrupt calling convention.
730736
#[allow(clippy::should_implement_trait)]
731737
#[inline]
732-
pub unsafe fn as_mut(&mut self) -> &mut InterruptStackFrameValue {
733-
&mut self.value
738+
pub unsafe fn as_mut(&mut self) -> Volatile<&mut InterruptStackFrameValue> {
739+
Volatile::new(&mut self.value)
734740
}
735741
}
736742

testing/tests/breakpoint_exception.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@ pub fn init_test_idt() {
5757
TEST_IDT.load();
5858
}
5959

60-
extern "x86-interrupt" fn breakpoint_handler(_stack_frame: &mut InterruptStackFrame) {
60+
extern "x86-interrupt" fn breakpoint_handler(_stack_frame: InterruptStackFrame) {
6161
BREAKPOINT_HANDLER_CALLED.fetch_add(1, Ordering::SeqCst);
6262
}

testing/tests/double_fault_stack_overflow.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub fn init_test_idt() {
5252
}
5353

5454
extern "x86-interrupt" fn double_fault_handler(
55-
_stack_frame: &mut InterruptStackFrame,
55+
_stack_frame: InterruptStackFrame,
5656
_error_code: u64,
5757
) -> ! {
5858
serial_println!("[ok]");

0 commit comments

Comments
 (0)