// SPDX-License-Identifier: GPL-2.0
/*
 *	mm/mremap.c
 *
 *	(C) Copyright 1996 Linus Torvalds
 *
 *	Address space accounting code	<alan@lxorguk.ukuu.org.uk>
 *	(C) Copyright 2002 Red Hat Inc, All Rights Reserved
 */

#include <linux/mm.h>
#include <linux/mm_inline.h>
#include <linux/hugetlb.h>
#include <linux/shm.h>
#include <linux/ksm.h>
#include <linux/mman.h>
#include <linux/swap.h>
#include <linux/capability.h>
#include <linux/fs.h>
#include <linux/swapops.h>
#include <linux/highmem.h>
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/mmu_notifier.h>
#include <linux/uaccess.h>
#include <linux/userfaultfd_k.h>
#include <linux/mempolicy.h>

#include <asm/cacheflush.h>
#include <asm/tlb.h>
#include <asm/pgalloc.h>

#include "internal.h"

/* Classify the kind of remap operation being performed. */
enum mremap_type {
	MREMAP_INVALID,		/* Initial state. */
	MREMAP_NO_RESIZE,	/* old_len == new_len, if not moved, do nothing. */
	MREMAP_SHRINK,		/* old_len > new_len. */
	MREMAP_EXPAND,		/* old_len < new_len. */
};

/*
 * Describes a VMA mremap() operation and is threaded throughout it.
 *
 * Any of the fields may be mutated by the operation, however these values will
 * always accurately reflect the remap (for instance, we may adjust lengths and
 * delta to account for hugetlb alignment).
 */
struct vma_remap_struct {
	/* User-provided state. */
	unsigned long addr;	/* User-specified address from which we remap. */
	unsigned long old_len;	/* Length of range being remapped. */
	unsigned long new_len;	/* Desired new length of mapping. */
	const unsigned long flags; /* user-specified MREMAP_* flags. */
	unsigned long new_addr;	/* Optionally, desired new address. */

	/* uffd state. */
	struct vm_userfaultfd_ctx *uf;
	struct list_head *uf_unmap_early;
	struct list_head *uf_unmap;

	/* VMA state, determined in do_mremap(). */
	struct vm_area_struct *vma;

	/* Internal state, determined in do_mremap(). */
	unsigned long delta;		/* Absolute delta of old_len,new_len. */
	bool populate_expand;		/* mlock()'d expanded, must populate. */
	enum mremap_type remap_type;	/* expand, shrink, etc. */
	bool mmap_locked;		/* Is mm currently write-locked? */
	unsigned long charged;		/* If VM_ACCOUNT, # pages to account. */
	bool vmi_needs_invalidate;	/* Is the VMA iterator invalidated? */
};

static pud_t *get_old_pud(struct mm_struct *mm, unsigned long addr)
{
	pgd_t *pgd;
	p4d_t *p4d;
	pud_t *pud;

	pgd = pgd_offset(mm, addr);
	if (pgd_none_or_clear_bad(pgd))
		return NULL;

	p4d = p4d_offset(pgd, addr);
	if (p4d_none_or_clear_bad(p4d))
		return NULL;

	pud = pud_offset(p4d, addr);
	if (pud_none_or_clear_bad(pud))
		return NULL;

	return pud;
}

static pmd_t *get_old_pmd(struct mm_struct *mm, unsigned long addr)
{
	pud_t *pud;
	pmd_t *pmd;

	pud = get_old_pud(mm, addr);
	if (!pud)
		return NULL;

	pmd = pmd_offset(pud, addr);
	if (pmd_none(*pmd))
		return NULL;

	return pmd;
}

static pud_t *alloc_new_pud(struct mm_struct *mm, unsigned long addr)
{
	pgd_t *pgd;
	p4d_t *p4d;

	pgd = pgd_offset(mm, addr);
	p4d = p4d_alloc(mm, pgd, addr);
	if (!p4d)
		return NULL;

	return pud_alloc(mm, p4d, addr);
}

static pmd_t *alloc_new_pmd(struct mm_struct *mm, unsigned long addr)
{
	pud_t *pud;
	pmd_t *pmd;

	pud = alloc_new_pud(mm, addr);
	if (!pud)
		return NULL;

	pmd = pmd_alloc(mm, pud, addr);
	if (!pmd)
		return NULL;

	VM_BUG_ON(pmd_trans_huge(*pmd));

	return pmd;
}

static void take_rmap_locks(struct vm_area_struct *vma)
{
	if (vma->vm_file)
		i_mmap_lock_write(vma->vm_file->f_mapping);
	if (vma->anon_vma)
		anon_vma_lock_write(vma->anon_vma);
}

static void drop_rmap_locks(struct vm_area_struct *vma)
{
	if (vma->anon_vma)
		anon_vma_unlock_write(vma->anon_vma);
	if (vma->vm_file)
		i_mmap_unlock_write(vma->vm_file->f_mapping);
}

static pte_t move_soft_dirty_pte(pte_t pte)
{
	/*
	 * Set soft dirty bit so we can notice
	 * in userspace the ptes were moved.
	 */
#ifdef CONFIG_MEM_SOFT_DIRTY
	if (pte_present(pte))
		pte = pte_mksoft_dirty(pte);
	else if (is_swap_pte(pte))
		pte = pte_swp_mksoft_dirty(pte);
#endif
	return pte;
}

static int mremap_folio_pte_batch(struct vm_area_struct *vma, unsigned long addr,
		pte_t *ptep, pte_t pte, int max_nr)
{
	struct folio *folio;

	if (max_nr == 1)
		return 1;

	/* Avoid expensive folio lookup if we stand no chance of benefit. */
	if (pte_batch_hint(ptep, pte) == 1)
		return 1;

	folio = vm_normal_folio(vma, addr, pte);
	if (!folio || !folio_test_large(folio))
		return 1;

	return folio_pte_batch(folio, ptep, pte, max_nr);
}

