1
1
//! Provides functions to read and write segment registers.
2
2
3
3
#[ 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
+ } ;
6
10
7
11
/// An x86 segment
8
12
///
@@ -30,17 +34,20 @@ pub trait Segment {
30
34
/// still partially used. Only the 64-bit segment base address is used, and this
31
35
/// address can be set via the GDT, or by using the `FSGSBASE` instructions.
32
36
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 ;
33
40
/// Reads the segment base address
34
41
///
35
42
/// ## Safety
36
43
///
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`.
38
45
unsafe fn read_base ( ) -> VirtAddr ;
39
46
/// Writes the segment base address
40
47
///
41
48
/// ## Safety
42
49
///
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`.
44
51
///
45
52
/// The caller must ensure that this write operation has no unsafe side
46
53
/// effects, as the segment base address might be in use.
@@ -81,8 +88,9 @@ macro_rules! segment_impl {
81
88
}
82
89
83
90
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) => {
85
92
impl Segment64 for $type {
93
+ const BASE : Msr = <$base>:: MSR ;
86
94
unsafe fn read_base( ) -> VirtAddr {
87
95
#[ cfg( feature = "inline_asm" ) ]
88
96
{
@@ -165,7 +173,7 @@ segment_impl!(ES, "es", x86_64_asm_get_es, x86_64_asm_load_es);
165
173
#[ derive( Debug ) ]
166
174
pub struct FS ;
167
175
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) ;
169
177
170
178
/// GS Segment
171
179
///
@@ -174,7 +182,7 @@ segment64_impl!(FS, "fs", x86_64_asm_rdfsbase, x86_64_asm_wrfsbase);
174
182
#[ derive( Debug ) ]
175
183
pub struct GS ;
176
184
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) ;
178
186
179
187
impl GS {
180
188
/// Swap `KernelGsBase` MSR and `GsBase` MSR.
0 commit comments