aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c80
1 files changed, 59 insertions, 21 deletions
diff --git a/mm/memory.c b/mm/memory.c
index e48945ab362b..9da8cab1b1b0 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1486,9 +1486,9 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
1486 struct vm_area_struct *vma; 1486 struct vm_area_struct *vma;
1487 1487
1488 vma = find_extend_vma(mm, start); 1488 vma = find_extend_vma(mm, start);
1489 if (!vma && in_gate_area(tsk, start)) { 1489 if (!vma && in_gate_area(mm, start)) {
1490 unsigned long pg = start & PAGE_MASK; 1490 unsigned long pg = start & PAGE_MASK;
1491 struct vm_area_struct *gate_vma = get_gate_vma(tsk); 1491 struct vm_area_struct *gate_vma = get_gate_vma(mm);
1492 pgd_t *pgd; 1492 pgd_t *pgd;
1493 pud_t *pud; 1493 pud_t *pud;
1494 pmd_t *pmd; 1494 pmd_t *pmd;
@@ -1569,6 +1569,8 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
1569 fault_flags |= FAULT_FLAG_WRITE; 1569 fault_flags |= FAULT_FLAG_WRITE;
1570 if (nonblocking) 1570 if (nonblocking)
1571 fault_flags |= FAULT_FLAG_ALLOW_RETRY; 1571 fault_flags |= FAULT_FLAG_ALLOW_RETRY;
1572 if (foll_flags & FOLL_NOWAIT)
1573 fault_flags |= (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_RETRY_NOWAIT);
1572 1574
1573 ret = handle_mm_fault(mm, vma, start, 1575 ret = handle_mm_fault(mm, vma, start,
1574 fault_flags); 1576 fault_flags);
@@ -1589,13 +1591,17 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
1589 return i ? i : -EFAULT; 1591 return i ? i : -EFAULT;
1590 BUG(); 1592 BUG();
1591 } 1593 }
1592 if (ret & VM_FAULT_MAJOR) 1594
1593 tsk->maj_flt++; 1595 if (tsk) {
1594 else 1596 if (ret & VM_FAULT_MAJOR)
1595 tsk->min_flt++; 1597 tsk->maj_flt++;
1598 else
1599 tsk->min_flt++;
1600 }
1596 1601
1597 if (ret & VM_FAULT_RETRY) { 1602 if (ret & VM_FAULT_RETRY) {
1598 *nonblocking = 0; 1603 if (nonblocking)
1604 *nonblocking = 0;
1599 return i; 1605 return i;
1600 } 1606 }
1601 1607
@@ -1638,7 +1644,8 @@ EXPORT_SYMBOL(__get_user_pages);
1638 1644
1639/** 1645/**
1640 * get_user_pages() - pin user pages in memory 1646 * get_user_pages() - pin user pages in memory
1641 * @tsk: task_struct of target task 1647 * @tsk: the task_struct to use for page fault accounting, or
1648 * NULL if faults are not to be recorded.
1642 * @mm: mm_struct of target mm 1649 * @mm: mm_struct of target mm
1643 * @start: starting user address 1650 * @start: starting user address
1644 * @nr_pages: number of pages from start to pin 1651 * @nr_pages: number of pages from start to pin
@@ -2764,7 +2771,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
2764 swp_entry_t entry; 2771 swp_entry_t entry;
2765 pte_t pte; 2772 pte_t pte;
2766 int locked; 2773 int locked;
2767 struct mem_cgroup *ptr = NULL; 2774 struct mem_cgroup *ptr;
2768 int exclusive = 0; 2775 int exclusive = 0;
2769 int ret = 0; 2776 int ret = 0;
2770 2777
@@ -3496,7 +3503,7 @@ static int __init gate_vma_init(void)
3496__initcall(gate_vma_init); 3503__initcall(gate_vma_init);
3497#endif 3504#endif
3498 3505
3499struct vm_area_struct *get_gate_vma(struct task_struct *tsk) 3506struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
3500{ 3507{
3501#ifdef AT_SYSINFO_EHDR 3508#ifdef AT_SYSINFO_EHDR
3502 return &gate_vma; 3509 return &gate_vma;
@@ -3505,7 +3512,7 @@ struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
3505#endif 3512#endif
3506} 3513}
3507 3514
3508int in_gate_area_no_task(unsigned long addr) 3515int in_gate_area_no_mm(unsigned long addr)
3509{ 3516{
3510#ifdef AT_SYSINFO_EHDR 3517#ifdef AT_SYSINFO_EHDR
3511 if ((addr >= FIXADDR_USER_START) && (addr < FIXADDR_USER_END)) 3518 if ((addr >= FIXADDR_USER_START) && (addr < FIXADDR_USER_END))
@@ -3646,20 +3653,15 @@ int generic_access_phys(struct vm_area_struct *vma, unsigned long addr,
3646#endif 3653#endif
3647 3654
3648/* 3655/*
3649 * Access another process' address space. 3656 * Access another process' address space as given in mm. If non-NULL, use the
3650 * Source/target buffer must be kernel space, 3657 * given task for page fault accounting.
3651 * Do not walk the page table directly, use get_user_pages
3652 */ 3658 */
3653int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write) 3659static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
3660 unsigned long addr, void *buf, int len, int write)
3654{ 3661{
3655 struct mm_struct *mm;
3656 struct vm_area_struct *vma; 3662 struct vm_area_struct *vma;
3657 void *old_buf = buf; 3663 void *old_buf = buf;
3658 3664
3659 mm = get_task_mm(tsk);
3660 if (!mm)
3661 return 0;
3662
3663 down_read(&mm->mmap_sem); 3665 down_read(&mm->mmap_sem);
3664 /* ignore errors, just check how much was successfully transferred */ 3666 /* ignore errors, just check how much was successfully transferred */
3665 while (len) { 3667 while (len) {
@@ -3708,11 +3710,47 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
3708 addr += bytes; 3710 addr += bytes;
3709 } 3711 }
3710 up_read(&mm->mmap_sem); 3712 up_read(&mm->mmap_sem);
3711 mmput(mm);
3712 3713
3713 return buf - old_buf; 3714 return buf - old_buf;
3714} 3715}
3715 3716
3717/**
3718 * access_remote_vm - access another process' address space
3719 * @mm: the mm_struct of the target address space
3720 * @addr: start address to access
3721 * @buf: source or destination buffer
3722 * @len: number of bytes to transfer
3723 * @write: whether the access is a write
3724 *
3725 * The caller must hold a reference on @mm.
3726 */
3727int access_remote_vm(struct mm_struct *mm, unsigned long addr,
3728 void *buf, int len, int write)
3729{
3730 return __access_remote_vm(NULL, mm, addr, buf, len, write);
3731}
3732
3733/*
3734 * Access another process' address space.
3735 * Source/target buffer must be kernel space,
3736 * Do not walk the page table directly, use get_user_pages
3737 */
3738int access_process_vm(struct task_struct *tsk, unsigned long addr,
3739 void *buf, int len, int write)
3740{
3741 struct mm_struct *mm;
3742 int ret;
3743
3744 mm = get_task_mm(tsk);
3745 if (!mm)
3746 return 0;
3747
3748 ret = __access_remote_vm(tsk, mm, addr, buf, len, write);
3749 mmput(mm);
3750
3751 return ret;
3752}
3753
3716/* 3754/*
3717 * Print the name of a VMA. 3755 * Print the name of a VMA.
3718 */ 3756 */