Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2003-06-13 04:26:52 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2003-06-13 04:26:52 -0700
commit47382294ae9ecca706f7386a0a890abcbf6bdf4b (patch)
treeecbadd3353b993c506a9c6cfa74bcfe09f6588c6
parent97782e54f4b63ba0e4bbdbb914ff80e67a2e7a9b (diff)
[PATCH] User FIXMAP area simplification
As per Linus' proposal: make special macros for the user-accessible fixmap, simplifying access checks to make it trivial to handle ia64 issues.
-rw-r--r--include/asm-i386/fixmap.h8
-rw-r--r--mm/memory.c14
2 files changed, 16 insertions, 6 deletions
diff --git a/include/asm-i386/fixmap.h b/include/asm-i386/fixmap.h
index 6570d0d65e02..9d99b8b53af0 100644
--- a/include/asm-i386/fixmap.h
+++ b/include/asm-i386/fixmap.h
@@ -107,6 +107,14 @@ extern void __set_fixmap (enum fixed_addresses idx,
#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);
/*
diff --git a/mm/memory.c b/mm/memory.c
index e0dee2c62f5d..c95671289175 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -689,15 +689,16 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
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 *tsk, struct mm_struct *mm,
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 *tsk, struct mm_struct *mm,
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);