static int move_ptes(struct pagetable_move_control *pmc,
		unsigned long extent, pmd_t *old_pmd, pmd_t *new_pmd)
{
	struct vm_area_struct *vma = pmc->old;
	bool need_clear_uffd_wp = vma_has_uffd_without_event_remap(vma);
	struct mm_struct *mm = vma->vm_mm;
	pte_t *old_ptep, *new_ptep;
	pte_t old_pte, pte;
	pmd_t dummy_pmdval;
	spinlock_t *old_ptl, *new_ptl;
	bool force_flush = false;
	unsigned long old_addr = pmc->old_addr;
	unsigned long new_addr = pmc->new_addr;
	unsigned long old_end = old_addr + extent;
	unsigned long len = old_end - old_addr;
	int max_nr_ptes;
	int nr_ptes;
	int err = 0;

	/*
	 * When need_rmap_locks is true, we take the i_mmap_rwsem and anon_vma
	 * locks to ensure that rmap will always observe either the old or the
	 * new ptes. This is the easiest way to avoid races with
	 * truncate_pagecache(), page migration, etc...
	 *
	 * When need_rmap_locks is false, we use other ways to avoid
	 * such races:
	 *
	 * - During exec() shift_arg_pages(), we use a specially tagged vma
	 *   which rmap call sites look for using vma_is_temporary_stack().
	 *
	 * - During mremap(), new_vma is often known to be placed after vma
	 *   in rmap traversal order. This ensures rmap will always observe
	 *   either the old pte, or the new pte, or both (the page table locks
	 *   serialize access to individual ptes, but only rmap traversal
	 *   order guarantees that we won't miss both the old and new ptes).
	 */
	if (pmc->need_rmap_locks)
		take_rmap_locks(vma);

	/*
	 * We don't have to worry about the ordering of src and dst
	 * pte locks because exclusive mmap_lock prevents deadlock.
	 */
	old_ptep = pte_offset_map_lock(mm, old_pmd, old_addr, &old_ptl);
	if (!old_ptep) {
		err = -EAGAIN;
		goto out;
	}
	/*
	 * Now new_pte is none, so hpage_collapse_scan_file() path can not find
	 * this by traversing file->f_mapping, so there is no concurrency with
	 * retract_page_tables(). In addition, we already hold the exclusive
	 * mmap_lock, so this new_pte page is stable, so there is no need to get
	 * pmdval and do pmd_same() check.
	 */
	new_ptep = pte_offset_map_rw_nolock(mm, new_pmd, new_addr, &dummy_pmdval,
					   &new_ptl);
	if (!new_ptep) {
		pte_unmap_unlock(old_ptep, old_ptl);
		err = -EAGAIN;
		goto out;
	}
	if (new_ptl != old_ptl)
		spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
	flush_tlb_batched_pending(vma->vm_mm);
	arch_enter_lazy_mmu_mode();

	for (; old_addr < old_end; old_ptep += nr_ptes, old_addr += nr_ptes * PAGE_SIZE,
		new_ptep += nr_ptes, new_addr += nr_ptes * PAGE_SIZE) {
		VM_WARN_ON_ONCE(!pte_none(*new_ptep));

		nr_ptes = 1;
		max_nr_ptes = (old_end - old_addr) >> PAGE_SHIFT;
		old_pte = ptep_get(old_ptep);
		if (pte_none(old_pte))
			continue;

		/*
		 * If we are remapping a valid PTE, make sure
		 * to flush TLB before we drop the PTL for the
		 * PTE.
		 *
		 * NOTE! Both old and new PTL matter: the old one
		 * for racing with folio_mkclean(), the new one to
		 * make sure the physical page stays valid until
		 * the TLB entry for the old mapping has been
		 * flushed.
		 */
		if (pte_present(old_pte)) {
			nr_ptes = mremap_folio_pte_batch(vma, old_addr, old_ptep,
							 old_pte, max_nr_ptes);
			force_flush = true;
		}
		pte = get_and_clear_ptes(mm, old_addr, old_ptep, nr_ptes);
		pte = move_pte(pte, old_addr, new_addr);
		pte = move_soft_dirty_pte(pte);

		if (need_clear_uffd_wp && pte_marker_uffd_wp(pte))
			pte_clear(mm, new_addr, new_ptep);
		else {
			if (need_clear_uffd_wp) {
				if (pte_present(pte))
					pte = pte_clear_uffd_wp(pte);
				else if (is_swap_pte(pte))
					pte = pte_swp_clear_uffd_wp(pte);
			}
			set_ptes(mm, new_addr, new_ptep, pte, nr_ptes);
		}
	}

	arch_leave_lazy_mmu_mode();
	if (force_flush)
		flush_tlb_range(vma, old_end - len, old_end);
	if (new_ptl != old_ptl)
		spin_unlock(new_ptl);
	pte_unmap(new_ptep - 1);
	pte_unmap_unlock(old_ptep - 1, old_ptl);
out:
	if (pmc->need_rmap_locks)
		drop_rmap_locks(vma);
	return err;
}

#ifndef arch_supports_page_table_move
#define arch_supports_page_table_move arch_supports_page_table_move
static inline bool arch_supports_page_table_move(void)
{
	return IS_ENABLED(CONFIG_HAVE_MOVE_PMD) ||
		IS_ENABLED(CONFIG_HAVE_MOVE_PUD);
}
#endif

static inline bool uffd_supports_page_table_move(struct pagetable_move_control *pmc)
{
	/*
	 * If we are moving a VMA that has uffd-wp registered but with
	 * remap events disabled (new VMA will not be registered with uffd), we
	 * need to ensure that the uffd-wp state is cleared from all pgtables.
	 * This means recursing into lower page tables in move_page_tables().
	 *
	 * We might get called with VMAs reversed when recovering from a
	 * failed page table move. In that case, the
	 * "old"-but-actually-"originally new" VMA during recovery will not have
	 * a uffd context. Recursing into lower page tables during the original
	 * move but not during the recovery move will cause trouble, because we
	 * run into already-existing page tables. So check both VMAs.
	 */
	return !vma_has_uffd_without_event_remap(pmc->old) &&
	       !vma_has_uffd_without_event_remap(pmc->new);
}

#ifdef CONFIG_HAVE_MOVE_PMD
static bool move_normal_pmd(struct pagetable_move_control *pmc,
			pmd_t *old_pmd, pmd_t *new_pmd)
{
	spinlock_t *old_ptl, *new_ptl;
	struct vm_area_struct *vma = pmc->old;
	struct mm_struct *mm = vma->vm_mm;
	bool res = false;
	pmd_t pmd;

	if (!arch_supports_page_table_move())
		return false;
	if (!uffd_supports_page_table_move(pmc))
		return false;
	/*
	 * The destination pmd shouldn't be established, free_pgtables()
	 * should have released it.
	 *
	 * However, there's a case during execve() where we use mremap
	 * to move the initial stack, and in that case the target area
	 * may overlap the source area (always moving down).
	 *
	 * If everything is PMD-aligned, that works fine, as moving
	 * each pmd down will clear the source pmd. But if we first
	 * have a few 4kB-only pages that get moved down, and then
	 * hit the "now the rest is PMD-aligned, let's do everything
	 * one pmd at a time", we will still have the old (now empty
	 * of any 4kB pages, but still there) PMD in the page table
	 * tree.
	 *
	 * Warn on it once - because we really should try to figure
	 * out how to do this better - but then say "I won't move
	 * this pmd".
	 *
	 * One alternative might be to just unmap the target pmd at
	 * this point, and verify that it really is empty. We'll see.
	 */
	if (WARN_ON_ONCE(!pmd_none(*new_pmd)))
		return false;

	/*
	 * We don't have to worry about the ordering of src and dst
	 * ptlocks because exclusive mmap_lock prevents deadlock.
	 */
	old_ptl = pmd_lock(mm, old_pmd);
	new_ptl = pmd_lockptr(mm, new_pmd);
	if (new_ptl != old_ptl)
		spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);

	pmd = *old_pmd;

	/* Racing with collapse? */
	if (unlikely(!pmd_present(pmd) || pmd_leaf(pmd)))
		goto out_unlock;
	/* Clear the pmd */
	pmd_clear(old_pmd);
	res = true;

	VM_BUG_ON(!pmd_none(*new_pmd));

	pmd_populate(mm, new_pmd, pmd_pgtable(pmd));
	flush_tlb_range(vma, pmc->old_addr, pmc->old_addr + PMD_SIZE);
out_unlock:
	if (new_ptl != old_ptl)
		spin_unlock(new_ptl);
	spin_unlock(old_ptl);

	return res;
}
#else
static inline bool move_normal_pmd(struct pagetable_move_control *pmc,
		pmd_t *old_pmd, pmd_t *new_pmd)
{
	return false;
}
#endif

#if CONFIG_PGTABLE_LEVELS > 2 && defined(CONFIG_HAVE_MOVE_PUD)
static bool move_normal_pud(struct pagetable_move_control *pmc,
		pud_t *old_pud, pud_t *new_pud)
{
	spinlock_t *old_ptl, *new_ptl;
	struct vm_area_struct *vma = pmc->old;
	struct mm_struct *mm = vma->vm_mm;
	pud_t pud;

	if (!arch_supports_page_table_move())
		return false;
	if (!uffd_supports_page_table_move(pmc))
		return false;
	/*
	 * The destination pud shouldn't be established, free_pgtables()
	 * should have released it.
	 */
	if (WARN_ON_ONCE(!pud_none(*new_pud)))
		return false;

	/*
	 * We don't have to worry about the ordering of src and dst
	 * ptlocks because exclusive mmap_lock prevents deadlock.
	 */
	old_ptl = pud_lock(mm, old_pud);
	new_ptl = pud_lockptr(mm, new_pud);
	if (new_ptl != old_ptl)
		spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);

	/* Clear the pud */
	pud = *old_pud;
	pud_clear(old_pud);

	VM_BUG_ON(!pud_none(*new_pud));

	pud_populate(mm, new_pud, pud_pgtable(pud));
	flush_tlb_range(vma, pmc->old_addr, pmc->old_addr + PUD_SIZE);
	if (new_ptl != old_ptl)
		spin_unlock(new_ptl);
	spin_unlock(old_ptl);

	return true;
}
#else
static inline bool move_normal_pud(struct pagetable_move_control *pmc,
		pud_t *old_pud, pud_t *new_pud)
{
	return false;
}
#endif

