diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c --- a/arch/powerpc/kvm/44x_tlb.c +++ b/arch/powerpc/kvm/44x_tlb.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "44x_tlb.h" @@ -29,6 +30,36 @@ #define PPC44x_TLB_SUPER_PERM_MASK (PPC44x_TLB_SX|PPC44x_TLB_SR|PPC44x_TLB_SW) static unsigned int kvmppc_tlb_44x_pos; + +void kvmppc_dump_tlb(struct kvm_vcpu *vcpu) +{ + struct tlbe *tlbe; + int i; + + printk("vcpu %d TLB dump:\n", vcpu->vcpu_id); + printk("| %2s | %8s | %8s | %8s | %8s |\n", + "nr", " tid ", "word0", "word1", "word2"); + + for (i = 0; i < PPC44x_TLB_SIZE; i++) + { + tlbe = &vcpu->arch.guest_tlb[i]; + if (tlbe->word0 & PPC44x_TLB_VALID) + printk("G%2d | %08X | %08X | %08X | %08X |\n", + i, tlbe->tid, tlbe->word0, tlbe->word1, tlbe->word2); + } + + msleep(500); + + for (i = 0; i < PPC44x_TLB_SIZE; i++) + { + tlbe = &vcpu->arch.shadow_tlb[i]; + if (tlbe->word0 & PPC44x_TLB_VALID) + printk("S%2d | %08X | %08X | %08X | %08X |\n", + i, tlbe->tid, tlbe->word0, tlbe->word1, tlbe->word2); + } + + msleep(500); +} static u32 kvmppc_44x_tlb_shadow_attrib(u32 attrib, int usermode) { diff --git a/arch/powerpc/kvm/44x_tlb.h b/arch/powerpc/kvm/44x_tlb.h --- a/arch/powerpc/kvm/44x_tlb.h +++ b/arch/powerpc/kvm/44x_tlb.h @@ -27,6 +27,8 @@ extern int kvmppc_44x_tlb_index(struct k unsigned int pid, unsigned int as); extern struct tlbe *kvmppc_44x_dtlb_search(struct kvm_vcpu *vcpu, gva_t eaddr); extern struct tlbe *kvmppc_44x_itlb_search(struct kvm_vcpu *vcpu, gva_t eaddr); + +extern void kvmppc_dump_tlb(struct kvm_vcpu *vcpu); /* TLB helper functions */ static inline unsigned int get_tlb_size(const struct tlbe *tlbe) diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -129,6 +130,7 @@ static int kvmppc_emul_tlbwe(struct kvm_ if (index > PPC44x_TLB_SIZE) { printk("%s: index %d\n", __func__, index); kvmppc_dump_vcpu(vcpu); + kvmppc_dump_tlb(vcpu); return EMULATE_FAIL; } @@ -138,6 +140,25 @@ static int kvmppc_emul_tlbwe(struct kvm_ #endif tlbe = &vcpu->arch.guest_tlb[index]; + + if ( ((get_tlb_eaddr(tlbe) & 0xf0000000) == 0xc0000000) + || + ((vcpu->arch.gpr[rs] & 0xf0000000) == 0xc0000000) ) { + printk("%s - writing or evicting guest kernel mapping" + "\n %02d: tid %08x w0 %08x w1 %08x w2 %08x," + "\n inst: ra %08x rs %08x ws %08x \n", + __func__, index, + tlbe->tid, tlbe->word0, tlbe->word1, tlbe->word2, + ra, rs, ws); + msleep(500); + kvmppc_dump_vcpu(vcpu); + msleep(500); + kvmppc_dump_tlb(vcpu); + msleep(500); + WARN_ON(1); + msleep(500); + } + /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */ if (tlbe->word0 & PPC44x_TLB_VALID) { @@ -250,6 +271,8 @@ int kvmppc_emulate_instruction(struct kv switch (get_op(inst)) { case 3: /* trap */ printk("trap!\n"); + kvmppc_dump_vcpu(vcpu); + kvmppc_dump_tlb(vcpu); kvmppc_queue_exception(vcpu, BOOKE_INTERRUPT_PROGRAM); advance = 0; break; diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -70,6 +70,7 @@ void kvmppc_dump_vcpu(struct kvm_vcpu *v printk("pc: %08x msr: %08x\n", vcpu->arch.pc, vcpu->arch.msr); printk("lr: %08x ctr: %08x\n", vcpu->arch.lr, vcpu->arch.ctr); printk("srr0: %08x srr1: %08x\n", vcpu->arch.srr0, vcpu->arch.srr1); + printk("dear: %08x esr: %08x\n", vcpu->arch.dear, vcpu->arch.esr); printk("exceptions: %08lx\n", vcpu->arch.pending_exceptions); @@ -218,6 +219,7 @@ int kvmppc_handle_exit(struct kvm_run *r case BOOKE_INTERRUPT_MACHINE_CHECK: printk("MACHINE CHECK: %lx\n", mfspr(SPRN_MCSR)); kvmppc_dump_vcpu(vcpu); + kvmppc_dump_tlb(vcpu); r = RESUME_HOST; break; @@ -309,7 +311,13 @@ int kvmppc_handle_exit(struct kvm_run *r /* Check the guest TLB. */ gtlbe = kvmppc_44x_dtlb_search(vcpu, eaddr); if (!gtlbe) { - /* The guest didn't have a mapping for it. */ + /* The guest didn't have a mapping for it. */ + if ((eaddr & 0xf0000000) == 0xc0000000) { + printk("DTLBMiss - Guest mapping f0r 0xc not found!\n"); + kvmppc_dump_vcpu(vcpu); + kvmppc_dump_tlb(vcpu); + } + kvmppc_queue_exception(vcpu, exit_nr); vcpu->arch.dear = vcpu->arch.fault_dear; vcpu->arch.esr = vcpu->arch.fault_esr; @@ -354,6 +362,12 @@ int kvmppc_handle_exit(struct kvm_run *r gtlbe = kvmppc_44x_itlb_search(vcpu, eaddr); if (!gtlbe) { /* The guest didn't have a mapping for it. */ + if ((eaddr & 0xf0000000) == 0xc0000000) { + printk("ITLBMiss - Guest mapping f0r 0xc not found!\n"); + kvmppc_dump_vcpu(vcpu); + kvmppc_dump_tlb(vcpu); + } + kvmppc_queue_exception(vcpu, exit_nr); r = RESUME_GUEST; break;