Skip to content

Commit a7de595

Browse files
committed
Improve Cross-Doc links
Signed-off-by: Joe Richey <[email protected]>
1 parent 40d20e4 commit a7de595

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

src/instructions/segmentation.rs

+15-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
//! Provides functions to read and write segment registers.
22
33
#[cfg(docsrs)]
4-
use crate::structures::gdt::GlobalDescriptorTable;
5-
use crate::{structures::gdt::SegmentSelector, VirtAddr};
4+
use crate::{registers::control::Cr4Flags, structures::gdt::GlobalDescriptorTable};
5+
use crate::{
6+
registers::model_specific::{FsBase, GsBase, Msr},
7+
structures::gdt::SegmentSelector,
8+
VirtAddr,
9+
};
610

711
/// An x86 segment
812
///
@@ -30,17 +34,20 @@ pub trait Segment {
3034
/// still partially used. Only the 64-bit segment base address is used, and this
3135
/// address can be set via the GDT, or by using the `FSGSBASE` instructions.
3236
pub trait Segment64: Segment {
37+
/// MSR containing the segment base. This MSR can be used to set the base
38+
/// when [`CR4.FSGSBASE`][Cr4Flags::FSGSBASE] is not set.
39+
const BASE: Msr;
3340
/// Reads the segment base address
3441
///
3542
/// ## Safety
3643
///
37-
/// If `CR4.FSGSBASE` is not set, this instruction will throw a `#UD`.
44+
/// If [`CR4.FSGSBASE`][Cr4Flags::FSGSBASE] is not set, this instruction will throw a `#UD`.
3845
unsafe fn read_base() -> VirtAddr;
3946
/// Writes the segment base address
4047
///
4148
/// ## Safety
4249
///
43-
/// If `CR4.FSGSBASE` is not set, this instruction will throw a `#UD`.
50+
/// If [`CR4.FSGSBASE`][Cr4Flags::FSGSBASE] is not set, this instruction will throw a `#UD`.
4451
///
4552
/// The caller must ensure that this write operation has no unsafe side
4653
/// effects, as the segment base address might be in use.
@@ -81,8 +88,9 @@ macro_rules! segment_impl {
8188
}
8289

8390
macro_rules! segment64_impl {
84-
($type:ty, $name:literal, $asm_rd:ident, $asm_wr:ident) => {
91+
($type:ty, $name:literal, $base:ty, $asm_rd:ident, $asm_wr:ident) => {
8592
impl Segment64 for $type {
93+
const BASE: Msr = <$base>::MSR;
8694
unsafe fn read_base() -> VirtAddr {
8795
#[cfg(feature = "inline_asm")]
8896
{
@@ -165,7 +173,7 @@ segment_impl!(ES, "es", x86_64_asm_get_es, x86_64_asm_load_es);
165173
#[derive(Debug)]
166174
pub struct FS;
167175
segment_impl!(FS, "fs", x86_64_asm_get_fs, x86_64_asm_load_fs);
168-
segment64_impl!(FS, "fs", x86_64_asm_rdfsbase, x86_64_asm_wrfsbase);
176+
segment64_impl!(FS, "fs", FsBase, x86_64_asm_rdfsbase, x86_64_asm_wrfsbase);
169177

170178
/// GS Segment
171179
///
@@ -174,7 +182,7 @@ segment64_impl!(FS, "fs", x86_64_asm_rdfsbase, x86_64_asm_wrfsbase);
174182
#[derive(Debug)]
175183
pub struct GS;
176184
segment_impl!(GS, "gs", x86_64_asm_get_gs, x86_64_asm_load_gs);
177-
segment64_impl!(GS, "gs", x86_64_asm_rdgsbase, x86_64_asm_wrgsbase);
185+
segment64_impl!(GS, "gs", GsBase, x86_64_asm_rdgsbase, x86_64_asm_wrgsbase);
178186

179187
impl GS {
180188
/// Swap `KernelGsBase` MSR and `GsBase` MSR.

src/registers/model_specific.rs

+24-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
//! Functions to read and write model specific registers.
22
3+
#[cfg(docsrs)]
4+
use crate::{
5+
instructions::segmentation::{Segment64, FS, GS},
6+
registers::control::Cr4Flags,
7+
};
8+
39
use bitflags::bitflags;
410

511
/// A model specific register.
@@ -18,15 +24,19 @@ impl Msr {
1824
#[derive(Debug)]
1925
pub struct Efer;
2026

21-
/// FS.Base Model Specific Register.
27+
/// [FS].Base Model Specific Register.
2228
#[derive(Debug)]
2329
pub struct FsBase;
2430

25-
/// GS.Base Model Specific Register.
31+
/// [GS].Base Model Specific Register.
32+
///
33+
/// [`GS::swap`] swaps this register with [`KernelGsBase`].
2634
#[derive(Debug)]
2735
pub struct GsBase;
2836

2937
/// KernelGsBase Model Specific Register.
38+
///
39+
/// [`GS::swap`] swaps this register with [`GsBase`].
3040
#[derive(Debug)]
3141
pub struct KernelGsBase;
3242

@@ -223,12 +233,18 @@ mod x86_64 {
223233

224234
impl FsBase {
225235
/// Read the current FsBase register.
236+
///
237+
/// If [`CR4.FSGSBASE`][Cr4Flags::FSGSBASE] is set, the more efficient
238+
/// [`FS::read_base`] can be used instead.
226239
#[inline]
227240
pub fn read() -> VirtAddr {
228241
VirtAddr::new(unsafe { Self::MSR.read() })
229242
}
230243

231244
/// Write a given virtual address to the FS.Base register.
245+
///
246+
/// If [`CR4.FSGSBASE`][Cr4Flags::FSGSBASE] is set, the more efficient
247+
/// [`FS::write_base`] can be used instead.
232248
#[inline]
233249
pub fn write(address: VirtAddr) {
234250
let mut msr = Self::MSR;
@@ -238,12 +254,18 @@ mod x86_64 {
238254

239255
impl GsBase {
240256
/// Read the current GsBase register.
257+
///
258+
/// If [`CR4.FSGSBASE`][Cr4Flags::FSGSBASE] is set, the more efficient
259+
/// [`GS::read_base`] can be used instead.
241260
#[inline]
242261
pub fn read() -> VirtAddr {
243262
VirtAddr::new(unsafe { Self::MSR.read() })
244263
}
245264

246265
/// Write a given virtual address to the GS.Base register.
266+
///
267+
/// If [`CR4.FSGSBASE`][Cr4Flags::FSGSBASE] is set, the more efficient
268+
/// [`GS::write_base`] can be used instead.
247269
#[inline]
248270
pub fn write(address: VirtAddr) {
249271
let mut msr = Self::MSR;

0 commit comments

Comments
 (0)