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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
bits 64
extern do_syscall
section .text
syscall_entry:
mov r11, rsp
mov rsp, 0xfffffffffffff000
push r11
push rcx
push rdx
push rsi
push rdi
push rax
mov rdi, rsp
lea rsi, [rsp + 8]
lea rdx, [rsp + 16]
lea rcx, [rsp + 24]
call do_syscall
pop rax
pop rdi
pop rsi
pop rdx
xor r8, r8
xor r9, r9
xor r10, r10
xor r11, r11
or r11, 0x200
pop rcx
pop rsp
o64 sysret
global init_applications_asm
init_applications_asm:
;efer <- efer | 0x1
mov rcx, 0xc0000080
rdmsr
or al, 1
wrmsr
;lstar <- syscall_entry
mov rdx, syscall_entry
mov eax, edx
shr rdx, 32
mov ecx, 0xc0000082
wrmsr
;star <- 0x0030.0028.0000.0000
mov edx, 0x00300028
xor eax, eax
mov ecx, 0xc0000081
wrmsr
;sfmask <- 0x0000.0000.0000.0200 (if)
xor edx, edx
mov eax, 0x200
mov ecx, 0xc0000084
wrmsr
ret
section .bss
resume_stack:
resb 4096
section .text
extern restore_syscall_stack
;rdi = pointer to copy
;rsi = intended rsp
global resume_thread
resume_thread:
;rdi = ptr to cpu_state
;rdi is not inside stack
;interrupts are disabled
mov al, byte [rdi + 160] ;in_syscall
test al, al
jnz .in_syscall
mov rax, 0x3b
mov rbx, 0x43
.common:
push rax
mov rax, qword [rdi + 56] ;rsp
push rax
mov rax, qword [rdi + 128] ;rflags
push rax
push rbx
mov rax, qword [rdi + 136] ;rip
push rax
mov rax, qword [rdi + 144] ;cr3
mov cr3, rax
mov rax, qword [rdi]
mov rbx, qword [rdi + 8]
mov rcx, qword [rdi + 16]
mov rdx, qword [rdi + 24]
mov rsi, qword [rdi + 40]
mov rbp, qword [rdi + 48]
mov r8, qword [rdi + 64]
mov r9, qword [rdi + 72]
mov r10, qword [rdi + 80]
mov r11, qword [rdi + 88]
mov r12, qword [rdi + 96]
mov r13, qword [rdi + 104]
mov r14, qword [rdi + 112]
mov r15, qword [rdi + 120]
mov rdi, qword [rdi + 32]
iretq
.in_syscall:
mov rsp, resume_stack + 4096
push rdi
mov rsi, qword [rdi + 56] ;rsp
mov rdi, qword [rdi + 152] ;kernel_stack_copy
call restore_syscall_stack
pop rdi
mov rax, 0x30
mov rbx, 0x28
jmp .common
extern copy_syscall_stack
;rdi = bottom
global save_thread_state
save_thread_state:
;rdi = pointer to cpu state structure
;only saving registers that need to be preserved by this function
mov qword [rdi + 8], rbx
mov qword [rdi + 48], rbp
mov qword [rdi + 56], rsp
mov qword [rdi + 96], r12
mov qword [rdi + 104], r13
mov qword [rdi + 112], r14
mov qword [rdi + 120], r15
mov qword [rdi + 136], .resume_to ;rip
mov rax, cr3
mov qword [rdi + 144], rax ;cr3
push rdi
lea rdi, [rsp + 8]
call copy_syscall_stack
pop rdi
mov qword [rdi + 152], rax ;kernel_stack_copy
mov byte [rdi + 160], 0x01 ;in_syscall
xor al, al
ret
.resume_to:
mov al, 0x01
ret
|