Skip to content

Commit

Permalink
From patchwork series 421241
Browse files Browse the repository at this point in the history
  • Loading branch information
Fox Snowpatch committed Aug 28, 2024
1 parent ddf9a4c commit 447ad5c
Show file tree
Hide file tree
Showing 20 changed files with 216 additions and 50 deletions.
10 changes: 10 additions & 0 deletions arch/arm/mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.length = len;
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
if (flags & MAP_BELOW_HINT)
info.high_limit = MIN(info.high_limit, addr + len);
info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
return vm_unmapped_area(&info);
Expand Down Expand Up @@ -122,6 +124,12 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.length = len;
info.low_limit = FIRST_USER_ADDRESS;
info.high_limit = mm->mmap_base;
if (flags & MAP_BELOW_HINT)
/*
* Subtract (STACK_TOP - mm->mmap_base) to get random
* offset defined in mmap_base() in mm/util.c
*/
info.high_limit = MIN(info.high_limit, (addr + len) - (STACK_TOP - mm->mmap_base));
info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
addr = vm_unmapped_area(&info);
Expand All @@ -137,6 +145,8 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.flags = 0;
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
if (flags & MAP_BELOW_HINT)
info.high_limit = MIN(info.high_limit, addr + len);
addr = vm_unmapped_area(&info);
}

Expand Down
34 changes: 29 additions & 5 deletions arch/arm64/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,36 @@
#endif /* CONFIG_COMPAT */

#ifndef CONFIG_ARM64_FORCE_52BIT
#define arch_get_mmap_end(addr, len, flags) \
(((addr) > DEFAULT_MAP_WINDOW) ? TASK_SIZE : DEFAULT_MAP_WINDOW)
#define arch_get_mmap_end(addr, len, flags) \
({ \
unsigned long mmap_end; \
typeof(flags) _flags = (flags); \
typeof(addr) _addr = (addr); \
typeof(len) _len = (len); \
if (_flags & MAP_BELOW_HINT && _addr != 0 && ((_addr + _len) > BIT(VA_BITS - 1))) \
mmap_end = (_addr + _len); \
else \
mmap_end = ((_addr > DEFAULT_MAP_WINDOW) ? TASK_SIZE : DEFAULT_MAP_WINDOW); \
mmap_end \
})

#define arch_get_mmap_base(addr, len, base, flags) \
({ \
unsigned long mmap_base; \
typeof(flags) _flags = (flags); \
typeof(addr) _addr = (addr); \
typeof(base) _base = (base); \
typeof(len) _len = (len); \
unsigned long rnd_gap = DEFAULT_MAP_WINDOW - (_base); \
if (_flags & MAP_BELOW_HINT && _addr != 0 && ((_addr + _len) > BIT(VA_BITS - 1)))\
mmap_base = (_addr + _len) - rnd_gap; \
else \
mmap_end = ((_addr > DEFAULT_MAP_WINDOW) ? \
_base + TASK_SIZE - DEFAULT_MAP_WINDOW : \
_base); \
mmap_end \
})

#define arch_get_mmap_base(addr, base) ((addr > DEFAULT_MAP_WINDOW) ? \
base + TASK_SIZE - DEFAULT_MAP_WINDOW :\
base)
#endif /* CONFIG_ARM64_FORCE_52BIT */

extern phys_addr_t arm64_dma_phys_limit;
Expand Down
11 changes: 11 additions & 0 deletions arch/loongarch/mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
info.flags = VM_UNMAPPED_AREA_TOPDOWN;
info.low_limit = PAGE_SIZE;
info.high_limit = mm->mmap_base;
if (flags & MAP_BELOW_HINT)
/*
* Subtract (STACK_TOP - mm->mmap_base) to get random
* offset defined in mmap_base() in mm/util.c
*/
info.high_limit = MIN(mm->mmap_base,
(addr + len) - (STACK_TOP - mm->mmap_base))
addr = vm_unmapped_area(&info);

if (!(addr & ~PAGE_MASK))
Expand All @@ -84,7 +91,11 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
}

info.low_limit = mm->mmap_base;

info.high_limit = TASK_SIZE;
if (flags & MAP_BELOW_HINT)
info.high_limit = MIN(info.high_limit, addr + len);

return vm_unmapped_area(&info);
}

