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.
3236pub 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
8390macro_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 ) ]
166174pub struct FS ;
167175segment_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 ) ]
175183pub struct GS ;
176184segment_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
179187impl GS {
180188 /// Swap `KernelGsBase` MSR and `GsBase` MSR.
0 commit comments