lkml.org 
[lkml]   [2021]   [May]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH v12 3/8] arm64: mte: Sync tags for pages where PTE is untagged
    On Mon, May 17, 2021 at 01:32:34PM +0100, Steven Price wrote:
    > A KVM guest could store tags in a page even if the VMM hasn't mapped
    > the page with PROT_MTE. So when restoring pages from swap we will
    > need to check to see if there are any saved tags even if !pte_tagged().
    >
    > However don't check pages for which pte_access_permitted() returns false
    > as these will not have been swapped out.
    >
    > Signed-off-by: Steven Price <steven.price@arm.com>
    > ---
    > arch/arm64/include/asm/pgtable.h | 9 +++++++--
    > arch/arm64/kernel/mte.c | 16 ++++++++++++++--
    > 2 files changed, 21 insertions(+), 4 deletions(-)
    >
    > diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
    > index 0b10204e72fc..275178a810c1 100644
    > --- a/arch/arm64/include/asm/pgtable.h
    > +++ b/arch/arm64/include/asm/pgtable.h
    > @@ -314,8 +314,13 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
    > if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte))
    > __sync_icache_dcache(pte);
    >
    > - if (system_supports_mte() &&
    > - pte_present(pte) && pte_tagged(pte) && !pte_special(pte))
    > + /*
    > + * If the PTE would provide user space access to the tags associated
    > + * with it then ensure that the MTE tags are synchronised. Exec-only
    > + * mappings don't expose tags (instruction fetches don't check tags).
    > + */
    > + if (system_supports_mte() && pte_present(pte) &&
    > + pte_access_permitted(pte, false) && !pte_special(pte))
    > mte_sync_tags(ptep, pte);

    Looking at the mte_sync_page_tags() logic, we bail out early if it's the
    old pte is not a swap one and the new pte is not tagged. So we only need
    to call mte_sync_tags() if it's a tagged new pte or the old one is swap.
    What about changing the set_pte_at() test to:

    if (system_supports_mte() && pte_present(pte) && !pte_special(pte) &&
    (pte_tagged(pte) || is_swap_pte(READ_ONCE(*ptep))))
    mte_sync_tags(ptep, pte);

    We can even change mte_sync_tags() to take the old pte directly:

    if (system_supports_mte() && pte_present(pte) && !pte_special(pte)) {
    pte_t old_pte = READ_ONCE(*ptep);
    if (pte_tagged(pte) || is_swap_pte(old_pte))
    mte_sync_tags(old_pte, pte);
    }

    It would save a function call in most cases where the page is not
    tagged.

    --
    Catalin

    \
     
     \ /
      Last update: 2021-05-19 20:07    [W:4.117 / U:0.104 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site