9ns: mnt: Don't use a 'bogus' struct
[akaros.git] / kern / arch / x86 / fsgsbase.h
1 /* Copyright (c) 2016 Google Inc.
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Getters and setters for FS Base and GS base. */
6
7 #pragma once
8
9 #include <cpu_feat.h>
10 #include <arch/x86.h>
11
12 static inline uintptr_t read_fsbase(void)
13 {
14         uintptr_t base;
15
16         if (!cpu_has_feat(CPU_FEAT_X86_FSGSBASE))
17                 return read_msr(MSR_FS_BASE);
18         asm volatile ("rdfsbase %0" : "=r"(base));
19         return base;
20 }
21
22 static inline void write_fsbase(uintptr_t base)
23 {
24         if (!cpu_has_feat(CPU_FEAT_X86_FSGSBASE)) {
25                 write_msr(MSR_FS_BASE, base);
26                 return;
27         }
28         asm volatile ("wrfsbase %0" : : "r"(base));
29 }
30
31 static inline uintptr_t read_gsbase(void)
32 {
33         uintptr_t base;
34
35         if (!cpu_has_feat(CPU_FEAT_X86_FSGSBASE))
36                 return read_msr(MSR_GS_BASE);
37         asm volatile ("rdgsbase %0" : "=r"(base));
38         return base;
39 }
40
41 static inline void write_gsbase(uintptr_t base)
42 {
43         if (!cpu_has_feat(CPU_FEAT_X86_FSGSBASE)) {
44                 write_msr(MSR_GS_BASE, base);
45                 return;
46         }
47         asm volatile ("wrgsbase %0" : : "r"(base));
48 }
49
50 /* If we have fast FS/GS access, we can use swapgs to quickly access
51  * kern_gsbase. */
52 static inline uintptr_t read_kern_gsbase(void)
53 {
54         uintptr_t base;
55         int8_t irq_state = 0;
56
57         if (!cpu_has_feat(CPU_FEAT_X86_FSGSBASE))
58                 return read_msr(MSR_KERNEL_GS_BASE);
59         disable_irqsave(&irq_state);
60         swap_gs();
61         base = read_gsbase();
62         swap_gs();
63         enable_irqsave(&irq_state);
64         return base;
65 }
66
67 static inline void write_kern_gsbase(uintptr_t base)
68 {
69         int8_t irq_state = 0;
70
71         if (!cpu_has_feat(CPU_FEAT_X86_FSGSBASE)) {
72                 write_msr(MSR_KERNEL_GS_BASE, base);
73                 return;
74         }
75         disable_irqsave(&irq_state);
76         swap_gs();
77         write_gsbase(base);
78         swap_gs();
79         enable_irqsave(&irq_state);
80 }