summaryrefslogtreecommitdiff
path: root/mm/mempolicy.c
diff options
context:
space:
mode:
authorNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>2014-04-23 08:27:05 +1000
committerStephen Rothwell <sfr@canb.auug.org.au>2014-04-23 08:27:05 +1000
commitd7bcf989a04ef2f8918f5745a79551953369a42e (patch)
tree4973b08a73c080a64c8d6a290af682427fc15415 /mm/mempolicy.c
parentfe5d4a685d60cfc331039b2451bd96e4f959a1cb (diff)
mm: add !pte_present() check on existing hugetlb_entry callbacks
Page table walker doesn't check non-present hugetlb entry in common path, so hugetlb_entry() callbacks must check it. The reason for this behavior is that some callers want to handle it in its own way. However, some callers don't check it now, which causes unpredictable result, for example when we have a race between migrating hugepage and reading /proc/pid/numa_maps. This patch fixes it by adding !pte_present checks on buggy callbacks. This bug exists for years and got visible by introducing hugepage migration. ChangeLog v2: - fix if condition (check !pte_present() instead of pte_present()) Reported-by: Sasha Levin <sasha.levin@oracle.com> Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> Cc: Rik van Riel <riel@redhat.com> Cc: <stable@vger.kernel.org> [3.12+] Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r--mm/mempolicy.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index af635c458dee..9d2ef4111a4c 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -524,8 +524,12 @@ static int queue_pages_hugetlb(pte_t *pte, unsigned long addr,
unsigned long flags = qp->flags;
int nid;
struct page *page;
+ pte_t entry;
- page = pte_page(huge_ptep_get(pte));
+ entry = huge_ptep_get(pte);
+ if (!pte_present(entry))
+ return 0;
+ page = pte_page(entry);
nid = page_to_nid(page);
if (node_isset(nid, *qp->nmask) == !!(flags & MPOL_MF_INVERT))
return 0;