]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm: Dump page tables at exit
authorPekka Enberg <penberg@cs.helsinki.fi>
Sun, 11 Apr 2010 06:28:14 +0000 (09:28 +0300)
committerPekka Enberg <penberg@cs.helsinki.fi>
Sun, 11 Apr 2010 06:28:14 +0000 (09:28 +0300)
To make debugging more easy, dump page tables at exit as suggested by Avi
Kivity.

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
tools/kvm/include/kvm/kvm.h
tools/kvm/kvm.c
tools/kvm/main.c

index cddcad0a9f1d01a7d88fcd6af6ae5aea8a9afc72..61100151de377b069c9eff3e690f156402ef9750 100644 (file)
@@ -45,6 +45,7 @@ bool kvm__emulate_io(struct kvm *self, uint16_t port, void *data, int direction,
  */
 void kvm__show_code(struct kvm *self);
 void kvm__show_registers(struct kvm *self);
+void kvm__show_page_tables(struct kvm *self);
 void kvm__dump_mem(struct kvm *self, unsigned long addr, unsigned long size);
 
 extern const char *kvm_exit_reasons[];
index 1ecf79d86a656f3e1dd9d114a6eac0830eb0be66..64316875db874e7e8cb7926d3ae7c5496ab954af 100644 (file)
@@ -351,6 +351,11 @@ static inline uint64_t ip_flat_to_real(struct kvm *self, uint64_t ip)
        return ip - (cs << 4);
 }
 
+static inline bool is_in_protected_mode(struct kvm *self)
+{
+       return self->sregs.cr0 & 0x01;
+}
+
 static inline uint64_t ip_to_flat(struct kvm *self, uint64_t ip)
 {
        uint64_t cs;
@@ -359,7 +364,7 @@ static inline uint64_t ip_to_flat(struct kvm *self, uint64_t ip)
         * NOTE! We should take code segment base address into account here.
         * Luckily it's usually zero because Linux uses flat memory model.
         */
-       if (self->sregs.cr0 & 0x01)
+       if (is_in_protected_mode(self))
                return ip;
 
        cs = self->sregs.cs.selector;
@@ -659,6 +664,31 @@ void kvm__show_code(struct kvm *self)
        kvm__dump_mem(self, self->regs.rsp, 32);
 }
 
+void kvm__show_page_tables(struct kvm *self)
+{
+       uint64_t *pte1;
+       uint64_t *pte2;
+       uint64_t *pte3;
+       uint64_t *pte4;
+
+       if (!is_in_protected_mode(self))
+               return;
+
+       if (ioctl(self->vcpu_fd, KVM_GET_SREGS, &self->sregs) < 0)
+               die("KVM_GET_SREGS failed");
+
+       pte4    = guest_flat_to_host(self, self->sregs.cr3);
+       pte3    = guest_flat_to_host(self, (*pte4 & ~0xfff));
+       pte2    = guest_flat_to_host(self, (*pte3 & ~0xfff));
+       pte1    = guest_flat_to_host(self, (*pte2 & ~0xfff));
+
+       printf("Page Tables:\n");
+       if (*pte2 & (1 << 7))
+               printf(" pte4: %016lx   pte3: %016lx   pte2: %016lx\n", *pte4, *pte3, *pte2);
+       else
+               printf(" pte4: %016lx   pte3: %016lx   pte2: %016lx   pte1: %016lx\n", *pte4, *pte3, *pte2, *pte1);
+}
+
 void kvm__dump_mem(struct kvm *self, unsigned long addr, unsigned long size)
 {
        unsigned char *p;
index aa25bd81ebdb5f00cae013955f32703fc0a650d7..5e72cf5f781673f549cd1956d1596a4ff561f0f2 100644 (file)
@@ -91,6 +91,7 @@ exit_kvm:
 
        kvm__show_registers(kvm);
        kvm__show_code(kvm);
+       kvm__show_page_tables(kvm);
 
        kvm__delete(kvm);