Re: FIXMAP-related change to mm/memory.c

From: Roland McGrath (roland@redhat.com)
Date: Fri Jun 13 2003 - 01:56:16 EST


> Could you test Linus' proposal? It would definitely do the trick for ia64.

This patch vs 2.5.70 works fine for me on x86. include/asm-x86_64/fixmap.h
needs the macros added for its vsyscall page too.

Enjoy,
Roland

--- linux-2.5.70/include/asm-i386/fixmap.h.~1~ Mon May 26 18:00:21 2003
+++ linux-2.5.70/include/asm-i386/fixmap.h Thu Jun 12 23:46:11 2003
@@ -107,6 +107,14 @@ extern void __set_fixmap (enum fixed_add
 #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
 #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
 
+/*
+ * This is the range that is readable by user mode, and things
+ * acting like user mode such as get_user_pages.
+ */
+#define FIXADDR_USER_START (__fix_to_virt(FIX_VSYSCALL))
+#define FIXADDR_USER_END (FIXADDR_USER_START + PAGE_SIZE)
+
+
 extern void __this_fixmap_does_not_exist(void);
 
 /*

--- linux-2.5.70/mm/memory.c.~1~ Mon May 26 18:00:39 2003
+++ linux-2.5.70/mm/memory.c Thu Jun 12 23:41:04 2003
@@ -689,15 +689,16 @@ int get_user_pages(struct task_struct *t
 
                 vma = find_extend_vma(mm, start);
 
-#ifdef FIXADDR_START
- if (!vma && start >= FIXADDR_START && start < FIXADDR_TOP) {
+#ifdef FIXADDR_USER_START
+ if (!vma &&
+ start >= FIXADDR_USER_START && start < FIXADDR_USER_END) {
                         static struct vm_area_struct fixmap_vma = {
                                 /* Catch users - if there are any valid
                                    ones, we can make this be "&init_mm" or
                                    something. */
                                 .vm_mm = NULL,
- .vm_start = FIXADDR_START,
- .vm_end = FIXADDR_TOP,
+ .vm_start = FIXADDR_USER_START,
+ .vm_end = FIXADDR_USER_END,
                                 .vm_page_prot = PAGE_READONLY,
                                 .vm_flags = VM_READ | VM_EXEC,
                         };
@@ -705,6 +706,8 @@ int get_user_pages(struct task_struct *t
                         pgd_t *pgd;
                         pmd_t *pmd;
                         pte_t *pte;
+ if (write) /* user fixmap pages are read-only */
+ return i ? : -EFAULT;
                         pgd = pgd_offset_k(pg);
                         if (!pgd)
                                 return i ? : -EFAULT;
@@ -712,8 +715,7 @@ int get_user_pages(struct task_struct *t
                         if (!pmd)
                                 return i ? : -EFAULT;
                         pte = pte_offset_kernel(pmd, pg);
- if (!pte || !pte_present(*pte) || !pte_user(*pte) ||
- !(write ? pte_write(*pte) : pte_read(*pte)))
+ if (!pte || !pte_present(*pte))
                                 return i ? : -EFAULT;
                         if (pages) {
                                 pages[i] = pte_page(*pte);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Jun 15 2003 - 22:00:35 EST