Merge tag 'for-linus-v4.8' of git://github.com/martinbrandenburg/linux
[deliverable/linux.git] / arch / mips / kvm / tlb.c
index 4825d0dbb65eee61bf7605f784c4afa2c2d11464..254377d8e0b9921ff56dab3c2ef17d0996d95c57 100644 (file)
@@ -86,19 +86,20 @@ void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu)
        for (i = 0; i < KVM_MIPS_GUEST_TLB_SIZE; i++) {
                tlb = vcpu->arch.guest_tlb[i];
                kvm_info("TLB%c%3d Hi 0x%08lx ",
-                        (tlb.tlb_lo[0] | tlb.tlb_lo[1]) & MIPS3_PG_V
+                        (tlb.tlb_lo[0] | tlb.tlb_lo[1]) & ENTRYLO_V
                                                        ? ' ' : '*',
                         i, tlb.tlb_hi);
                kvm_info("Lo0=0x%09llx %c%c attr %lx ",
                         (u64) mips3_tlbpfn_to_paddr(tlb.tlb_lo[0]),
-                        (tlb.tlb_lo[0] & MIPS3_PG_D) ? 'D' : ' ',
-                        (tlb.tlb_lo[0] & MIPS3_PG_G) ? 'G' : ' ',
-                        (tlb.tlb_lo[0] >> 3) & 7);
+                        (tlb.tlb_lo[0] & ENTRYLO_D) ? 'D' : ' ',
+                        (tlb.tlb_lo[0] & ENTRYLO_G) ? 'G' : ' ',
+                        (tlb.tlb_lo[0] & ENTRYLO_C) >> ENTRYLO_C_SHIFT);
                kvm_info("Lo1=0x%09llx %c%c attr %lx sz=%lx\n",
                         (u64) mips3_tlbpfn_to_paddr(tlb.tlb_lo[1]),
-                        (tlb.tlb_lo[1] & MIPS3_PG_D) ? 'D' : ' ',
-                        (tlb.tlb_lo[1] & MIPS3_PG_G) ? 'G' : ' ',
-                        (tlb.tlb_lo[1] >> 3) & 7, tlb.tlb_mask);
+                        (tlb.tlb_lo[1] & ENTRYLO_D) ? 'D' : ' ',
+                        (tlb.tlb_lo[1] & ENTRYLO_G) ? 'G' : ' ',
+                        (tlb.tlb_lo[1] & ENTRYLO_C) >> ENTRYLO_C_SHIFT,
+                        tlb.tlb_mask);
        }
 }
 EXPORT_SYMBOL_GPL(kvm_mips_dump_guest_tlbs);
@@ -146,12 +147,12 @@ int kvm_mips_host_tlb_write(struct kvm_vcpu *vcpu, unsigned long entryhi,
 
        /* Flush D-cache */
        if (flush_dcache_mask) {
-               if (entrylo0 & MIPS3_PG_V) {
+               if (entrylo0 & ENTRYLO_V) {
                        ++vcpu->stat.flush_dcache_exits;
                        flush_data_cache_page((entryhi & VPN2_MASK) &
                                              ~flush_dcache_mask);
                }
-               if (entrylo1 & MIPS3_PG_V) {
+               if (entrylo1 & ENTRYLO_V) {
                        ++vcpu->stat.flush_dcache_exits;
                        flush_data_cache_page(((entryhi & VPN2_MASK) &
                                               ~flush_dcache_mask) |
@@ -170,23 +171,24 @@ EXPORT_SYMBOL_GPL(kvm_mips_host_tlb_write);
 int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr,
        struct kvm_vcpu *vcpu)
 {
-       kvm_pfn_t pfn0, pfn1;
+       kvm_pfn_t pfn;
        unsigned long flags, old_entryhi = 0, vaddr = 0;
-       unsigned long entrylo0 = 0, entrylo1 = 0;
+       unsigned long entrylo[2] = { 0, 0 };
+       unsigned int pair_idx;
 
-       pfn0 = CPHYSADDR(vcpu->arch.kseg0_commpage) >> PAGE_SHIFT;
-       pfn1 = 0;
-       entrylo0 = mips3_paddr_to_tlbpfn(pfn0 << PAGE_SHIFT) | (0x3 << 3) |
-                  (1 << 2) | (0x1 << 1);
-       entrylo1 = 0;
+       pfn = PFN_DOWN(virt_to_phys(vcpu->arch.kseg0_commpage));
+       pair_idx = (badvaddr >> PAGE_SHIFT) & 1;
+       entrylo[pair_idx] = mips3_paddr_to_tlbpfn(pfn << PAGE_SHIFT) |
+               ((_page_cachable_default >> _CACHE_SHIFT) << ENTRYLO_C_SHIFT) |
+               ENTRYLO_D | ENTRYLO_V;
 
        local_irq_save(flags);
 
        old_entryhi = read_c0_entryhi();
        vaddr = badvaddr & (PAGE_MASK << 1);
        write_c0_entryhi(vaddr | kvm_mips_get_kernel_asid(vcpu));
-       write_c0_entrylo0(entrylo0);
-       write_c0_entrylo1(entrylo1);
+       write_c0_entrylo0(entrylo[0]);
+       write_c0_entrylo1(entrylo[1]);
        write_c0_index(kvm_mips_get_commpage_asid(vcpu));
        mtc0_tlbw_hazard();
        tlb_write_indexed();
@@ -330,6 +332,8 @@ void kvm_mips_flush_host_tlb(int skip_kseg0)
                        /* Don't blow away guest kernel entries */
                        if (KVM_GUEST_KSEGX(entryhi) == KVM_GUEST_KSEG0)
                                continue;
+
+                       write_c0_pagemask(old_pagemask);
                }
 
                /* Make sure all entries differ. */
This page took 0.026403 seconds and 5 git commands to generate.