diff options
author | Greg Banks <gnb@melbourne.sgi.com> | 2005-01-04 05:41:31 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-01-04 05:41:31 -0800 |
commit | 9a3ed4ef5e77e28427c33745d6317348123714c0 (patch) | |
tree | e7592ad02be1112e078038b78167a3c61da5d13e /mm | |
parent | 066752a33fe75667a5e0e65b0e1fac8653ba4535 (diff) | |
download | history-9a3ed4ef5e77e28427c33745d6317348123714c0.tar.gz |
[PATCH] oprofile: add check_user_page_readable()
Add check_user_page_readable() for kernel modules which need to follow user
space addresses but can't use get_user().
Signed-off-by: John Levon <levon@movementarian.org>
Signed-off-by: Greg Banks <gnb@melbourne.sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/memory.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/mm/memory.c b/mm/memory.c index 58ba5fe6660420..b0c61dac23e6a5 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -747,8 +747,8 @@ void zap_page_range(struct vm_area_struct *vma, unsigned long address, * Do a quick page-table lookup for a single page. * mm->page_table_lock must be held. */ -struct page * -follow_page(struct mm_struct *mm, unsigned long address, int write) +static struct page * +__follow_page(struct mm_struct *mm, unsigned long address, int read, int write) { pgd_t *pgd; pud_t *pud; @@ -784,6 +784,8 @@ follow_page(struct mm_struct *mm, unsigned long address, int write) if (pte_present(pte)) { if (write && !pte_write(pte)) goto out; + if (read && !pte_read(pte)) + goto out; pfn = pte_pfn(pte); if (pfn_valid(pfn)) { page = pfn_to_page(pfn); @@ -798,6 +800,20 @@ out: return NULL; } +struct page * +follow_page(struct mm_struct *mm, unsigned long address, int write) +{ + return __follow_page(mm, address, /*read*/0, write); +} + +int +check_user_page_readable(struct mm_struct *mm, unsigned long address) +{ + return __follow_page(mm, address, /*read*/1, /*write*/0) != NULL; +} + +EXPORT_SYMBOL(check_user_page_readable); + /* * Given a physical address, is there a useful struct page pointing to * it? This may become more complex in the future if we start dealing |