1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
.intel_syntax noprefix
// Define a string literal.
.macro defstr name str
\name:
.ascii "\str"
\name\()_len:
.8byte . - \name
.endm
// Print a string literal.
.macro pstr name
mov dx, 0x42 // Magic IO port for strings.
lea rsi, [rip + \name] // Address of string.
mov rcx, [rip + \name\()_len] // Len of string.
rep outsb // Write ds:rsi to output port rdx.
.endm
.section .boot, "ax", @progbits
// -- SWAPGS test -----------------------------------------------------------
// Setup IA32_GS_BASE.
mov rcx, 0xc0000101
mov rax, 0xbbbbbbbb
call wrmsr
// Setup IA32_KERNEL_GS_BASE.
mov rcx, 0xc0000102
mov rax, 0xaaaaaaaa
call wrmsr
// Print IA32_GS_BASE.
pstr gsbase
mov rcx, 0xc0000101
call rdmsr
call pu64
// Print IA32_KERNEL_GS_BASE.
pstr kgsbase
mov rcx, 0xc0000102
call rdmsr
call pu64
pstr swapgs
// Swap IA32_GS_BASE and IA32_KERNEL_GS_BASE.
swapgs
// Print IA32_GS_BASE.
pstr gsbase
mov rcx, 0xc0000101
call rdmsr
call pu64
// Print IA32_KERNEL_GS_BASE.
pstr kgsbase
mov rcx, 0xc0000102
call rdmsr
call pu64
// Trigger `KVM_EXIT_HLT`.
hlt
// in : ecx address of msr register
// out: rax value of msr register
rdmsr:
rdmsr
shl rdx, 32
or rax, rdx
ret
// in: ecx address of msr register
// in: rax value to write into msr register
wrmsr:
mov rdx, rax
shr rdx, 32
wrmsr
ret
// in: rax holds 64bit word to be printed
pu64:
xor dx, dx // Port to print values.
out dx, eax // Print lower-half (u32) of rax.
//shr rax, 32
//out dx, eax // Print upper-half (u32) of rax.
ret
.section .rodata, "a", @progbits
defstr fsbase, "fsbase: "
defstr gsbase, "gsbase: "
defstr kgsbase, "kernel_gsbase: "
defstr swapgs, "-- swapgs --\n"
|