#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
static bool move_huge_pud(struct pagetable_move_control *pmc,
		pud_t *old_pud, pud_t *new_pud)
{
	spinlock_t *old_ptl, *new_ptl;
	struct vm_area_struct *vma = pmc->old;
	struct mm_struct *mm = vma->vm_mm;
	pud_t pud;

	/*
	 * The destination pud shouldn't be established, free_pgtables()
	 * should have released it.
	 */
	if (WARN_ON_ONCE(!pud_none(*new_pud)))
		return false;

	/*
	 * We don't have to worry about the ordering of src and dst
	 * ptlocks because exclusive mmap_lock prevents deadlock.
	 */
	old_ptl = pud_lock(mm, old_pud);
	new_ptl = pud_lockptr(mm, new_pud);
	if (new_ptl != old_ptl)
		spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);

	/* Clear the pud */
	pud = *old_pud;
	pud_clear(old_pud);

	VM_BUG_ON(!pud_none(*new_pud));

	/* Set the new pud */
	/* mark soft_ditry when we add pud level soft dirty support */
	set_pud_at(mm, pmc->new_addr, new_pud, pud);
	flush_pud_tlb_range(vma, pmc->old_addr, pmc->old_addr + HPAGE_PUD_SIZE);
	if (new_ptl != old_ptl)
		spin_unlock(new_ptl);
	spin_unlock(old_ptl);

	return true;
}
#else
static bool move_huge_pud(struct pagetable_move_control *pmc,
		pud_t *old_pud, pud_t *new_pud)

{
	WARN_ON_ONCE(1);
	return false;

}
#endif

enum pgt_entry {
	NORMAL_PMD,
	HPAGE_PMD,
	NORMAL_PUD,
	HPAGE_PUD,
};

/*
 * Returns an extent of the corresponding size for the pgt_entry specified if
 * valid. Else returns a smaller extent bounded by the end of the source and
 * destination pgt_entry.
 */
static __always_inline unsigned long get_extent(enum pgt_entry entry,
						struct pagetable_move_control *pmc)
{
	unsigned long next, extent, mask, size;
	unsigned long old_addr = pmc->old_addr;
	unsigned long old_end = pmc->old_end;
	unsigned long new_addr = pmc->new_addr;

	switch (entry) {
	case HPAGE_PMD:
	case NORMAL_PMD:
		mask = PMD_MASK;
		size = PMD_SIZE;
		break;
	case HPAGE_PUD:
	case NORMAL_PUD:
		mask = PUD_MASK;
		size = PUD_SIZE;
		break;
	default:
		BUILD_BUG();
		break;
	}

	next = (old_addr + size) & mask;
	/* even if next overflowed, extent below will be ok */
	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;
	return extent;
}

/*
 * Should move_pgt_entry() acquire the rmap locks? This is either expressed in
 * the PMC, or overridden in the case of normal, larger page tables.
 */
static bool should_take_rmap_locks(struct pagetable_move_control *pmc,
				   enum pgt_entry entry)
{
	switch (entry) {
	case NORMAL_PMD:
	case NORMAL_PUD:
		return true;
	default:
		return pmc->need_rmap_locks;
	}
}

/*
 * Attempts to speedup the move by moving entry at the level corresponding to
 * pgt_entry. Returns true if the move was successful, else false.
 */
static bool move_pgt_entry(struct pagetable_move_control *pmc,
			   enum pgt_entry entry, void *old_entry, void *new_entry)
{
	bool moved = false;
	bool need_rmap_locks = should_take_rmap_locks(pmc, entry);

	/* See comment in move_ptes() */
	if (need_rmap_locks)
		take_rmap_locks(pmc->old);

	switch (entry) {
	case NORMAL_PMD:
		moved = move_normal_pmd(pmc, old_entry, new_entry);
		break;
	case NORMAL_PUD:
		moved = move_normal_pud(pmc, old_entry, new_entry);
		break;
	case HPAGE_PMD:
		moved = IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) &&
			move_huge_pmd(pmc->old, pmc->old_addr, pmc->new_addr, old_entry,
				      new_entry);
		break;
	case HPAGE_PUD:
		moved = IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) &&
			move_huge_pud(pmc, old_entry, new_entry);
		break;

	default:
		WARN_ON_ONCE(1);
		break;
	}

	if (need_rmap_locks)
		drop_rmap_locks(pmc->old);

	return moved;
}

/*
 * A helper to check if aligning down is OK. The aligned address should fall
 * on *no mapping*. For the stack moving down, that's a special move within
 * the VMA that is created to span the source and destination of the move,
 * so we make an exception for it.
 */
static bool can_align_down(struct pagetable_move_control *pmc,
			   struct vm_area_struct *vma, unsigned long addr_to_align,
			   unsigned long mask)
{
	unsigned long addr_masked = addr_to_align & mask;

	/*
	 * If @addr_to_align of either source or destination is not the beginning
	 * of the corresponding VMA, we can't align down or we will destroy part
	 * of the current mapping.
	 */
	if (!pmc->for_stack && vma->vm_start != addr_to_align)
		return false;

	/* In the stack case we explicitly permit in-VMA alignment. */
	if (pmc->for_stack && addr_masked >= vma->vm_start)
		return true;

	/*
	 * Make sure the realignment doesn't cause the address to fall on an
	 * existing mapping.
	 */
	return find_vma_intersection(vma->vm_mm, addr_masked, vma->vm_start) == NULL;
}

/*
 * Determine if are in fact able to realign for efficiency to a higher page
 * table boundary.
 */
static bool can_realign_addr(struct pagetable_move_control *pmc,
			     unsigned long pagetable_mask)
{
	unsigned long align_mask = ~pagetable_mask;
	unsigned long old_align = pmc->old_addr & align_mask;
	unsigned long new_align = pmc->new_addr & align_mask;
	unsigned long pagetable_size = align_mask + 1;
	unsigned long old_align_next = pagetable_size - old_align;

	/*
	 * We don't want to have to go hunting for VMAs from the end of the old
	 * VMA to the next page table boundary, also we want to make sure the
	 * operation is wortwhile.
	 *
	 * So ensure that we only perform this realignment if the end of the
	 * range being copied reaches or crosses the page table boundary.
	 *
	 * boundary                        boundary
	 *    .<- old_align ->                .
	 *    .              |----------------.-----------|
	 *    .              |          vma   .           |
	 *    .              |----------------.-----------|
	 *    .              <----------------.----------->
	 *    .                          len_in
	 *    <------------------------------->
	 *    .         pagetable_size        .
	 *    .              <---------------->
	 *    .                old_align_next .
	 */
	if (pmc->len_in < old_align_next)
		return false;

	/* Skip if the addresses are already aligned. */
	if (old_align == 0)
		return false;

	/* Only realign if the new and old addresses are mutually aligned. */
	if (old_align != new_align)
		return false;

	/* Ensure realignment doesn't cause overlap with existing mappings. */
	if (!can_align_down(pmc, pmc->old, pmc->old_addr, pagetable_mask) ||
	    !can_align_down(pmc, pmc->new, pmc->new_addr, pagetable_mask))
		return false;

	return true;
}

/*
 * Opportunistically realign to specified boundary for faster copy.
 *
 * Consider an mremap() of a VMA with page table boundaries as below, and no
 * preceding VMAs from the lower page table boundary to the start of the VMA,
 * with the end of the range reaching or crossing the page table boundary.
 *
 *   boundary                        boundary
 *      .              |----------------.-----------|
 *      .              |          vma   .           |
 *      .              |----------------.-----------|
 *      .         pmc->old_addr         .      pmc->old_end
 *      .              <---------------------------->
 *      .                  move these page tables
 *
 * If we proceed with moving page tables in this scenario, we will have a lot of
 * work to do traversing old page tables and establishing new ones in the
 * destination across multiple lower level page tables.
 *
 * The idea here is simply to align pmc->old_addr, pmc->new_addr down to the
 * page table boundary, so we can simply copy a single page table entry for the
 * aligned portion of the VMA instead:
 *
 *   boundary                        boundary
 *      .              |----------------.-----------|
 *      .              |          vma   .           |
 *      .              |----------------.-----------|
 * pmc->old_addr                        .      pmc->old_end
 *      <------------------------------------------->
 *      .           move these page tables
 */
