]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Make get_user_pages() work again for ia64 gate area
authorDavid Mosberger <davidm@napali.hpl.hp.com>
Wed, 28 Jul 2004 16:01:30 +0000 (09:01 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Wed, 28 Jul 2004 16:01:30 +0000 (09:01 -0700)
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: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
include/asm-generic/pgtable.h
include/asm-ia64/pgtable.h
mm/memory.c

index ee74be68c19e96f34bfe3b9d5b483ac81908558a..29573197c3eebf695da3f776b08baacc837ef378 100644 (file)
@@ -122,4 +122,8 @@ static inline void ptep_mkdirty(pte_t *ptep)
 #define page_test_and_clear_young(page) (0)
 #endif
 
+#ifndef __HAVE_ARCH_PGD_OFFSET_GATE
+#define pgd_offset_gate(mm, addr)      pgd_offset(mm, addr)
+#endif
+
 #endif /* _ASM_GENERIC_PGTABLE_H */
index c30329a308b4477a3db77ff0bf1d8c32f01ae420..8433966536e625cd1e2a803c5f87817bb48e6ac6 100644 (file)
@@ -321,6 +321,11 @@ pgd_offset (struct mm_struct *mm, unsigned long address)
 #define pgd_offset_k(addr) \
        (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.. */
 #define pmd_offset(dir,addr) \
        ((pmd_t *) pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
@@ -552,6 +557,7 @@ do {                                                                                        \
 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
 #define __HAVE_ARCH_PTEP_MKDIRTY
 #define __HAVE_ARCH_PTE_SAME
+#define __HAVE_ARCH_PGD_OFFSET_GATE
 #include <asm-generic/pgtable.h>
 
 #endif /* _ASM_IA64_PGTABLE_H */
index 8738b38ac628b90ac249e293bb69a3d25b51541d..05ff4993852b0e7939737e10aaebb72fb791fab8 100644 (file)
@@ -727,7 +727,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                        pte_t *pte;
                        if (write) /* user gate pages are read-only */
                                return i ? : -EFAULT;
-                       pgd = pgd_offset(mm, pg);
+                       pgd = pgd_offset_gate(mm, pg);
                        if (!pgd)
                                return i ? : -EFAULT;
                        pmd = pmd_offset(pgd, pg);