kvm: Dump page tables at exit

To make debugging more easy, dump page tables at exit as suggested by Avi
Kivity.

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
This commit is contained in:
Pekka Enberg
2010-04-11 09:28:14 +03:00
committed by Will Deacon
parent 2a7d39a4f0
commit f01944c845
3 changed files with 33 additions and 1 deletions
+1
View 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[];
+31 -1
View 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;
+1
View File
@@ -91,6 +91,7 @@ exit_kvm:
kvm__show_registers(kvm);
kvm__show_code(kvm);
kvm__show_page_tables(kvm);
kvm__delete(kvm);