Commit 47382294 authored by Roland McGrath's avatar Roland McGrath Committed by Linus Torvalds

[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.
parent 97782e54
...@@ -107,6 +107,14 @@ extern void __set_fixmap (enum fixed_addresses idx, ...@@ -107,6 +107,14 @@ extern void __set_fixmap (enum fixed_addresses idx,
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> 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); extern void __this_fixmap_does_not_exist(void);
/* /*
......
...@@ -689,15 +689,16 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, ...@@ -689,15 +689,16 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
vma = find_extend_vma(mm, start); vma = find_extend_vma(mm, start);
#ifdef FIXADDR_START #ifdef FIXADDR_USER_START
if (!vma && start >= FIXADDR_START && start < FIXADDR_TOP) { if (!vma &&
start >= FIXADDR_USER_START && start < FIXADDR_USER_END) {
static struct vm_area_struct fixmap_vma = { static struct vm_area_struct fixmap_vma = {
/* Catch users - if there are any valid /* Catch users - if there are any valid
ones, we can make this be "&init_mm" or ones, we can make this be "&init_mm" or
something. */ something. */
.vm_mm = NULL, .vm_mm = NULL,
.vm_start = FIXADDR_START, .vm_start = FIXADDR_USER_START,
.vm_end = FIXADDR_TOP, .vm_end = FIXADDR_USER_END,
.vm_page_prot = PAGE_READONLY, .vm_page_prot = PAGE_READONLY,
.vm_flags = VM_READ | VM_EXEC, .vm_flags = VM_READ | VM_EXEC,
}; };
...@@ -705,6 +706,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, ...@@ -705,6 +706,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
pgd_t *pgd; pgd_t *pgd;
pmd_t *pmd; pmd_t *pmd;
pte_t *pte; pte_t *pte;
if (write) /* user fixmap pages are read-only */
return i ? : -EFAULT;
pgd = pgd_offset_k(pg); pgd = pgd_offset_k(pg);
if (!pgd) if (!pgd)
return i ? : -EFAULT; return i ? : -EFAULT;
...@@ -712,8 +715,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, ...@@ -712,8 +715,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
if (!pmd) if (!pmd)
return i ? : -EFAULT; return i ? : -EFAULT;
pte = pte_offset_kernel(pmd, pg); pte = pte_offset_kernel(pmd, pg);
if (!pte || !pte_present(*pte) || !pte_user(*pte) || if (!pte || !pte_present(*pte))
!(write ? pte_write(*pte) : pte_read(*pte)))
return i ? : -EFAULT; return i ? : -EFAULT;
if (pages) { if (pages) {
pages[i] = pte_page(*pte); pages[i] = pte_page(*pte);
......
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