From: Toshi Kani <toshi.kani@hpe.com>
To: akpm@linux-foundation.org
Cc: kirill.shutemov@linux.intel.com, willy@linux.intel.com,
ross.zwisler@linux.intel.com, dan.j.williams@intel.com,
mauricio.porto@hpe.com, linux-mm@kvack.org,
linux-fsdevel@vger.kernel.org, linux-nvdimm@ml01.01.org,
linux-kernel@vger.kernel.org, Toshi Kani <toshi.kani@hpe.com>
Subject: [PATCH] mm: Fix mmap MAP_POPULATE for DAX pmd mapping
Date: Mon, 23 Nov 2015 13:04:42 -0700 [thread overview]
Message-ID: <1448309082-20851-1-git-send-email-toshi.kani@hpe.com> (raw)
The following oops was observed when mmap() with MAP_POPULATE
pre-faulted pmd mappings of a DAX file. follow_trans_huge_pmd()
expects that a target address has a struct page.
BUG: unable to handle kernel paging request at ffffea0012220000
follow_trans_huge_pmd+0xba/0x390
follow_page_mask+0x33d/0x420
__get_user_pages+0xdc/0x800
populate_vma_page_range+0xb5/0xe0
__mm_populate+0xc5/0x150
vm_mmap_pgoff+0xd5/0xe0
SyS_mmap_pgoff+0x1c1/0x290
SyS_mmap+0x1b/0x30
Fix it by making the PMD pre-fault handling consistent with PTE.
After pre-faulted in faultin_page(), follow_page_mask() calls
follow_trans_huge_pmd(), which is changed to call follow_pfn_pmd()
for VM_PFNMAP or VM_MIXEDMAP. follow_pfn_pmd() handles FOLL_TOUCH
and returns with -EEXIST.
Reported-by: Mauricio Porto <mauricio.porto@hpe.com>
Signed-off-by: Toshi Kani <toshi.kani@hpe.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Matthew Wilcox <willy@linux.intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Ross Zwisler <ross.zwisler@linux.intel.com>
---
mm/huge_memory.c | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index d5b8920..f56e034 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1267,6 +1267,32 @@ out_unlock:
return ret;
}
+/*
+ * Follow a pmd inserted by vmf_insert_pfn_pmd(). See follow_pfn_pte() for pte.
+ */
+static int follow_pfn_pmd(struct vm_area_struct *vma, unsigned long address,
+ pmd_t *pmd, unsigned int flags)
+{
+ /* No page to get reference */
+ if (flags & FOLL_GET)
+ return -EFAULT;
+
+ if (flags & FOLL_TOUCH) {
+ pmd_t entry = *pmd;
+
+ /* Set the dirty bit per follow_trans_huge_pmd() */
+ entry = pmd_mkyoung(pmd_mkdirty(entry));
+
+ if (!pmd_same(*pmd, entry)) {
+ set_pmd_at(vma->vm_mm, address, pmd, entry);
+ update_mmu_cache_pmd(vma, address, pmd);
+ }
+ }
+
+ /* Proper page table entry exists, but no corresponding struct page */
+ return -EEXIST;
+}
+
struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
unsigned long addr,
pmd_t *pmd,
@@ -1274,6 +1300,7 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
{
struct mm_struct *mm = vma->vm_mm;
struct page *page = NULL;
+ int ret;
assert_spin_locked(pmd_lockptr(mm, pmd));
@@ -1288,6 +1315,13 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
if ((flags & FOLL_NUMA) && pmd_protnone(*pmd))
goto out;
+ /* pfn map does not have a struct page */
+ if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP)) {
+ ret = follow_pfn_pmd(vma, addr, pmd, flags);
+ page = ERR_PTR(ret);
+ goto out;
+ }
+
page = pmd_page(*pmd);
VM_BUG_ON_PAGE(!PageHead(page), page);
if (flags & FOLL_TOUCH) {
next reply other threads:[~2015-11-23 20:09 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-23 20:04 Toshi Kani [this message]
2015-11-23 20:53 ` [PATCH] mm: Fix mmap MAP_POPULATE for DAX pmd mapping Dan Williams
2015-11-23 22:15 ` Toshi Kani
2015-11-30 22:08 ` Dan Williams
2015-12-02 2:19 ` Toshi Kani
2015-12-02 3:45 ` Dan Williams
2015-12-02 17:43 ` Toshi Kani
2015-12-02 17:01 ` Dan Williams
2015-12-02 18:06 ` Dan Williams
2015-12-02 19:26 ` Toshi Kani
2015-12-02 19:00 ` Dan Williams
2015-12-02 20:02 ` Toshi Kani
2015-12-02 20:12 ` Toshi Kani
2015-12-02 19:57 ` Dan Williams
2015-12-02 21:37 ` Toshi Kani
2015-12-02 20:54 ` Dan Williams
2015-12-02 21:55 ` Toshi Kani
2015-12-03 23:43 ` Dan Williams
2015-12-04 16:55 ` Toshi Kani
2015-12-02 22:00 ` Dave Hansen
2015-12-02 22:03 ` Dan Williams
2015-12-02 22:09 ` Dave Hansen
2015-12-03 0:21 ` Toshi Kani
2015-12-02 23:33 ` Dan Williams
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1448309082-20851-1-git-send-email-toshi.kani@hpe.com \
--to=toshi.kani@hpe.com \
--cc=akpm@linux-foundation.org \
--cc=dan.j.williams@intel.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-nvdimm@ml01.01.org \
--cc=mauricio.porto@hpe.com \
--cc=ross.zwisler@linux.intel.com \
--cc=willy@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).