summaryrefslogtreecommitdiffstats
path: root/arch/arm/include/asm/kvm_mmu.h
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2017-01-25 13:29:59 +0100
committerMarc Zyngier <marc.zyngier@arm.com>2017-01-30 14:47:37 +0100
commit8f36ebaf21fdae99c091c67e8b6fab33969f2667 (patch)
tree19f178720ef8382deb6247a6b4c5c388fe479799 /arch/arm/include/asm/kvm_mmu.h
parentKVM: arm/arm64: Documentation: Update arm-vgic-v3.txt (diff)
downloadlinux-8f36ebaf21fdae99c091c67e8b6fab33969f2667.tar.xz
linux-8f36ebaf21fdae99c091c67e8b6fab33969f2667.zip
arm/arm64: KVM: Enforce unconditional flush to PoC when mapping to stage-2
When we fault in a page, we flush it to the PoC (Point of Coherency) if the faulting vcpu has its own caches off, so that it can observe the page we just brought it. But if the vcpu has its caches on, we skip that step. Bad things happen when *another* vcpu tries to access that page with its own caches disabled. At that point, there is no garantee that the data has made it to the PoC, and we access stale data. The obvious fix is to always flush to PoC when a page is faulted in, no matter what the state of the vcpu is. Cc: stable@vger.kernel.org Fixes: 2d58b733c876 ("arm64: KVM: force cache clean on page fault when caches are off") Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'arch/arm/include/asm/kvm_mmu.h')
-rw-r--r--arch/arm/include/asm/kvm_mmu.h9
1 files changed, 1 insertions, 8 deletions
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 74a44727f8e1..a58bbaa3ec60 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -150,18 +150,12 @@ static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu,
* and iterate over the range.
*/
- bool need_flush = !vcpu_has_cache_enabled(vcpu) || ipa_uncached;
-
VM_BUG_ON(size & ~PAGE_MASK);
- if (!need_flush && !icache_is_pipt())
- goto vipt_cache;
-
while (size) {
void *va = kmap_atomic_pfn(pfn);
- if (need_flush)
- kvm_flush_dcache_to_poc(va, PAGE_SIZE);
+ kvm_flush_dcache_to_poc(va, PAGE_SIZE);
if (icache_is_pipt())
__cpuc_coherent_user_range((unsigned long)va,
@@ -173,7 +167,6 @@ static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu,
kunmap_atomic(va);
}
-vipt_cache:
if (!icache_is_pipt() && !icache_is_vivt_asid_tagged()) {
/* any kind of VIPT cache */
__flush_icache_all();