Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: PPC: Add cache flush on page map

When we map a page that wasn't icache cleared before, do so when first
mapping it in KVM using the same information bits as the Linux mapping
logic. That way we are 100% sure that any page we map does not have stale
entries in the icache.

Signed-off-by: Alexander Graf <agraf@suse.de>

+22
+1
arch/powerpc/include/asm/kvm_host.h
··· 33 33 #include <asm/kvm_asm.h> 34 34 #include <asm/processor.h> 35 35 #include <asm/page.h> 36 + #include <asm/cacheflush.h> 36 37 37 38 #define KVM_MAX_VCPUS NR_CPUS 38 39 #define KVM_MAX_VCORES NR_CPUS
+12
arch/powerpc/include/asm/kvm_ppc.h
··· 219 219 void kvmppc_free_lpid(long lpid); 220 220 void kvmppc_init_lpid(unsigned long nr_lpids); 221 221 222 + static inline void kvmppc_mmu_flush_icache(pfn_t pfn) 223 + { 224 + /* Clear i-cache for new pages */ 225 + struct page *page; 226 + page = pfn_to_page(pfn); 227 + if (!test_bit(PG_arch_1, &page->flags)) { 228 + flush_dcache_icache_page(page); 229 + set_bit(PG_arch_1, &page->flags); 230 + } 231 + } 232 + 233 + 222 234 #endif /* __POWERPC_KVM_PPC_H__ */
+3
arch/powerpc/kvm/book3s_32_mmu_host.c
··· 211 211 pteg1 |= PP_RWRX; 212 212 } 213 213 214 + if (orig_pte->may_execute) 215 + kvmppc_mmu_flush_icache(hpaddr >> PAGE_SHIFT); 216 + 214 217 local_irq_disable(); 215 218 216 219 if (pteg[rr]) {
+2
arch/powerpc/kvm/book3s_64_mmu_host.c
··· 126 126 127 127 if (!orig_pte->may_execute) 128 128 rflags |= HPTE_R_N; 129 + else 130 + kvmppc_mmu_flush_icache(hpaddr >> PAGE_SHIFT); 129 131 130 132 hash = hpt_hash(va, PTE_SIZE, MMU_SEGSIZE_256M); 131 133
+3
arch/powerpc/kvm/e500_tlb.c
··· 539 539 540 540 kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize, 541 541 ref, gvaddr, stlbe); 542 + 543 + /* Clear i-cache for new pages */ 544 + kvmppc_mmu_flush_icache(pfn); 542 545 } 543 546 544 547 /* XXX only map the one-one case, for now use TLB0 */
+1
arch/powerpc/mm/mem.c
··· 469 469 __flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT); 470 470 #endif 471 471 } 472 + EXPORT_SYMBOL(flush_dcache_icache_page); 472 473 473 474 void clear_user_page(void *page, unsigned long vaddr, struct page *pg) 474 475 {