kernel/arch/x86_64/cpu/
gs_info.rs1use crate::lib::addr::VirtAddr;
7use core::mem::offset_of;
8use core::sync::atomic::{AtomicU64, Ordering};
9use x86_64::registers::model_specific::{GsBase, KernelGsBase};
10
11#[repr(C, align(64))]
13pub struct GsInfo {
14 self_ptr: AtomicU64,
15 kernel_stack_top: AtomicU64,
16 user_rsp: AtomicU64
17}
18
19pub const GS_INFO_SELF_PTR: usize = offset_of!(GsInfo, self_ptr);
20pub const GS_INFO_KERNEL_STACK_TOP: usize = offset_of!(GsInfo, kernel_stack_top);
21pub const GS_INFO_USER_RSP: usize = offset_of!(GsInfo, user_rsp);
22
23impl GsInfo {
24 pub const fn new() -> Self {
26 Self {
27 self_ptr: AtomicU64::new(0),
28 kernel_stack_top: AtomicU64::new(0),
29 user_rsp: AtomicU64::new(0)
30 }
31 }
32
33 pub unsafe fn init(&'static self) {
41 let self_ptr = VirtAddr::from_ptr(self as *const Self);
42
43 self.self_ptr.store(self_ptr.as_u64(), Ordering::Relaxed);
44 self.kernel_stack_top.store(0u64, Ordering::Relaxed);
45
46 KernelGsBase::write(self_ptr.as_x86_64());
47 GsBase::write(VirtAddr::null().as_x86_64());
48 }
49
50 pub unsafe fn set_kernel_stack_top(&self, kernel_stack_top: VirtAddr) {
56 self.kernel_stack_top.store(kernel_stack_top.as_u64(), Ordering::Relaxed);
57 }
58
59 pub fn self_ptr(&self) -> u64 {
61 self.self_ptr.load(Ordering::Relaxed)
62 }
63
64 pub fn kernel_stack_top(&self) -> u64 {
66 self.kernel_stack_top.load(Ordering::Relaxed)
67 }
68
69 pub fn user_rsp(&self) -> u64 {
71 self.user_rsp.load(Ordering::Relaxed)
72 }
73}