Skip to content
  • Toshi Kani's avatar
    x86/mm/pat: Add untrack_pfn_moved for mremap · d9fe4fab
    Toshi Kani authored
    
    
    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: default avatarStas Sergeev <stsp@list.ru>
    Signed-off-by: default avatarToshi 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: default avatarThomas Gleixner <tglx@linutronix.de>
    d9fe4fab