static void try_realign_addr(struct pagetable_move_control *pmc,
			     unsigned long pagetable_mask)
{

	if (!can_realign_addr(pmc, pagetable_mask))
		return;

	/*
	 * Simply align to page table boundaries. Note that we do NOT update the
	 * pmc->old_end value, and since the move_page_tables() operation spans
	 * from [old_addr, old_end) (offsetting new_addr as it is performed),
	 * this simply changes the start of the copy, not the end.
	 */
	pmc->old_addr &= pagetable_mask;
	pmc->new_addr &= pagetable_mask;
}

/* Is the page table move operation done? */
static bool pmc_done(struct pagetable_move_control *pmc)
{
	return pmc->old_addr >= pmc->old_end;
}

/* Advance to the next page table, offset by extent bytes. */
static void pmc_next(struct pagetable_move_control *pmc, unsigned long extent)
{
	pmc->old_addr += extent;
	pmc->new_addr += extent;
}

/*
 * Determine how many bytes in the specified input range have had their page
 * tables moved so far.
 */
static unsigned long pmc_progress(struct pagetable_move_control *pmc)
{
	unsigned long orig_old_addr = pmc->old_end - pmc->len_in;
	unsigned long old_addr = pmc->old_addr;

	/*
	 * Prevent negative return values when {old,new}_addr was realigned but
	 * we broke out of the loop in move_page_tables() for the first PMD
	 * itself.
	 */
	return old_addr < orig_old_addr ? 0 : old_addr - orig_old_addr;
}

unsigned long move_page_tables(struct pagetable_move_control *pmc)
{
	unsigned long extent;
	struct mmu_notifier_range range;
	pmd_t *old_pmd, *new_pmd;
	pud_t *old_pud, *new_pud;
	struct mm_struct *mm = pmc->old->vm_mm;

	if (!pmc->len_in)
		return 0;

	if (is_vm_hugetlb_page(pmc->old))
		return move_hugetlb_page_tables(pmc->old, pmc->new, pmc->old_addr,
						pmc->new_addr, pmc->len_in);

	/*
	 * If possible, realign addresses to PMD boundary for faster copy.
	 * Only realign if the mremap copying hits a PMD boundary.
	 */
	try_realign_addr(pmc, PMD_MASK);

	flush_cache_range(pmc->old, pmc->old_addr, pmc->old_end);
	mmu_notifier_range_init(&range, MMU_NOTIFY_UNMAP, 0, mm,
				pmc->old_addr, pmc->old_end);
	mmu_notifier_invalidate_range_start(&range);

	for (; !pmc_done(pmc); pmc_next(pmc, extent)) {
		cond_resched();
		/*
		 * If extent is PUD-sized try to speed up the move by moving at the
		 * PUD level if possible.
		 */
		extent = get_extent(NORMAL_PUD, pmc);

		old_pud = get_old_pud(mm, pmc->old_addr);
		if (!old_pud)
			continue;
		new_pud = alloc_new_pud(mm, pmc->new_addr);
		if (!new_pud)
			break;
		if (pud_trans_huge(*old_pud)) {
			if (extent == HPAGE_PUD_SIZE) {
				move_pgt_entry(pmc, HPAGE_PUD, old_pud, new_pud);
				/* We ignore and continue on error? */
				continue;
			}
		} else if (IS_ENABLED(CONFIG_HAVE_MOVE_PUD) && extent == PUD_SIZE) {
			if (move_pgt_entry(pmc, NORMAL_PUD, old_pud, new_pud))
				continue;
		}

		extent = get_extent(NORMAL_PMD, pmc);
		old_pmd = get_old_pmd(mm, pmc->old_addr);
		if (!old_pmd)
			continue;
		new_pmd = alloc_new_pmd(mm, pmc->new_addr);
		if (!new_pmd)
			break;
again:
		if (is_swap_pmd(*old_pmd) || pmd_trans_huge(*old_pmd)) {
			if (extent == HPAGE_PMD_SIZE &&
			    move_pgt_entry(pmc, HPAGE_PMD, old_pmd, new_pmd))
				continue;
			split_huge_pmd(pmc->old, old_pmd, pmc->old_addr);
		} else if (IS_ENABLED(CONFIG_HAVE_MOVE_PMD) &&
			   extent == PMD_SIZE) {
			/*
			 * If the extent is PMD-sized, try to speed the move by
			 * moving at the PMD level if possible.
			 */
			if (move_pgt_entry(pmc, NORMAL_PMD, old_pmd, new_pmd))
				continue;
		}
		if (pmd_none(*old_pmd))
			continue;
		if (pte_alloc(pmc->new->vm_mm, new_pmd))
			break;
		if (move_ptes(pmc, extent, old_pmd, new_pmd) < 0)
			goto again;
	}

	mmu_notifier_invalidate_range_end(&range);

	return pmc_progress(pmc);
}

/* Set vrm->delta to the difference in VMA size specified by user. */
static void vrm_set_delta(struct vma_remap_struct *vrm)
{
	vrm->delta = abs_diff(vrm->old_len, vrm->new_len);
}

/* Determine what kind of remap this is - shrink, expand or no resize at all. */
static enum mremap_type vrm_remap_type(struct vma_remap_struct *vrm)
{
	if (vrm->delta == 0)
		return MREMAP_NO_RESIZE;

	if (vrm->old_len > vrm->new_len)
		return MREMAP_SHRINK;

	return MREMAP_EXPAND;
}

/*
 * When moving a VMA to vrm->new_adr, does this result in the new and old VMAs
 * overlapping?
 */
static bool vrm_overlaps(struct vma_remap_struct *vrm)
{
	unsigned long start_old = vrm->addr;
	unsigned long start_new = vrm->new_addr;
	unsigned long end_old = vrm->addr + vrm->old_len;
	unsigned long end_new = vrm->new_addr + vrm->new_len;

	/*
	 * start_old    end_old
	 *     |-----------|
	 *     |           |
	 *     |-----------|
	 *             |-------------|
	 *             |             |
	 *             |-------------|
	 *         start_new      end_new
	 */
	if (end_old > start_new && end_new > start_old)
		return true;

	return false;
}

/*
 * Will a new address definitely be assigned? This either if the user specifies
 * it via MREMAP_FIXED, or if MREMAP_DONTUNMAP is used, indicating we will
 * always detemrine a target address.
 */
static bool vrm_implies_new_addr(struct vma_remap_struct *vrm)
{
	return vrm->flags & (MREMAP_FIXED | MREMAP_DONTUNMAP);
}

/*
 * Find an unmapped area for the requested vrm->new_addr.
 *
 * If MREMAP_FIXED then this is equivalent to a MAP_FIXED mmap() call. If only
 * MREMAP_DONTUNMAP is set, then this is equivalent to providing a hint to
 * mmap(), otherwise this is equivalent to mmap() specifying a NULL address.
 *
 * Returns 0 on success (with vrm->new_addr updated), or an error code upon
 * failure.
 */
static unsigned long vrm_set_new_addr(struct vma_remap_struct *vrm)
{
	struct vm_area_struct *vma = vrm->vma;
	unsigned long map_flags = 0;
	/* Page Offset _into_ the VMA. */
	pgoff_t internal_pgoff = (vrm->addr - vma->vm_start) >> PAGE_SHIFT;
	pgoff_t pgoff = vma->vm_pgoff + internal_pgoff;
	unsigned long new_addr = vrm_implies_new_addr(vrm) ? vrm->new_addr : 0;
	unsigned long res;

	if (vrm->flags & MREMAP_FIXED)
		map_flags |= MAP_FIXED;
	if (vma->vm_flags & VM_MAYSHARE)
		map_flags |= MAP_SHARED;

	res = get_unmapped_area(vma->vm_file, new_addr, vrm->new_len, pgoff,
				map_flags);
	if (IS_ERR_VALUE(res))
		return res;

	vrm->new_addr = res;
	return 0;
}

/*
 * Keep track of pages which have been added to the memory mapping. If the VMA
 * is accounted, also check to see if there is sufficient memory.
 *
 * Returns true on success, false if insufficient memory to charge.
 */
