1 /*-
2 * Copyright (c) 2006 Peter Wemm
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26 /*
27 * AMD64 machine dependent routines for kvm and minidumps.
28 */
29
30 #include <sys/user.h> /* MUST BE FIRST */
31 #include <sys/param.h>
32 #include <sys/stat.h>
33 #include <sys/mman.h>
34 #include <sys/fnv_hash.h>
35 #include <strings.h>
36 #include <string.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39 #include <nlist.h>
40
41 #include <cpu/pmap.h>
42 #include <vm/vm.h>
43 #include <vm/vm_param.h>
44
45 #include <machine/elf.h>
46 #include <machine/cpufunc.h>
47 #include <machine/minidump.h>
48
49 #include <limits.h>
50
51 #include "kvm.h"
52 #include "kvm_private.h"
53
54 struct hpte {
55 struct hpte *next;
56 vm_paddr_t pa;
57 int64_t off;
58 };
59
60 #define HPT_SIZE 1024
61
62 /* minidump must be the first item! */
63 struct vmstate {
64 int minidump; /* 1 = minidump mode */
65 int pgtable; /* pagetable mode */
66 void *hpt_head[HPT_SIZE];
67 uint64_t *bitmap;
68 uint64_t *ptemap;
69 uint64_t kernbase;
70 uint64_t dmapbase;
71 uint64_t dmapend;
72 uint64_t bitmapsize;
73 };
74
75 static void
hpt_insert(kvm_t * kd,vm_paddr_t pa,int64_t off)76 hpt_insert(kvm_t *kd, vm_paddr_t pa, int64_t off)
77 {
78 struct hpte *hpte;
79 uint32_t fnv = FNV1_32_INIT;
80
81 fnv = fnv_32_buf(&pa, sizeof(pa), fnv);
82 fnv &= (HPT_SIZE - 1);
83 hpte = malloc(sizeof(*hpte));
84 hpte->pa = pa;
85 hpte->off = off;
86 hpte->next = kd->vmst->hpt_head[fnv];
87 kd->vmst->hpt_head[fnv] = hpte;
88 }
89
90 static int64_t
hpt_find(kvm_t * kd,vm_paddr_t pa)91 hpt_find(kvm_t *kd, vm_paddr_t pa)
92 {
93 struct hpte *hpte;
94 uint32_t fnv = FNV1_32_INIT;
95
96 fnv = fnv_32_buf(&pa, sizeof(pa), fnv);
97 fnv &= (HPT_SIZE - 1);
98 for (hpte = kd->vmst->hpt_head[fnv]; hpte != NULL; hpte = hpte->next) {
99 if (pa == hpte->pa)
100 return (hpte->off);
101 }
102 return (-1);
103 }
104
105 static int
inithash(kvm_t * kd,uint64_t * base,int len,off_t off)106 inithash(kvm_t *kd, uint64_t *base, int len, off_t off)
107 {
108 uint64_t idx;
109 uint64_t bit, bits;
110 vm_paddr_t pa;
111
112 for (idx = 0; idx < len / sizeof(*base); idx++) {
113 bits = base[idx];
114 while (bits) {
115 bit = bsfq(bits);
116 bits &= ~(1ul << bit);
117 pa = (idx * sizeof(*base) * NBBY + bit) * PAGE_SIZE;
118 hpt_insert(kd, pa, off);
119 off += PAGE_SIZE;
120 }
121 }
122 return (off);
123 }
124
125 void
_kvm_minidump_freevtop(kvm_t * kd)126 _kvm_minidump_freevtop(kvm_t *kd)
127 {
128 struct vmstate *vm = kd->vmst;
129
130 if (vm->bitmap)
131 free(vm->bitmap);
132 if (vm->ptemap)
133 free(vm->ptemap);
134 free(vm);
135 kd->vmst = NULL;
136 }
137
138 static int _kvm_minidump_init_hdr1(kvm_t *kd, struct vmstate *vmst,
139 struct minidumphdr1 *hdr);
140 static int _kvm_minidump_init_hdr2(kvm_t *kd, struct vmstate *vmst,
141 struct minidumphdr2 *hdr);
142
143 int
_kvm_minidump_initvtop(kvm_t * kd)144 _kvm_minidump_initvtop(kvm_t *kd)
145 {
146 struct vmstate *vmst;
147 int error;
148 union {
149 struct minidumphdr1 hdr1;
150 struct minidumphdr2 hdr2;
151 } u;
152
153 vmst = _kvm_malloc(kd, sizeof(*vmst));
154 if (vmst == NULL) {
155 _kvm_err(kd, kd->program, "cannot allocate vm");
156 return (-1);
157 }
158 kd->vmst = vmst;
159 bzero(vmst, sizeof(*vmst));
160 vmst->minidump = 1;
161
162 if (pread(kd->pmfd, &u, sizeof(u), 0) != sizeof(u)) {
163 _kvm_err(kd, kd->program, "cannot read dump header");
164 return (-1);
165 }
166 if (strncmp(MINIDUMP1_MAGIC, u.hdr1.magic, sizeof(u.hdr1.magic)) == 0 &&
167 u.hdr1.version == MINIDUMP1_VERSION) {
168 error = _kvm_minidump_init_hdr1(kd, vmst, &u.hdr1);
169 } else
170 if (strncmp(MINIDUMP2_MAGIC, u.hdr1.magic, sizeof(u.hdr1.magic)) == 0 &&
171 u.hdr2.version == MINIDUMP2_VERSION) {
172 error = _kvm_minidump_init_hdr2(kd, vmst, &u.hdr2);
173 } else {
174 _kvm_err(kd, kd->program, "not a minidump for this platform");
175 error = -1;
176 }
177 return error;
178 }
179
180 static
181 int
_kvm_minidump_init_hdr1(kvm_t * kd,struct vmstate * vmst,struct minidumphdr1 * hdr)182 _kvm_minidump_init_hdr1(kvm_t *kd, struct vmstate *vmst,
183 struct minidumphdr1 *hdr)
184 {
185 off_t off;
186
187 /* Skip header and msgbuf */
188 off = PAGE_SIZE + round_page(hdr->msgbufsize);
189
190 vmst->bitmap = _kvm_malloc(kd, hdr->bitmapsize);
191 if (vmst->bitmap == NULL) {
192 _kvm_err(kd, kd->program,
193 "cannot allocate %jd bytes for bitmap",
194 (intmax_t)hdr->bitmapsize);
195 return (-1);
196 }
197 if (pread(kd->pmfd, vmst->bitmap, hdr->bitmapsize, off) !=
198 hdr->bitmapsize) {
199 _kvm_err(kd, kd->program,
200 "cannot read %jd bytes for page bitmap",
201 (intmax_t)hdr->bitmapsize);
202 return (-1);
203 }
204 off += round_page(vmst->bitmapsize);
205
206 vmst->ptemap = _kvm_malloc(kd, hdr->ptesize);
207 if (vmst->ptemap == NULL) {
208 _kvm_err(kd, kd->program,
209 "cannot allocate %jd bytes for ptemap",
210 (intmax_t)hdr->ptesize);
211 return (-1);
212 }
213 if (pread(kd->pmfd, vmst->ptemap, hdr->ptesize, off) !=
214 hdr->ptesize) {
215 _kvm_err(kd, kd->program,
216 "cannot read %jd bytes for ptemap",
217 (intmax_t)hdr->ptesize);
218 return (-1);
219 }
220 off += hdr->ptesize;
221
222 vmst->kernbase = hdr->kernbase;
223 vmst->dmapbase = hdr->dmapbase;
224 vmst->dmapend = hdr->dmapend;
225 vmst->bitmapsize = hdr->bitmapsize;
226 vmst->pgtable = 0;
227
228 /* build physical address hash table for sparse pages */
229 inithash(kd, vmst->bitmap, hdr->bitmapsize, off);
230
231 return (0);
232 }
233
234 static
235 int
_kvm_minidump_init_hdr2(kvm_t * kd,struct vmstate * vmst,struct minidumphdr2 * hdr)236 _kvm_minidump_init_hdr2(kvm_t *kd, struct vmstate *vmst,
237 struct minidumphdr2 *hdr)
238 {
239 off_t off;
240
241 /* Skip header and msgbuf */
242 off = PAGE_SIZE + round_page(hdr->msgbufsize);
243
244 vmst->bitmap = _kvm_malloc(kd, hdr->bitmapsize);
245 if (vmst->bitmap == NULL) {
246 _kvm_err(kd, kd->program,
247 "cannot allocate %jd bytes for bitmap",
248 (intmax_t)hdr->bitmapsize);
249 return (-1);
250 }
251 if (pread(kd->pmfd, vmst->bitmap, hdr->bitmapsize, off) !=
252 (intmax_t)hdr->bitmapsize) {
253 _kvm_err(kd, kd->program,
254 "cannot read %jd bytes for page bitmap",
255 (intmax_t)hdr->bitmapsize);
256 return (-1);
257 }
258 off += round_page(hdr->bitmapsize);
259
260 vmst->ptemap = _kvm_malloc(kd, hdr->ptesize);
261 if (vmst->ptemap == NULL) {
262 _kvm_err(kd, kd->program,
263 "cannot allocate %jd bytes for ptemap",
264 (intmax_t)hdr->ptesize);
265 return (-1);
266 }
267 if (pread(kd->pmfd, vmst->ptemap, hdr->ptesize, off) !=
268 (intmax_t)hdr->ptesize) {
269 _kvm_err(kd, kd->program,
270 "cannot read %jd bytes for ptemap",
271 (intmax_t)hdr->ptesize);
272 return (-1);
273 }
274 off += hdr->ptesize;
275
276 vmst->kernbase = hdr->kernbase;
277 vmst->dmapbase = hdr->dmapbase;
278 vmst->bitmapsize = hdr->bitmapsize;
279 vmst->pgtable = 1;
280
281 /* build physical address hash table for sparse pages */
282 inithash(kd, vmst->bitmap, hdr->bitmapsize, off);
283
284 return (0);
285 }
286
287 static int
_kvm_minidump_vatop(kvm_t * kd,u_long va,off_t * pa)288 _kvm_minidump_vatop(kvm_t *kd, u_long va, off_t *pa)
289 {
290 struct vmstate *vm;
291 u_long offset;
292 pt_entry_t pte;
293 u_long pteindex;
294 u_long a;
295 off_t ofs;
296
297 vm = kd->vmst;
298 offset = va & (PAGE_SIZE - 1);
299 va -= offset; /* put va on page boundary */
300
301 if (va >= vm->kernbase) {
302 switch (vm->pgtable) {
303 case 0:
304 /*
305 * Page tables are specifically dumped (old style)
306 */
307 pteindex = (va - vm->kernbase) >> PAGE_SHIFT;
308 pte = vm->ptemap[pteindex];
309 if (((u_long)pte & X86_PG_V) == 0) {
310 _kvm_err(kd, kd->program,
311 "_kvm_vatop: pte not valid");
312 goto invalid;
313 }
314 a = pte & PG_FRAME;
315 break;
316 case 1:
317 /*
318 * Kernel page table pages are included in the
319 * sparse map. We only dump the contents of
320 * the PDs (zero-filling any empty entries).
321 *
322 * Index of PD entry in PDP & PDP in PML4E together.
323 *
324 * First shift by 30 (1GB) - gives us an index
325 * into PD entries. We do not PDP entries in the
326 * PML4E, so there are 512 * 512 PD entries possible.
327 */
328 pteindex = (va >> PDPSHIFT) & (512 * 512 - 1);
329 pte = vm->ptemap[pteindex];
330 if ((pte & X86_PG_V) == 0) {
331 _kvm_err(kd, kd->program,
332 "_kvm_vatop: pd not valid");
333 goto invalid;
334 }
335 if (pte & X86_PG_PS) { /* 1GB pages */
336 a = (pte & PG_PS_FRAME) +
337 (va & (1024 * 1024 * 1024 - 1));
338 break;
339 }
340 /* PD page */
341 ofs = hpt_find(kd, pte & PG_FRAME);
342 if (ofs == -1) {
343 _kvm_err(kd, kd->program,
344 "_kvm_vatop: no phys page for pd");
345 goto invalid;
346 }
347
348 /*
349 * Index of PT entry in PD
350 */
351 pteindex = (va >> PDRSHIFT) & 511;
352 if (pread(kd->pmfd, &pte, sizeof(pte),
353 ofs + pteindex * sizeof(pte)) != sizeof(pte)) {
354 _kvm_err(kd, kd->program,
355 "_kvm_vatop: pd lookup not valid");
356 goto invalid;
357 }
358 if ((pte & X86_PG_V) == 0) {
359 _kvm_err(kd, kd->program,
360 "_kvm_vatop: pt not valid");
361 goto invalid;
362 }
363 if (pte & X86_PG_PS) { /* 2MB pages */
364 a = (pte & PG_PS_FRAME) +
365 (va & (2048 * 1024 - 1));
366 break;
367 }
368 ofs = hpt_find(kd, pte & PG_FRAME);
369 if (ofs == -1) {
370 _kvm_err(kd, kd->program,
371 "_kvm_vatop: no phys page for pt");
372 goto invalid;
373 }
374
375 /*
376 * Index of pte entry in PT
377 */
378 pteindex = (va >> PAGE_SHIFT) & 511;
379 if (pread(kd->pmfd, &pte, sizeof(pte),
380 ofs + pteindex * sizeof(pte)) != sizeof(pte)) {
381 _kvm_err(kd, kd->program,
382 "_kvm_vatop: pte lookup not valid");
383 goto invalid;
384 }
385
386 /*
387 * Calculate end page
388 */
389 a = pte & PG_FRAME;
390 break;
391 default:
392 _kvm_err(kd, kd->program,
393 "_kvm_vatop: bad pgtable mode ");
394 goto invalid;
395 }
396 ofs = hpt_find(kd, a);
397 if (ofs == -1) {
398 _kvm_err(kd, kd->program, "_kvm_vatop: physical address 0x%lx not in minidump", a);
399 goto invalid;
400 }
401 *pa = ofs + offset;
402 return (PAGE_SIZE - offset);
403 } else if (va >= vm->dmapbase && va < vm->dmapend) {
404 a = (va - vm->dmapbase) & ~PAGE_MASK;
405 ofs = hpt_find(kd, a);
406 if (ofs == -1) {
407 _kvm_err(kd, kd->program, "_kvm_vatop: direct map address 0x%lx not in minidump", va);
408 goto invalid;
409 }
410 *pa = ofs + offset;
411 return (PAGE_SIZE - offset);
412 } else {
413 _kvm_err(kd, kd->program, "_kvm_vatop: virtual address 0x%lx not minidumped", va);
414 goto invalid;
415 }
416
417 invalid:
418 _kvm_err(kd, 0, "invalid address (0x%lx)", va);
419 return (0);
420 }
421
422 int
_kvm_minidump_kvatop(kvm_t * kd,u_long va,off_t * pa)423 _kvm_minidump_kvatop(kvm_t *kd, u_long va, off_t *pa)
424 {
425 if (kvm_ishost(kd)) {
426 _kvm_err(kd, 0, "kvm_vatop called in live kernel!");
427 return((off_t)0);
428 }
429
430 return (_kvm_minidump_vatop(kd, va, pa));
431 }
432