aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--build.rs2
-rw-r--r--examples/check_caps.rs1
-rw-r--r--examples/long_mode.rs1
-rw-r--r--src/x86_64.rs309
4 files changed, 160 insertions, 153 deletions
diff --git a/build.rs b/build.rs
index fa1bef2..c710dfc 100644
--- a/build.rs
+++ b/build.rs
@@ -1,6 +1,6 @@
use std::env;
-use std::path::Path;
use std::io::Write;
+use std::path::Path;
fn main() {
// Generate KVM constants from the system header <linux/kvm.h>.
diff --git a/examples/check_caps.rs b/examples/check_caps.rs
index e4baf83..b9e1125 100644
--- a/examples/check_caps.rs
+++ b/examples/check_caps.rs
@@ -2,6 +2,7 @@ use kvm_rs::cap::CapBool::*;
use kvm_rs::cap::CapInt::*;
use kvm_rs::kvm::Kvm;
+#[rustfmt::skip]
fn main() -> std::io::Result<()> {
let kvm = Kvm::new()?;
diff --git a/examples/long_mode.rs b/examples/long_mode.rs
index 668364f..0696ae4 100644
--- a/examples/long_mode.rs
+++ b/examples/long_mode.rs
@@ -57,6 +57,7 @@ fn setup_long_mode_segments(sregs: &mut kvm_sys::kvm_sregs) {
data_seg(&mut sregs.es);
}
+#[rustfmt::skip]
fn setup_long_mode_4level_paging(mem: &mut UserMem) -> PhysAddr {
assert_eq!(0x8000, mem.as_ref().len());
diff --git a/src/x86_64.rs b/src/x86_64.rs
index c16a6ad..ac153e9 100644
--- a/src/x86_64.rs
+++ b/src/x86_64.rs
@@ -1,154 +1,159 @@
//! `x86_64` flags and bitfields.
-/* Rflags Register */
-
-/// Carry flag.
-pub const RFLAGS_CF: u64 = 1 << 0;
-/// Parity flag.
-pub const RFLAGS_PF: u64 = 1 << 2;
-/// Adjust flag.
-pub const RFLAGS_AF: u64 = 1 << 4;
-/// Zero flag.
-pub const RFLAGS_ZF: u64 = 1 << 6;
-/// Sign flag.
-pub const RFLAGS_SF: u64 = 1 << 7;
-/// Sign flag.
-pub const RFLAGS_IF: u64 = 1 << 9;
-/// Direction flag.
-pub const RFLAGS_DF: u64 = 1 << 10;
-/// Overflow flag.
-pub const RFLAGS_OF: u64 = 1 << 11;
-/// I/O privilege level.
-pub const RFLAGS_IOPL: u64 = 0b11 << 12;
-/// Alignment check.
-pub const RFLAGS_AC: u64 = 1 << 18;
-
-pub const fn rflags_cf(r: u64) -> u64 { (r & RFLAGS_CF) >> 0 }
-pub const fn rflags_pf(r: u64) -> u64 { (r & RFLAGS_PF) >> 2 }
-pub const fn rflags_af(r: u64) -> u64 { (r & RFLAGS_AF) >> 4 }
-pub const fn rflags_zf(r: u64) -> u64 { (r & RFLAGS_ZF) >> 6 }
-pub const fn rflags_sf(r: u64) -> u64 { (r & RFLAGS_SF) >> 7 }
-pub const fn rflags_if(r: u64) -> u64 { (r & RFLAGS_IF) >> 9 }
-pub const fn rflags_df(r: u64) -> u64 { (r & RFLAGS_DF) >> 10 }
-pub const fn rflags_of(r: u64) -> u64 { (r & RFLAGS_OF) >> 11 }
-pub const fn rflags_iopl(r: u64) -> u64 { (r & RFLAGS_IOPL) >> 12 }
-pub const fn rflags_ac(r: u64) -> u64 { (r & RFLAGS_AC) >> 18 }
-
-/* Segment Selector */
-
-/// Requested privilege level.
-///
-/// Privilege level of the segment selector, where `0` is the most privileged mode and `3` the
-/// least.
-pub const SEG_SELECTOR_RPL : u16 = 0b11 << 0;
-/// Table indicator.
-///
-/// | TI | Table |
-/// |----|-------|
-/// | 0 | GDT |
-/// | 1 | LDT |
-pub const SEG_SELECTOR_TI : u16 = 1 << 2;
-/// Table index.
-///
-/// Index into the `GDT` or `LDT` table to select the segment descriptor. `GDT.base + 8 * index`
-/// gives the address of the segment descriptor (times `8` because every segment descriptor is `8
-/// byte`).
-pub const SEG_SELECTOR_INDEX : u16 = 0x1fff << 3;
-
-pub const fn seg_selector_rpl(s : u16) -> u16 { (s & SEG_SELECTOR_RPL) >> 0 }
-pub const fn seg_selector_ti(s : u16) -> u16 { (s & SEG_SELECTOR_TI) >> 2 }
-pub const fn seg_selector_index(s : u16) -> u16 { (s & SEG_SELECTOR_INDEX) >> 3 }
-
-/* Control Register CR0 (operation mode & state of the processor) */
-
-/// Protection Enable.
-///
-/// Enables `protected mode` when set and `real-address mode` when cleared. This enables
-/// `segment-level protection` not paging.
-pub const CR0_PE: u64 = 1 << 0;
-/// Monitor Coprocessor.
-pub const CR0_MP: u64 = 1 << 1;
-/// Emulation.
-///
-/// When set indicates the process does not have a FPU. FPU instructions will generate an exception
-/// that software can emulate the instruction.
-pub const CR0_EM: u64 = 1 << 2;
-/// Task Switched.
-pub const CR0_TS: u64 = 1 << 3;
-/// Extension Type.
-pub const CR0_ET: u64 = 1 << 4;
-/// Numeric Error.
-pub const CR0_NE: u64 = 1 << 5;
-/// Write Protect.
-///
-/// When set supervisor-level procedures can't write to read-only pages.
-pub const CR0_WP: u64 = 1 << 16;
-/// Alignment Mask.
-///
-/// Enables alignment check for `CPL=3`, check is only done if the [AC
-/// bit](crate::x86_64::RFLAGS_AC) of the `rflags` register ist set.
-pub const CR0_AM: u64 = 1 << 18;
-/// Not Write-Torugh.
-pub const CR0_NW: u64 = 1 << 29;
-/// Cachine disable.
-pub const CR0_CD: u64 = 1 << 30;
-/// Paging.
-///
-/// Enables paging when set, requires [CR0_PE](crate::x86_64::CR0_PE) to be set as well.
-pub const CR0_PG: u64 = 1 << 31;
-
-/* Control Register CR3 (paging information)
- *
- * Holds the physical base address of the first paging structure. The 12 lower bytes of the base
- * address are assumed to be 0 and hence the first paging structure must be aligned to a 4K
- * boundary.
- */
-
-/// Mask for physical base address of paging structure.
-pub const CR3_PAGE_BASE_MASK: u64 = 0xffff_ffff_ffff_0000;
-
-/// Page-level Write-Through.
-pub const CR3_PWT: u64 = 1 << 3;
-/// Page-level Cache Disable.
-pub const CR3_PCD: u64 = 1 << 4;
-
-/* Control Register CR4 (flags for arch extenstions processor capabilities) */
-
-/// Physical Address Extenstion.
-///
-/// When set enables paging to produce physicall addresses with more than 32 bits. Required before
-/// entering `long mode`.
-pub const CR4_PAE: u64 = 1 << 5;
-/// 57-bit Linear Addresses.
-///
-/// When set in `long mode` enables `5-level` paging to translate `57-bit` linear addresses. When
-/// cleared use `4-level` paging to translate `48-bit` linear addresses.
-pub const CR4_LA57: u64 = 1 << 5;
-
-/* Extended Feature Enable Register (EFER) */
-
-/// Extended Feature Enable Register MSR number.
-///
-/// MSR number used with the [`rdmsr`][msr] and [`wrmsr`][msr] instructions to read/write the
-/// `EFER` model specific register.
-///
-/// [msr]: https://johannst.github.io/notes/arch/x86_64.html#model-specific-register-msr
-pub const MSR_EFER: u64 = 0xc000_0080;
-
-/// Long Mode Enable.
-///
-/// When set enables long mode operations.
-pub const EFER_LME: u64 = 1 << 8;
-/// Long Mode Active (readonly).
-///
-/// When set indicates long mode is active.
-pub const EFER_LMA: u64 = 1 << 10;
-
-/* Paging */
-
-/// Page entry present.
-pub const PAGE_ENTRY_PRESENT : u64 = 1 << 0;
-/// Page region read/write.
-///
-/// If set, region reference by paging entry is writeable.
-pub const PAGE_RENTRY_RW : u64 = 1 << 1;
+pub use x86_64::*;
+
+#[rustfmt::skip]
+mod x86_64 {
+ /* Rflags Register */
+
+ /// Carry flag.
+ pub const RFLAGS_CF: u64 = 1 << 0;
+ /// Parity flag.
+ pub const RFLAGS_PF: u64 = 1 << 2;
+ /// Adjust flag.
+ pub const RFLAGS_AF: u64 = 1 << 4;
+ /// Zero flag.
+ pub const RFLAGS_ZF: u64 = 1 << 6;
+ /// Sign flag.
+ pub const RFLAGS_SF: u64 = 1 << 7;
+ /// Sign flag.
+ pub const RFLAGS_IF: u64 = 1 << 9;
+ /// Direction flag.
+ pub const RFLAGS_DF: u64 = 1 << 10;
+ /// Overflow flag.
+ pub const RFLAGS_OF: u64 = 1 << 11;
+ /// I/O privilege level.
+ pub const RFLAGS_IOPL: u64 = 0b11 << 12;
+ /// Alignment check.
+ pub const RFLAGS_AC: u64 = 1 << 18;
+
+ pub const fn rflags_cf(r: u64) -> u64 { (r & RFLAGS_CF) >> 0 }
+ pub const fn rflags_pf(r: u64) -> u64 { (r & RFLAGS_PF) >> 2 }
+ pub const fn rflags_af(r: u64) -> u64 { (r & RFLAGS_AF) >> 4 }
+ pub const fn rflags_zf(r: u64) -> u64 { (r & RFLAGS_ZF) >> 6 }
+ pub const fn rflags_sf(r: u64) -> u64 { (r & RFLAGS_SF) >> 7 }
+ pub const fn rflags_if(r: u64) -> u64 { (r & RFLAGS_IF) >> 9 }
+ pub const fn rflags_df(r: u64) -> u64 { (r & RFLAGS_DF) >> 10 }
+ pub const fn rflags_of(r: u64) -> u64 { (r & RFLAGS_OF) >> 11 }
+ pub const fn rflags_iopl(r: u64) -> u64 { (r & RFLAGS_IOPL) >> 12 }
+ pub const fn rflags_ac(r: u64) -> u64 { (r & RFLAGS_AC) >> 18 }
+
+ /* Segment Selector */
+
+ /// Requested privilege level.
+ ///
+ /// Privilege level of the segment selector, where `0` is the most privileged mode and `3` the
+ /// least.
+ pub const SEG_SELECTOR_RPL: u16 = 0b11 << 0;
+ /// Table indicator.
+ ///
+ /// | TI | Table |
+ /// |----|-------|
+ /// | 0 | GDT |
+ /// | 1 | LDT |
+ pub const SEG_SELECTOR_TI: u16 = 1 << 2;
+ /// Table index.
+ ///
+ /// Index into the `GDT` or `LDT` table to select the segment descriptor. `GDT.base + 8 * index`
+ /// gives the address of the segment descriptor (times `8` because every segment descriptor is `8
+ /// byte`).
+ pub const SEG_SELECTOR_INDEX: u16 = 0x1fff << 3;
+
+ pub const fn seg_selector_rpl(s: u16) -> u16 { (s & SEG_SELECTOR_RPL) >> 0 }
+ pub const fn seg_selector_ti(s: u16) -> u16 { (s & SEG_SELECTOR_TI) >> 2 }
+ pub const fn seg_selector_index(s: u16) -> u16 { (s & SEG_SELECTOR_INDEX) >> 3 }
+
+ /* Control Register CR0 (operation mode & state of the processor) */
+
+ /// Protection Enable.
+ ///
+ /// Enables `protected mode` when set and `real-address mode` when cleared. This enables
+ /// `segment-level protection` not paging.
+ pub const CR0_PE: u64 = 1 << 0;
+ /// Monitor Coprocessor.
+ pub const CR0_MP: u64 = 1 << 1;
+ /// Emulation.
+ ///
+ /// When set indicates the process does not have a FPU. FPU instructions will generate an exception
+ /// that software can emulate the instruction.
+ pub const CR0_EM: u64 = 1 << 2;
+ /// Task Switched.
+ pub const CR0_TS: u64 = 1 << 3;
+ /// Extension Type.
+ pub const CR0_ET: u64 = 1 << 4;
+ /// Numeric Error.
+ pub const CR0_NE: u64 = 1 << 5;
+ /// Write Protect.
+ ///
+ /// When set supervisor-level procedures can't write to read-only pages.
+ pub const CR0_WP: u64 = 1 << 16;
+ /// Alignment Mask.
+ ///
+ /// Enables alignment check for `CPL=3`, check is only done if the [AC
+ /// bit](crate::x86_64::RFLAGS_AC) of the `rflags` register ist set.
+ pub const CR0_AM: u64 = 1 << 18;
+ /// Not Write-Torugh.
+ pub const CR0_NW: u64 = 1 << 29;
+ /// Cachine disable.
+ pub const CR0_CD: u64 = 1 << 30;
+ /// Paging.
+ ///
+ /// Enables paging when set, requires [CR0_PE](crate::x86_64::CR0_PE) to be set as well.
+ pub const CR0_PG: u64 = 1 << 31;
+
+ /* Control Register CR3 (paging information)
+ *
+ * Holds the physical base address of the first paging structure. The 12 lower bytes of the base
+ * address are assumed to be 0 and hence the first paging structure must be aligned to a 4K
+ * boundary.
+ */
+
+ /// Mask for physical base address of paging structure.
+ pub const CR3_PAGE_BASE_MASK: u64 = 0xffff_ffff_ffff_0000;
+
+ /// Page-level Write-Through.
+ pub const CR3_PWT: u64 = 1 << 3;
+ /// Page-level Cache Disable.
+ pub const CR3_PCD: u64 = 1 << 4;
+
+ /* Control Register CR4 (flags for arch extenstions processor capabilities) */
+
+ /// Physical Address Extenstion.
+ ///
+ /// When set enables paging to produce physicall addresses with more than 32 bits. Required before
+ /// entering `long mode`.
+ pub const CR4_PAE: u64 = 1 << 5;
+ /// 57-bit Linear Addresses.
+ ///
+ /// When set in `long mode` enables `5-level` paging to translate `57-bit` linear addresses. When
+ /// cleared use `4-level` paging to translate `48-bit` linear addresses.
+ pub const CR4_LA57: u64 = 1 << 5;
+
+ /* Extended Feature Enable Register (EFER) */
+
+ /// Extended Feature Enable Register MSR number.
+ ///
+ /// MSR number used with the [`rdmsr`][msr] and [`wrmsr`][msr] instructions to read/write the
+ /// `EFER` model specific register.
+ ///
+ /// [msr]: https://johannst.github.io/notes/arch/x86_64.html#model-specific-register-msr
+ pub const MSR_EFER: u64 = 0xc000_0080;
+
+ /// Long Mode Enable.
+ ///
+ /// When set enables long mode operations.
+ pub const EFER_LME: u64 = 1 << 8;
+ /// Long Mode Active (readonly).
+ ///
+ /// When set indicates long mode is active.
+ pub const EFER_LMA: u64 = 1 << 10;
+
+ /* Paging */
+
+ /// Page entry present.
+ pub const PAGE_ENTRY_PRESENT: u64 = 1 << 0;
+ /// Page region read/write.
+ ///
+ /// If set, region reference by paging entry is writeable.
+ pub const PAGE_RENTRY_RW: u64 = 1 << 1;
+}