static bool vrm_calc_charge(struct vma_remap_struct *vrm)
{
	unsigned long charged;

	if (!(vrm->vma->vm_flags & VM_ACCOUNT))
		return true;

	/*
	 * If we don't unmap the old mapping, then we account the entirety of
	 * the length of the new one. Otherwise it's just the delta in size.
	 */
	if (vrm->flags & MREMAP_DONTUNMAP)
		charged = vrm->new_len >> PAGE_SHIFT;
	else
		charged = vrm->delta >> PAGE_SHIFT;


	/* This accounts 'charged' pages of memory. */
	if (security_vm_enough_memory_mm(current->mm, charged))
		return false;

	vrm->charged = charged;
	return true;
}

/*
 * an error has occurred so we will not be using vrm->charged memory. Unaccount
 * this memory if the VMA is accounted.
 */
static void vrm_uncharge(struct vma_remap_struct *vrm)
{
	if (!(vrm->vma->vm_flags & VM_ACCOUNT))
		return;

	vm_unacct_memory(vrm->charged);
	vrm->charged = 0;
}

/*
 * Update mm exec_vm, stack_vm, data_vm, and locked_vm fields as needed to
 * account for 'bytes' memory used, and if locked, indicate this in the VRM so
 * we can handle this correctly later.
 */
static void vrm_stat_account(struct vma_remap_struct *vrm,
			     unsigned long bytes)
{
	unsigned long pages = bytes >> PAGE_SHIFT;
	struct mm_struct *mm = current->mm;
	struct vm_area_struct *vma = vrm->vma;

	vm_stat_account(mm, vma->vm_flags, pages);
	if (vma->vm_flags & VM_LOCKED)
		mm->locked_vm += pages;
}

/*
 * Perform checks before attempting to write a VMA prior to it being
 * moved.
 */
static unsigned long prep_move_vma(struct vma_remap_struct *vrm)
{
	unsigned long err = 0;
	struct vm_area_struct *vma = vrm->vma;
	unsigned long old_addr = vrm->addr;
	unsigned long old_len = vrm->old_len;
	vm_flags_t dummy = vma->vm_flags;

	/*
	 * We'd prefer to avoid failure later on in do_munmap:
	 * which may split one vma into three before unmapping.
	 */
	if (current->mm->map_count >= sysctl_max_map_count - 3)
		return -ENOMEM;

	if (vma->vm_ops && vma->vm_ops->may_split) {
		if (vma->vm_start != old_addr)
			err = vma->vm_ops->may_split(vma, old_addr);
		if (!err && vma->vm_end != old_addr + old_len)
			err = vma->vm_ops->may_split(vma, old_addr + old_len);
		if (err)
			return err;
	}

	/*
	 * Advise KSM to break any KSM pages in the area to be moved:
	 * it would be confusing if they were to turn up at the new
	 * location, where they happen to coincide with different KSM
	 * pages recently unmapped.  But leave vma->vm_flags as it was,
	 * so KSM can come around to merge on vma and new_vma afterwards.
	 */
	err = ksm_madvise(vma, old_addr, old_addr + old_len,
			  MADV_UNMERGEABLE, &dummy);
	if (err)
		return err;

	return 0;
}

/*
 * Unmap source VMA for VMA move, turning it from a copy to a move, being
 * careful to ensure we do not underflow memory account while doing so if an
 * accountable move.
 *
 * This is best effort, if we fail to unmap then we simply try to correct
 * accounting and exit.
 */
static void unmap_source_vma(struct vma_remap_struct *vrm)
{
	struct mm_struct *mm = current->mm;
	unsigned long addr = vrm->addr;
	unsigned long len = vrm->old_len;
	struct vm_area_struct *vma = vrm->vma;
	VMA_ITERATOR(vmi, mm, addr);
	int err;
	unsigned long vm_start;
	unsigned long vm_end;
	/*
	 * It might seem odd that we check for MREMAP_DONTUNMAP here, given this
	 * function implies that we unmap the original VMA, which seems
	 * contradictory.
	 *
	 * However, this occurs when this operation was attempted and an error
	 * arose, in which case we _do_ wish to unmap the _new_ VMA, which means
	 * we actually _do_ want it be unaccounted.
	 */
	bool accountable_move = (vma->vm_flags & VM_ACCOUNT) &&
		!(vrm->flags & MREMAP_DONTUNMAP);

	/*
	 * So we perform a trick here to prevent incorrect accounting. Any merge
	 * or new VMA allocation performed in copy_vma() does not adjust
	 * accounting, it is expected that callers handle this.
	 *
	 * And indeed we already have, accounting appropriately in the case of
	 * both in vrm_charge().
	 *
	 * However, when we unmap the existing VMA (to effect the move), this
	 * code will, if the VMA has VM_ACCOUNT set, attempt to unaccount
	 * removed pages.
	 *
	 * To avoid this we temporarily clear this flag, reinstating on any
	 * portions of the original VMA that remain.
	 */
	if (accountable_move) {
		vm_flags_clear(vma, VM_ACCOUNT);
		/* We are about to split vma, so store the start/end. */
		vm_start = vma->vm_start;
		vm_end = vma->vm_end;
	}

	err = do_vmi_munmap(&vmi, mm, addr, len, vrm->uf_unmap, /* unlock= */false);
	vrm->vma = NULL; /* Invalidated. */
	vrm->vmi_needs_invalidate = true;
	if (err) {
		/* OOM: unable to split vma, just get accounts right */
		vm_acct_memory(len >> PAGE_SHIFT);
		return;
	}

	/*
	 * If we mremap() from a VMA like this:
	 *
	 *    addr  end
	 *     |     |
	 *     v     v
	 * |-------------|
	 * |             |
	 * |-------------|
	 *
	 * Having cleared VM_ACCOUNT from the whole VMA, after we unmap above
	 * we'll end up with:
	 *
	 *    addr  end
	 *     |     |
	 *     v     v
	 * |---|     |---|
	 * | A |     | B |
	 * |---|     |---|
	 *
	 * The VMI is still pointing at addr, so vma_prev() will give us A, and
	 * a subsequent or lone vma_next() will give as B.
	 *
	 * do_vmi_munmap() will have restored the VMI back to addr.
	 */
	if (accountable_move) {
		unsigned long end = addr + len;

		if (vm_start < addr) {
			struct vm_area_struct *prev = vma_prev(&vmi);

			vm_flags_set(prev, VM_ACCOUNT); /* Acquires VMA lock. */
		}

		if (vm_end > end) {
			struct vm_area_struct *next = vma_next(&vmi);

			vm_flags_set(next, VM_ACCOUNT); /* Acquires VMA lock. */
		}
	}
}

/*
 * Copy vrm->vma over to vrm->new_addr possibly adjusting size as part of the
 * process. Additionally handle an error occurring on moving of page tables,
 * where we reset vrm state to cause unmapping of the new VMA.
 *
 * Outputs the newly installed VMA to new_vma_ptr. Returns 0 on success or an
 * error code.
 */
static int copy_vma_and_data(struct vma_remap_struct *vrm,
			     struct vm_area_struct **new_vma_ptr)
{
	unsigned long internal_offset = vrm->addr - vrm->vma->vm_start;
	unsigned long internal_pgoff = internal_offset >> PAGE_SHIFT;
	unsigned long new_pgoff = vrm->vma->vm_pgoff + internal_pgoff;
	unsigned long moved_len;
	struct vm_area_struct *vma = vrm->vma;
	struct vm_area_struct *new_vma;
	int err = 0;
	PAGETABLE_MOVE(pmc, NULL, NULL, vrm->addr, vrm->new_addr, vrm->old_len);

	new_vma = copy_vma(&vma, vrm->new_addr, vrm->new_len, new_pgoff,
			   &pmc.need_rmap_locks);
	if (!new_vma) {
		vrm_uncharge(vrm);
		*new_vma_ptr = NULL;
		return -ENOMEM;
	}
	/* By merging, we may have invalidated any iterator in use. */
	if (vma != vrm->vma)
		vrm->vmi_needs_invalidate = true;

	vrm->vma = vma;
	pmc.old = vma;
	pmc.new = new_vma;

	moved_len = move_page_tables(&pmc);
	if (moved_len < vrm->old_len)
		err = -ENOMEM;
	else if (vma->vm_ops && vma->vm_ops->mremap)
		err = vma->vm_ops->mremap(new_vma);

