Skip to content

Use SegmentSelector in InterruptStackFrame #263

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

Merged
merged 1 commit into from
Jun 12, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions src/structures/idt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use core::ops::Bound::{Excluded, Included, Unbounded};
use core::ops::{Deref, Index, IndexMut, RangeBounds};
use volatile::Volatile;

use super::gdt::SegmentSelector;

/// An Interrupt Descriptor Table with 256 entries.
///
/// The first 32 entries are used for CPU exceptions. These entries can be either accessed through
Expand Down Expand Up @@ -748,10 +750,8 @@ impl EntryOptions {
/// This wrapper type ensures that no accidental modification of the interrupt stack frame
/// occurs, which can cause undefined behavior (see the [`as_mut`](InterruptStackFrame::as_mut)
/// method for more information).
#[repr(C)]
pub struct InterruptStackFrame {
value: InterruptStackFrameValue,
}
#[repr(transparent)]
pub struct InterruptStackFrame(InterruptStackFrameValue);

impl InterruptStackFrame {
/// Gives mutable access to the contents of the interrupt stack frame.
Expand All @@ -770,7 +770,7 @@ impl InterruptStackFrame {
/// officially supported by LLVM's x86 interrupt calling convention.
#[inline]
pub unsafe fn as_mut(&mut self) -> Volatile<&mut InterruptStackFrameValue> {
Volatile::new(&mut self.value)
Volatile::new(&mut self.0)
}
}

Expand All @@ -779,14 +779,14 @@ impl Deref for InterruptStackFrame {

#[inline]
fn deref(&self) -> &Self::Target {
&self.value
&self.0
}
}

impl fmt::Debug for InterruptStackFrame {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.value.fmt(f)
self.0.fmt(f)
}
}

Expand All @@ -800,14 +800,16 @@ pub struct InterruptStackFrameValue {
/// this value points to the faulting instruction, so that the instruction is restarted on
/// return. See the documentation of the [`InterruptDescriptorTable`] fields for more details.
pub instruction_pointer: VirtAddr,
/// The code segment selector, padded with zeros.
pub code_segment: u64,
/// The code segment selector at the time of the interrupt.
pub code_segment: SegmentSelector,
_reserved1: [u8; 6],
/// The flags register before the interrupt handler was invoked.
pub cpu_flags: u64,
/// The stack pointer at the time of the interrupt.
pub stack_pointer: VirtAddr,
/// The stack segment descriptor at the time of the interrupt (often zero in 64-bit mode).
pub stack_segment: u64,
pub stack_segment: SegmentSelector,
_reserved2: [u8; 6],
}

impl fmt::Debug for InterruptStackFrameValue {
Expand Down Expand Up @@ -866,6 +868,8 @@ mod test {
use core::mem::size_of;
assert_eq!(size_of::<Entry<HandlerFunc>>(), 16);
assert_eq!(size_of::<InterruptDescriptorTable>(), 256 * 16);
assert_eq!(size_of::<InterruptStackFrame>(), 40);
assert_eq!(size_of::<InterruptStackFrameValue>(), 40);
}

#[test]
Expand Down