annotate src/impl/vm_impl_private.cbc @ 306:97c6157bac16

fix_goto_switchuvm_check_pgdirvm_impl
author anatofuz
date Wed, 05 Feb 2020 15:22:41 +0900
parents 9fa2e66bc9ed
children 50fd5d414066
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
226
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
1 #include "param.h"
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
2 #include "proc.h"
206
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
3 #include "mmu.h"
222
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
4 #include "defs.h"
206
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
5 #include "memlayout.h"
200
1301727600cc success build
anatofuz
parents:
diff changeset
6 #interface "vm_impl.h"
1301727600cc success build
anatofuz
parents:
diff changeset
7
206
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
8 /*
281
4d76280758db move context.pm to util.pm ...
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 270
diff changeset
9 vm_impl* createvm_impl2(); //:skip
206
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
10 */
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
11
304
9fa2e66bc9ed comment at vm_impl private field
anatofuz
parents: 281
diff changeset
12 __code loaduvm_ptesize_checkvm_impl(struct vm_impl* vm_impl,char* addr, __code next(int ret, ...)) {
208
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
13 if ((uint) addr %PTE_SZ != 0) {
206
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
14 // goto panic
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
15 }
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
16
219
b8597756f701 fix loaduvm loop
tobaru
parents: 218
diff changeset
17 goto loaduvm_loopvm_impl(vm_impl, next(ret, ...));
200
1301727600cc success build
anatofuz
parents:
diff changeset
18 }
1301727600cc success build
anatofuz
parents:
diff changeset
19
304
9fa2e66bc9ed comment at vm_impl private field
anatofuz
parents: 281
diff changeset
20 __code loaduvm_loopvm_impl(struct vm_impl* vm_impl, uint i, uint sz,__code next(int ret, ...)) {
208
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
21 if (i < sz) {
219
b8597756f701 fix loaduvm loop
tobaru
parents: 218
diff changeset
22 goto loaduvm_check_pgdir(vm_impl, next(ret, ...));
206
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
23 }
208
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
24
219
b8597756f701 fix loaduvm loop
tobaru
parents: 218
diff changeset
25 goto loaduvm_exit(vm_impl, next(ret, ...));
200
1301727600cc success build
anatofuz
parents:
diff changeset
26 }
208
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
27
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
28
206
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
29 static pte_t* walkpgdir (pde_t *pgdir, const void *va, int alloc)
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
30 {
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
31 pde_t *pde;
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
32 pte_t *pgtab;
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
33
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
34 // pgdir points to the page directory, get the page direcotry entry (pde)
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
35 pde = &pgdir[PDE_IDX(va)];
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
36
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
37 if (*pde & PE_TYPES) {
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
38 pgtab = (pte_t*) p2v(PT_ADDR(*pde));
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
39
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
40 } else {
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
41 if (!alloc || (pgtab = (pte_t*) kpt_alloc()) == 0) {
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
42 return 0;
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
43 }
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
44
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
45 // Make sure all those PTE_P bits are zero.
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
46 memset(pgtab, 0, PT_SZ);
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
47
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
48 // The permissions here are overly generous, but they can
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
49 // be further restricted by the permissions in the page table
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
50 // entries, if necessary.
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
51 *pde = v2p(pgtab) | UPDE_TYPE;
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
52 }
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
53
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
54 return &pgtab[PTE_IDX(va)];
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
55 }
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
56
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
57
304
9fa2e66bc9ed comment at vm_impl private field
anatofuz
parents: 281
diff changeset
58 __code loaduvm_check_pgdir(struct vm_impl* vm_impl, pte_t* pte, pde_t* pgdir, uint i, char* addr, uint pa, __code next(int ret, ...)) {
208
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
59 if ((pte = walkpgdir(pgdir, addr + i, 0)) == 0) {
206
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
60 // goto panic
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
61 }
208
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
62 pa = PTE_ADDR(*pte);
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
63
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
64 vm_impl->pte = pte;
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
65 vm_impl->pgdir = pgdir;
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
66 vm_impl->addr = addr;
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
67 vm_impl->pa = pa;
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
68
219
b8597756f701 fix loaduvm loop
tobaru
parents: 218
diff changeset
69 goto loaduvm_check_PTE_SZ(vm_impl, next(ret, ...));
206
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
70 }
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
71
304
9fa2e66bc9ed comment at vm_impl private field
anatofuz
parents: 281
diff changeset
72 __code loaduvm_check_PTE_SZ(struct vm_impl* vm_impl, uint sz, uint i, uint n, struct inode* ip, uint pa, uint offset, __code next(int ret, ...)) {
208
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
73
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
74 if (sz - i < PTE_SZ) {
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
75 n = sz - i;
207
8a55878f6a25 loaduvm
tobaru
parents: 206
diff changeset
76 } else {
208
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
77 n = PTE_SZ;
207
8a55878f6a25 loaduvm
tobaru
parents: 206
diff changeset
78 }
8a55878f6a25 loaduvm
tobaru
parents: 206
diff changeset
79
208
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
80 if (readi(ip, p2v(pa), offset + i, n) != n) {
219
b8597756f701 fix loaduvm loop
tobaru
parents: 218
diff changeset
81 ret = -1;
b8597756f701 fix loaduvm loop
tobaru
parents: 218
diff changeset
82 goto next(ret, ...);
207
8a55878f6a25 loaduvm
tobaru
parents: 206
diff changeset
83 }
8a55878f6a25 loaduvm
tobaru
parents: 206
diff changeset
84
208
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
85 vm_impl->n = n;
a0620ca23f19 be functional loaduvm
tobaru
parents: 207
diff changeset
86
219
b8597756f701 fix loaduvm loop
tobaru
parents: 218
diff changeset
87 goto loaduvm_loopvm_impl(vm_impl, next(ret, ...));
206
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
88 }
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
89
219
b8597756f701 fix loaduvm loop
tobaru
parents: 218
diff changeset
90 __code loaduvm_exit(struct vm_impl* vm_impl, __code next(int ret, ...)) {
b8597756f701 fix loaduvm loop
tobaru
parents: 218
diff changeset
91 ret = 0;
b8597756f701 fix loaduvm loop
tobaru
parents: 218
diff changeset
92 goto next(ret, ...);
206
247aa9ee931c loaduvm_loopvm_impl
tobaru
parents: 205
diff changeset
93 }
211
66db83ec1ec2 kpt_alloc_check_impl and freerange
tobaru
parents: 208
diff changeset
94
212
6e03cee9733e can use r
tobaru
parents: 211
diff changeset
95 struct run {
6e03cee9733e can use r
tobaru
parents: 211
diff changeset
96 struct run *next;
6e03cee9733e can use r
tobaru
parents: 211
diff changeset
97 };
6e03cee9733e can use r
tobaru
parents: 211
diff changeset
98
6e03cee9733e can use r
tobaru
parents: 211
diff changeset
99 struct {
6e03cee9733e can use r
tobaru
parents: 211
diff changeset
100 struct spinlock lock;
6e03cee9733e can use r
tobaru
parents: 211
diff changeset
101 struct run* freelist;
6e03cee9733e can use r
tobaru
parents: 211
diff changeset
102 } kpt_mem;
6e03cee9733e can use r
tobaru
parents: 211
diff changeset
103
215
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
104
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
105 static int mappages (pde_t *pgdir, void *va, uint size, uint pa, int ap)
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
106 {
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
107 char *a, *last;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
108 pte_t *pte;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
109
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
110 a = (char*) align_dn(va, PTE_SZ);
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
111 last = (char*) align_dn((uint)va + size - 1, PTE_SZ);
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
112
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
113 for (;;) {
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
114 if ((pte = walkpgdir(pgdir, a, 1)) == 0) {
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
115 return -1;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
116 }
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
117
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
118 if (*pte & PE_TYPES) {
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
119 panic("remap");
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
120 }
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
121
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
122 *pte = pa | ((ap & 0x3) << 4) | PE_CACHE | PE_BUF | PTE_TYPE;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
123
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
124 if (a == last) {
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
125 break;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
126 }
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
127
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
128 a += PTE_SZ;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
129 pa += PTE_SZ;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
130 }
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
131
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
132 return 0;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
133 }
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
134
211
66db83ec1ec2 kpt_alloc_check_impl and freerange
tobaru
parents: 208
diff changeset
135 __code kpt_alloc_check_impl(struct vm_impl* vm_impl, __code next(...)) {
212
6e03cee9733e can use r
tobaru
parents: 211
diff changeset
136 struct run* r;
6e03cee9733e can use r
tobaru
parents: 211
diff changeset
137 if ((r = kpt_mem.freelist) != NULL ) {
6e03cee9733e can use r
tobaru
parents: 211
diff changeset
138 kpt_mem.freelist = r->next;
6e03cee9733e can use r
tobaru
parents: 211
diff changeset
139 }
213
f4effd36aefc kpt_alloc
tobaru
parents: 212
diff changeset
140 release(&kpt_mem.lock);
211
66db83ec1ec2 kpt_alloc_check_impl and freerange
tobaru
parents: 208
diff changeset
141
213
f4effd36aefc kpt_alloc
tobaru
parents: 212
diff changeset
142 if ((r == NULL) && ((r = kmalloc (PT_ORDER)) == NULL)) {
f4effd36aefc kpt_alloc
tobaru
parents: 212
diff changeset
143 // panic("oom: kpt_alloc");
f4effd36aefc kpt_alloc
tobaru
parents: 212
diff changeset
144 // goto panic
f4effd36aefc kpt_alloc
tobaru
parents: 212
diff changeset
145 }
f4effd36aefc kpt_alloc
tobaru
parents: 212
diff changeset
146
f4effd36aefc kpt_alloc
tobaru
parents: 212
diff changeset
147 memset(r, 0, PT_SZ);
211
66db83ec1ec2 kpt_alloc_check_impl and freerange
tobaru
parents: 208
diff changeset
148 goto next((char*)r);
66db83ec1ec2 kpt_alloc_check_impl and freerange
tobaru
parents: 208
diff changeset
149 }
214
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
150
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
151 __code allocuvm_check_newszvm_impl(struct vm_impl* vm_impl, pde_t* pgdir, uint oldsz, uint newsz, __code next(int ret, ...)){
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
152 if (newsz >= UADDR_SZ) {
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
153 goto next(0, ...);
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
154 }
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
155
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
156 if (newsz < oldsz) {
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
157 ret = newsz;
215
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
158 goto next(ret, ...);
214
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
159 }
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
160
215
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
161 char* mem;
214
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
162 uint a = align_up(oldsz, PTE_SZ);
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
163
215
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
164 goto allocuvm_loopvm_impl(vm_impl, pgdir, oldsz, newsz, mem, a, next(ret, ...));
214
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
165 }
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
166
215
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
167 __code allocuvm_loopvm_impl(struct vm_impl* vm_impl, pde_t* pgdir, uint oldsz, uint newsz, char* mem, uint a, __code next(int ret, ...)){
214
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
168
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
169 if (a < newsz) {
215
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
170 mem = alloc_page();
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
171
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
172 if (mem == 0) {
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
173 cprintf("allocuvm out of memory\n");
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
174 deallocuvm(pgdir, newsz, oldsz);
216
0f1700bd5cff cleapteu
tobaru
parents: 215
diff changeset
175 goto next(0, ...);
215
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
176 }
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
177
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
178 memset(mem, 0, PTE_SZ);
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
179 mappages(pgdir, (char*) a, PTE_SZ, v2p(mem), AP_KU);
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
180
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
181 goto allocuvm_loopvm_impl(vm_impl, pgdir, oldsz, newsz, a + PTE_SZ, next(ret, ...));
214
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
182 }
215
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
183 ret = newsz;
291d4e9304a1 allocuvm_loopvm_imp
tobaru
parents: 214
diff changeset
184 goto next(ret, ...);
214
2ecf1e09e981 allocuvm_loop and return
tobaru
parents: 213
diff changeset
185 }
216
0f1700bd5cff cleapteu
tobaru
parents: 215
diff changeset
186
0f1700bd5cff cleapteu
tobaru
parents: 215
diff changeset
187 __code clearpteu_check_ptevm_impl(struct vm_impl* vm_impl, pde_t* pgdir, char* uva, __code next(int ret, ...)) {
0f1700bd5cff cleapteu
tobaru
parents: 215
diff changeset
188 pte_t *pte;
0f1700bd5cff cleapteu
tobaru
parents: 215
diff changeset
189
0f1700bd5cff cleapteu
tobaru
parents: 215
diff changeset
190 pte = walkpgdir(pgdir, uva, 0);
0f1700bd5cff cleapteu
tobaru
parents: 215
diff changeset
191 if (pte == 0) {
0f1700bd5cff cleapteu
tobaru
parents: 215
diff changeset
192 // panic("clearpteu");
0f1700bd5cff cleapteu
tobaru
parents: 215
diff changeset
193 // goto panic;
0f1700bd5cff cleapteu
tobaru
parents: 215
diff changeset
194 }
0f1700bd5cff cleapteu
tobaru
parents: 215
diff changeset
195
0f1700bd5cff cleapteu
tobaru
parents: 215
diff changeset
196 // in ARM, we change the AP field (ap & 0x3) << 4)
0f1700bd5cff cleapteu
tobaru
parents: 215
diff changeset
197 *pte = (*pte & ~(0x03 << 4)) | AP_KO << 4;
0f1700bd5cff cleapteu
tobaru
parents: 215
diff changeset
198
0f1700bd5cff cleapteu
tobaru
parents: 215
diff changeset
199 goto next(ret, ...);
0f1700bd5cff cleapteu
tobaru
parents: 215
diff changeset
200 }
217
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
201
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
202 __code copyuvm_check_nullvm_impl(struct vm_impl* vm_impl, pde_t* pgdir, uint sz, __code next(int ret, ...)) {
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
203 pde_t *d;
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
204 pte_t *pte;
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
205 uint pa, i, ap;
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
206 char *mem;
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
207
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
208 // allocate a new first level page directory
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
209 d = kpt_alloc();
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
210 if (d == NULL ) {
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
211 ret = NULL;
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
212 goto next(ret, ...);
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
213 }
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
214 i = 0;
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
215
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
216 goto copyuvm_loopvm_impl(vm_impl, pgdir, sz, *d, *pte, pa, i, ap, *mem, next(ret, ...));
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
217 }
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
218
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
219 __code copyuvm_loopvm_impl(struct vm_impl* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...)) {
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
220
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
221 if (i < sz) {
218
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
222 goto copyuvm_loop_check_walkpgdir(vm_impl, pgdir, sz, d, pte, pa, i, ap, mem, __code next(int ret, ...));
217
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
223
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
224 }
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
225 ret = d;
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
226 goto next(ret, ...);
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
227 }
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
228
218
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
229 __code copyuvm_loop_check_walkpgdir(struct vm_impl* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...)) {
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
230 if ((pte = walkpgdir(pgdir, (void *) i, 0)) == 0) {
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
231 // panic("copyuvm: pte should exist");
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
232 // goto panic();
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
233 }
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
234 goto copyuvm_loop_check_pte(vm_impl, pgdir, sz, d, pte, pa, i, ap, mem, __code next(int ret, ...));
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
235 }
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
236
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
237 __code copyuvm_loop_check_pte(struct vm_impl* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...)) {
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
238
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
239 if (!(*pte & PE_TYPES)) {
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
240 // panic("copyuvm: page not present");
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
241 // goto panic();
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
242 }
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
243
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
244 goto copyuvm_loop_check_mem(vm_impl, pgdir, sz, d, pte, pa, i, ap, mem, __code next(int ret, ...));
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
245 }
217
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
246
218
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
247 __code copyuvm_loop_check_mem(struct vm_impl* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...)) {
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
248 pa = PTE_ADDR (*pte);
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
249 ap = PTE_AP (*pte);
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
250
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
251 if ((mem = alloc_page()) == 0) {
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
252 goto copyuvm_loop_bad(vm_impl, d, next(...));
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
253 }
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
254 goto copyuvm_loop_check_mappages(vm_impl, pgdir, sz, d, pte, pa, i, ap, mem, __code next(int ret, ...));
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
255
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
256 }
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
257
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
258 __code copyuvm_loop_check_mappages(struct vm_impl* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...)) {
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
259
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
260 memmove(mem, (char*) p2v(pa), PTE_SZ);
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
261
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
262 if (mappages(d, (void*) i, PTE_SZ, v2p(mem), ap) < 0) {
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
263 goto copyuvm_loop_bad(vm_impl, d, next(...));
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
264 }
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
265 goto copyuvm_loopvm_impl(vm_impl, pgdir, sz, d, pte, pa, i, ap, mem, __code next(int ret, ...));
1c923ae14607 copyuvm
tobaru
parents: 217
diff changeset
266
217
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
267 }
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
268
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
269 __code copyuvm_loop_bad(struct vm_impl* vm_impl, pde_t* d, __code next(int ret, ...)) {
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
270 freevm(d);
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
271 ret = 0;
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
272 goto next(ret, ...);
f940ff602312 copyuvm_loop
tobaru
parents: 216
diff changeset
273 }
220
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
274
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
275
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
276 __code uva2ka_check_pe_types(struct vm_impl* vm, pde_t* pgdir, char* uva, __code next(int ret, ...)) {
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
277 pte_t* pte;
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
278
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
279 pte = walkpgdir(pgdir, uva, 0);
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
280
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
281 // make sure it exists
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
282 if ((*pte & PE_TYPES) == 0) {
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
283 ret = 0;
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
284 goto next(ret, ...);
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
285 }
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
286 goto uva2ka_check_pte_ap(vm, pgdir, uva, pte, next(...));
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
287 }
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
288
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
289 __code uva2ka_check_pte_ap(struct vm_impl* vm, pde_t* pgdir, char* uva, pte_t* pte, __code next(int ret, ...)) {
221
098942ff5f44 uva2ka_check_pte_ap
tobaru
parents: 220
diff changeset
290 // make sure it is a user page
098942ff5f44 uva2ka_check_pte_ap
tobaru
parents: 220
diff changeset
291 if (PTE_AP(*pte) != AP_KU) {
098942ff5f44 uva2ka_check_pte_ap
tobaru
parents: 220
diff changeset
292 ret = 0;
098942ff5f44 uva2ka_check_pte_ap
tobaru
parents: 220
diff changeset
293 goto next(ret, ...);
098942ff5f44 uva2ka_check_pte_ap
tobaru
parents: 220
diff changeset
294 }
098942ff5f44 uva2ka_check_pte_ap
tobaru
parents: 220
diff changeset
295 ret = (char*) p2v(PTE_ADDR(*pte));
220
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
296 goto next(ret, ...);
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
297 }
c1d1721fd907 uva2ka_check_pe_types
tobaru
parents: 219
diff changeset
298
222
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
299 // flush all TLB
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
300 static void flush_tlb (void)
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
301 {
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
302 uint val = 0;
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
303 asm("MCR p15, 0, %[r], c8, c7, 0" : :[r]"r" (val):);
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
304
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
305 // invalid entire data and instruction cache
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
306 asm ("MCR p15,0,%[r],c7,c10,0": :[r]"r" (val):);
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
307 asm ("MCR p15,0,%[r],c7,c11,0": :[r]"r" (val):);
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
308 }
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
309
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
310 __code paging_intvmvm_impl(struct vm_impl* vm_impl, uint phy_low, uint phy_hi, __code next(...)) {
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
311 mappages (P2V(&_kernel_pgtbl), P2V(phy_low), phy_hi - phy_low, phy_low, AP_KU);
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
312 flush_tlb ();
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
313
223
90b65036d9a2 paging_init
tobaru
parents: 222
diff changeset
314 goto next(...);
222
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
315 }
7a4d299a35be paging_init
tobaru
parents: 221
diff changeset
316
224
37900976db8e copyout
tobaru
parents: 223
diff changeset
317 __code copyout_loopvm_impl(struct vm_impl* vm_impl, pde_t* pgdir, uint va, void* pp, uint len, uint va0, char* pa0, __code next(int ret, ...)) {
37900976db8e copyout
tobaru
parents: 223
diff changeset
318 if (len > 0) {
37900976db8e copyout
tobaru
parents: 223
diff changeset
319 va0 = align_dn(va, PTE_SZ);
37900976db8e copyout
tobaru
parents: 223
diff changeset
320 pa0 = uva2ka(pgdir, (char*) va0);
37900976db8e copyout
tobaru
parents: 223
diff changeset
321 goto copyout_loop_check_pa0(vm_impl, pgdir, va, pp, len, va0, pa0, n, next(...));
37900976db8e copyout
tobaru
parents: 223
diff changeset
322 }
37900976db8e copyout
tobaru
parents: 223
diff changeset
323 ret = 0;
37900976db8e copyout
tobaru
parents: 223
diff changeset
324 goto next(ret, ...);
223
90b65036d9a2 paging_init
tobaru
parents: 222
diff changeset
325
90b65036d9a2 paging_init
tobaru
parents: 222
diff changeset
326 }
90b65036d9a2 paging_init
tobaru
parents: 222
diff changeset
327
224
37900976db8e copyout
tobaru
parents: 223
diff changeset
328 __code copyout_loop_check_pa0(struct vm_impl* vm_impl, pde_t* pgdir, uint va, void* pp, uint len, uint va0, char* pa0, uint n, __code next(int ret, ...)) {
37900976db8e copyout
tobaru
parents: 223
diff changeset
329 if (pa0 == 0) {
37900976db8e copyout
tobaru
parents: 223
diff changeset
330 ret = -1;
37900976db8e copyout
tobaru
parents: 223
diff changeset
331 goto next(ret, ...);
37900976db8e copyout
tobaru
parents: 223
diff changeset
332 }
37900976db8e copyout
tobaru
parents: 223
diff changeset
333 goto copyout_loop_check_n(vm_impl, pgdir, va, pp, len, va0, pa0, n, buf, next(...));
37900976db8e copyout
tobaru
parents: 223
diff changeset
334 }
37900976db8e copyout
tobaru
parents: 223
diff changeset
335 __code copyout_loop_check_n(struct vm_impl* vm_impl, pde_t* pgdir, uint va, void* pp, uint len, uint va0, char* pa0, uint n, char* buf, __code next(...)) {
37900976db8e copyout
tobaru
parents: 223
diff changeset
336 n = PTE_SZ - (va - va0);
223
90b65036d9a2 paging_init
tobaru
parents: 222
diff changeset
337
224
37900976db8e copyout
tobaru
parents: 223
diff changeset
338 if (n > len) {
37900976db8e copyout
tobaru
parents: 223
diff changeset
339 n = len;
37900976db8e copyout
tobaru
parents: 223
diff changeset
340 }
37900976db8e copyout
tobaru
parents: 223
diff changeset
341
37900976db8e copyout
tobaru
parents: 223
diff changeset
342 len -= n;
37900976db8e copyout
tobaru
parents: 223
diff changeset
343 buf += n;
37900976db8e copyout
tobaru
parents: 223
diff changeset
344 va = va0 + PTE_SZ;
37900976db8e copyout
tobaru
parents: 223
diff changeset
345 goto copyout_loopvm_impl(vm_impl, pgdir, va, pp, len, va0, pa0, next(...));
37900976db8e copyout
tobaru
parents: 223
diff changeset
346 }
37900976db8e copyout
tobaru
parents: 223
diff changeset
347
226
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
348 typedef struct proc proc_struct;
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
349 __code switchuvm_check_pgdirvm_impl(struct vm_impl* vm_impl, proc_struct* p, __code next(...)) { //:skip
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
350 uint val;
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
351
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
352 pushcli();
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
353
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
354 if (p->pgdir == 0) {
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
355 panic("switchuvm: no pgdir");
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
356 }
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
357
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
358 val = (uint) V2P(p->pgdir) | 0x00;
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
359
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
360 asm("MCR p15, 0, %[v], c2, c0, 0": :[v]"r" (val):);
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
361 flush_tlb();
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
362
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
363 popcli();
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
364
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
365 goto next(...);
415081e357ec switchuvm_check_pgdirvm_impl
tobaru
parents: 224
diff changeset
366 }
227
80398e02ae72 init_inituvm
tobaru
parents: 226
diff changeset
367
80398e02ae72 init_inituvm
tobaru
parents: 226
diff changeset
368 __code init_inituvm_check_sz(struct vm_impl* vm_impl, pde_t* pgdir, char* init, uint sz, __code next(...)) {
80398e02ae72 init_inituvm
tobaru
parents: 226
diff changeset
369 char* mem;
80398e02ae72 init_inituvm
tobaru
parents: 226
diff changeset
370
80398e02ae72 init_inituvm
tobaru
parents: 226
diff changeset
371 if (sz >= PTE_SZ) {
80398e02ae72 init_inituvm
tobaru
parents: 226
diff changeset
372 // goto panic;
80398e02ae72 init_inituvm
tobaru
parents: 226
diff changeset
373 // panic("inituvm: more than a page");
80398e02ae72 init_inituvm
tobaru
parents: 226
diff changeset
374 }
80398e02ae72 init_inituvm
tobaru
parents: 226
diff changeset
375
80398e02ae72 init_inituvm
tobaru
parents: 226
diff changeset
376 mem = alloc_page();
80398e02ae72 init_inituvm
tobaru
parents: 226
diff changeset
377 memset(mem, 0, PTE_SZ);
80398e02ae72 init_inituvm
tobaru
parents: 226
diff changeset
378 mappages(pgdir, 0, PTE_SZ, v2p(mem), AP_KU);
80398e02ae72 init_inituvm
tobaru
parents: 226
diff changeset
379 memmove(mem, init, sz);
80398e02ae72 init_inituvm
tobaru
parents: 226
diff changeset
380
80398e02ae72 init_inituvm
tobaru
parents: 226
diff changeset
381 goto next(...);
80398e02ae72 init_inituvm
tobaru
parents: 226
diff changeset
382 }
269
bd948528b2d6 impl_vm_void_ret
anatofuz
parents: 227
diff changeset
383