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