diff options
Diffstat (limited to 'arch/powerpc/kvm/booke_interrupts.S')
-rw-r--r-- | arch/powerpc/kvm/booke_interrupts.S | 79 |
1 files changed, 47 insertions, 32 deletions
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S index 3b653b5309b8..95e165baf85f 100644 --- a/arch/powerpc/kvm/booke_interrupts.S +++ b/arch/powerpc/kvm/booke_interrupts.S @@ -42,7 +42,8 @@ #define HOST_STACK_LR (HOST_STACK_SIZE + 4) /* In caller stack frame. */ #define NEED_INST_MASK ((1<<BOOKE_INTERRUPT_PROGRAM) | \ - (1<<BOOKE_INTERRUPT_DTLB_MISS)) + (1<<BOOKE_INTERRUPT_DTLB_MISS) | \ + (1<<BOOKE_INTERRUPT_DEBUG)) #define NEED_DEAR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \ (1<<BOOKE_INTERRUPT_DTLB_MISS)) @@ -331,51 +332,57 @@ lightweight_exit: mfspr r3, SPRN_PID stw r3, VCPU_HOST_PID(r4) - lwz r3, VCPU_PID(r4) + lwz r3, VCPU_SHADOW_PID(r4) mtspr SPRN_PID, r3 - /* Prevent all TLB updates. */ + /* Prevent all asynchronous TLB updates. */ mfmsr r5 lis r6, (MSR_EE|MSR_CE|MSR_ME|MSR_DE)@h ori r6, r6, (MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l andc r6, r5, r6 mtmsr r6 - /* Save the host's non-pinned TLB mappings, and load the guest mappings - * over them. Leave the host's "pinned" kernel mappings in place. */ - /* XXX optimization: use generation count to avoid swapping unmodified - * entries. */ + /* Load the guest mappings, leaving the host's "pinned" kernel mappings + * in place. */ mfspr r10, SPRN_MMUCR /* Save host MMUCR. */ - lis r8, tlb_44x_hwater@ha - lwz r8, tlb_44x_hwater@l(r8) - addi r3, r4, VCPU_HOST_TLB - 4 - addi r9, r4, VCPU_SHADOW_TLB - 4 - li r6, 0 + li r5, PPC44x_TLB_SIZE + lis r5, tlb_44x_hwater@ha + lwz r5, tlb_44x_hwater@l(r5) + mtctr r5 + addi r9, r4, VCPU_SHADOW_TLB + addi r5, r4, VCPU_SHADOW_MOD + li r3, 0 1: - /* Save host entry. */ - tlbre r7, r6, PPC44x_TLB_PAGEID - mfspr r5, SPRN_MMUCR - stwu r5, 4(r3) - stwu r7, 4(r3) - tlbre r7, r6, PPC44x_TLB_XLAT - stwu r7, 4(r3) - tlbre r7, r6, PPC44x_TLB_ATTRIB - stwu r7, 4(r3) + lbzx r7, r3, r5 + cmpwi r7, 0 + beq 3f + /* Load guest entry. */ - lwzu r7, 4(r9) + mulli r11, r3, TLBE_BYTES + add r11, r11, r9 + lwz r7, 0(r11) mtspr SPRN_MMUCR, r7 - lwzu r7, 4(r9) - tlbwe r7, r6, PPC44x_TLB_PAGEID - lwzu r7, 4(r9) - tlbwe r7, r6, PPC44x_TLB_XLAT - lwzu r7, 4(r9) - tlbwe r7, r6, PPC44x_TLB_ATTRIB - /* Increment index. */ - addi r6, r6, 1 - cmpw r6, r8 - blt 1b + lwz r7, 4(r11) + tlbwe r7, r3, PPC44x_TLB_PAGEID + lwz r7, 8(r11) + tlbwe r7, r3, PPC44x_TLB_XLAT + lwz r7, 12(r11) + tlbwe r7, r3, PPC44x_TLB_ATTRIB +3: + addi r3, r3, 1 /* Increment index. */ + bdnz 1b + mtspr SPRN_MMUCR, r10 /* Restore host MMUCR. */ + /* Clear bitmap of modified TLB entries */ + li r5, PPC44x_TLB_SIZE>>2 + mtctr r5 + addi r5, r4, VCPU_SHADOW_MOD - 4 + li r6, 0 +1: + stwu r6, 4(r5) + bdnz 1b + iccci 0, 0 /* XXX hack */ /* Load some guest volatiles. */ @@ -431,6 +438,14 @@ lightweight_exit: oris r3, r3, KVMPPC_MSR_MASK@h ori r3, r3, KVMPPC_MSR_MASK@l mtsrr1 r3 + + /* Clear any debug events which occurred since we disabled MSR[DE]. + * XXX This gives us a 3-instruction window in which a breakpoint + * intended for guest context could fire in the host instead. */ + lis r3, 0xffff + ori r3, r3, 0xffff + mtspr SPRN_DBSR, r3 + lwz r3, VCPU_GPR(r3)(r4) lwz r4, VCPU_GPR(r4)(r4) rfi |