lkml.org 
[lkml]   [2020]   [May]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.6 19/47] s390/mm: fix set_huge_pte_at() for empty ptes
    Date
    From: Gerald Schaefer <gerald.schaefer@de.ibm.com>

    [ Upstream commit ac8372f3b4e41015549b331a4f350224661e7fc6 ]

    On s390, the layout of normal and large ptes (i.e. pmds/puds) differs.
    Therefore, set_huge_pte_at() does a conversion from a normal pte to
    the corresponding large pmd/pud. So, when converting an empty pte, this
    should result in an empty pmd/pud, which would return true for
    pmd/pud_none().

    However, after conversion we also mark the pmd/pud as large, and
    therefore present. For empty ptes, this will result in an empty pmd/pud
    that is also marked as large, and pmd/pud_none() would not return true.

    There is currently no issue with this behaviour, as set_huge_pte_at()
    does not seem to be called for empty ptes. It would be valid though, so
    let's fix this by not marking empty ptes as large in set_huge_pte_at().

    This was found by testing a patch from from Anshuman Khandual, which is
    currently discussed on LKML ("mm/debug: Add more arch page table helper
    tests").

    Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
    Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    arch/s390/mm/hugetlbpage.c | 9 ++++++---
    1 file changed, 6 insertions(+), 3 deletions(-)

    diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c
    index 5674710a4841..7dfae86afa47 100644
    --- a/arch/s390/mm/hugetlbpage.c
    +++ b/arch/s390/mm/hugetlbpage.c
    @@ -159,10 +159,13 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
    rste &= ~_SEGMENT_ENTRY_NOEXEC;

    /* Set correct table type for 2G hugepages */
    - if ((pte_val(*ptep) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3)
    - rste |= _REGION_ENTRY_TYPE_R3 | _REGION3_ENTRY_LARGE;
    - else
    + if ((pte_val(*ptep) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) {
    + if (likely(pte_present(pte)))
    + rste |= _REGION3_ENTRY_LARGE;
    + rste |= _REGION_ENTRY_TYPE_R3;
    + } else if (likely(pte_present(pte)))
    rste |= _SEGMENT_ENTRY_LARGE;
    +
    clear_huge_pte_skeys(mm, rste);
    pte_val(*ptep) = rste;
    }
    --
    2.25.1
    \
     
     \ /
      Last update: 2020-05-28 14:11    [W:4.126 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site