vma.c (01c373e9a5ce2273812eaf83036c5357829fb3f7) vma.c (659c55ef981bb63355a65ffc3b3b5cad562b806a)
1// SPDX-License-Identifier: GPL-2.0-or-later
2
3/*
4 * VMA-specific functions.
5 */
6
7#include "vma_internal.h"
8#include "vma.h"

--- 1157 unchanged lines hidden (view full) ---

1166/*
1167 * vms_gather_munmap_vmas() - Put all VMAs within a range into a maple tree
1168 * for removal at a later date. Handles splitting first and last if necessary
1169 * and marking the vmas as isolated.
1170 *
1171 * @vms: The vma munmap struct
1172 * @mas_detach: The maple state tracking the detached tree
1173 *
1// SPDX-License-Identifier: GPL-2.0-or-later
2
3/*
4 * VMA-specific functions.
5 */
6
7#include "vma_internal.h"
8#include "vma.h"

--- 1157 unchanged lines hidden (view full) ---

1166/*
1167 * vms_gather_munmap_vmas() - Put all VMAs within a range into a maple tree
1168 * for removal at a later date. Handles splitting first and last if necessary
1169 * and marking the vmas as isolated.
1170 *
1171 * @vms: The vma munmap struct
1172 * @mas_detach: The maple state tracking the detached tree
1173 *
1174 * Return: 0 on success, -EPERM on mseal vmas, -ENOMEM otherwise
1174 * Return: 0 on success, error otherwise
1175 */
1176int vms_gather_munmap_vmas(struct vma_munmap_struct *vms,
1177 struct ma_state *mas_detach)
1178{
1179 struct vm_area_struct *next = NULL;
1175 */
1176int vms_gather_munmap_vmas(struct vma_munmap_struct *vms,
1177 struct ma_state *mas_detach)
1178{
1179 struct vm_area_struct *next = NULL;
1180 int error = -ENOMEM;
1180 int error;
1181
1182 /*
1183 * If we need to split any vma, do it now to save pain later.
1184 * Does it split the first one?
1185 */
1186 if (vms->start > vms->vma->vm_start) {
1187
1188 /*
1189 * Make sure that map_count on return from munmap() will
1190 * not exceed its limit; but let map_count go just above
1191 * its limit temporarily, to help free resources as expected.
1192 */
1193 if (vms->end < vms->vma->vm_end &&
1181
1182 /*
1183 * If we need to split any vma, do it now to save pain later.
1184 * Does it split the first one?
1185 */
1186 if (vms->start > vms->vma->vm_start) {
1187
1188 /*
1189 * Make sure that map_count on return from munmap() will
1190 * not exceed its limit; but let map_count go just above
1191 * its limit temporarily, to help free resources as expected.
1192 */
1193 if (vms->end < vms->vma->vm_end &&
1194 vms->vma->vm_mm->map_count >= sysctl_max_map_count)
1194 vms->vma->vm_mm->map_count >= sysctl_max_map_count) {
1195 error = -ENOMEM;
1195 goto map_count_exceeded;
1196 goto map_count_exceeded;
1197 }
1196
1197 /* Don't bother splitting the VMA if we can't unmap it anyway */
1198 if (!can_modify_vma(vms->vma)) {
1199 error = -EPERM;
1200 goto start_split_failed;
1201 }
1202
1198
1199 /* Don't bother splitting the VMA if we can't unmap it anyway */
1200 if (!can_modify_vma(vms->vma)) {
1201 error = -EPERM;
1202 goto start_split_failed;
1203 }
1204
1203 if (__split_vma(vms->vmi, vms->vma, vms->start, 1))
1205 error = __split_vma(vms->vmi, vms->vma, vms->start, 1);
1206 if (error)
1204 goto start_split_failed;
1205 }
1206 vms->prev = vma_prev(vms->vmi);
1207 if (vms->prev)
1208 vms->unmap_start = vms->prev->vm_end;
1209
1210 /*
1211 * Detach a range of VMAs from the mm. Using next as a temp variable as
1212 * it is always overwritten.
1213 */
1214 for_each_vma_range(*(vms->vmi), next, vms->end) {
1215 long nrpages;
1216
1217 if (!can_modify_vma(next)) {
1218 error = -EPERM;
1219 goto modify_vma_failed;
1220 }
1221 /* Does it split the end? */
1222 if (next->vm_end > vms->end) {
1207 goto start_split_failed;
1208 }
1209 vms->prev = vma_prev(vms->vmi);
1210 if (vms->prev)
1211 vms->unmap_start = vms->prev->vm_end;
1212
1213 /*
1214 * Detach a range of VMAs from the mm. Using next as a temp variable as
1215 * it is always overwritten.
1216 */
1217 for_each_vma_range(*(vms->vmi), next, vms->end) {
1218 long nrpages;
1219
1220 if (!can_modify_vma(next)) {
1221 error = -EPERM;
1222 goto modify_vma_failed;
1223 }
1224 /* Does it split the end? */
1225 if (next->vm_end > vms->end) {
1223 if (__split_vma(vms->vmi, next, vms->end, 0))
1226 error = __split_vma(vms->vmi, next, vms->end, 0);
1227 if (error)
1224 goto end_split_failed;
1225 }
1226 vma_start_write(next);
1227 mas_set(mas_detach, vms->vma_count++);
1228 goto end_split_failed;
1229 }
1230 vma_start_write(next);
1231 mas_set(mas_detach, vms->vma_count++);
1228 if (mas_store_gfp(mas_detach, next, GFP_KERNEL))
1232 error = mas_store_gfp(mas_detach, next, GFP_KERNEL);
1233 if (error)
1229 goto munmap_gather_failed;
1230
1231 vma_mark_detached(next, true);
1232 nrpages = vma_pages(next);
1233
1234 vms->nr_pages += nrpages;
1235 if (next->vm_flags & VM_LOCKED)
1236 vms->locked_vm += nrpages;

--- 13 unchanged lines hidden (view full) ---

1250 * If userfaultfd_unmap_prep returns an error the vmas
1251 * will remain split, but userland will get a
1252 * highly unexpected error anyway. This is no
1253 * different than the case where the first of the two
1254 * __split_vma fails, but we don't undo the first
1255 * split, despite we could. This is unlikely enough
1256 * failure that it's not worth optimizing it for.
1257 */
1234 goto munmap_gather_failed;
1235
1236 vma_mark_detached(next, true);
1237 nrpages = vma_pages(next);
1238
1239 vms->nr_pages += nrpages;
1240 if (next->vm_flags & VM_LOCKED)
1241 vms->locked_vm += nrpages;

--- 13 unchanged lines hidden (view full) ---

1255 * If userfaultfd_unmap_prep returns an error the vmas
1256 * will remain split, but userland will get a
1257 * highly unexpected error anyway. This is no
1258 * different than the case where the first of the two
1259 * __split_vma fails, but we don't undo the first
1260 * split, despite we could. This is unlikely enough
1261 * failure that it's not worth optimizing it for.
1262 */
1258 if (userfaultfd_unmap_prep(next, vms->start, vms->end,
1259 vms->uf))
1263 error = userfaultfd_unmap_prep(next, vms->start,
1264 vms->end, vms->uf);
1265 if (error)
1260 goto userfaultfd_error;
1261 }
1262#ifdef CONFIG_DEBUG_VM_MAPLE_TREE
1263 BUG_ON(next->vm_start < vms->start);
1264 BUG_ON(next->vm_start > vms->end);
1265#endif
1266 }
1267

--- 795 unchanged lines hidden ---
1266 goto userfaultfd_error;
1267 }
1268#ifdef CONFIG_DEBUG_VM_MAPLE_TREE
1269 BUG_ON(next->vm_start < vms->start);
1270 BUG_ON(next->vm_start > vms->end);
1271#endif
1272 }
1273

--- 795 unchanged lines hidden ---