Skip to content
  • Youquan Song's avatar
    thp: add compound tail page _mapcount when mapped · b6999b19
    Youquan Song authored
    
    
    With the 3.2-rc kernel, IOMMU 2M pages in KVM works.  But when I tried
    to use IOMMU 1GB pages in KVM, I encountered an oops and the 1GB page
    failed to be used.
    
    The root cause is that 1GB page allocation calls gup_huge_pud() while 2M
    page calls gup_huge_pmd.  If compound pages are used and the page is a
    tail page, gup_huge_pmd() increases _mapcount to record tail page are
    mapped while gup_huge_pud does not do that.
    
    So when the mapped page is relesed, it will result in kernel oops
    because the page is not marked mapped.
    
    This patch add tail process for compound page in 1GB huge page which
    keeps the same process as 2M page.
    
    Reproduce like:
    1. Add grub boot option: hugepagesz=1G hugepages=8
    2. mount -t hugetlbfs -o pagesize=1G hugetlbfs /dev/hugepages
    3. qemu-kvm -m 2048 -hda os-kvm.img -cpu kvm64 -smp 4 -mem-path /dev/hugepages
    	-net none -device pci-assign,host=07:00.1
    
      kernel BUG at mm/swap.c:114!
      invalid opcode: 0000 [#1] SMP
      Call Trace:
        put_page+0x15/0x37
        kvm_release_pfn_clean+0x31/0x36
        kvm_iommu_put_pages+0x94/0xb1
        kvm_iommu_unmap_memslots+0x80/0xb6
        kvm_assign_device+0xba/0x117
        kvm_vm_ioctl_assigned_device+0x301/0xa47
        kvm_vm_ioctl+0x36c/0x3a2
        do_vfs_ioctl+0x49e/0x4e4
        sys_ioctl+0x5a/0x7c
        system_call_fastpath+0x16/0x1b
      RIP  put_compound_page+0xd4/0x168
    
    Signed-off-by: default avatarYouquan Song <youquan.song@intel.com>
    Reviewed-by: default avatarAndrea Arcangeli <aarcange@redhat.com>
    Cc: Andi Kleen <andi@firstfloor.org>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    b6999b19