diff mbox series

mm: fix extend calculation for move_page_tables()

Message ID 20201229174517.GA31435@ls3530.fritz.box (mailing list archive)
State New, archived
Headers show
Series mm: fix extend calculation for move_page_tables() | expand

Commit Message

Helge Deller Dec. 29, 2020, 5:45 p.m. UTC
On parisc the kernel fails to start the init process because in
shift_arg_pages() in fs/exec.c, move_page_tables() is called to e.g.
move pages from start addr 0xffeff000 to the new start addr 0xf9ccb000
with a length of 0x1000 bytes, but move_page_tables() instead returns
that it apparently moved 0x57000 bytes. Since the number of bytes is
different than the number of bytes which should have been moved,
shift_arg_pages() aborts with -ENOMEM.

Debugging shows that commit c49dd34018026 ("mm: speedup mremap on
1GB or larger regions") is the culprit.
In this commit, the extent calculation was tried to be optimized, but
got it wrong for this case.
The patch below reverts to the previous way to calculate the extent and
thus fixes the boot problem.

Fixes: c49dd34018026 ("mm: speedup mremap on 1GB or larger regions")
Signed-off-by: Helge Deller <deller@gmx.de>
Cc: Kalesh Singh <kaleshsingh@google.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Andrew Morton <akpm@linux-foundation.org>

---

Comments

Andrew Morton Dec. 29, 2020, 7:04 p.m. UTC | #1
On Tue, 29 Dec 2020 18:45:29 +0100 Helge Deller <deller@gmx.de> wrote:

> On parisc the kernel fails to start the init process because in
> shift_arg_pages() in fs/exec.c, move_page_tables() is called to e.g.
> move pages from start addr 0xffeff000 to the new start addr 0xf9ccb000
> with a length of 0x1000 bytes, but move_page_tables() instead returns
> that it apparently moved 0x57000 bytes. Since the number of bytes is
> different than the number of bytes which should have been moved,
> shift_arg_pages() aborts with -ENOMEM.
> 
> Debugging shows that commit c49dd34018026 ("mm: speedup mremap on
> 1GB or larger regions") is the culprit.
> In this commit, the extent calculation was tried to be optimized, but
> got it wrong for this case.
> The patch below reverts to the previous way to calculate the extent and
> thus fixes the boot problem.
> 

Thanks.  The same as
https://lkml.kernel.org/r/20201219170433.2418867-1-kaleshsingh@google.com.
I'll get that sent to Linus today.
diff mbox series

Patch

diff --git a/mm/mremap.c b/mm/mremap.c
index c5590afe7165..f554320281cc 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -358,7 +358,9 @@  static unsigned long get_extent(enum pgt_entry entry, unsigned long old_addr,

 	next = (old_addr + size) & mask;
 	/* even if next overflowed, extent below will be ok */
-	extent = (next > old_end) ? old_end - old_addr : next - old_addr;
+	extent = next - old_addr;
+	if (extent > old_end - old_addr)
+		extent = old_end - old_addr;
 	next = (new_addr + size) & mask;
 	if (extent > next - new_addr)
 		extent = next - new_addr;