lkml.org 
[lkml]   [2016]   [Aug]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 031/305] arm/arm64: KVM: Enforce Break-Before-Make on Stage-2 page tables
    3.16.37-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Marc Zyngier <marc.zyngier@arm.com>

    commit d4b9e0790aa764c0b01e18d4e8d33e93ba36d51f upstream.

    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.

    Reported-by: Christoffer Dall <christoffer.dall@linaro.org>
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
    Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    arch/arm/kvm/mmu.c | 17 +++++++++++------
    1 file changed, 11 insertions(+), 6 deletions(-)

    --- a/arch/arm/kvm/mmu.c
    +++ b/arch/arm/kvm/mmu.c
    @@ -682,11 +682,14 @@ static int stage2_set_pmd_huge(struct kv
    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;
    }

    @@ -723,12 +726,14 @@ static int stage2_set_pte(struct kvm *kv

    /* 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;
    }

    \
     
     \ /
      Last update: 2016-09-17 09:56    [W:4.046 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site