hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/mm/frame_vector.c
....@@ -29,7 +29,7 @@
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
+ * This function takes care of grabbing mmap_lock as necessary.
3333 */
3434 int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
3535 unsigned int gup_flags, struct frame_vector *vec)
....@@ -37,7 +37,6 @@
3737 struct mm_struct *mm = current->mm;
3838 struct vm_area_struct *vma;
3939 int ret = 0;
40
- int err;
4140 int locked;
4241
4342 if (nr_frames == 0)
....@@ -48,7 +47,7 @@
4847
4948 start = untagged_addr(start);
5049
51
- down_read(&mm->mmap_sem);
50
+ mmap_read_lock(mm);
5251 locked = 1;
5352 vma = find_vma_intersection(mm, start, start + 1);
5453 if (!vma) {
....@@ -72,37 +71,19 @@
7271 if (!(vma->vm_flags & (VM_IO | VM_PFNMAP))) {
7372 vec->got_ref = true;
7473 vec->is_pfns = false;
75
- ret = get_user_pages_locked(start, nr_frames,
74
+ ret = pin_user_pages_locked(start, nr_frames,
7675 gup_flags, (struct page **)(vec->ptrs), &locked);
77
- goto out;
76
+ if (likely(ret > 0))
77
+ goto out;
7878 }
7979
80
- vec->got_ref = false;
81
- vec->is_pfns = true;
82
- do {
83
- unsigned long *nums = frame_vector_pfns(vec);
80
+ /* This used to (racily) return non-refcounted pfns. Let people know */
81
+ WARN_ONCE(1, "get_vaddr_frames() cannot follow VM_IO mapping");
82
+ vec->nr_frames = 0;
8483
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));
10384 out:
10485 if (locked)
105
- up_read(&mm->mmap_sem);
86
+ mmap_read_unlock(mm);
10687 if (!ret)
10788 ret = -EFAULT;
10889 if (ret > 0)
....@@ -122,7 +103,6 @@
122103 */
123104 void put_vaddr_frames(struct frame_vector *vec)
124105 {
125
- int i;
126106 struct page **pages;
127107
128108 if (!vec->got_ref)
....@@ -135,8 +115,8 @@
135115 */
136116 if (WARN_ON(IS_ERR(pages)))
137117 goto out;
138
- for (i = 0; i < vec->nr_frames; i++)
139
- put_page(pages[i]);
118
+
119
+ unpin_user_pages(pages, vec->nr_frames);
140120 vec->got_ref = false;
141121 out:
142122 vec->nr_frames = 0;