summaryrefslogtreecommitdiffstats
path: root/0003-powerpc-64s-hash-Fix-128TB-512TB-virtual-address-bou.patch
diff options
context:
space:
mode:
Diffstat (limited to '0003-powerpc-64s-hash-Fix-128TB-512TB-virtual-address-bou.patch')
-rw-r--r--0003-powerpc-64s-hash-Fix-128TB-512TB-virtual-address-bou.patch129
1 files changed, 0 insertions, 129 deletions
diff --git a/0003-powerpc-64s-hash-Fix-128TB-512TB-virtual-address-bou.patch b/0003-powerpc-64s-hash-Fix-128TB-512TB-virtual-address-bou.patch
deleted file mode 100644
index 009068a3b..000000000
--- a/0003-powerpc-64s-hash-Fix-128TB-512TB-virtual-address-bou.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From e90387a8d2227f95bf5e5b5ffd816d48a87466e2 Mon Sep 17 00:00:00 2001
-From: Nicholas Piggin <npiggin@gmail.com>
-Date: Tue, 28 Nov 2017 11:26:56 +0100
-Subject: [PATCH 3/5] powerpc/64s/hash: Fix 128TB-512TB virtual address
- boundary case allocation
-
-commit 6a72dc038b615229a1b285829d6c8378d15c2347 upstream.
-
-When allocating VA space with a hint that crosses 128TB, the SLB
-addr_limit variable is not expanded if addr is not > 128TB, but the
-slice allocation looks at task_size, which is 512TB. This results in
-slice_check_fit() incorrectly succeeding because the slice_count
-truncates off bit 128 of the requested mask, so the comparison to the
-available mask succeeds.
-
-Fix this by using mm->context.addr_limit instead of mm->task_size for
-testing allocation limits. This causes such allocations to fail.
-
-Fixes: f4ea6dcb08ea ("powerpc/mm: Enable mappings above 128TB")
-Reported-by: Florian Weimer <fweimer@redhat.com>
-Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
-Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/powerpc/mm/slice.c | 50 ++++++++++++++++++++++++-------------------------
- 1 file changed, 24 insertions(+), 26 deletions(-)
-
-diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
-index 48a5312103a1..3889201b560c 100644
---- a/arch/powerpc/mm/slice.c
-+++ b/arch/powerpc/mm/slice.c
-@@ -96,7 +96,7 @@ static int slice_area_is_free(struct mm_struct *mm, unsigned long addr,
- {
- struct vm_area_struct *vma;
-
-- if ((mm->task_size - len) < addr)
-+ if ((mm->context.addr_limit - len) < addr)
- return 0;
- vma = find_vma(mm, addr);
- return (!vma || (addr + len) <= vm_start_gap(vma));
-@@ -133,7 +133,7 @@ static void slice_mask_for_free(struct mm_struct *mm, struct slice_mask *ret)
- if (!slice_low_has_vma(mm, i))
- ret->low_slices |= 1u << i;
-
-- if (mm->task_size <= SLICE_LOW_TOP)
-+ if (mm->context.addr_limit <= SLICE_LOW_TOP)
- return;
-
- for (i = 0; i < GET_HIGH_SLICE_INDEX(mm->context.addr_limit); i++)
-@@ -412,25 +412,31 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
- struct slice_mask compat_mask;
- int fixed = (flags & MAP_FIXED);
- int pshift = max_t(int, mmu_psize_defs[psize].shift, PAGE_SHIFT);
-+ unsigned long page_size = 1UL << pshift;
- struct mm_struct *mm = current->mm;
- unsigned long newaddr;
- unsigned long high_limit;
-
-- /*
-- * Check if we need to expland slice area.
-- */
-- if (unlikely(addr >= mm->context.addr_limit &&
-- mm->context.addr_limit != TASK_SIZE)) {
-- mm->context.addr_limit = TASK_SIZE;
-+ high_limit = DEFAULT_MAP_WINDOW;
-+ if (addr >= high_limit)
-+ high_limit = TASK_SIZE;
-+
-+ if (len > high_limit)
-+ return -ENOMEM;
-+ if (len & (page_size - 1))
-+ return -EINVAL;
-+ if (fixed) {
-+ if (addr & (page_size - 1))
-+ return -EINVAL;
-+ if (addr > high_limit - len)
-+ return -ENOMEM;
-+ }
-+
-+ if (high_limit > mm->context.addr_limit) {
-+ mm->context.addr_limit = high_limit;
- on_each_cpu(slice_flush_segments, mm, 1);
- }
-- /*
-- * This mmap request can allocate upt to 512TB
-- */
-- if (addr >= DEFAULT_MAP_WINDOW)
-- high_limit = mm->context.addr_limit;
-- else
-- high_limit = DEFAULT_MAP_WINDOW;
-+
- /*
- * init different masks
- */
-@@ -446,27 +452,19 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
-
- /* Sanity checks */
- BUG_ON(mm->task_size == 0);
-+ BUG_ON(mm->context.addr_limit == 0);
- VM_BUG_ON(radix_enabled());
-
- slice_dbg("slice_get_unmapped_area(mm=%p, psize=%d...\n", mm, psize);
- slice_dbg(" addr=%lx, len=%lx, flags=%lx, topdown=%d\n",
- addr, len, flags, topdown);
-
-- if (len > mm->task_size)
-- return -ENOMEM;
-- if (len & ((1ul << pshift) - 1))
-- return -EINVAL;
-- if (fixed && (addr & ((1ul << pshift) - 1)))
-- return -EINVAL;
-- if (fixed && addr > (mm->task_size - len))
-- return -ENOMEM;
--
- /* If hint, make sure it matches our alignment restrictions */
- if (!fixed && addr) {
-- addr = _ALIGN_UP(addr, 1ul << pshift);
-+ addr = _ALIGN_UP(addr, page_size);
- slice_dbg(" aligned addr=%lx\n", addr);
- /* Ignore hint if it's too large or overlaps a VMA */
-- if (addr > mm->task_size - len ||
-+ if (addr > high_limit - len ||
- !slice_area_is_free(mm, addr, len))
- addr = 0;
- }
---
-2.14.3
-