From: Christoffer Dall <christoffer.dall@arm.com> To: "Paolo Bonzini" <pbonzini@redhat.com>, "Radim Krčmář" <rkrcmar@redhat.com> Cc: kvm@vger.kernel.org, Marc Zyngier <marc.zyngier@arm.com>, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PULL 1/4] KVM: arm/arm64: Clean dcache to PoC when changing PTE due to CoW Date: Mon, 3 Sep 2018 15:45:13 +0200 [thread overview] Message-ID: <20180903134516.17796-2-christoffer.dall@arm.com> (raw) In-Reply-To: <20180903134516.17796-1-christoffer.dall@arm.com> From: Marc Zyngier <marc.zyngier@arm.com> When triggering a CoW, we unmap the RO page via an MMU notifier (invalidate_range_start), and then populate the new PTE using another one (change_pte). In the meantime, we'll have copied the old page into the new one. The problem is that the data for the new page is sitting in the cache, and should the guest have an uncached mapping to that page (or its MMU off), following accesses will bypass the cache. In a way, this is similar to what happens on a translation fault: We need to clean the page to the PoC before mapping it. So let's just do that. This fixes a KVM unit test regression observed on a HiSilicon platform, and subsequently reproduced on Seattle. Fixes: a9c0e12ebee5 ("KVM: arm/arm64: Only clean the dcache on translation fault") Reported-by: Mike Galbraith <efault@gmx.de> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@arm.com> --- virt/kvm/arm/mmu.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c index 91aaf73b00df..111a660be3be 100644 --- a/virt/kvm/arm/mmu.c +++ b/virt/kvm/arm/mmu.c @@ -1860,13 +1860,20 @@ static int kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *data void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) { unsigned long end = hva + PAGE_SIZE; + kvm_pfn_t pfn = pte_pfn(pte); pte_t stage2_pte; if (!kvm->arch.pgd) return; trace_kvm_set_spte_hva(hva); - stage2_pte = pfn_pte(pte_pfn(pte), PAGE_S2); + + /* + * We've moved a page around, probably through CoW, so let's treat it + * just like a translation fault and clean the cache to the PoC. + */ + clean_dcache_guest_page(pfn, PAGE_SIZE); + stage2_pte = pfn_pte(pfn, PAGE_S2); handle_hva_to_gpa(kvm, hva, end, &kvm_set_spte_handler, &stage2_pte); } -- 2.18.0
WARNING: multiple messages have this Message-ID (diff)
From: christoffer.dall@arm.com (Christoffer Dall) To: linux-arm-kernel@lists.infradead.org Subject: [PULL 1/4] KVM: arm/arm64: Clean dcache to PoC when changing PTE due to CoW Date: Mon, 3 Sep 2018 15:45:13 +0200 [thread overview] Message-ID: <20180903134516.17796-2-christoffer.dall@arm.com> (raw) In-Reply-To: <20180903134516.17796-1-christoffer.dall@arm.com> From: Marc Zyngier <marc.zyngier@arm.com> When triggering a CoW, we unmap the RO page via an MMU notifier (invalidate_range_start), and then populate the new PTE using another one (change_pte). In the meantime, we'll have copied the old page into the new one. The problem is that the data for the new page is sitting in the cache, and should the guest have an uncached mapping to that page (or its MMU off), following accesses will bypass the cache. In a way, this is similar to what happens on a translation fault: We need to clean the page to the PoC before mapping it. So let's just do that. This fixes a KVM unit test regression observed on a HiSilicon platform, and subsequently reproduced on Seattle. Fixes: a9c0e12ebee5 ("KVM: arm/arm64: Only clean the dcache on translation fault") Reported-by: Mike Galbraith <efault@gmx.de> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@arm.com> --- virt/kvm/arm/mmu.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c index 91aaf73b00df..111a660be3be 100644 --- a/virt/kvm/arm/mmu.c +++ b/virt/kvm/arm/mmu.c @@ -1860,13 +1860,20 @@ static int kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *data void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) { unsigned long end = hva + PAGE_SIZE; + kvm_pfn_t pfn = pte_pfn(pte); pte_t stage2_pte; if (!kvm->arch.pgd) return; trace_kvm_set_spte_hva(hva); - stage2_pte = pfn_pte(pte_pfn(pte), PAGE_S2); + + /* + * We've moved a page around, probably through CoW, so let's treat it + * just like a translation fault and clean the cache to the PoC. + */ + clean_dcache_guest_page(pfn, PAGE_SIZE); + stage2_pte = pfn_pte(pfn, PAGE_S2); handle_hva_to_gpa(kvm, hva, end, &kvm_set_spte_handler, &stage2_pte); } -- 2.18.0
next prev parent reply other threads:[~2018-09-03 13:45 UTC|newest] Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-09-03 13:45 [PULL 0/4] KVM/ARM Fixes for v4.19 Christoffer Dall 2018-09-03 13:45 ` Christoffer Dall 2018-09-03 13:45 ` Christoffer Dall [this message] 2018-09-03 13:45 ` [PULL 1/4] KVM: arm/arm64: Clean dcache to PoC when changing PTE due to CoW Christoffer Dall 2018-09-03 13:45 ` [PULL 2/4] arm64: KVM: Only force FPEXC32_EL2.EN if trapping FPSIMD Christoffer Dall 2018-09-03 13:45 ` Christoffer Dall 2018-09-04 11:39 ` Dave Martin 2018-09-04 11:39 ` Dave Martin 2018-09-04 12:51 ` Christoffer Dall 2018-09-04 12:51 ` Christoffer Dall 2018-09-05 11:28 ` Dave Martin 2018-09-05 11:28 ` Dave Martin 2018-09-05 15:03 ` Christoffer Dall 2018-09-05 15:03 ` Christoffer Dall 2018-09-07 11:19 ` Dave Martin 2018-09-07 11:19 ` Dave Martin 2018-09-03 13:45 ` [PULL 3/4] KVM: Remove obsolete kvm_unmap_hva notifier backend Christoffer Dall 2018-09-03 13:45 ` Christoffer Dall 2018-09-03 13:45 ` [PULL 4/4] arm64: KVM: Remove pgd_lock Christoffer Dall 2018-09-03 13:45 ` Christoffer Dall
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20180903134516.17796-2-christoffer.dall@arm.com \ --to=christoffer.dall@arm.com \ --cc=kvm@vger.kernel.org \ --cc=kvmarm@lists.cs.columbia.edu \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=marc.zyngier@arm.com \ --cc=pbonzini@redhat.com \ --cc=rkrcmar@redhat.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.