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
|
#include "param.h"
#include "x86.h"
#include "mmu.h"
# the offset of cs in trapframe (i.e., tf->cs - tf)
#define CSOFF 144
# vectors.S sends all traps here.
.globl alltraps
alltraps:
# Build trap frame.
push %r15
push %r14
push %r13
push %r12
push %r11
push %r10
push %r9
push %r8
push %rdi
push %rsi
push %rbp
push %rdx
push %rcx
push %rbx
push %rax
cmpw $SEG_KCODE, CSOFF(%rsp) # compare to saved cs
jz 1f
swapgs
1:mov %rsp, %rdi # frame in arg1
call trap
# Return falls through to trapret...
.globl trapret
trapret:
cli
cmpw $SEG_KCODE, CSOFF(%rsp) # compare to saved cs
jz 1f
swapgs
1:pop %rax
pop %rbx
pop %rcx
pop %rdx
pop %rbp
pop %rsi
pop %rdi
pop %r8
pop %r9
pop %r10
pop %r11
pop %r12
pop %r13
pop %r14
pop %r15
add $16, %rsp # discard trapnum and errorcode
iretq
#PAGEBREAK!
# syscall jumps here after syscall instruction
.globl sysentry
sysentry: # Build syscall frame.
// load kernel stack address
swapgs
movq %rax, %gs:0 // save %rax in syscallno of cpu entry
movq %rsp, %gs:8 // user sp
movq %gs:16, %rax // proc entry
movq %ss:0(%rax), %rax // load kstack from proc
addq $(KSTACKSIZE), %rax
movq %rax, %rsp
movq %gs:0, %rax // restore rax
push %gs:8
push %rcx
push %r11
push %rax
push %rbp
push %rbx
push %r12
push %r13
push %r14
push %r15
push %r9
push %r8
push %r10
push %rdx
push %rsi
push %rdi
mov %rsp, %rdi # frame in arg1
call syscall
# fall through to sysexit
.globl sysexit
sysexit:
# to make sure we don't get any interrupts on the user stack while in
# supervisor mode. insufficient? (see vunerability reports for sysret)
cli
pop %rdi
pop %rsi
pop %rdx
pop %r10
pop %r8
pop %r9
pop %r15
pop %r14
pop %r13
pop %r12
pop %rbx
pop %rbp
pop %rax
pop %r11
pop %rcx
mov (%rsp),%rsp # switch to the user stack
# there are two more values on the stack, but we don't care about them
swapgs
sysretq
|