Expand Down
9 changes: 9 additions & 0 deletions arch/mips/mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
info.flags = VM_UNMAPPED_AREA_TOPDOWN;
info.low_limit = PAGE_SIZE;
info.high_limit = mm->mmap_base;
if (flags & MAP_BELOW_HINT)
/*
* Subtract (STACK_TOP - mm->mmap_base) to get random
* offset defined in mmap_base() in mm/util.c
*/
info.high_limit = MIN(info.high_limit,
(addr + len) - (STACK_TOP - mm->mmap_base));
addr = vm_unmapped_area(&info);

if (!(addr & ~PAGE_MASK))
Expand All @@ -94,6 +101,8 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,

info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
if (flags & MAP_BELOW_HINT)
info.high_limit = MIN(info.high_limit, addr + len);
return vm_unmapped_area(&info);
}

Expand Down
1 change: 1 addition & 0 deletions arch/parisc/include/uapi/asm/mman.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#define MAP_HUGETLB 0x80000 /* create a huge page mapping */
#define MAP_FIXED_NOREPLACE 0x100000 /* MAP_FIXED which doesn't unmap underlying mapping */
#define MAP_UNINITIALIZED 0 /* uninitialized anonymous mmap */
#define MAP_BELOW_HINT 0x200000 /* give out address that is below (inclusive) hint address */

#define MS_SYNC 1 /* synchronous memory sync */
#define MS_ASYNC 2 /* sync memory asynchronously */
Expand Down
9 changes: 9 additions & 0 deletions arch/parisc/kernel/sys_parisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,13 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
info.flags = VM_UNMAPPED_AREA_TOPDOWN;
info.low_limit = PAGE_SIZE;
info.high_limit = mm->mmap_base;
if (flags & MAP_BELOW_HINT)
/*
* Subtract (STACK_TOP - mm->mmap_base) to get random
* offset defined in mmap_base() in mm/util.c
*/
info.high_limit = MIN(info.high_limit,
(addr + len) - (STACK_TOP - mm->mmap_base));
addr = vm_unmapped_area(&info);
if (!(addr & ~PAGE_MASK))
return addr;
Expand All @@ -163,6 +170,8 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,

info.low_limit = mm->mmap_base;
info.high_limit = mmap_upper_limit(NULL);
if (flags & MAP_BELOW_HINT)
info.high_limit = MIN(info.high_limit, addr + len);
return vm_unmapped_area(&info);
}

Expand Down
36 changes: 30 additions & 6 deletions arch/powerpc/include/asm/task_size_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,36 @@
#define STACK_TOP_MAX TASK_SIZE_USER64
#define STACK_TOP (is_32bit_task() ? STACK_TOP_USER32 : STACK_TOP_USER64)

#define arch_get_mmap_base(addr, base) \
(((addr) > DEFAULT_MAP_WINDOW) ? (base) + TASK_SIZE - DEFAULT_MAP_WINDOW : (base))
#define arch_get_mmap_base(addr, len, base, flags) \
({ \
unsigned long mmap_base; \
typeof(flags) _flags = (flags); \
typeof(addr) _addr = (addr); \
typeof(base) _base = (base); \
typeof(len) _len = (len); \
unsigned long rnd_gap = DEFAULT_MAP_WINDOW - (_base); \
if (_flags & MAP_BELOW_HINT && _addr != 0 && ((_addr + _len) > BIT(VA_BITS - 1)))\
mmap_base = (_addr + _len) - rnd_gap; \
else \
mmap_end = ((_addr > DEFAULT_MAP_WINDOW) ? \

Check failure on line 86 in arch/powerpc/include/asm/task_size_64.h

View workflow job for this annotation

GitHub Actions / kernel (corenet64_smp_defconfig, fedora-40)

assignment of read-only variable 'mmap_end'

Check failure on line 86 in arch/powerpc/include/asm/task_size_64.h

View workflow job for this annotation

GitHub Actions / kernel (g5_defconfig, fedora-40, /linux/arch/powerpc/configs/g5-qemu.config)

assignment of read-only variable 'mmap_end'
_base + TASK_SIZE - DEFAULT_MAP_WINDOW : \
_base); \
mmap_end; \
})

