From: Mark Rutland <mark.rutland@arm.com>
To: Marc Zyngier <marc.zyngier@arm.com>
Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu
Subject: Re: [PATCH] arm/arm64: KVM: Enforce Break-Before-Make on Stage-2 page tables
Date: Thu, 28 Apr 2016 17:07:05 +0100 [thread overview]
Message-ID: <20160428160705.GA17867@leverpostej> (raw)
In-Reply-To: <1461856591-5751-1-git-send-email-marc.zyngier@arm.com>
On Thu, Apr 28, 2016 at 04:16:31PM +0100, Marc Zyngier wrote:
> The ARM architecture mandates that when changing a page table entry
> from a valid entry to another valid entry, an invalid entry is first
> written, TLB invalidated, and only then the new entry being written.
>
> The current code doesn't respect this, directly writing the new
> entry and only then invalidating TLBs. Let's fix it up.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
FWIW, this looks correct to me.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Mark.
> ---
> arch/arm/kvm/mmu.c | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
> index 58dbd5c..edf1cd1 100644
> --- a/arch/arm/kvm/mmu.c
> +++ b/arch/arm/kvm/mmu.c
> @@ -893,11 +893,14 @@ static int stage2_set_pmd_huge(struct kvm *kvm, struct kvm_mmu_memory_cache
> VM_BUG_ON(pmd_present(*pmd) && pmd_pfn(*pmd) != pmd_pfn(*new_pmd));
>
> old_pmd = *pmd;
> - kvm_set_pmd(pmd, *new_pmd);
> - if (pmd_present(old_pmd))
> + if (pmd_present(old_pmd)) {
> + pmd_clear(pmd);
> kvm_tlb_flush_vmid_ipa(kvm, addr);
> - else
> + } else {
> get_page(virt_to_page(pmd));
> + }
> +
> + kvm_set_pmd(pmd, *new_pmd);
> return 0;
> }
>
> @@ -946,12 +949,14 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
>
> /* Create 2nd stage page table mapping - Level 3 */
> old_pte = *pte;
> - kvm_set_pte(pte, *new_pte);
> - if (pte_present(old_pte))
> + if (pte_present(old_pte)) {
> + kvm_set_pte(pte, __pte(0));
> kvm_tlb_flush_vmid_ipa(kvm, addr);
> - else
> + } else {
> get_page(virt_to_page(pte));
> + }
>
> + kvm_set_pte(pte, *new_pte);
> return 0;
> }
>
> --
> 2.1.4
>
> _______________________________________________
> kvmarm mailing list
> kvmarm@lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
>
WARNING: multiple messages have this Message-ID (diff)
From: mark.rutland@arm.com (Mark Rutland)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] arm/arm64: KVM: Enforce Break-Before-Make on Stage-2 page tables
Date: Thu, 28 Apr 2016 17:07:05 +0100 [thread overview]
Message-ID: <20160428160705.GA17867@leverpostej> (raw)
In-Reply-To: <1461856591-5751-1-git-send-email-marc.zyngier@arm.com>
On Thu, Apr 28, 2016 at 04:16:31PM +0100, Marc Zyngier wrote:
> The ARM architecture mandates that when changing a page table entry
> from a valid entry to another valid entry, an invalid entry is first
> written, TLB invalidated, and only then the new entry being written.
>
> The current code doesn't respect this, directly writing the new
> entry and only then invalidating TLBs. Let's fix it up.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
FWIW, this looks correct to me.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Mark.
> ---
> arch/arm/kvm/mmu.c | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
> index 58dbd5c..edf1cd1 100644
> --- a/arch/arm/kvm/mmu.c
> +++ b/arch/arm/kvm/mmu.c
> @@ -893,11 +893,14 @@ static int stage2_set_pmd_huge(struct kvm *kvm, struct kvm_mmu_memory_cache
> VM_BUG_ON(pmd_present(*pmd) && pmd_pfn(*pmd) != pmd_pfn(*new_pmd));
>
> old_pmd = *pmd;
> - kvm_set_pmd(pmd, *new_pmd);
> - if (pmd_present(old_pmd))
> + if (pmd_present(old_pmd)) {
> + pmd_clear(pmd);
> kvm_tlb_flush_vmid_ipa(kvm, addr);
> - else
> + } else {
> get_page(virt_to_page(pmd));
> + }
> +
> + kvm_set_pmd(pmd, *new_pmd);
> return 0;
> }
>
> @@ -946,12 +949,14 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
>
> /* Create 2nd stage page table mapping - Level 3 */
> old_pte = *pte;
> - kvm_set_pte(pte, *new_pte);
> - if (pte_present(old_pte))
> + if (pte_present(old_pte)) {
> + kvm_set_pte(pte, __pte(0));
> kvm_tlb_flush_vmid_ipa(kvm, addr);
> - else
> + } else {
> get_page(virt_to_page(pte));
> + }
>
> + kvm_set_pte(pte, *new_pte);
> return 0;
> }
>
> --
> 2.1.4
>
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
>
next prev parent reply other threads:[~2016-04-28 16:05 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-28 15:16 [PATCH] arm/arm64: KVM: Enforce Break-Before-Make on Stage-2 page tables Marc Zyngier
2016-04-28 15:16 ` Marc Zyngier
2016-04-28 16:07 ` Mark Rutland [this message]
2016-04-28 16:07 ` Mark Rutland
2016-04-29 11:31 ` Christoffer Dall
2016-04-29 11:31 ` 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=20160428160705.GA17867@leverpostej \
--to=mark.rutland@arm.com \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=marc.zyngier@arm.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: link
Be 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.