x86/mm/pat: Add untrack_pfn_moved for mremap
mremap() with MREMAP_FIXED on a VM_PFNMAP range causes the following
WARN_ON_ONCE() message in untrack_pfn().
WARNING: CPU: 1 PID: 3493 at arch/x86/mm/pat.c:985 untrack_pfn+0xbd/0xd0()
Call Trace:
[<
ffffffff817729ea>] dump_stack+0x45/0x57
[<
ffffffff8109e4b6>] warn_slowpath_common+0x86/0xc0
[<
ffffffff8109e5ea>] warn_slowpath_null+0x1a/0x20
[<
ffffffff8106a88d>] untrack_pfn+0xbd/0xd0
[<
ffffffff811d2d5e>] unmap_single_vma+0x80e/0x860
[<
ffffffff811d3725>] unmap_vmas+0x55/0xb0
[<
ffffffff811d916c>] unmap_region+0xac/0x120
[<
ffffffff811db86a>] do_munmap+0x28a/0x460
[<
ffffffff811dec33>] move_vma+0x1b3/0x2e0
[<
ffffffff811df113>] SyS_mremap+0x3b3/0x510
[<
ffffffff817793ee>] entry_SYSCALL_64_fastpath+0x12/0x71
MREMAP_FIXED moves a pfnmap from old vma to new vma. untrack_pfn() is
called with the old vma after its pfnmap page table has been removed,
which causes follow_phys() to fail. The new vma has a new pfnmap to
the same pfn & cache type with VM_PAT set. Therefore, we only need to
clear VM_PAT from the old vma in this case.
Add untrack_pfn_moved(), which clears VM_PAT from a given old vma.
move_vma() is changed to call this function with the old vma when
VM_PFNMAP is set. move_vma() then calls do_munmap(), and untrack_pfn()
is a no-op since VM_PAT is cleared.
Reported-by: Stas Sergeev <stsp@list.ru>
Signed-off-by: Toshi Kani <toshi.kani@hpe.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: linux-mm@kvack.org
Link: http://lkml.kernel.org/r/1450832064-10093-2-git-send-email-toshi.kani@hpe.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>