#define arch_get_mmap_end(addr, len, flags) \
(((addr) > DEFAULT_MAP_WINDOW) || \
(((flags) & MAP_FIXED) && ((addr) + (len) > DEFAULT_MAP_WINDOW)) ? TASK_SIZE : \
DEFAULT_MAP_WINDOW)
#define arch_get_mmap_end(addr, len, flags) \
({ \

Check failure on line 93 in arch/powerpc/include/asm/task_size_64.h

View workflow job for this annotation

GitHub Actions / kernel (corenet64_smp_defconfig, fedora-40)

void value not ignored as it ought to be

Check failure on line 93 in arch/powerpc/include/asm/task_size_64.h

View workflow job for this annotation

GitHub Actions / kernel (corenet64_smp_defconfig, fedora-40)

void value not ignored as it ought to be

Check failure on line 93 in arch/powerpc/include/asm/task_size_64.h

View workflow job for this annotation

GitHub Actions / kernel (g5_defconfig, fedora-40, /linux/arch/powerpc/configs/g5-qemu.config)

void value not ignored as it ought to be

Check failure on line 93 in arch/powerpc/include/asm/task_size_64.h

View workflow job for this annotation

GitHub Actions / kernel (g5_defconfig, fedora-40, /linux/arch/powerpc/configs/g5-qemu.config)

void value not ignored as it ought to be
unsigned long mmap_end; \
typeof(flags) _flags = (flags); \
typeof(addr) _addr = (addr); \
typeof(len) _len = (len); \
if (_flags & MAP_BELOW_HINT && _addr != 0 && ((_addr + _len) > BIT(VA_BITS - 1))) \

Check failure on line 98 in arch/powerpc/include/asm/task_size_64.h

View workflow job for this annotation

GitHub Actions / kernel (corenet64_smp_defconfig, fedora-40)

'VA_BITS' undeclared (first use in this function)

Check failure on line 98 in arch/powerpc/include/asm/task_size_64.h

View workflow job for this annotation

GitHub Actions / kernel (corenet64_smp_defconfig, fedora-40)

'VA_BITS' undeclared (first use in this function)
mmap_end = (_addr + _len); \
else \
mmap_end = (((_addr) > DEFAULT_MAP_WINDOW) || \
(((_flags) & MAP_FIXED) && ((_addr) + (_len) > DEFAULT_MAP_WINDOW))\
? TASK_SIZE : DEFAULT_MAP_WINDOW) \
mmap_end; \

Check failure on line 104 in arch/powerpc/include/asm/task_size_64.h

View workflow job for this annotation

GitHub Actions / kernel (corenet64_smp_defconfig, fedora-40)

expected ';' before 'mmap_end'

Check failure on line 104 in arch/powerpc/include/asm/task_size_64.h

View workflow job for this annotation

GitHub Actions / kernel (corenet64_smp_defconfig, fedora-40)

expected ';' before 'mmap_end'

Check failure on line 104 in arch/powerpc/include/asm/task_size_64.h

View workflow job for this annotation

GitHub Actions / kernel (g5_defconfig, fedora-40, /linux/arch/powerpc/configs/g5-qemu.config)

expected ';' before 'mmap_end'

Check failure on line 104 in arch/powerpc/include/asm/task_size_64.h

View workflow job for this annotation

GitHub Actions / kernel (g5_defconfig, fedora-40, /linux/arch/powerpc/configs/g5-qemu.config)

expected ';' before 'mmap_end'
})

#endif /* _ASM_POWERPC_TASK_SIZE_64_H */
32 changes: 0 additions & 32 deletions arch/riscv/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,6 @@

#include <asm/ptrace.h>

/*
* addr is a hint to the maximum userspace address that mmap should provide, so
* this macro needs to return the largest address space available so that
* mmap_end < addr, being mmap_end the top of that address space.
* See Documentation/arch/riscv/vm-layout.rst for more details.
*/
#define arch_get_mmap_end(addr, len, flags) \
({ \
unsigned long mmap_end; \
typeof(addr) _addr = (addr); \
if ((_addr) == 0 || is_compat_task() || \
((_addr + len) > BIT(VA_BITS - 1))) \
mmap_end = STACK_TOP_MAX; \
else \
mmap_end = (_addr + len); \
mmap_end; \
})

#define arch_get_mmap_base(addr, base) \
({ \
unsigned long mmap_base; \
typeof(addr) _addr = (addr); \
typeof(base) _base = (base); \
unsigned long rnd_gap = DEFAULT_MAP_WINDOW - (_base); \
if ((_addr) == 0 || is_compat_task() || \
((_addr + len) > BIT(VA_BITS - 1))) \
mmap_base = (_base); \
else \
mmap_base = (_addr + len) - rnd_gap; \
mmap_base; \
})

