From: Greg Kroah-Hartman Date: Sat, 28 Feb 2015 22:52:51 +0000 (-0800) Subject: 3.14-stable patches X-Git-Tag: v3.10.71~41 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=933cf4f1a1c9fcf5ec8dd2ba5dc53d425bd2aca7;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches added patches: mm-hugetlb-pmd_huge-returns-true-for-non-present-hugepage.patch --- diff --git a/queue-3.14/mm-hugetlb-pmd_huge-returns-true-for-non-present-hugepage.patch b/queue-3.14/mm-hugetlb-pmd_huge-returns-true-for-non-present-hugepage.patch new file mode 100644 index 00000000000..4410701f685 --- /dev/null +++ b/queue-3.14/mm-hugetlb-pmd_huge-returns-true-for-non-present-hugepage.patch @@ -0,0 +1,94 @@ +From cbef8478bee55775ac312a574aad48af7bb9cf9f Mon Sep 17 00:00:00 2001 +From: Naoya Horiguchi +Date: Wed, 11 Feb 2015 15:25:19 -0800 +Subject: mm/hugetlb: pmd_huge() returns true for non-present hugepage + +From: Naoya Horiguchi + +commit cbef8478bee55775ac312a574aad48af7bb9cf9f upstream. + +Migrating hugepages and hwpoisoned hugepages are considered as non-present +hugepages, and they are referenced via migration entries and hwpoison +entries in their page table slots. + +This behavior causes race condition because pmd_huge() doesn't tell +non-huge pages from migrating/hwpoisoned hugepages. follow_page_mask() is +one example where the kernel would call follow_page_pte() for such +hugepage while this function is supposed to handle only normal pages. + +To avoid this, this patch makes pmd_huge() return true when pmd_none() is +true *and* pmd_present() is false. We don't have to worry about mixing up +non-present pmd entry with normal pmd (pointing to leaf level pte entry) +because pmd_present() is true in normal pmd. + +The same race condition could happen in (x86-specific) gup_pmd_range(), +where this patch simply adds pmd_present() check instead of pmd_huge(). +This is because gup_pmd_range() is fast path. If we have non-present +hugepage in this function, we will go into gup_huge_pmd(), then return 0 +at flag mask check, and finally fall back to the slow path. + +Fixes: 290408d4a2 ("hugetlb: hugepage migration core") +Signed-off-by: Naoya Horiguchi +Cc: Hugh Dickins +Cc: James Hogan +Cc: David Rientjes +Cc: Mel Gorman +Cc: Johannes Weiner +Cc: Michal Hocko +Cc: Rik van Riel +Cc: Andrea Arcangeli +Cc: Luiz Capitulino +Cc: Nishanth Aravamudan +Cc: Lee Schermerhorn +Cc: Steve Capper +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/mm/gup.c | 2 +- + arch/x86/mm/hugetlbpage.c | 8 +++++++- + mm/hugetlb.c | 2 ++ + 3 files changed, 10 insertions(+), 2 deletions(-) + +--- a/arch/x86/mm/gup.c ++++ b/arch/x86/mm/gup.c +@@ -172,7 +172,7 @@ static int gup_pmd_range(pud_t pud, unsi + */ + if (pmd_none(pmd) || pmd_trans_splitting(pmd)) + return 0; +- if (unlikely(pmd_large(pmd))) { ++ if (unlikely(pmd_large(pmd) || !pmd_present(pmd))) { + /* + * NUMA hinting faults need to be handled in the GUP + * slowpath for accounting purposes and so that they +--- a/arch/x86/mm/hugetlbpage.c ++++ b/arch/x86/mm/hugetlbpage.c +@@ -66,9 +66,15 @@ follow_huge_addr(struct mm_struct *mm, u + return ERR_PTR(-EINVAL); + } + ++/* ++ * pmd_huge() returns 1 if @pmd is hugetlb related entry, that is normal ++ * hugetlb entry or non-present (migration or hwpoisoned) hugetlb entry. ++ * Otherwise, returns 0. ++ */ + int pmd_huge(pmd_t pmd) + { +- return !!(pmd_val(pmd) & _PAGE_PSE); ++ return !pmd_none(pmd) && ++ (pmd_val(pmd) & (_PAGE_PRESENT|_PAGE_PSE)) != _PAGE_PRESENT; + } + + int pud_huge(pud_t pud) +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -3456,6 +3456,8 @@ follow_huge_pmd(struct mm_struct *mm, un + { + struct page *page; + ++ if (!pmd_present(*pmd)) ++ return NULL; + page = pte_page(*(pte_t *)pmd); + if (page) + page += ((address & ~PMD_MASK) >> PAGE_SHIFT); diff --git a/queue-3.14/series b/queue-3.14/series index 2c2d9401e56..6e088934638 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -26,3 +26,4 @@ em28xx-audio-fix-missing-newlines.patch mmc-sdhci-pxav3-fix-setting-of-pdata-clk_delay_cycles.patch nfs-don-t-call-blocking-operations-while-task_running.patch mips-kvm-deliver-guest-interrupts-after-local_irq_disable.patch +mm-hugetlb-pmd_huge-returns-true-for-non-present-hugepage.patch