	if (unlikely(err)) {
		PAGETABLE_MOVE(pmc_revert, new_vma, vma, vrm->new_addr,
			       vrm->addr, moved_len);

		/*
		 * On error, move entries back from new area to old,
		 * which will succeed since page tables still there,
		 * and then proceed to unmap new area instead of old.
		 */
		pmc_revert.need_rmap_locks = true;
		move_page_tables(&pmc_revert);

		vrm->vma = new_vma;
		vrm->old_len = vrm->new_len;
		vrm->addr = vrm->new_addr;
	} else {
		mremap_userfaultfd_prep(new_vma, vrm->uf);
	}

	fixup_hugetlb_reservations(vma);

	*new_vma_ptr = new_vma;
	return err;
}

/*
 * Perform final tasks for MADV_DONTUNMAP operation, clearing mlock() and
 * account flags on remaining VMA by convention (it cannot be mlock()'d any
 * longer, as pages in range are no longer mapped), and removing anon_vma_chain
 * links from it (if the entire VMA was copied over).
 */
static void dontunmap_complete(struct vma_remap_struct *vrm,
			       struct vm_area_struct *new_vma)
{
	unsigned long start = vrm->addr;
	unsigned long end = vrm->addr + vrm->old_len;
	unsigned long old_start = vrm->vma->vm_start;
	unsigned long old_end = vrm->vma->vm_end;

	/*
	 * We always clear VM_LOCKED[ONFAULT] | VM_ACCOUNT on the old
	 * vma.
	 */
	vm_flags_clear(vrm->vma, VM_LOCKED_MASK | VM_ACCOUNT);

	/*
	 * anon_vma links of the old vma is no longer needed after its page
	 * table has been moved.
	 */
	if (new_vma != vrm->vma && start == old_start && end == old_end)
		unlink_anon_vmas(vrm->vma);

	/* Because we won't unmap we don't need to touch locked_vm. */
}

static unsigned long move_vma(struct vma_remap_struct *vrm)
{
	struct mm_struct *mm = current->mm;
	struct vm_area_struct *new_vma;
	unsigned long hiwater_vm;
	int err;

	err = prep_move_vma(vrm);
	if (err)
		return err;

	/*
	 * If accounted, determine the number of bytes the operation will
	 * charge.
	 */
	if (!vrm_calc_charge(vrm))
		return -ENOMEM;

	/* We don't want racing faults. */
	vma_start_write(vrm->vma);

	/* Perform copy step. */
	err = copy_vma_and_data(vrm, &new_vma);
	/*
	 * If we established the copied-to VMA, we attempt to recover from the
	 * error by setting the destination VMA to the source VMA and unmapping
	 * it below.
	 */
	if (err && !new_vma)
		return err;

	/*
	 * If we failed to move page tables we still do total_vm increment
	 * since do_munmap() will decrement it by old_len == new_len.
	 *
	 * Since total_vm is about to be raised artificially high for a
	 * moment, we need to restore high watermark afterwards: if stats
	 * are taken meanwhile, total_vm and hiwater_vm appear too high.
	 * If this were a serious issue, we'd add a flag to do_munmap().
	 */
	hiwater_vm = mm->hiwater_vm;

	vrm_stat_account(vrm, vrm->new_len);
	if (unlikely(!err && (vrm->flags & MREMAP_DONTUNMAP)))
		dontunmap_complete(vrm, new_vma);
	else
		unmap_source_vma(vrm);

	mm->hiwater_vm = hiwater_vm;

	return err ? (unsigned long)err : vrm->new_addr;
}

/*
 * The user has requested that the VMA be shrunk (i.e., old_len > new_len), so
 * execute this, optionally dropping the mmap lock when we do so.
 *
 * In both cases this invalidates the VMA, however if we don't drop the lock,
 * then load the correct VMA into vrm->vma afterwards.
 */
static unsigned long shrink_vma(struct vma_remap_struct *vrm,
				bool drop_lock)
{
	struct mm_struct *mm = current->mm;
	unsigned long unmap_start = vrm->addr + vrm->new_len;
	unsigned long unmap_bytes = vrm->delta;
	unsigned long res;
	VMA_ITERATOR(vmi, mm, unmap_start);

	VM_BUG_ON(vrm->remap_type != MREMAP_SHRINK);

	res = do_vmi_munmap(&vmi, mm, unmap_start, unmap_bytes,
			    vrm->uf_unmap, drop_lock);
	vrm->vma = NULL; /* Invalidated. */
	if (res)
		return res;

	/*
	 * If we've not dropped the lock, then we should reload the VMA to
	 * replace the invalidated VMA with the one that may have now been
	 * split.
	 */
	if (drop_lock) {
		vrm->mmap_locked = false;
	} else {
		vrm->vma = vma_lookup(mm, vrm->addr);
		if (!vrm->vma)
			return -EFAULT;
	}

	return 0;
}

/*
 * mremap_to() - remap a vma to a new location.
 * Returns: The new address of the vma or an error.
 */
static unsigned long mremap_to(struct vma_remap_struct *vrm)
{
	struct mm_struct *mm = current->mm;
	unsigned long err;

	if (vrm->flags & MREMAP_FIXED) {
		/*
		 * In mremap_to().
		 * VMA is moved to dst address, and munmap dst first.
		 * do_munmap will check if dst is sealed.
		 */
		err = do_munmap(mm, vrm->new_addr, vrm->new_len,
				vrm->uf_unmap_early);
		vrm->vma = NULL; /* Invalidated. */
		vrm->vmi_needs_invalidate = true;
		if (err)
			return err;

		/*
		 * If we remap a portion of a VMA elsewhere in the same VMA,
		 * this can invalidate the old VMA. Reset.
		 */
		vrm->vma = vma_lookup(mm, vrm->addr);
		if (!vrm->vma)
			return -EFAULT;
	}

	if (vrm->remap_type == MREMAP_SHRINK) {
		err = shrink_vma(vrm, /* drop_lock= */false);
		if (err)
			return err;

		/* Set up for the move now shrink has been executed. */
		vrm->old_len = vrm->new_len;
	}

	/* MREMAP_DONTUNMAP expands by old_len since old_len == new_len */
	if (vrm->flags & MREMAP_DONTUNMAP) {
		vm_flags_t vm_flags = vrm->vma->vm_flags;
		unsigned long pages = vrm->old_len >> PAGE_SHIFT;

		if (!may_expand_vm(mm, vm_flags, pages))
			return -ENOMEM;
	}

	err = vrm_set_new_addr(vrm);
	if (err)
		return err;

	return move_vma(vrm);
}

static int vma_expandable(struct vm_area_struct *vma, unsigned long delta)
{
	unsigned long end = vma->vm_end + delta;

	if (end < vma->vm_end) /* overflow */
		return 0;
	if (find_vma_intersection(vma->vm_mm, vma->vm_end, end))
		return 0;
	if (get_unmapped_area(NULL, vma->vm_start, end - vma->vm_start,
			      0, MAP_FIXED) & ~PAGE_MASK)
		return 0;
	return 1;
}

/* Determine whether we are actually able to execute an in-place expansion. */
static bool vrm_can_expand_in_place(struct vma_remap_struct *vrm)
{
	/* Number of bytes from vrm->addr to end of VMA. */
	unsigned long suffix_bytes = vrm->vma->vm_end - vrm->addr;

	/* If end of range aligns to end of VMA, we can just expand in-place. */
	if (suffix_bytes != vrm->old_len)
		return false;

	/* Check whether this is feasible. */
	if (!vma_expandable(vrm->vma, vrm->delta))
		return false;

	return true;
}

/*
 * We know we can expand the VMA in-place by delta pages, so do so.
 *
 * If we discover the VMA is locked, update mm_struct statistics accordingly and
 * indicate so to the caller.
 */
static unsigned long expand_vma_in_place(struct vma_remap_struct *vrm)
{
	struct mm_struct *mm = current->mm;
	struct vm_area_struct *vma = vrm->vma;
	VMA_ITERATOR(vmi, mm, vma->vm_end);

	if (!vrm_calc_charge(vrm))
		return -ENOMEM;

	/*
	 * Function vma_merge_extend() is called on the
	 * extension we are adding to the already existing vma,
	 * vma_merge_extend() will merge this extension with the
	 * already existing vma (expand operation itself) and
	 * possibly also with the next vma if it becomes
	 * adjacent to the expanded vma and otherwise
	 * compatible.
	 */
	vma = vma_merge_extend(&vmi, vma, vrm->delta);
	if (!vma) {
		vrm_uncharge(vrm);
		return -ENOMEM;
	}
	vrm->vma = vma;

	vrm_stat_account(vrm, vrm->delta);

	return 0;
}