#ifdef CONFIG_64BIT
#define DEFAULT_MAP_WINDOW (UL(1) << (MMAP_VA_BITS - 1))
#define STACK_TOP_MAX TASK_SIZE_64
Expand Down
10 changes: 10 additions & 0 deletions arch/s390/mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.length = len;
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
if (flags & MAP_BELOW_HINT)
info.high_limit = MIN(info.high_limit, addr + len);
info.align_mask = get_align_mask(filp, flags);
info.align_offset = pgoff << PAGE_SHIFT;
addr = vm_unmapped_area(&info);
Expand Down Expand Up @@ -143,6 +145,12 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long ad
info.length = len;
info.low_limit = PAGE_SIZE;
info.high_limit = mm->mmap_base;
if (flags & MAP_BELOW_HINT)
/*
* Subtract (STACK_TOP - mm->mmap_base) to get random
* offset defined in mmap_base() in mm/util.c
*/
info.high_limit = MIN(info.high_limit, addr + len) - (STACK_TOP - mm->mmap_base);
info.align_mask = get_align_mask(filp, flags);
info.align_offset = pgoff << PAGE_SHIFT;
addr = vm_unmapped_area(&info);
Expand All @@ -158,6 +166,8 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long ad
info.flags = 0;
info.low_limit = TASK_UNMAPPED_BASE;
info.high_limit = TASK_SIZE;
if (flags & MAP_BELOW_HINT)
info.high_limit = MIN(TASK_SIZE, addr + len);
addr = vm_unmapped_area(&info);
if (offset_in_page(addr))
return addr;
Expand Down
10 changes: 10 additions & 0 deletions arch/sh/mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.length = len;
info.low_limit = TASK_UNMAPPED_BASE;
info.high_limit = TASK_SIZE;
if (flags & MAP_BELOW_HINT)
info.high_limit = MIN(info.high_limit, addr + len);
info.align_mask = do_colour_align ? (PAGE_MASK & shm_align_mask) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
return vm_unmapped_area(&info);
Expand Down Expand Up @@ -141,6 +143,12 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.length = len;
info.low_limit = PAGE_SIZE;
info.high_limit = mm->mmap_base;
if (flags & MAP_BELOW_HINT)
/*
* Subtract (STACK_TOP - mm->mmap_base) to get random
* offset defined in mmap_base() in mm/util.c
*/
info.high_limit = MIN(info.high_limit, (addr + len) - (STACK_TOP - mm->mmap_base));
info.align_mask = do_colour_align ? (PAGE_MASK & shm_align_mask) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
addr = vm_unmapped_area(&info);
Expand All @@ -156,6 +164,8 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.flags = 0;
info.low_limit = TASK_UNMAPPED_BASE;
info.high_limit = TASK_SIZE;
if (flags & MAP_BELOW_HINT)
info.high_limit = MIN(info.high_limit, addr + len);
addr = vm_unmapped_area(&info);
}

Expand Down
8 changes: 8 additions & 0 deletions arch/sparc/kernel/sys_sparc_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
info.length = len;
info.low_limit = TASK_UNMAPPED_BASE;
info.high_limit = min(task_size, VA_EXCLUDE_START);
if (flags & MAP_BELOW_HINT)
info.high_limit = MIN(info.high_limit, addr + len);
info.align_mask = do_color_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
addr = vm_unmapped_area(&info);
Expand All @@ -137,6 +139,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
VM_BUG_ON(addr != -ENOMEM);
info.low_limit = VA_EXCLUDE_END;
info.high_limit = task_size;
if (flags & MAP_BELOW_HINT)
info.high_limit = MIN(info.high_limit, addr + len);
addr = vm_unmapped_area(&info);
}

Expand Down Expand Up @@ -192,6 +196,8 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.length = len;
info.low_limit = PAGE_SIZE;
info.high_limit = mm->mmap_base;
if (flags & MAP_BELOW_HINT)
info.high_limit = MIN(info.high_limit, addr + len);
info.align_mask = do_color_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
addr = vm_unmapped_area(&info);
Expand All @@ -207,6 +213,8 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.flags = 0;
info.low_limit = TASK_UNMAPPED_BASE;
info.high_limit = STACK_TOP32;
if (flags & MAP_BELOW_HINT)
info.high_limit = MIN(info.high_limit, addr + len);
addr = vm_unmapped_area(&info);
}

Expand Down
Loading

0 comments on commit 447ad5c

Please sign in to comment.