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

Only enable instructions on x86_64 #483

Merged
merged 2 commits into from
Apr 28, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest, macos-latest, windows-latest]
platform: [ubuntu-latest, macos-12, macos-latest, windows-latest]

runs-on: ${{ matrix.platform }}
timeout-minutes: 15
Expand Down
2 changes: 1 addition & 1 deletion src/instructions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![cfg(feature = "instructions")]
#![cfg(all(feature = "instructions", target_arch = "x86_64"))]

//! Special x86_64 instructions.

Expand Down
2 changes: 1 addition & 1 deletion src/registers/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ bitflags! {
}
}

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
mod x86_64 {
use super::*;
use crate::{
Expand Down
12 changes: 6 additions & 6 deletions src/registers/debug.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Functions to read and write debug registers.

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
use core::arch::asm;
use core::ops::Range;

Expand All @@ -15,11 +15,11 @@ pub trait DebugAddressRegister {
const NUM: DebugAddressRegisterNumber;

/// Reads the current breakpoint address.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
fn read() -> u64;

/// Writes the provided breakpoint address.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
fn write(addr: u64);
}

Expand All @@ -34,7 +34,7 @@ macro_rules! debug_address_register {
impl DebugAddressRegister for $Dr {
const NUM: DebugAddressRegisterNumber = DebugAddressRegisterNumber::$Dr;

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[inline]
fn read() -> u64 {
let addr;
Expand All @@ -44,7 +44,7 @@ macro_rules! debug_address_register {
addr
}

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[inline]
fn write(addr: u64) {
unsafe {
Expand Down Expand Up @@ -437,7 +437,7 @@ impl Dr7Value {
#[derive(Debug)]
pub struct Dr7;

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
mod x86_64 {
use super::*;

Expand Down
2 changes: 1 addition & 1 deletion src/registers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ pub mod rflags;
pub mod segmentation;
pub mod xcontrol;

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
pub use crate::instructions::read_rip;
11 changes: 7 additions & 4 deletions src/registers/model_specific.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use bitflags::bitflags;
use crate::registers::segmentation::{FS, GS};

/// A model specific register.
#[cfg_attr(not(feature = "instructions"), allow(dead_code))] // FIXME
#[cfg_attr(
not(all(feature = "instructions", target_arch = "x86_64")),
allow(dead_code)
)] // FIXME
#[derive(Debug)]
pub struct Msr(u32);

Expand All @@ -29,7 +32,7 @@ pub struct FsBase;
/// [GS].Base Model Specific Register.
///
#[cfg_attr(
feature = "instructions",
all(feature = "instructions", target_arch = "x86_64"),
doc = "[`GS::swap`] swaps this register with [`KernelGsBase`]."
)]
#[derive(Debug)]
Expand All @@ -38,7 +41,7 @@ pub struct GsBase;
/// KernelGsBase Model Specific Register.
///
#[cfg_attr(
feature = "instructions",
all(feature = "instructions", target_arch = "x86_64"),
doc = "[`GS::swap`] swaps this register with [`GsBase`]."
)]
#[derive(Debug)]
Expand Down Expand Up @@ -158,7 +161,7 @@ bitflags! {
}
}

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
mod x86_64 {
use super::*;
use crate::addr::VirtAddr;
Expand Down
4 changes: 2 additions & 2 deletions src/registers/mxcsr.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Functions to read and write MXCSR register.

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
pub use self::x86_64::*;

use bitflags::bitflags;
Expand Down Expand Up @@ -60,7 +60,7 @@ impl Default for MxCsr {
}
}

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
mod x86_64 {
use super::*;
use core::arch::asm;
Expand Down
4 changes: 2 additions & 2 deletions src/registers/rflags.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Processor state stored in the RFLAGS register.

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
pub use self::x86_64::*;

use bitflags::bitflags;
Expand Down Expand Up @@ -64,7 +64,7 @@ bitflags! {
}
}

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
mod x86_64 {
use super::*;
use core::arch::asm;
Expand Down
2 changes: 1 addition & 1 deletion src/registers/xcontrol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ bitflags! {
}
}

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
mod x86_64 {
use super::*;
use core::arch::asm;
Expand Down
21 changes: 12 additions & 9 deletions src/structures/gdt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ use core::fmt;
#[cfg(doc)]
use crate::registers::segmentation::{Segment, CS, SS};

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
use core::sync::atomic::{AtomicU64 as EntryValue, Ordering};
#[cfg(not(feature = "instructions"))]
#[cfg(not(all(feature = "instructions", target_arch = "x86_64")))]
use u64 as EntryValue;

/// 8-byte entry in a descriptor table.
Expand All @@ -28,7 +28,7 @@ pub struct Entry(EntryValue);
impl Entry {
// Create a new Entry from a raw value.
const fn new(raw: u64) -> Self {
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
let raw = EntryValue::new(raw);
Self(raw)
}
Expand All @@ -37,9 +37,9 @@ impl Entry {
/// bits may correspond to those in [`DescriptorFlags`].
pub fn raw(&self) -> u64 {
// TODO: Make this const fn when AtomicU64::load is const.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
let raw = self.0.load(Ordering::SeqCst);
#[cfg(not(feature = "instructions"))]
#[cfg(not(all(feature = "instructions", target_arch = "x86_64")))]
let raw = self.0;
raw
}
Expand Down Expand Up @@ -153,7 +153,10 @@ impl<const MAX: usize> GlobalDescriptorTable<MAX> {
/// * the provided slice has more than `MAX` entries
/// * the provided slice is empty
/// * the first entry is not zero
#[cfg_attr(not(feature = "instructions"), allow(rustdoc::broken_intra_doc_links))]
#[cfg_attr(
not(all(feature = "instructions", target_arch = "x86_64")),
allow(rustdoc::broken_intra_doc_links)
)]
#[inline]
pub const fn from_raw_entries(slice: &[u64]) -> Self {
let len = slice.len();
Expand Down Expand Up @@ -215,7 +218,7 @@ impl<const MAX: usize> GlobalDescriptorTable<MAX> {
/// segment registers; you **must** (re)load them yourself using [the appropriate
/// functions](crate::instructions::segmentation):
/// [`SS::set_reg()`] and [`CS::set_reg()`].
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[inline]
pub fn load(&'static self) {
// SAFETY: static lifetime ensures no modification after loading.
Expand All @@ -233,7 +236,7 @@ impl<const MAX: usize> GlobalDescriptorTable<MAX> {
/// this means its up to the user to ensure that there will be no modifications
/// after loading and that the GDT will live for as long as it's loaded.
///
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[inline]
pub unsafe fn load_unsafe(&self) {
use crate::instructions::tables::lgdt;
Expand Down Expand Up @@ -261,7 +264,7 @@ impl<const MAX: usize> GlobalDescriptorTable<MAX> {

/// Creates the descriptor pointer for this table. This pointer can only be
/// safely used if the table is never modified or destroyed while in use.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
fn pointer(&self) -> super::DescriptorTablePointer {
super::DescriptorTablePointer {
base: crate::VirtAddr::new(self.table.as_ptr() as u64),
Expand Down
36 changes: 26 additions & 10 deletions src/structures/idt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ impl InterruptDescriptorTable {
}

/// Loads the IDT in the CPU using the `lidt` command.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[inline]
pub fn load(&'static self) {
unsafe { self.load_unsafe() }
Expand All @@ -505,7 +505,7 @@ impl InterruptDescriptorTable {
/// - `self` always stays at the same memory location. It is recommended to wrap it in
/// a `Box`.
///
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[inline]
pub unsafe fn load_unsafe(&self) {
use crate::instructions::tables::lidt;
Expand All @@ -516,7 +516,7 @@ impl InterruptDescriptorTable {

/// Creates the descriptor pointer for this table. This pointer can only be
/// safely used if the table is never modified or destroyed while in use.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
fn pointer(&self) -> crate::structures::DescriptorTablePointer {
use core::mem::size_of;
crate::structures::DescriptorTablePointer {
Expand Down Expand Up @@ -792,7 +792,7 @@ impl<F> Entry<F> {
///
/// The caller must ensure that `addr` is the address of a valid interrupt handler function,
/// and the signature of such a function is correct for the entry type.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[inline]
pub unsafe fn set_handler_addr(&mut self, addr: VirtAddr) -> &mut EntryOptions {
use crate::instructions::segmentation::{Segment, CS};
Expand Down Expand Up @@ -821,7 +821,7 @@ impl<F> Entry<F> {
}
}

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
impl<F: HandlerFuncType> Entry<F> {
/// Sets the handler function for the IDT entry and sets the following defaults:
/// - The code selector is the code segment currently active in the CPU
Expand Down Expand Up @@ -1093,7 +1093,7 @@ impl InterruptStackFrameValue {
/// CS and SS register can all cause undefined behaviour when done incorrectly.
///
#[inline(always)]
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
pub unsafe fn iretq(&self) -> ! {
unsafe {
core::arch::asm!(
Expand Down Expand Up @@ -1328,7 +1328,11 @@ pub enum ExceptionVector {
Security = 0x1E,
}

#[cfg(all(feature = "instructions", feature = "abi_x86_interrupt"))]
#[cfg(all(
feature = "instructions",
feature = "abi_x86_interrupt",
target_arch = "x86_64"
))]
#[macro_export]
/// Set a general handler in an [`InterruptDescriptorTable`].
/// ```
Expand Down Expand Up @@ -1390,7 +1394,11 @@ macro_rules! set_general_handler {
}};
}

#[cfg(all(feature = "instructions", feature = "abi_x86_interrupt"))]
#[cfg(all(
feature = "instructions",
feature = "abi_x86_interrupt",
target_arch = "x86_64"
))]
#[macro_export]
#[doc(hidden)]
/// We can't loop in macros, but we can use recursion.
Expand All @@ -1412,7 +1420,11 @@ macro_rules! set_general_handler_recursive_bits {
};
}

#[cfg(all(feature = "instructions", feature = "abi_x86_interrupt"))]
#[cfg(all(
feature = "instructions",
feature = "abi_x86_interrupt",
target_arch = "x86_64"
))]
#[macro_export]
#[doc(hidden)]
macro_rules! set_general_handler_entry {
Expand Down Expand Up @@ -1575,7 +1587,11 @@ mod test {
assert_eq!(size_of::<InterruptStackFrameValue>(), 40);
}

#[cfg(all(feature = "instructions", feature = "abi_x86_interrupt"))]
#[cfg(all(
feature = "instructions",
feature = "abi_x86_interrupt",
target_arch = "x86_64"
))]
// there seems to be a bug in LLVM that causes rustc to crash on windows when compiling this test:
// https://github.com/rust-osdev/x86_64/pull/285#issuecomment-962642984
#[cfg(not(windows))]
Expand Down
Loading