static bool align_hugetlb(struct vma_remap_struct *vrm)
{
	struct hstate *h __maybe_unused = hstate_vma(vrm->vma);

	vrm->old_len = ALIGN(vrm->old_len, huge_page_size(h));
	vrm->new_len = ALIGN(vrm->new_len, huge_page_size(h));

	/* addrs must be huge page aligned */
	if (vrm->addr & ~huge_page_mask(h))
		return false;
	if (vrm->new_addr & ~huge_page_mask(h))
		return false;

	/*
	 * Don't allow remap expansion, because the underlying hugetlb
	 * reservation is not yet capable to handle split reservation.
	 */
	if (vrm->new_len > vrm->old_len)
		return false;

	return true;
}

/*
 * We are mremap()'ing without specifying a fixed address to move to, but are
 * requesting that the VMA's size be increased.
 *
 * Try to do so in-place, if this fails, then move the VMA to a new location to
 * action the change.
 */
static unsigned long expand_vma(struct vma_remap_struct *vrm)
{
	unsigned long err;

	/*
	 * [addr, old_len) spans precisely to the end of the VMA, so try to
	 * expand it in-place.
	 */
	if (vrm_can_expand_in_place(vrm)) {
		err = expand_vma_in_place(vrm);
		if (err)
			return err;

		/* OK we're done! */
		return vrm->addr;
	}

	/*
	 * We weren't able to just expand or shrink the area,
	 * we need to create a new one and move it.
	 */

	/* We're not allowed to move the VMA, so error out. */
	if (!(vrm->flags & MREMAP_MAYMOVE))
		return -ENOMEM;

	/* Find a new location to move the VMA to. */
	err = vrm_set_new_addr(vrm);
	if (err)
		return err;

	return move_vma(vrm);
}

/*
 * Attempt to resize the VMA in-place, if we cannot, then move the VMA to the
 * first available address to perform the operation.
 */
static unsigned long mremap_at(struct vma_remap_struct *vrm)
{
	unsigned long res;

	switch (vrm->remap_type) {
	case MREMAP_INVALID:
		break;
	case MREMAP_NO_RESIZE:
		/* NO-OP CASE - resizing to the same size. */
		return vrm->addr;
	case MREMAP_SHRINK:
		/*
		 * SHRINK CASE. Can always be done in-place.
		 *
		 * Simply unmap the shrunken portion of the VMA. This does all
		 * the needed commit accounting, and we indicate that the mmap
		 * lock should be dropped.
		 */
		res = shrink_vma(vrm, /* drop_lock= */true);
		if (res)
			return res;

		return vrm->addr;
	case MREMAP_EXPAND:
		return expand_vma(vrm);
	}

	/* Should not be possible. */
	WARN_ON_ONCE(1);
	return -EINVAL;
}

/*
 * Will this operation result in the VMA being expanded or moved and thus need
 * to map a new portion of virtual address space?
 */
static bool vrm_will_map_new(struct vma_remap_struct *vrm)
{
	if (vrm->remap_type == MREMAP_EXPAND)
		return true;

	if (vrm_implies_new_addr(vrm))
		return true;

	return false;
}

/* Does this remap ONLY move mappings? */
static bool vrm_move_only(struct vma_remap_struct *vrm)
{
	if (!(vrm->flags & MREMAP_FIXED))
		return false;

	if (vrm->old_len != vrm->new_len)
		return false;

	return true;
}

static void notify_uffd(struct vma_remap_struct *vrm, bool failed)
{
	struct mm_struct *mm = current->mm;

	/* Regardless of success/failure, we always notify of any unmaps. */
	userfaultfd_unmap_complete(mm, vrm->uf_unmap_early);
	if (failed)
		mremap_userfaultfd_fail(vrm->uf);
	else
		mremap_userfaultfd_complete(vrm->uf, vrm->addr,
			vrm->new_addr, vrm->old_len);
	userfaultfd_unmap_complete(mm, vrm->uf_unmap);
}

static bool vma_multi_allowed(struct vm_area_struct *vma)
{
	struct file *file = vma->vm_file;

	/*
	 * We can't support moving multiple uffd VMAs as notify requires
	 * mmap lock to be dropped.
	 */
	if (userfaultfd_armed(vma))
		return false;

	/*
	 * Custom get unmapped area might result in MREMAP_FIXED not
	 * being obeyed.
	 */
	if (!file || !file->f_op->get_unmapped_area)
		return true;
	/* Known good. */
	if (vma_is_shmem(vma))
		return true;
	if (is_vm_hugetlb_page(vma))
		return true;
	if (file->f_op->get_unmapped_area == thp_get_unmapped_area)
		return true;

	return false;
}

static int check_prep_vma(struct vma_remap_struct *vrm)
{
	struct vm_area_struct *vma = vrm->vma;
	struct mm_struct *mm = current->mm;
	unsigned long addr = vrm->addr;
	unsigned long old_len, new_len, pgoff;

	if (!vma)
		return -EFAULT;

	/* If mseal()'d, mremap() is prohibited. */
	if (vma_is_sealed(vma))
		return -EPERM;

	/* Align to hugetlb page size, if required. */
	if (is_vm_hugetlb_page(vma) && !align_hugetlb(vrm))
		return -EINVAL;

	vrm_set_delta(vrm);
	vrm->remap_type = vrm_remap_type(vrm);
	/* For convenience, we set new_addr even if VMA won't move. */
	if (!vrm_implies_new_addr(vrm))
		vrm->new_addr = addr;

	/* Below only meaningful if we expand or move a VMA. */
	if (!vrm_will_map_new(vrm))
		return 0;

	old_len = vrm->old_len;
	new_len = vrm->new_len;

	/*
	 * !old_len is a special case where an attempt is made to 'duplicate'
	 * a mapping.  This makes no sense for private mappings as it will
	 * instead create a fresh/new mapping unrelated to the original.  This
	 * is contrary to the basic idea of mremap which creates new mappings
	 * based on the original.  There are no known use cases for this
	 * behavior.  As a result, fail such attempts.
	 */
	if (!old_len && !(vma->vm_flags & (VM_SHARED | VM_MAYSHARE))) {
		pr_warn_once("%s (%d): attempted to duplicate a private mapping with mremap.  This is not supported.\n",
			     current->comm, current->pid);
		return -EINVAL;
	}

	if ((vrm->flags & MREMAP_DONTUNMAP) &&
			(vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)))
		return -EINVAL;

	/*
	 * We permit crossing of boundaries for the range being unmapped due to
	 * a shrink.
	 */
	if (vrm->remap_type == MREMAP_SHRINK)
		old_len = new_len;

	/*
	 * We can't remap across the end of VMAs, as another VMA may be
	 * adjacent:
	 *
	 *       addr   vma->vm_end
	 *  |-----.----------|
	 *  |     .          |
	 *  |-----.----------|
	 *        .<--------->xxx>
	 *            old_len
	 *
	 * We also require that vma->vm_start <= addr < vma->vm_end.
	 */
	if (old_len > vma->vm_end - addr)
		return -EFAULT;

	if (new_len == old_len)
		return 0;

	/* We are expanding and the VMA is mlock()'d so we need to populate. */
	if (vma->vm_flags & VM_LOCKED)
		vrm->populate_expand = true;

	/* Need to be careful about a growing mapping */
	pgoff = (addr - vma->vm_start) >> PAGE_SHIFT;
	pgoff += vma->vm_pgoff;
	if (pgoff + (new_len >> PAGE_SHIFT) < pgoff)
		return -EINVAL;

	if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP))
		return -EFAULT;

	if (!mlock_future_ok(mm, vma->vm_flags, vrm->delta))
		return -EAGAIN;

	if (!may_expand_vm(mm, vma->vm_flags, vrm->delta >> PAGE_SHIFT))
		return -ENOMEM;

	return 0;
}

/*
 * Are the parameters passed to mremap() valid? If so return 0, otherwise return
 * error.
 */
