From 75b9c508dfff6e8de3eb43b5409b6a9d6b7c8335 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 18 Jan 2017 08:26:06 +0100 Subject: [PATCH] 4.9-stable patches added patches: arm64-hugetlb-fix-the-wrong-address-for-several-functions.patch arm64-hugetlb-fix-the-wrong-return-value-for-huge_ptep_set_access_flags.patch arm64-hugetlb-remove-the-wrong-pmd-check-in-find_num_contig.patch --- ...-wrong-address-for-several-functions.patch | 65 +++++++++++++++++ ...value-for-huge_ptep_set_access_flags.patch | 35 +++++++++ ...e-wrong-pmd-check-in-find_num_contig.patch | 71 +++++++++++++++++++ queue-4.9/series | 3 + 4 files changed, 174 insertions(+) create mode 100644 queue-4.9/arm64-hugetlb-fix-the-wrong-address-for-several-functions.patch create mode 100644 queue-4.9/arm64-hugetlb-fix-the-wrong-return-value-for-huge_ptep_set_access_flags.patch create mode 100644 queue-4.9/arm64-hugetlb-remove-the-wrong-pmd-check-in-find_num_contig.patch diff --git a/queue-4.9/arm64-hugetlb-fix-the-wrong-address-for-several-functions.patch b/queue-4.9/arm64-hugetlb-fix-the-wrong-address-for-several-functions.patch new file mode 100644 index 00000000000..6f8e3b72e35 --- /dev/null +++ b/queue-4.9/arm64-hugetlb-fix-the-wrong-address-for-several-functions.patch @@ -0,0 +1,65 @@ +From 0c2f0afe3582c58efeef93bc57bc07d502132618 Mon Sep 17 00:00:00 2001 +From: Huang Shijie +Date: Tue, 8 Nov 2016 13:44:39 +0800 +Subject: arm64: hugetlb: fix the wrong address for several functions + +From: Huang Shijie + +commit 0c2f0afe3582c58efeef93bc57bc07d502132618 upstream. + +The libhugetlbfs meets several failures since the following functions +do not use the correct address: + huge_ptep_get_and_clear() + huge_ptep_set_access_flags() + huge_ptep_set_wrprotect() + huge_ptep_clear_flush() + +This patch fixes the wrong address for them. + +Signed-off-by: Huang Shijie +Reviewed-by: Catalin Marinas +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/mm/hugetlbpage.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/arch/arm64/mm/hugetlbpage.c ++++ b/arch/arm64/mm/hugetlbpage.c +@@ -212,7 +212,7 @@ pte_t huge_ptep_get_and_clear(struct mm_ + ncontig = find_num_contig(mm, addr, cpte, *cpte, &pgsize); + /* save the 1st pte to return */ + pte = ptep_get_and_clear(mm, addr, cpte); +- for (i = 1; i < ncontig; ++i) { ++ for (i = 1, addr += pgsize; i < ncontig; ++i, addr += pgsize) { + /* + * If HW_AFDBM is enabled, then the HW could + * turn on the dirty bit for any of the page +@@ -250,7 +250,7 @@ int huge_ptep_set_access_flags(struct vm + pfn = pte_pfn(*cpte); + ncontig = find_num_contig(vma->vm_mm, addr, cpte, + *cpte, &pgsize); +- for (i = 0; i < ncontig; ++i, ++cpte) { ++ for (i = 0; i < ncontig; ++i, ++cpte, addr += pgsize) { + changed = ptep_set_access_flags(vma, addr, cpte, + pfn_pte(pfn, + hugeprot), +@@ -273,7 +273,7 @@ void huge_ptep_set_wrprotect(struct mm_s + + cpte = huge_pte_offset(mm, addr); + ncontig = find_num_contig(mm, addr, cpte, *cpte, &pgsize); +- for (i = 0; i < ncontig; ++i, ++cpte) ++ for (i = 0; i < ncontig; ++i, ++cpte, addr += pgsize) + ptep_set_wrprotect(mm, addr, cpte); + } else { + ptep_set_wrprotect(mm, addr, ptep); +@@ -291,7 +291,7 @@ void huge_ptep_clear_flush(struct vm_are + cpte = huge_pte_offset(vma->vm_mm, addr); + ncontig = find_num_contig(vma->vm_mm, addr, cpte, + *cpte, &pgsize); +- for (i = 0; i < ncontig; ++i, ++cpte) ++ for (i = 0; i < ncontig; ++i, ++cpte, addr += pgsize) + ptep_clear_flush(vma, addr, cpte); + } else { + ptep_clear_flush(vma, addr, ptep); diff --git a/queue-4.9/arm64-hugetlb-fix-the-wrong-return-value-for-huge_ptep_set_access_flags.patch b/queue-4.9/arm64-hugetlb-fix-the-wrong-return-value-for-huge_ptep_set_access_flags.patch new file mode 100644 index 00000000000..e29abb75e08 --- /dev/null +++ b/queue-4.9/arm64-hugetlb-fix-the-wrong-return-value-for-huge_ptep_set_access_flags.patch @@ -0,0 +1,35 @@ +From 69d012345a1a32d3f03957f14d972efccc106a98 Mon Sep 17 00:00:00 2001 +From: Huang Shijie +Date: Wed, 11 Jan 2017 14:02:00 +0800 +Subject: arm64: hugetlb: fix the wrong return value for huge_ptep_set_access_flags + +From: Huang Shijie + +commit 69d012345a1a32d3f03957f14d972efccc106a98 upstream. + +In current code, the @changed always returns the last one's status for +the huge page with the contiguous bit set. This is really not what we +want. Even one of the PTEs is changed, we should tell it to the caller. + +This patch fixes this issue. + +Fixes: 66b3923a1a0f ("arm64: hugetlb: add support for PTE contiguous bit") +Signed-off-by: Huang Shijie +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/mm/hugetlbpage.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm64/mm/hugetlbpage.c ++++ b/arch/arm64/mm/hugetlbpage.c +@@ -239,7 +239,7 @@ int huge_ptep_set_access_flags(struct vm + ncontig = find_num_contig(vma->vm_mm, addr, cpte, + *cpte, &pgsize); + for (i = 0; i < ncontig; ++i, ++cpte, addr += pgsize) { +- changed = ptep_set_access_flags(vma, addr, cpte, ++ changed |= ptep_set_access_flags(vma, addr, cpte, + pfn_pte(pfn, + hugeprot), + dirty); diff --git a/queue-4.9/arm64-hugetlb-remove-the-wrong-pmd-check-in-find_num_contig.patch b/queue-4.9/arm64-hugetlb-remove-the-wrong-pmd-check-in-find_num_contig.patch new file mode 100644 index 00000000000..7813ea98473 --- /dev/null +++ b/queue-4.9/arm64-hugetlb-remove-the-wrong-pmd-check-in-find_num_contig.patch @@ -0,0 +1,71 @@ +From 20156ce2365d61beaa6f5a78a7a789044e0e7acc Mon Sep 17 00:00:00 2001 +From: Huang Shijie +Date: Tue, 8 Nov 2016 13:44:38 +0800 +Subject: arm64: hugetlb: remove the wrong pmd check in find_num_contig() + +From: Huang Shijie + +commit 20156ce2365d61beaa6f5a78a7a789044e0e7acc upstream. + +The find_num_contig() will return 1 when the pmd is not present. +It will cause a kernel dead loop in the following scenaro: + + 1.) pmd entry is not present. + + 2.) the page fault occurs: + ... hugetlb_fault() --> hugetlb_no_page() --> set_huge_pte_at() + + 3.) set_huge_pte_at() will only set the first PMD entry, since the + find_num_contig just return 1 in this case. So the PMD entries + are all empty except the first one. + + 4.) when kernel accesses the address mapped by the second PMD entry, + a new page fault occurs: + ... hugetlb_fault() --> huge_ptep_set_access_flags() + + The second PMD entry is still empty now. + + 5.) When the kernel returns, the access will cause a page fault again. + The kernel will run like the "4)" above. + We will see a dead loop since here. + +The dead loop is caught in the 32M hugetlb page (2M PMD + Contiguous bit). + +This patch removes wrong pmd check, and fixes this dead loop. + +This patch also removes the redundant checks for PGD/PUD in +the find_num_contig(). + +Acked-by: Steve Capper +Signed-off-by: Huang Shijie +Reviewed-by: Catalin Marinas +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/mm/hugetlbpage.c | 12 ------------ + 1 file changed, 12 deletions(-) + +--- a/arch/arm64/mm/hugetlbpage.c ++++ b/arch/arm64/mm/hugetlbpage.c +@@ -51,20 +51,8 @@ static int find_num_contig(struct mm_str + *pgsize = PAGE_SIZE; + if (!pte_cont(pte)) + return 1; +- if (!pgd_present(*pgd)) { +- VM_BUG_ON(!pgd_present(*pgd)); +- return 1; +- } + pud = pud_offset(pgd, addr); +- if (!pud_present(*pud)) { +- VM_BUG_ON(!pud_present(*pud)); +- return 1; +- } + pmd = pmd_offset(pud, addr); +- if (!pmd_present(*pmd)) { +- VM_BUG_ON(!pmd_present(*pmd)); +- return 1; +- } + if ((pte_t *)pmd == ptep) { + *pgsize = PMD_SIZE; + return CONT_PMDS; diff --git a/queue-4.9/series b/queue-4.9/series index c7615972ffe..2ec8be9e89d 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -114,3 +114,6 @@ powerpc-mm-correct-process-and-partition-table-max-size.patch powerpc-ibmebus-fix-further-device-reference-leaks.patch powerpc-ibmebus-fix-device-reference-leaks-in-sysfs-interface.patch powerpc-powernv-don-t-warn-on-pe-init-if-unfreeze-is-unsupported.patch +arm64-hugetlb-fix-the-wrong-address-for-several-functions.patch +arm64-hugetlb-remove-the-wrong-pmd-check-in-find_num_contig.patch +arm64-hugetlb-fix-the-wrong-return-value-for-huge_ptep_set_access_flags.patch -- 2.47.3