hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/mm/frame_vector.c
....@@ -29,7 +29,11 @@
2929 * different type underlying the specified range of virtual addresses.
3030 * When the function isn't able to map a single page, it returns error.
3131 *
32
- * This function takes care of grabbing mmap_sem as necessary.
32
+ * Note that get_vaddr_frames() cannot follow VM_IO mappings. It used
33
+ * to be able to do that, but that could (racily) return non-refcounted
34
+ * pfns.
35
+ *
36
+ * This function takes care of grabbing mmap_lock as necessary.
3337 */
3438 int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
3539 unsigned int gup_flags, struct frame_vector *vec)
....@@ -37,7 +41,6 @@
3741 struct mm_struct *mm = current->mm;
3842 struct vm_area_struct *vma;
3943 int ret = 0;
40
- int err;
4144 int locked;
4245
4346 if (nr_frames == 0)
....@@ -48,7 +51,7 @@
4851
4952 start = untagged_addr(start);
5053
51
- down_read(&mm->mmap_sem);
54
+ mmap_read_lock(mm);
5255 locked = 1;
5356 vma = find_vma_intersection(mm, start, start + 1);
5457 if (!vma) {
....@@ -72,37 +75,17 @@
7275 if (!(vma->vm_flags & (VM_IO | VM_PFNMAP))) {
7376 vec->got_ref = true;
7477 vec->is_pfns = false;
75
- ret = get_user_pages_locked(start, nr_frames,
78
+ ret = pin_user_pages_locked(start, nr_frames,
7679 gup_flags, (struct page **)(vec->ptrs), &locked);
77
- goto out;
80
+ if (likely(ret > 0))
81
+ goto out;
7882 }
7983
80
- vec->got_ref = false;
81
- vec->is_pfns = true;
82
- do {
83
- unsigned long *nums = frame_vector_pfns(vec);
84
+ vec->nr_frames = 0;
8485
85
- while (ret < nr_frames && start + PAGE_SIZE <= vma->vm_end) {
86
- err = follow_pfn(vma, start, &nums[ret]);
87
- if (err) {
88
- if (ret == 0)
89
- ret = err;
90
- goto out;
91
- }
92
- start += PAGE_SIZE;
93
- ret++;
94
- }
95
- /*
96
- * We stop if we have enough pages or if VMA doesn't completely
97
- * cover the tail page.
98
- */
99
- if (ret >= nr_frames || start < vma->vm_end)
100
- break;
101
- vma = find_vma_intersection(mm, start, start + 1);
102
- } while (vma && vma->vm_flags & (VM_IO | VM_PFNMAP));
10386 out:
10487 if (locked)
105
- up_read(&mm->mmap_sem);
88
+ mmap_read_unlock(mm);
10689 if (!ret)
10790 ret = -EFAULT;
10891 if (ret > 0)
....@@ -122,7 +105,6 @@
122105 */
123106 void put_vaddr_frames(struct frame_vector *vec)
124107 {
125
- int i;
126108 struct page **pages;
127109
128110 if (!vec->got_ref)
....@@ -135,8 +117,8 @@
135117 */
136118 if (WARN_ON(IS_ERR(pages)))
137119 goto out;
138
- for (i = 0; i < vec->nr_frames; i++)
139
- put_page(pages[i]);
120
+
121
+ unpin_user_pages(pages, vec->nr_frames);
140122 vec->got_ref = false;
141123 out:
142124 vec->nr_frames = 0;