]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - tools/kvm/kvm.c
kvm: Don't crash debug dump if address isn't in guest memory
[karo-tx-linux.git] / tools / kvm / kvm.c
1 #include "kvm/kvm.h"
2
3 #include "kvm/interrupt.h"
4 #include "kvm/util.h"
5
6 #include <linux/kvm.h>
7
8 #include <asm/bootparam.h>
9
10 #include <sys/ioctl.h>
11 #include <inttypes.h>
12 #include <sys/mman.h>
13 #include <stdbool.h>
14 #include <assert.h>
15 #include <limits.h>
16 #include <stdarg.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <stdio.h>
21 #include <fcntl.h>
22
23 /*
24  * Compatibility code. Remove this when we move to tools/kvm.
25  */
26 #ifndef KVM_EXIT_INTERNAL_ERROR
27 # define KVM_EXIT_INTERNAL_ERROR                17
28 #endif
29
30 #define DEFINE_KVM_EXIT_REASON(reason) [reason] = #reason
31
32 const char *kvm_exit_reasons[] = {
33         DEFINE_KVM_EXIT_REASON(KVM_EXIT_UNKNOWN),
34         DEFINE_KVM_EXIT_REASON(KVM_EXIT_EXCEPTION),
35         DEFINE_KVM_EXIT_REASON(KVM_EXIT_IO),
36         DEFINE_KVM_EXIT_REASON(KVM_EXIT_HYPERCALL),
37         DEFINE_KVM_EXIT_REASON(KVM_EXIT_DEBUG),
38         DEFINE_KVM_EXIT_REASON(KVM_EXIT_HLT),
39         DEFINE_KVM_EXIT_REASON(KVM_EXIT_MMIO),
40         DEFINE_KVM_EXIT_REASON(KVM_EXIT_IRQ_WINDOW_OPEN),
41         DEFINE_KVM_EXIT_REASON(KVM_EXIT_SHUTDOWN),
42         DEFINE_KVM_EXIT_REASON(KVM_EXIT_FAIL_ENTRY),
43         DEFINE_KVM_EXIT_REASON(KVM_EXIT_INTR),
44         DEFINE_KVM_EXIT_REASON(KVM_EXIT_SET_TPR),
45         DEFINE_KVM_EXIT_REASON(KVM_EXIT_TPR_ACCESS),
46         DEFINE_KVM_EXIT_REASON(KVM_EXIT_S390_SIEIC),
47         DEFINE_KVM_EXIT_REASON(KVM_EXIT_S390_RESET),
48         DEFINE_KVM_EXIT_REASON(KVM_EXIT_DCR),
49         DEFINE_KVM_EXIT_REASON(KVM_EXIT_NMI),
50         DEFINE_KVM_EXIT_REASON(KVM_EXIT_INTERNAL_ERROR),
51 };
52
53 static inline bool host_ptr_in_ram(struct kvm *self, void *p)
54 {
55         return self->ram_start <= p && p < (self->ram_start + self->ram_size);
56 }
57
58 static inline uint32_t segment_to_flat(uint16_t selector, uint16_t offset)
59 {
60         return ((uint32_t)selector << 4) + (uint32_t) offset;
61 }
62
63 static inline void *guest_flat_to_host(struct kvm *self, unsigned long offset)
64 {
65         return self->ram_start + offset;
66 }
67
68 static inline void *guest_real_to_host(struct kvm *self, uint16_t selector, uint16_t offset)
69 {
70         unsigned long flat = segment_to_flat(selector, offset);
71
72         return guest_flat_to_host(self, flat);
73 }
74
75 static bool kvm__supports_extension(struct kvm *self, unsigned int extension)
76 {
77         int ret;
78
79         ret = ioctl(self->sys_fd, KVM_CHECK_EXTENSION, extension);
80         if (ret < 0)
81                 return false;
82
83         return ret;
84 }
85
86 static struct kvm *kvm__new(void)
87 {
88         struct kvm *self = calloc(1, sizeof *self);
89
90         if (!self)
91                 die("out of memory");
92
93         return self;
94 }
95
96 void kvm__delete(struct kvm *self)
97 {
98         free(self->ram_start);
99         free(self);
100 }
101
102 struct kvm *kvm__init(void)
103 {
104         struct kvm_userspace_memory_region mem;
105         struct kvm *self;
106         long page_size;
107         int mmap_size;
108         int ret;
109
110         self = kvm__new();
111
112         self->sys_fd = open("/dev/kvm", O_RDWR);
113         if (self->sys_fd < 0)
114                 die_perror("open");
115
116         ret = ioctl(self->sys_fd, KVM_GET_API_VERSION, 0);
117         if (ret != KVM_API_VERSION)
118                 die_perror("KVM_API_VERSION ioctl");
119
120         self->vm_fd = ioctl(self->sys_fd, KVM_CREATE_VM, 0);
121         if (self->vm_fd < 0)
122                 die_perror("KVM_CREATE_VM ioctl");
123
124         if (!kvm__supports_extension(self, KVM_CAP_USER_MEMORY))
125                 die("KVM_CAP_USER_MEMORY is not supported");
126
127         self->ram_size          = 64UL * 1024UL * 1024UL;
128
129         page_size       = sysconf(_SC_PAGESIZE);
130         if (posix_memalign(&self->ram_start, page_size, self->ram_size) != 0)
131                 die("out of memory");
132
133         mem = (struct kvm_userspace_memory_region) {
134                 .slot                   = 0,
135                 .guest_phys_addr        = 0x0UL,
136                 .memory_size            = self->ram_size,
137                 .userspace_addr         = (unsigned long) self->ram_start,
138         };
139
140         ret = ioctl(self->vm_fd, KVM_SET_USER_MEMORY_REGION, &mem, 1);
141         if (ret < 0)
142                 die_perror("KVM_SET_USER_MEMORY_REGION ioctl");
143
144         if (!kvm__supports_extension(self, KVM_CAP_SET_TSS_ADDR))
145                 die("KVM_CAP_SET_TSS_ADDR is not supported");
146
147         ret = ioctl(self->vm_fd, KVM_SET_TSS_ADDR, 0xfffbd000);
148         if (ret < 0)
149                 die_perror("KVM_SET_TSS_ADDR ioctl");
150
151         self->vcpu_fd = ioctl(self->vm_fd, KVM_CREATE_VCPU, 0);
152         if (self->vcpu_fd < 0)
153                 die_perror("KVM_CREATE_VCPU ioctl");
154
155         mmap_size = ioctl(self->sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0);
156         if (mmap_size < 0)
157                 die_perror("KVM_GET_VCPU_MMAP_SIZE ioctl");
158
159         self->kvm_run = mmap(NULL, mmap_size, PROT_READ|PROT_WRITE, MAP_SHARED, self->vcpu_fd, 0);
160         if (self->kvm_run == MAP_FAILED)
161                 die("unable to mmap vcpu fd");
162
163         return self;
164 }
165
166 void kvm__enable_singlestep(struct kvm *self)
167 {
168         struct kvm_guest_debug debug = {
169                 .control        = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP,
170         };
171
172         if (ioctl(self->vcpu_fd, KVM_SET_GUEST_DEBUG, &debug) < 0)
173                 warning("KVM_SET_GUEST_DEBUG failed");
174 }
175
176 #define BOOT_LOADER_SELECTOR    0x1000
177 #define BOOT_LOADER_IP          0x0000
178 #define BOOT_LOADER_SP          0x8000
179
180 static int load_flat_binary(struct kvm *self, int fd)
181 {
182         void *p;
183         int nr;
184
185         if (lseek(fd, 0, SEEK_SET) < 0)
186                 die_perror("lseek");
187
188         p = guest_real_to_host(self, BOOT_LOADER_SELECTOR, BOOT_LOADER_IP);
189
190         while ((nr = read(fd, p, 65536)) > 0)
191                 p += nr;
192
193         self->boot_selector     = BOOT_LOADER_SELECTOR;
194         self->boot_ip           = BOOT_LOADER_IP;
195         self->boot_sp           = BOOT_LOADER_SP;
196
197         return true;
198 }
199
200 /*
201  * The protected mode kernel part of a modern bzImage is loaded at 1 MB by
202  * default.
203  */
204 #define BZ_KERNEL_START                 0x100000UL
205
206 static const char *BZIMAGE_MAGIC        = "HdrS";
207
208 #define BZ_DEFAULT_SETUP_SECTS          4
209
210 static bool load_bzimage(struct kvm *self, int fd, const char *kernel_cmdline)
211 {
212         struct real_intr_desc intr;
213         struct boot_params boot;
214         unsigned long setup_sects;
215         unsigned int intr_addr;
216         size_t cmdline_size, cmdline_offset;
217         ssize_t setup_size;
218         void *p;
219         int nr;
220
221         /*
222          * See Documentation/x86/boot.txt for details no bzImage on-disk and
223          * memory layout.
224          */
225
226         if (lseek(fd, 0, SEEK_SET) < 0)
227                 die_perror("lseek");
228
229         read(fd, &boot, sizeof(boot));
230
231         if (memcmp(&boot.hdr.header, BZIMAGE_MAGIC, strlen(BZIMAGE_MAGIC)) != 0)
232                 return false;
233
234         if (boot.hdr.version < 0x0200) {
235                 warning("Too old kernel");
236                 return false;
237         }
238
239         if (lseek(fd, 0, SEEK_SET) < 0)
240                 die_perror("lseek");
241
242         if (!boot.hdr.setup_sects)
243                 boot.hdr.setup_sects = BZ_DEFAULT_SETUP_SECTS;
244         setup_sects = boot.hdr.setup_sects + 1;
245
246         setup_size = setup_sects << 9;
247         p = guest_real_to_host(self, BOOT_LOADER_SELECTOR, BOOT_LOADER_IP);
248
249         if (read(fd, p, setup_size) != setup_size)
250                 die_perror("read");
251
252         p = guest_flat_to_host(self, BZ_KERNEL_START);
253
254         while ((nr = read(fd, p, 65536)) > 0)
255                 p += nr;
256
257         if (boot.hdr.version < 0x0206)
258                 boot.hdr.cmdline_size = 256;
259
260         if (kernel_cmdline) {
261                 cmdline_size = strlen(kernel_cmdline) + 1;
262                 if (cmdline_size > boot.hdr.cmdline_size)
263                         cmdline_size = boot.hdr.cmdline_size;
264         } else
265                 cmdline_size = 0;
266                 
267
268         if (boot.hdr.version < 0x0202 || !(boot.hdr.loadflags & 0x01))
269                 cmdline_offset = (0x9ff0 - cmdline_size) & ~15;
270         else
271                 cmdline_offset = 0x10000;
272
273         if (kernel_cmdline) {
274                 p = guest_flat_to_host(self, cmdline_offset);
275                 memset(p, 0, cmdline_size);
276                 strcpy(p, kernel_cmdline);
277         }
278
279         if (boot.hdr.version >= 0x0200) {
280                 if (boot.hdr.version >= 0x0202) {
281                         boot.hdr.cmd_line_ptr =
282                                 (BOOT_LOADER_SELECTOR << 4) + cmdline_offset;
283                 } else if (boot.hdr.version >= 0x0201) {
284                         boot.hdr.heap_end_ptr = cmdline_offset - 0x0200;
285                         boot.hdr.loadflags |= CAN_USE_HEAP;
286                 }
287
288         }
289
290         self->boot_selector     = BOOT_LOADER_SELECTOR;
291         /*
292          * The real-mode setup code starts at offset 0x200 of a bzImage. See
293          * Documentation/x86/boot.txt for details.
294          */
295         self->boot_ip           = BOOT_LOADER_IP + 0x200;
296         self->boot_sp           = BOOT_LOADER_SP;
297
298         /*
299          * Setup a *fake* real mode vector table, it has only
300          * one real hadler which does just iret
301          *
302          * This is where the BIOS lives -- BDA area
303          */
304         intr_addr = BIOS_INTR_NEXT(BDA_START + 0, 16);
305         p = guest_flat_to_host(self, intr_addr);
306         memcpy(p, intfake, intfake_size);
307         intr = (struct real_intr_desc) {
308                 .segment        = REAL_SEGMENT(intr_addr),
309                 .offset         = 0,
310         };
311         interrupt_table__setup(&self->interrupt_table, &intr);
312
313         intr_addr = BIOS_INTR_NEXT(BDA_START + intfake_size, 16);
314         p = guest_flat_to_host(self, intr_addr);
315         memcpy(p, int10, int10_size);
316         intr = (struct real_intr_desc) {
317                 .segment        = REAL_SEGMENT(intr_addr),
318                 .offset         = 0,
319         };
320         interrupt_table__set(&self->interrupt_table, &intr, 0x10);
321
322         p = guest_flat_to_host(self, 0);
323         interrupt_table__copy(&self->interrupt_table, p, REAL_INTR_SIZE);
324
325         return true;
326 }
327
328 bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,
329                         const char *kernel_cmdline)
330 {
331         bool ret;
332         int fd;
333
334         fd = open(kernel_filename, O_RDONLY);
335         if (fd < 0)
336                 die("unable to open kernel");
337
338         ret = load_bzimage(kvm, fd, kernel_cmdline);
339         if (ret)
340                 goto found_kernel;
341
342         ret = load_flat_binary(kvm, fd);
343         if (ret)
344                 goto found_kernel;
345
346         die("%s is not a valid bzImage or flat binary", kernel_filename);
347
348 found_kernel:
349         return ret;
350 }
351
352 static inline uint64_t ip_flat_to_real(struct kvm *self, uint64_t ip)
353 {
354         uint64_t cs = self->sregs.cs.selector;
355
356         return ip - (cs << 4);
357 }
358
359 static inline bool is_in_protected_mode(struct kvm *self)
360 {
361         return self->sregs.cr0 & 0x01;
362 }
363
364 static inline uint64_t ip_to_flat(struct kvm *self, uint64_t ip)
365 {
366         uint64_t cs;
367
368         /*
369          * NOTE! We should take code segment base address into account here.
370          * Luckily it's usually zero because Linux uses flat memory model.
371          */
372         if (is_in_protected_mode(self))
373                 return ip;
374
375         cs = self->sregs.cs.selector;
376
377         return ip + (cs << 4);
378 }
379
380 static inline uint32_t selector_to_base(uint16_t selector)
381 {
382         /*
383          * KVM on Intel requires 'base' to be 'selector * 16' in real mode.
384          */
385         return (uint32_t)selector * 16;
386 }
387
388 static struct kvm_msrs *kvm_msrs__new(size_t nmsrs)
389 {
390         struct kvm_msrs *self = calloc(1, sizeof(*self) + (sizeof(struct kvm_msr_entry) * nmsrs));
391
392         if (!self)
393                 die("out of memory");
394
395         return self;
396 }
397
398 #define MSR_IA32_TIME_STAMP_COUNTER     0x10
399
400 #define MSR_IA32_SYSENTER_CS            0x174
401 #define MSR_IA32_SYSENTER_ESP           0x175
402 #define MSR_IA32_SYSENTER_EIP           0x176
403
404 #define MSR_IA32_STAR                   0xc0000081
405 #define MSR_IA32_LSTAR                  0xc0000082
406 #define MSR_IA32_CSTAR                  0xc0000083
407 #define MSR_IA32_FMASK                  0xc0000084
408 #define MSR_IA32_KERNEL_GS_BASE         0xc0000102
409
410 #define KVM_MSR_ENTRY(_index, _data)    \
411         (struct kvm_msr_entry) { .index = _index, .data = _data }
412
413 static void kvm__setup_msrs(struct kvm *self)
414 {
415         unsigned long ndx = 0;
416
417         self->msrs = kvm_msrs__new(100);
418
419         self->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_SYSENTER_CS,        0x0);
420         self->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_SYSENTER_ESP,       0x0);
421         self->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_SYSENTER_EIP,       0x0);
422         self->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_STAR,               0x0);
423         self->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_CSTAR,              0x0);
424         self->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_KERNEL_GS_BASE,     0x0);
425         self->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_FMASK,              0x0);
426         self->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_LSTAR,              0x0);
427         self->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_TIME_STAMP_COUNTER, 0x0);
428
429         self->msrs->nmsrs       = ndx;
430
431         if (ioctl(self->vcpu_fd, KVM_SET_MSRS, self->msrs) < 0)
432                 die_perror("KVM_SET_MSRS failed");
433 }
434
435 static void kvm__setup_fpu(struct kvm *self)
436 {
437         self->fpu = (struct kvm_fpu) {
438                 .fcw            = 0x37f,
439                 .mxcsr          = 0x1f80,
440         };
441
442         if (ioctl(self->vcpu_fd, KVM_SET_FPU, &self->fpu) < 0)
443                 die_perror("KVM_SET_FPU failed");
444 }
445
446 static void kvm__setup_regs(struct kvm *self)
447 {
448         self->regs = (struct kvm_regs) {
449                 /* We start the guest in 16-bit real mode  */
450                 .rflags         = 0x0000000000000002ULL,
451
452                 .rip            = self->boot_ip,
453                 .rsp            = self->boot_sp,
454                 .rbp            = self->boot_sp,
455         };
456
457         if (self->regs.rip > USHRT_MAX)
458                 die("ip 0x%" PRIx64 " is too high for real mode", (uint64_t) self->regs.rip);
459
460         if (ioctl(self->vcpu_fd, KVM_SET_REGS, &self->regs) < 0)
461                 die_perror("KVM_SET_REGS failed");
462 }
463
464 static void kvm__setup_sregs(struct kvm *self)
465 {
466         self->sregs = (struct kvm_sregs) {
467                 .cr0            = 0x60000010ULL,
468                 .cs             = (struct kvm_segment) {
469                         .selector       = self->boot_selector,
470                         .base           = selector_to_base(self->boot_selector),
471                         .limit          = 0xffffU,
472                         .type           = 0x0bU,
473                         .present        = 1,
474                         .dpl            = 0x03,
475                         .s              = 1,
476                 },
477                 .ss             = (struct kvm_segment) {
478                         .selector       = self->boot_selector,
479                         .base           = selector_to_base(self->boot_selector),
480                         .limit          = 0xffffU,
481                         .type           = 0x03U,
482                         .present        = 1,
483                         .dpl            = 0x03,
484                         .s              = 1,
485                 },
486                 .ds             = (struct kvm_segment) {
487                         .selector       = self->boot_selector,
488                         .base           = selector_to_base(self->boot_selector),
489                         .limit          = 0xffffU,
490                         .type           = 0x03U,
491                         .present        = 1,
492                         .dpl            = 0x03,
493                         .s              = 1,
494                 },
495                 .es             = (struct kvm_segment) {
496                         .selector       = self->boot_selector,
497                         .base           = selector_to_base(self->boot_selector),
498                         .limit          = 0xffffU,
499                         .type           = 0x03U,
500                         .present        = 1,
501                         .dpl            = 0x03,
502                         .s              = 1,
503                 },
504                 .fs             = (struct kvm_segment) {
505                         .selector       = self->boot_selector,
506                         .base           = selector_to_base(self->boot_selector),
507                         .limit          = 0xffffU,
508                         .type           = 0x03U,
509                         .present        = 1,
510                         .dpl            = 0x03,
511                         .s              = 1,
512                 },
513                 .gs             = (struct kvm_segment) {
514                         .selector       = self->boot_selector,
515                         .base           = selector_to_base(self->boot_selector),
516                         .limit          = 0xffffU,
517                         .type           = 0x03U,
518                         .present        = 1,
519                         .dpl            = 0x03,
520                         .s              = 1,
521                 },
522                 .tr             = (struct kvm_segment) {
523                         .limit          = 0xffffU,
524                         .present        = 1,
525                         .type           = 0x03U,
526                 },
527                 .ldt            = (struct kvm_segment) {
528                         .limit          = 0xffffU,
529                         .present        = 1,
530                         .type           = 0x02U,
531                 },
532                 .gdt            = (struct kvm_dtable) {
533                         .limit          = 0xffffU,
534                 },
535                 .idt            = (struct kvm_dtable) {
536                         .limit          = 0xffffU,
537                 },
538         };
539
540         if (ioctl(self->vcpu_fd, KVM_SET_SREGS, &self->sregs) < 0)
541                 die_perror("KVM_SET_SREGS failed");
542 }
543
544 void kvm__reset_vcpu(struct kvm *self)
545 {
546         kvm__setup_sregs(self);
547
548         kvm__setup_regs(self);
549
550         kvm__setup_fpu(self);
551
552         kvm__setup_msrs(self);
553 }
554
555 void kvm__run(struct kvm *self)
556 {
557         if (ioctl(self->vcpu_fd, KVM_RUN, 0) < 0)
558                 die_perror("KVM_RUN failed");
559 }
560
561 static void print_dtable(const char *name, struct kvm_dtable *dtable)
562 {
563         printf(" %s                 %016" PRIx64 "  %08" PRIx16 "\n",
564                 name, (uint64_t) dtable->base, (uint16_t) dtable->limit);
565 }
566
567 static void print_segment(const char *name, struct kvm_segment *seg)
568 {
569         printf(" %s       %04" PRIx16 "      %016" PRIx64 "  %08" PRIx32 "  %02" PRIx8 "    %x %x   %x  %x %x %x %x\n",
570                 name, (uint16_t) seg->selector, (uint64_t) seg->base, (uint32_t) seg->limit,
571                 (uint8_t) seg->type, seg->present, seg->dpl, seg->db, seg->s, seg->l, seg->g, seg->avl);
572 }
573
574 void kvm__show_registers(struct kvm *self)
575 {
576         unsigned long cr0, cr2, cr3;
577         unsigned long cr4, cr8;
578         unsigned long rax, rbx, rcx;
579         unsigned long rdx, rsi, rdi;
580         unsigned long rbp,  r8,  r9;
581         unsigned long r10, r11, r12;
582         unsigned long r13, r14, r15;
583         unsigned long rip, rsp;
584         struct kvm_sregs sregs;
585         unsigned long rflags;
586         struct kvm_regs regs;
587         int i;
588
589         if (ioctl(self->vcpu_fd, KVM_GET_REGS, &regs) < 0)
590                 die("KVM_GET_REGS failed");
591
592         rflags = regs.rflags;
593
594         rip = regs.rip; rsp = regs.rsp;
595         rax = regs.rax; rbx = regs.rbx; rcx = regs.rcx;
596         rdx = regs.rdx; rsi = regs.rsi; rdi = regs.rdi;
597         rbp = regs.rbp; r8  = regs.r8;  r9  = regs.r9;
598         r10 = regs.r10; r11 = regs.r11; r12 = regs.r12;
599         r13 = regs.r13; r14 = regs.r14; r15 = regs.r15;
600
601         printf("Registers:\n");
602         printf(" rip: %016lx   rsp: %016lx flags: %016lx\n", rip, rsp, rflags);
603         printf(" rax: %016lx   rbx: %016lx   rcx: %016lx\n", rax, rbx, rcx);
604         printf(" rdx: %016lx   rsi: %016lx   rdi: %016lx\n", rdx, rsi, rdi);
605         printf(" rbp: %016lx   r8:  %016lx   r9:  %016lx\n", rbp, r8,  r9);
606         printf(" r10: %016lx   r11: %016lx   r12: %016lx\n", r10, r11, r12);
607         printf(" r13: %016lx   r14: %016lx   r15: %016lx\n", r13, r14, r15);
608
609         if (ioctl(self->vcpu_fd, KVM_GET_SREGS, &sregs) < 0)
610                 die("KVM_GET_REGS failed");
611
612         cr0 = sregs.cr0; cr2 = sregs.cr2; cr3 = sregs.cr3;
613         cr4 = sregs.cr4; cr8 = sregs.cr8;
614
615         printf(" cr0: %016lx   cr2: %016lx   cr3: %016lx\n", cr0, cr2, cr3);
616         printf(" cr4: %016lx   cr8: %016lx\n", cr4, cr8);
617         printf("Segment registers:\n");
618         printf(" register  selector  base              limit     type  p dpl db s l g avl\n");
619         print_segment("cs ", &sregs.cs);
620         print_segment("ss ", &sregs.ss);
621         print_segment("ds ", &sregs.ds);
622         print_segment("es ", &sregs.es);
623         print_segment("fs ", &sregs.fs);
624         print_segment("gs ", &sregs.gs);
625         print_segment("tr ", &sregs.tr);
626         print_segment("ldt", &sregs.ldt);
627         print_dtable("gdt", &sregs.gdt);
628         print_dtable("idt", &sregs.idt);
629         printf(" [ efer: %016lx  apic base: %016lx  nmi: %s ]\n", (uint64_t) sregs.efer, (uint64_t) sregs.apic_base,
630                 (self->nmi_disabled ? "disabled" : "enabled"));
631         printf("Interrupt bitmap:\n");
632         printf(" ");
633         for (i = 0; i < (KVM_NR_INTERRUPTS + 63) / 64; i++)
634                 printf("%016lx ", (uint64_t) sregs.interrupt_bitmap[i]);
635         printf("\n");
636 }
637
638 void kvm__show_code(struct kvm *self)
639 {
640         unsigned int code_bytes = 64;
641         unsigned int code_prologue = code_bytes * 43 / 64;
642         unsigned int code_len = code_bytes;
643         unsigned char c;
644         unsigned int i;
645         uint8_t *ip;
646
647         if (ioctl(self->vcpu_fd, KVM_GET_REGS, &self->regs) < 0)
648                 die("KVM_GET_REGS failed");
649
650         if (ioctl(self->vcpu_fd, KVM_GET_SREGS, &self->sregs) < 0)
651                 die("KVM_GET_SREGS failed");
652
653         ip = guest_flat_to_host(self, ip_to_flat(self, self->regs.rip) - code_prologue);
654
655         printf("Code: ");
656
657         for (i = 0; i < code_len; i++, ip++) {
658                 if (!host_ptr_in_ram(self, ip))
659                         break;
660
661                 c = *ip;
662
663                 if (ip == guest_flat_to_host(self, ip_to_flat(self, self->regs.rip)))
664                         printf("<%02x> ", c);
665                 else
666                         printf("%02x ", c);
667         }
668
669         printf("\n");
670
671         printf("Stack:\n");
672         kvm__dump_mem(self, self->regs.rsp, 32);
673 }
674
675 void kvm__show_page_tables(struct kvm *self)
676 {
677         uint64_t *pte1;
678         uint64_t *pte2;
679         uint64_t *pte3;
680         uint64_t *pte4;
681
682         if (!is_in_protected_mode(self))
683                 return;
684
685         if (ioctl(self->vcpu_fd, KVM_GET_SREGS, &self->sregs) < 0)
686                 die("KVM_GET_SREGS failed");
687
688         pte4    = guest_flat_to_host(self, self->sregs.cr3);
689         if (!host_ptr_in_ram(self, pte4))
690                 return;
691
692         pte3    = guest_flat_to_host(self, (*pte4 & ~0xfff));
693         if (!host_ptr_in_ram(self, pte3))
694                 return;
695
696         pte2    = guest_flat_to_host(self, (*pte3 & ~0xfff));
697         if (!host_ptr_in_ram(self, pte2))
698                 return;
699
700         pte1    = guest_flat_to_host(self, (*pte2 & ~0xfff));
701         if (!host_ptr_in_ram(self, pte1))
702                 return;
703
704         printf("Page Tables:\n");
705         if (*pte2 & (1 << 7))
706                 printf(" pte4: %016lx   pte3: %016lx   pte2: %016lx\n", *pte4, *pte3, *pte2);
707         else
708                 printf(" pte4: %016lx   pte3: %016lx   pte2: %016lx   pte1: %016lx\n", *pte4, *pte3, *pte2, *pte1);
709 }
710
711 void kvm__dump_mem(struct kvm *self, unsigned long addr, unsigned long size)
712 {
713         unsigned char *p;
714         unsigned long n;
715
716         size &= ~7; /* mod 8 */
717         if (!size)
718                 return;
719
720         p = guest_flat_to_host(self, addr);
721
722         for (n = 0; n < size; n+=8) {
723                 if (!host_ptr_in_ram(self, p + n))
724                         break;
725
726                 printf("  0x%08lx: %02x %02x %02x %02x  %02x %02x %02x %02x\n",
727                         addr + n, p[n + 0], p[n + 1], p[n + 2], p[n + 3],
728                                   p[n + 4], p[n + 5], p[n + 6], p[n + 7]);
729         }
730 }