mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-26 11:47:31 +00:00
Vm map code performs clipping when map entry covers region which is
larger than the operational region. If the op region size is zero, clipping would create a zero-sized map entry. The result is that vm map splay starts behaving inconsistently, sometimes returning zero-sized entry, sometimes the next (or previous) entry. One step further, it could result in e.g. vm_map_wire() setting MAP_ENTRY_IN_TRANSITION on the zero-sized entry, but failing to clear it in the done part. The vm_map_delete() than hangs forever waiting for the flag removal. Verify for zero-length requests and act as if it is always successfull without performing any action on the address space. Diagnosed by: pho Tested by: pho (previous version) Reviewed by: alc (previous version) Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
ff3ae454c0
commit
79e9451f07
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=258367
@ -1876,6 +1876,9 @@ vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end,
|
||||
struct ucred *cred;
|
||||
vm_prot_t old_prot;
|
||||
|
||||
if (start == end)
|
||||
return (KERN_SUCCESS);
|
||||
|
||||
vm_map_lock(map);
|
||||
|
||||
VM_MAP_RANGE_CHECK(map, start, end);
|
||||
@ -2030,12 +2033,16 @@ vm_map_madvise(
|
||||
case MADV_AUTOSYNC:
|
||||
case MADV_NOCORE:
|
||||
case MADV_CORE:
|
||||
if (start == end)
|
||||
return (KERN_SUCCESS);
|
||||
modify_map = 1;
|
||||
vm_map_lock(map);
|
||||
break;
|
||||
case MADV_WILLNEED:
|
||||
case MADV_DONTNEED:
|
||||
case MADV_FREE:
|
||||
if (start == end)
|
||||
return (KERN_SUCCESS);
|
||||
vm_map_lock_read(map);
|
||||
break;
|
||||
default:
|
||||
@ -2190,6 +2197,8 @@ vm_map_inherit(vm_map_t map, vm_offset_t start, vm_offset_t end,
|
||||
default:
|
||||
return (KERN_INVALID_ARGUMENT);
|
||||
}
|
||||
if (start == end)
|
||||
return (KERN_SUCCESS);
|
||||
vm_map_lock(map);
|
||||
VM_MAP_RANGE_CHECK(map, start, end);
|
||||
if (vm_map_lookup_entry(map, start, &temp_entry)) {
|
||||
@ -2222,6 +2231,8 @@ vm_map_unwire(vm_map_t map, vm_offset_t start, vm_offset_t end,
|
||||
int rv;
|
||||
boolean_t need_wakeup, result, user_unwire;
|
||||
|
||||
if (start == end)
|
||||
return (KERN_SUCCESS);
|
||||
user_unwire = (flags & VM_MAP_WIRE_USER) ? TRUE : FALSE;
|
||||
vm_map_lock(map);
|
||||
VM_MAP_RANGE_CHECK(map, start, end);
|
||||
@ -2392,6 +2403,8 @@ vm_map_wire(vm_map_t map, vm_offset_t start, vm_offset_t end,
|
||||
boolean_t fictitious, need_wakeup, result, user_wire;
|
||||
vm_prot_t prot;
|
||||
|
||||
if (start == end)
|
||||
return (KERN_SUCCESS);
|
||||
prot = 0;
|
||||
if (flags & VM_MAP_WIRE_WRITE)
|
||||
prot |= VM_PROT_WRITE;
|
||||
@ -2833,6 +2846,8 @@ vm_map_delete(vm_map_t map, vm_offset_t start, vm_offset_t end)
|
||||
vm_map_entry_t first_entry;
|
||||
|
||||
VM_MAP_ASSERT_LOCKED(map);
|
||||
if (start == end)
|
||||
return (KERN_SUCCESS);
|
||||
|
||||
/*
|
||||
* Find the start of the region, and clip it
|
||||
|
Loading…
Reference in New Issue
Block a user