| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * linux/arch/arm/lib/uaccess_with_memcpy.c |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Written by: Lennert Buytenhek and Nicolas Pitre |
|---|
| 5 | 6 | * Copyright (C) 2009 Marvell Semiconductor |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 9 | | - * published by the Free Software Foundation. |
|---|
| 10 | 7 | */ |
|---|
| 11 | 8 | |
|---|
| 12 | 9 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 27 | 24 | { |
|---|
| 28 | 25 | unsigned long addr = (unsigned long)_addr; |
|---|
| 29 | 26 | pgd_t *pgd; |
|---|
| 27 | + p4d_t *p4d; |
|---|
| 30 | 28 | pmd_t *pmd; |
|---|
| 31 | 29 | pte_t *pte; |
|---|
| 32 | 30 | pud_t *pud; |
|---|
| .. | .. |
|---|
| 36 | 34 | if (unlikely(pgd_none(*pgd) || pgd_bad(*pgd))) |
|---|
| 37 | 35 | return 0; |
|---|
| 38 | 36 | |
|---|
| 39 | | - pud = pud_offset(pgd, addr); |
|---|
| 37 | + p4d = p4d_offset(pgd, addr); |
|---|
| 38 | + if (unlikely(p4d_none(*p4d) || p4d_bad(*p4d))) |
|---|
| 39 | + return 0; |
|---|
| 40 | + |
|---|
| 41 | + pud = pud_offset(p4d, addr); |
|---|
| 40 | 42 | if (unlikely(pud_none(*pud) || pud_bad(*pud))) |
|---|
| 41 | 43 | return 0; |
|---|
| 42 | 44 | |
|---|
| .. | .. |
|---|
| 99 | 101 | atomic = faulthandler_disabled(); |
|---|
| 100 | 102 | |
|---|
| 101 | 103 | if (!atomic) |
|---|
| 102 | | - down_read(¤t->mm->mmap_sem); |
|---|
| 104 | + mmap_read_lock(current->mm); |
|---|
| 103 | 105 | while (n) { |
|---|
| 104 | 106 | pte_t *pte; |
|---|
| 105 | 107 | spinlock_t *ptl; |
|---|
| .. | .. |
|---|
| 107 | 109 | |
|---|
| 108 | 110 | while (!pin_page_for_write(to, &pte, &ptl)) { |
|---|
| 109 | 111 | if (!atomic) |
|---|
| 110 | | - up_read(¤t->mm->mmap_sem); |
|---|
| 112 | + mmap_read_unlock(current->mm); |
|---|
| 111 | 113 | if (__put_user(0, (char __user *)to)) |
|---|
| 112 | 114 | goto out; |
|---|
| 113 | 115 | if (!atomic) |
|---|
| 114 | | - down_read(¤t->mm->mmap_sem); |
|---|
| 116 | + mmap_read_lock(current->mm); |
|---|
| 115 | 117 | } |
|---|
| 116 | 118 | |
|---|
| 117 | 119 | tocopy = (~(unsigned long)to & ~PAGE_MASK) + 1; |
|---|
| .. | .. |
|---|
| 131 | 133 | spin_unlock(ptl); |
|---|
| 132 | 134 | } |
|---|
| 133 | 135 | if (!atomic) |
|---|
| 134 | | - up_read(¤t->mm->mmap_sem); |
|---|
| 136 | + mmap_read_unlock(current->mm); |
|---|
| 135 | 137 | |
|---|
| 136 | 138 | out: |
|---|
| 137 | 139 | return n; |
|---|
| .. | .. |
|---|
| 168 | 170 | return 0; |
|---|
| 169 | 171 | } |
|---|
| 170 | 172 | |
|---|
| 171 | | - down_read(¤t->mm->mmap_sem); |
|---|
| 173 | + mmap_read_lock(current->mm); |
|---|
| 172 | 174 | while (n) { |
|---|
| 173 | 175 | pte_t *pte; |
|---|
| 174 | 176 | spinlock_t *ptl; |
|---|
| 175 | 177 | int tocopy; |
|---|
| 176 | 178 | |
|---|
| 177 | 179 | while (!pin_page_for_write(addr, &pte, &ptl)) { |
|---|
| 178 | | - up_read(¤t->mm->mmap_sem); |
|---|
| 180 | + mmap_read_unlock(current->mm); |
|---|
| 179 | 181 | if (__put_user(0, (char __user *)addr)) |
|---|
| 180 | 182 | goto out; |
|---|
| 181 | | - down_read(¤t->mm->mmap_sem); |
|---|
| 183 | + mmap_read_lock(current->mm); |
|---|
| 182 | 184 | } |
|---|
| 183 | 185 | |
|---|
| 184 | 186 | tocopy = (~(unsigned long)addr & ~PAGE_MASK) + 1; |
|---|
| .. | .. |
|---|
| 196 | 198 | else |
|---|
| 197 | 199 | spin_unlock(ptl); |
|---|
| 198 | 200 | } |
|---|
| 199 | | - up_read(¤t->mm->mmap_sem); |
|---|
| 201 | + mmap_read_unlock(current->mm); |
|---|
| 200 | 202 | |
|---|
| 201 | 203 | out: |
|---|
| 202 | 204 | return n; |
|---|