static unsigned long check_mremap_params(struct vma_remap_struct *vrm)

{
	unsigned long addr = vrm->addr;
	unsigned long flags = vrm->flags;

	/* Ensure no unexpected flag values. */
	if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE | MREMAP_DONTUNMAP))
		return -EINVAL;

	/* Start address must be page-aligned. */
	if (offset_in_page(addr))
		return -EINVAL;

	/*
	 * We allow a zero old-len as a special case
	 * for DOS-emu "duplicate shm area" thing. But
	 * a zero new-len is nonsensical.
	 */
	if (!vrm->new_len)
		return -EINVAL;

	/* Is the new length or address silly? */
	if (vrm->new_len > TASK_SIZE ||
	    vrm->new_addr > TASK_SIZE - vrm->new_len)
		return -EINVAL;

	/* Remainder of checks are for cases with specific new_addr. */
	if (!vrm_implies_new_addr(vrm))
		return 0;

	/* The new address must be page-aligned. */
	if (offset_in_page(vrm->new_addr))
		return -EINVAL;

	/* A fixed address implies a move. */
	if (!(flags & MREMAP_MAYMOVE))
		return -EINVAL;

	/* MREMAP_DONTUNMAP does not allow resizing in the process. */
	if (flags & MREMAP_DONTUNMAP && vrm->old_len != vrm->new_len)
		return -EINVAL;

	/* Target VMA must not overlap source VMA. */
	if (vrm_overlaps(vrm))
		return -EINVAL;

	/*
	 * move_vma() need us to stay 4 maps below the threshold, otherwise
	 * it will bail out at the very beginning.
	 * That is a problem if we have already unmaped the regions here
	 * (new_addr, and old_addr), because userspace will not know the
	 * state of the vma's after it gets -ENOMEM.
	 * So, to avoid such scenario we can pre-compute if the whole
	 * operation has high chances to success map-wise.
	 * Worst-scenario case is when both vma's (new_addr and old_addr) get
	 * split in 3 before unmapping it.
	 * That means 2 more maps (1 for each) to the ones we already hold.
	 * Check whether current map count plus 2 still leads us to 4 maps below
	 * the threshold, otherwise return -ENOMEM here to be more safe.
	 */
	if ((current->mm->map_count + 2) >= sysctl_max_map_count - 3)
		return -ENOMEM;

	return 0;
}

static unsigned long remap_move(struct vma_remap_struct *vrm)
{
	struct vm_area_struct *vma;
	unsigned long start = vrm->addr;
	unsigned long end = vrm->addr + vrm->old_len;
	unsigned long new_addr = vrm->new_addr;
	unsigned long target_addr = new_addr;
	unsigned long res = -EFAULT;
	unsigned long last_end;
	bool seen_vma = false;

	VMA_ITERATOR(vmi, current->mm, start);

	/*
	 * When moving VMAs we allow for batched moves across multiple VMAs,
	 * with all VMAs in the input range [addr, addr + old_len) being moved
	 * (and split as necessary).
	 */
	for_each_vma_range(vmi, vma, end) {
		/* Account for start, end not aligned with VMA start, end. */
		unsigned long addr = max(vma->vm_start, start);
		unsigned long len = min(end, vma->vm_end) - addr;
		unsigned long offset, res_vma;
		bool multi_allowed;

		/* No gap permitted at the start of the range. */
		if (!seen_vma && start < vma->vm_start)
			return -EFAULT;

		/*
		 * To sensibly move multiple VMAs, accounting for the fact that
		 * get_unmapped_area() may align even MAP_FIXED moves, we simply
		 * attempt to move such that the gaps between source VMAs remain
		 * consistent in destination VMAs, e.g.:
		 *
		 *           X        Y                       X        Y
		 *         <--->     <->                    <--->     <->
		 * |-------|   |-----| |-----|      |-------|   |-----| |-----|
		 * |   A   |   |  B  | |  C  | ---> |   A'  |   |  B' | |  C' |
		 * |-------|   |-----| |-----|      |-------|   |-----| |-----|
		 *                               new_addr
		 *
		 * So we map B' at A'->vm_end + X, and C' at B'->vm_end + Y.
		 */
		offset = seen_vma ? vma->vm_start - last_end : 0;
		last_end = vma->vm_end;

		vrm->vma = vma;
		vrm->addr = addr;
		vrm->new_addr = target_addr + offset;
		vrm->old_len = vrm->new_len = len;

		multi_allowed = vma_multi_allowed(vma);
		if (!multi_allowed) {
			/* This is not the first VMA, abort immediately. */
			if (seen_vma)
				return -EFAULT;
			/* This is the first, but there are more, abort. */
			if (vma->vm_end < end)
				return -EFAULT;
		}

		res_vma = check_prep_vma(vrm);
		if (!res_vma)
			res_vma = mremap_to(vrm);
		if (IS_ERR_VALUE(res_vma))
			return res_vma;

		if (!seen_vma) {
			VM_WARN_ON_ONCE(multi_allowed && res_vma != new_addr);
			res = res_vma;
		}

		/* mmap lock is only dropped on shrink. */
		VM_WARN_ON_ONCE(!vrm->mmap_locked);
		/* This is a move, no expand should occur. */
		VM_WARN_ON_ONCE(vrm->populate_expand);

		if (vrm->vmi_needs_invalidate) {
			vma_iter_invalidate(&vmi);
			vrm->vmi_needs_invalidate = false;
		}
		seen_vma = true;
		target_addr = res_vma + vrm->new_len;
	}

	return res;
}

static unsigned long do_mremap(struct vma_remap_struct *vrm)
{
	struct mm_struct *mm = current->mm;
	unsigned long res;
	bool failed;

	vrm->old_len = PAGE_ALIGN(vrm->old_len);
	vrm->new_len = PAGE_ALIGN(vrm->new_len);

	res = check_mremap_params(vrm);
	if (res)
		return res;

	if (mmap_write_lock_killable(mm))
		return -EINTR;
	vrm->mmap_locked = true;

	if (vrm_move_only(vrm)) {
		res = remap_move(vrm);
	} else {
		vrm->vma = vma_lookup(current->mm, vrm->addr);
		res = check_prep_vma(vrm);
		if (res)
			goto out;

		/* Actually execute mremap. */
		res = vrm_implies_new_addr(vrm) ? mremap_to(vrm) : mremap_at(vrm);
	}

out:
	failed = IS_ERR_VALUE(res);

	if (vrm->mmap_locked)
		mmap_write_unlock(mm);

	/* VMA mlock'd + was expanded, so populated expanded region. */
	if (!failed && vrm->populate_expand)
		mm_populate(vrm->new_addr + vrm->old_len, vrm->delta);

	notify_uffd(vrm, failed);
	return res;
}

/*
 * Expand (or shrink) an existing mapping, potentially moving it at the
 * same time (controlled by the MREMAP_MAYMOVE flag and available VM space)
 *
 * MREMAP_FIXED option added 5-Dec-1999 by Benjamin LaHaise
 * This option implies MREMAP_MAYMOVE.
 */
SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
		unsigned long, new_len, unsigned long, flags,
		unsigned long, new_addr)
{
	struct vm_userfaultfd_ctx uf = NULL_VM_UFFD_CTX;
	LIST_HEAD(uf_unmap_early);
	LIST_HEAD(uf_unmap);
	/*
	 * There is a deliberate asymmetry here: we strip the pointer tag
	 * from the old address but leave the new address alone. This is
	 * for consistency with mmap(), where we prevent the creation of
	 * aliasing mappings in userspace by leaving the tag bits of the
	 * mapping address intact. A non-zero tag will cause the subsequent
	 * range checks to reject the address as invalid.
	 *
	 * See Documentation/arch/arm64/tagged-address-abi.rst for more
	 * information.
	 */
	struct vma_remap_struct vrm = {
		.addr = untagged_addr(addr),
		.old_len = old_len,
		.new_len = new_len,
		.flags = flags,
		.new_addr = new_addr,

		.uf = &uf,
		.uf_unmap_early = &uf_unmap_early,
		.uf_unmap = &uf_unmap,

		.remap_type = MREMAP_INVALID, /* We set later. */
	};

	return do_mremap(&vrm);
}
