From: Jarkko Sakkinen <jarkko@kernel.org>
To: linux-mm@kvack.org, linux-fsdevel@vger.kernel.org
Cc: Dave Hansen <dave.hansen@linux.intel.com>,
Nathaniel McCallum <nathaniel@profian.com>,
Reinette Chatre <reinette.chatre@intel.com>,
Alexander Viro <viro@zeniv.linux.org.uk>,
linux-sgx@vger.kernel.org, linux-kernel@vger.kernel.org,
Andrew Morton <akpm@linux-foundation.org>,
Jarkko Sakkinen <jarkko@kernel.org>
Subject: [PATCH RFC v3 1/3] mm: Add f_op->populate() for populating memory outside of core mm
Date: Tue, 8 Mar 2022 13:28:31 +0200 [thread overview]
Message-ID: <20220308112833.262805-2-jarkko@kernel.org> (raw)
In-Reply-To: <20220308112833.262805-1-jarkko@kernel.org>
SGX memory is managed outside the core mm. It doesn't have a 'struct
page' and get_user_pages() doesn't work on it. Its VMAs are marked with
VM_IO. So, none of the existing methods for avoiding page faults work
on SGX memory.
Add f_op->populate() to overcome this issue:
int (*populate)(struct file *, unsigned long start, unsigned long end);
Then in populate_vma_page_range(), allow it to be used in the place of
get_user_pages() for memory that falls outside of its scope.
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
---
v5:
* In v4, one diff was left out of staging area in __mm_populate(). It
was unintentional to remove the conditional statement.
v4:
* Reimplement based on Dave's suggestion:
https://lore.kernel.org/linux-sgx/c3083144-bfc1-3260-164c-e59b2d110df8@intel.com/
* Copy the text from the suggestion as part of the commit message (and
cover letter).
v3:
- if (!ret && do_populate && file->f_op->populate)
+ if (!ret && do_populate && file->f_op->populate &&
+ !!(vma->vm_flags & (VM_IO | VM_PFNMAP)))
(reported by Matthew Wilcox)
v2:
- if (!ret && do_populate)
+ if (!ret && do_populate && file->f_op->populate)
(reported by Jan Harkes)
---
include/linux/fs.h | 1 +
mm/gup.c | 11 ++++++++---
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e2d892b201b0..54151af88ee0 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1993,6 +1993,7 @@ struct file_operations {
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
+ int (*populate)(struct file *, unsigned long start, unsigned long end);
unsigned long mmap_supported_flags;
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *, fl_owner_t id);
diff --git a/mm/gup.c b/mm/gup.c
index a9d4d724aef7..1f3a1d0b6e0d 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1519,8 +1519,11 @@ long populate_vma_page_range(struct vm_area_struct *vma,
* We made sure addr is within a VMA, so the following will
* not result in a stack expansion that recurses back here.
*/
- return __get_user_pages(mm, start, nr_pages, gup_flags,
- NULL, NULL, locked);
+ if ((vma->vm_flags & (VM_IO | VM_PFNMAP)) && vma->vm_file->f_op->populate)
+ return vma->vm_file->f_op->populate(vma->vm_file, start, end);
+ else
+ return __get_user_pages(mm, start, nr_pages, gup_flags,
+ NULL, NULL, locked);
}
/*
@@ -1598,6 +1601,7 @@ int __mm_populate(unsigned long start, unsigned long len, int ignore_errors)
struct vm_area_struct *vma = NULL;
int locked = 0;
long ret = 0;
+ bool is_io;
end = start + len;
@@ -1619,7 +1623,8 @@ int __mm_populate(unsigned long start, unsigned long len, int ignore_errors)
* range with the first VMA. Also, skip undesirable VMA types.
*/
nend = min(end, vma->vm_end);
- if (vma->vm_flags & (VM_IO | VM_PFNMAP))
+ is_io = !!(vma->vm_flags & (VM_IO | VM_PFNMAP));
+ if (is_io && !(is_io && vma->vm_file->f_op->populate))
continue;
if (nstart < vma->vm_start)
nstart = vma->vm_start;
--
2.35.1
next prev parent reply other threads:[~2022-03-08 11:29 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-08 11:28 [PATCH RFC v3 0/3] MAP_POPULATE for device memory Jarkko Sakkinen
2022-03-08 11:28 ` Jarkko Sakkinen [this message]
2022-03-08 11:28 ` [PATCH RFC v3 2/3] x86/sgx: Export sgx_encl_page_alloc() Jarkko Sakkinen
2022-03-08 11:28 ` [PATCH RFC v3 3/3] x86/sgx: Implement EAUG population with MAP_POPULATE Jarkko Sakkinen
2022-03-08 11:41 ` Jarkko Sakkinen
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=20220308112833.262805-2-jarkko@kernel.org \
--to=jarkko@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=dave.hansen@linux.intel.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-sgx@vger.kernel.org \
--cc=nathaniel@profian.com \
--cc=reinette.chatre@intel.com \
--cc=viro@zeniv.linux.org.uk \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.