diff options
Diffstat (limited to 'arch/s390/lib/uaccess_pt.c')
| -rw-r--r-- | arch/s390/lib/uaccess_pt.c | 154 |
1 files changed, 0 insertions, 154 deletions
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c deleted file mode 100644 index 633249c3ba9..00000000000 --- a/arch/s390/lib/uaccess_pt.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * arch/s390/lib/uaccess_pt.c - * - * User access functions based on page table walks. - * - * Copyright IBM Corp. 2006 - * Author(s): Gerald Schaefer (gerald.schaefer@de.ibm.com) - */ - -#include <linux/errno.h> -#include <linux/mm.h> -#include <asm/uaccess.h> -#include <asm/futex.h> - -static inline int __handle_fault(struct mm_struct *mm, unsigned long address, - int write_access) -{ - struct vm_area_struct *vma; - int ret = -EFAULT; - - down_read(&mm->mmap_sem); - vma = find_vma(mm, address); - if (unlikely(!vma)) - goto out; - if (unlikely(vma->vm_start > address)) { - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto out; - if (expand_stack(vma, address)) - goto out; - } - - if (!write_access) { - /* page not present, check vm flags */ - if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) - goto out; - } else { - if (!(vma->vm_flags & VM_WRITE)) - goto out; - } - -survive: - switch (handle_mm_fault(mm, vma, address, write_access)) { - case VM_FAULT_MINOR: - current->min_flt++; - break; - case VM_FAULT_MAJOR: - current->maj_flt++; - break; - case VM_FAULT_SIGBUS: - goto out_sigbus; - case VM_FAULT_OOM: - goto out_of_memory; - default: - BUG(); - } - ret = 0; -out: - up_read(&mm->mmap_sem); - return ret; - -out_of_memory: - up_read(&mm->mmap_sem); - if (is_init(current)) { - yield(); - down_read(&mm->mmap_sem); - goto survive; - } - printk("VM: killing process %s\n", current->comm); - return ret; - -out_sigbus: - up_read(&mm->mmap_sem); - current->thread.prot_addr = address; - current->thread.trap_no = 0x11; - force_sig(SIGBUS, current); - return ret; -} - -static inline size_t __user_copy_pt(unsigned long uaddr, void *kptr, - size_t n, int write_user) -{ - struct mm_struct *mm = current->mm; - unsigned long offset, pfn, done, size; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - void *from, *to; - - done = 0; -retry: - spin_lock(&mm->page_table_lock); - do { - pgd = pgd_offset(mm, uaddr); - if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) - goto fault; - - pmd = pmd_offset(pgd, uaddr); - if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) - goto fault; - - pte = pte_offset_map(pmd, uaddr); - if (!pte || !pte_present(*pte) || - (write_user && !pte_write(*pte))) - goto fault; - - pfn = pte_pfn(*pte); - if (!pfn_valid(pfn)) - goto out; - - offset = uaddr & (PAGE_SIZE - 1); - size = min(n - done, PAGE_SIZE - offset); - if (write_user) { - to = (void *)((pfn << PAGE_SHIFT) + offset); - from = kptr + done; - } else { - from = (void *)((pfn << PAGE_SHIFT) + offset); - to = kptr + done; - } - memcpy(to, from, size); - done += size; - uaddr += size; - } while (done < n); -out: - spin_unlock(&mm->page_table_lock); - return n - done; -fault: - spin_unlock(&mm->page_table_lock); - if (__handle_fault(mm, uaddr, write_user)) - return n - done; - goto retry; -} - -size_t copy_from_user_pt(size_t n, const void __user *from, void *to) -{ - size_t rc; - - if (segment_eq(get_fs(), KERNEL_DS)) { - memcpy(to, (void __kernel __force *) from, n); - return 0; - } - rc = __user_copy_pt((unsigned long) from, to, n, 0); - if (unlikely(rc)) - memset(to + n - rc, 0, rc); - return rc; -} - -size_t copy_to_user_pt(size_t n, void __user *to, const void *from) -{ - if (segment_eq(get_fs(), KERNEL_DS)) { - memcpy((void __kernel __force *) to, from, n); - return 0; - } - return __user_copy_pt((unsigned long) to, (void *) from, n, 1); -} |
