Commit cf8b1162 authored by David Mosberger's avatar David Mosberger Committed by Linus Torvalds

[PATCH] Make get_user_pages() work again for ia64 gate area

Changeset

  roland@redhat.com[torvalds]|ChangeSet|20040624165002|30880

inadvertently broke ia64 because the patch assumed that pgd_offset_k() is
just an optimization of pgd_offset(), which it is not.  This patch fixes
the problem by introducing pgd_offset_gate().  On architectures on which
the gate area lives in the user's address-space, this should be aliased to
pgd_offset() and on architectures on which the gate area lives in the
kernel-mapped segment, this should be aliased to pgd_offset_k().

This bug was found and tracked down by Peter Chubb.

Signed-off-by: <davidm@hpl.hp.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f97804ea
...@@ -122,4 +122,8 @@ static inline void ptep_mkdirty(pte_t *ptep) ...@@ -122,4 +122,8 @@ static inline void ptep_mkdirty(pte_t *ptep)
#define page_test_and_clear_young(page) (0) #define page_test_and_clear_young(page) (0)
#endif #endif
#ifndef __HAVE_ARCH_PGD_OFFSET_GATE
#define pgd_offset_gate(mm, addr) pgd_offset(mm, addr)
#endif
#endif /* _ASM_GENERIC_PGTABLE_H */ #endif /* _ASM_GENERIC_PGTABLE_H */
...@@ -321,6 +321,11 @@ pgd_offset (struct mm_struct *mm, unsigned long address) ...@@ -321,6 +321,11 @@ pgd_offset (struct mm_struct *mm, unsigned long address)
#define pgd_offset_k(addr) \ #define pgd_offset_k(addr) \
(init_mm.pgd + (((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))) (init_mm.pgd + (((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)))
/* Look up a pgd entry in the gate area. On IA-64, the gate-area
resides in the kernel-mapped segment, hence we use pgd_offset_k()
here. */
#define pgd_offset_gate(mm, addr) pgd_offset_k(addr)
/* Find an entry in the second-level page table.. */ /* Find an entry in the second-level page table.. */
#define pmd_offset(dir,addr) \ #define pmd_offset(dir,addr) \
((pmd_t *) pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))) ((pmd_t *) pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
...@@ -552,6 +557,7 @@ do { \ ...@@ -552,6 +557,7 @@ do { \
#define __HAVE_ARCH_PTEP_SET_WRPROTECT #define __HAVE_ARCH_PTEP_SET_WRPROTECT
#define __HAVE_ARCH_PTEP_MKDIRTY #define __HAVE_ARCH_PTEP_MKDIRTY
#define __HAVE_ARCH_PTE_SAME #define __HAVE_ARCH_PTE_SAME
#define __HAVE_ARCH_PGD_OFFSET_GATE
#include <asm-generic/pgtable.h> #include <asm-generic/pgtable.h>
#endif /* _ASM_IA64_PGTABLE_H */ #endif /* _ASM_IA64_PGTABLE_H */
...@@ -727,7 +727,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, ...@@ -727,7 +727,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
pte_t *pte; pte_t *pte;
if (write) /* user gate pages are read-only */ if (write) /* user gate pages are read-only */
return i ? : -EFAULT; return i ? : -EFAULT;
pgd = pgd_offset(mm, pg); pgd = pgd_offset_gate(mm, pg);
if (!pgd) if (!pgd)
return i ? : -EFAULT; return i ? : -EFAULT;
pmd = pmd_offset(pgd, pg); pmd = pmd_offset(pgd, pg);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment