mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
mm: always expand the stack with the mmap write lock held
This finishes the job of always holding the mmap write lock when extending the user stack vma, and removes the 'write_locked' argument from the vm helper functions again. For some cases, we just avoid expanding the stack at all: drivers and page pinning really shouldn't be extending any stacks. Let's see if any strange users really wanted that. It's worth noting that architectures that weren't converted to the new lock_mm_and_find_vma() helper function are left using the legacy "expand_stack()" function, but it has been changed to drop the mmap_lock and take it for writing while expanding the vma. This makes it fairly straightforward to convert the remaining architectures. As a result of dropping and re-taking the lock, the calling conventions for this function have also changed, since the old vma may no longer be valid. So it will now return the new vma if successful, and NULL - and the lock dropped - if the area could not be extended. Tested-by: Vegard Nossum <vegard.nossum@oracle.com> Tested-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> # ia64 Tested-by: Frank Scheiner <frank.scheiner@web.de> # ia64 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
f313c51d26
commit
8d7071af89
17 changed files with 169 additions and 116 deletions
|
@ -110,10 +110,12 @@ retry:
|
|||
* register backing store that needs to expand upwards, in
|
||||
* this case vma will be null, but prev_vma will ne non-null
|
||||
*/
|
||||
if (( !vma && prev_vma ) || (address < vma->vm_start) )
|
||||
goto check_expansion;
|
||||
if (( !vma && prev_vma ) || (address < vma->vm_start) ) {
|
||||
vma = expand_stack(mm, address);
|
||||
if (!vma)
|
||||
goto bad_area_nosemaphore;
|
||||
}
|
||||
|
||||
good_area:
|
||||
code = SEGV_ACCERR;
|
||||
|
||||
/* OK, we've got a good vm_area for this memory area. Check the access permissions: */
|
||||
|
@ -177,35 +179,9 @@ retry:
|
|||
mmap_read_unlock(mm);
|
||||
return;
|
||||
|
||||
check_expansion:
|
||||
if (!(prev_vma && (prev_vma->vm_flags & VM_GROWSUP) && (address == prev_vma->vm_end))) {
|
||||
if (!vma)
|
||||
goto bad_area;
|
||||
if (!(vma->vm_flags & VM_GROWSDOWN))
|
||||
goto bad_area;
|
||||
if (REGION_NUMBER(address) != REGION_NUMBER(vma->vm_start)
|
||||
|| REGION_OFFSET(address) >= RGN_MAP_LIMIT)
|
||||
goto bad_area;
|
||||
if (expand_stack(vma, address))
|
||||
goto bad_area;
|
||||
} else {
|
||||
vma = prev_vma;
|
||||
if (REGION_NUMBER(address) != REGION_NUMBER(vma->vm_start)
|
||||
|| REGION_OFFSET(address) >= RGN_MAP_LIMIT)
|
||||
goto bad_area;
|
||||
/*
|
||||
* Since the register backing store is accessed sequentially,
|
||||
* we disallow growing it by more than a page at a time.
|
||||
*/
|
||||
if (address > vma->vm_end + PAGE_SIZE - sizeof(long))
|
||||
goto bad_area;
|
||||
if (expand_upwards(vma, address))
|
||||
goto bad_area;
|
||||
}
|
||||
goto good_area;
|
||||
|
||||
bad_area:
|
||||
mmap_read_unlock(mm);
|
||||
bad_area_nosemaphore:
|
||||
if ((isr & IA64_ISR_SP)
|
||||
|| ((isr & IA64_ISR_NA) && (isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH))
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue