From: Greg Kroah-Hartman Date: Tue, 3 May 2022 14:21:48 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v5.4.192~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f062fa28f95041efc84f6a3c4d247eb30fa6b33c;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: mm-hugetlb-allow-for-high-userspace-addresses.patch --- diff --git a/queue-5.4/mm-hugetlb-allow-for-high-userspace-addresses.patch b/queue-5.4/mm-hugetlb-allow-for-high-userspace-addresses.patch new file mode 100644 index 00000000000..591925cdf38 --- /dev/null +++ b/queue-5.4/mm-hugetlb-allow-for-high-userspace-addresses.patch @@ -0,0 +1,127 @@ +From 5f24d5a579d1eace79d505b148808a850b417d4c Mon Sep 17 00:00:00 2001 +From: Christophe Leroy +Date: Thu, 21 Apr 2022 16:35:46 -0700 +Subject: mm, hugetlb: allow for "high" userspace addresses + +From: Christophe Leroy + +commit 5f24d5a579d1eace79d505b148808a850b417d4c upstream. + +This is a fix for commit f6795053dac8 ("mm: mmap: Allow for "high" +userspace addresses") for hugetlb. + +This patch adds support for "high" userspace addresses that are +optionally supported on the system and have to be requested via a hint +mechanism ("high" addr parameter to mmap). + +Architectures such as powerpc and x86 achieve this by making changes to +their architectural versions of hugetlb_get_unmapped_area() function. +However, arm64 uses the generic version of that function. + +So take into account arch_get_mmap_base() and arch_get_mmap_end() in +hugetlb_get_unmapped_area(). To allow that, move those two macros out +of mm/mmap.c into include/linux/sched/mm.h + +If these macros are not defined in architectural code then they default +to (TASK_SIZE) and (base) so should not introduce any behavioural +changes to architectures that do not define them. + +For the time being, only ARM64 is affected by this change. + +Catalin (ARM64) said + "We should have fixed hugetlb_get_unmapped_area() as well when we added + support for 52-bit VA. The reason for commit f6795053dac8 was to + prevent normal mmap() from returning addresses above 48-bit by default + as some user-space had hard assumptions about this. + + It's a slight ABI change if you do this for hugetlb_get_unmapped_area() + but I doubt anyone would notice. It's more likely that the current + behaviour would cause issues, so I'd rather have them consistent. + + Basically when arm64 gained support for 52-bit addresses we did not + want user-space calling mmap() to suddenly get such high addresses, + otherwise we could have inadvertently broken some programs (similar + behaviour to x86 here). Hence we added commit f6795053dac8. But we + missed hugetlbfs which could still get such high mmap() addresses. So + in theory that's a potential regression that should have bee addressed + at the same time as commit f6795053dac8 (and before arm64 enabled + 52-bit addresses)" + +Link: https://lkml.kernel.org/r/ab847b6edb197bffdfe189e70fb4ac76bfe79e0d.1650033747.git.christophe.leroy@csgroup.eu +Fixes: f6795053dac8 ("mm: mmap: Allow for "high" userspace addresses") +Signed-off-by: Christophe Leroy +Reviewed-by: Catalin Marinas +Cc: Steve Capper +Cc: Will Deacon +Cc: [5.0.x] +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + fs/hugetlbfs/inode.c | 5 +++-- + include/linux/sched/mm.h | 8 ++++++++ + mm/mmap.c | 8 -------- + 3 files changed, 11 insertions(+), 10 deletions(-) + +--- a/fs/hugetlbfs/inode.c ++++ b/fs/hugetlbfs/inode.c +@@ -208,6 +208,7 @@ hugetlb_get_unmapped_area(struct file *f + struct vm_area_struct *vma; + struct hstate *h = hstate_file(file); + struct vm_unmapped_area_info info; ++ const unsigned long mmap_end = arch_get_mmap_end(addr); + + if (len & ~huge_page_mask(h)) + return -EINVAL; +@@ -223,7 +224,7 @@ hugetlb_get_unmapped_area(struct file *f + if (addr) { + addr = ALIGN(addr, huge_page_size(h)); + vma = find_vma(mm, addr); +- if (TASK_SIZE - len >= addr && ++ if (mmap_end - len >= addr && + (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } +@@ -231,7 +232,7 @@ hugetlb_get_unmapped_area(struct file *f + info.flags = 0; + info.length = len; + info.low_limit = TASK_UNMAPPED_BASE; +- info.high_limit = TASK_SIZE; ++ info.high_limit = arch_get_mmap_end(addr); + info.align_mask = PAGE_MASK & ~huge_page_mask(h); + info.align_offset = 0; + return vm_unmapped_area(&info); +--- a/include/linux/sched/mm.h ++++ b/include/linux/sched/mm.h +@@ -133,6 +133,14 @@ static inline void mm_update_next_owner( + #endif /* CONFIG_MEMCG */ + + #ifdef CONFIG_MMU ++#ifndef arch_get_mmap_end ++#define arch_get_mmap_end(addr) (TASK_SIZE) ++#endif ++ ++#ifndef arch_get_mmap_base ++#define arch_get_mmap_base(addr, base) (base) ++#endif ++ + extern void arch_pick_mmap_layout(struct mm_struct *mm, + struct rlimit *rlim_stack); + extern unsigned long +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -2077,14 +2077,6 @@ found_highest: + } + + +-#ifndef arch_get_mmap_end +-#define arch_get_mmap_end(addr) (TASK_SIZE) +-#endif +- +-#ifndef arch_get_mmap_base +-#define arch_get_mmap_base(addr, base) (base) +-#endif +- + /* Get an address range which is currently unmapped. + * For shmat() with addr=0. + * diff --git a/queue-5.4/series b/queue-5.4/series index fb3ac132740..9bc614cb3af 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -80,3 +80,4 @@ tty-n_gsm-fix-missing-explicit-ldisc-flush.patch tty-n_gsm-fix-wrong-command-retry-handling.patch tty-n_gsm-fix-wrong-command-frame-length-field-encoding.patch tty-n_gsm-fix-incorrect-ua-handling.patch +mm-hugetlb-allow-for-high-userspace-addresses.patch