[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <a9377db2-715d-acba-bd5c-3b7b8e4d5db7@codeaurora.org>
Date: Fri, 14 Apr 2017 13:29:42 -0600
From: "Baicar, Tyler" <tbaicar@...eaurora.org>
To: Punit Agrawal <punit.agrawal@....com>, catalin.marinas@....com,
will.deacon@....com
Cc: linux-arm-kernel@...ts.infradead.org, steve.capper@....com,
linux-kernel@...r.kernel.org, David Woods <dwoods@...lanox.com>
Subject: Re: [PATCH 1/3] arm64: hugetlb: Fix huge_pte_offset to return
poisoned page table entries
On 4/12/2017 8:04 AM, Punit Agrawal wrote:
> When memory failure is enabled, a poisoned hugepage pte is marked as a
> swap entry. huge_pte_offset() does not return the poisoned page table
> entries when it encounters PUD/PMD hugepages.
>
> This behaviour of huge_pte_offset() leads to error such as below when
> munmap is called on poisoned hugepages.
>
> [ 344.165544] mm/pgtable-generic.c:33: bad pmd 000000083af00074.
>
> Fix huge_pte_offset() to return the poisoned pte which is then
> appropriately handled by the generic layer code.
>
> Signed-off-by: Punit Agrawal <punit.agrawal@....com>
> Cc: Catalin Marinas <catalin.marinas@....com>
> Cc: Steve Capper <steve.capper@....com>
> Cc: David Woods <dwoods@...lanox.com>
Tested-by: Tyler Baicar <tbaicar@...eaurora.org>
Thanks,
Tyler
> ---
> arch/arm64/mm/hugetlbpage.c | 20 +++++++++++++++-----
> 1 file changed, 15 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index 7514a000e361..5f1832165d69 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -143,15 +143,24 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
> pr_debug("%s: addr:0x%lx pgd:%p\n", __func__, addr, pgd);
> if (!pgd_present(*pgd))
> return NULL;
> - pud = pud_offset(pgd, addr);
> - if (!pud_present(*pud))
> - return NULL;
>
> - if (pud_huge(*pud))
> + pud = pud_offset(pgd, addr);
> + /*
> + * In case of HW Poisoning, a hugepage pud/pmd can contain
> + * poisoned entries. Poisoned entries are marked as swap
> + * entries.
> + *
> + * For puds/pmds that are not present, check to see if it
> + * could be a swap entry (!present and !none).
> + */
> + if ((!pte_present(pud_pte(*pud)) && !pud_none(*pud)) || pud_huge(*pud))
> return (pte_t *)pud;
> +
> pmd = pmd_offset(pud, addr);
> - if (!pmd_present(*pmd))
> + if (pmd_none(*pmd))
> return NULL;
> + if (!pmd_present(*pmd) && !pmd_none(*pmd))
> + return (pte_t *)pmd;
>
> if (pte_cont(pmd_pte(*pmd))) {
> pmd = pmd_offset(
> @@ -160,6 +169,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
> }
> if (pmd_huge(*pmd))
> return (pte_t *)pmd;
> +
> pte = pte_offset_kernel(pmd, addr);
> if (pte_present(*pte) && pte_cont(*pte)) {
> pte = pte_offset_kernel(
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.
Powered by blists - more mailing lists