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