lkml.org 
[lkml]   [2011]   [Dec]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[11/45] thp: set compound tail page _count to zero
    3.0-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Youquan Song <youquan.song@intel.com>

    commit 58a84aa92723d1ac3e1cc4e3b0ff49291663f7e1 upstream.

    Commit 70b50f94f1644 ("mm: thp: tail page refcounting fix") keeps all
    page_tail->_count zero at all times. But the current kernel does not
    set page_tail->_count to zero if a 1GB page is utilized. So when an
    IOMMU 1GB page is used by KVM, it wil result in a kernel oops because a
    tail page's _count does not equal zero.

    kernel BUG at include/linux/mm.h:386!
    invalid opcode: 0000 [#1] SMP
    Call Trace:
    gup_pud_range+0xb8/0x19d
    get_user_pages_fast+0xcb/0x192
    ? trace_hardirqs_off+0xd/0xf
    hva_to_pfn+0x119/0x2f2
    gfn_to_pfn_memslot+0x2c/0x2e
    kvm_iommu_map_pages+0xfd/0x1c1
    kvm_iommu_map_memslots+0x7c/0xbd
    kvm_iommu_map_guest+0xaa/0xbf
    kvm_vm_ioctl_assigned_device+0x2ef/0xa47
    kvm_vm_ioctl+0x36c/0x3a2
    do_vfs_ioctl+0x49e/0x4e4
    sys_ioctl+0x5a/0x7c
    system_call_fastpath+0x16/0x1b
    RIP gup_huge_pud+0xf2/0x159

    Signed-off-by: Youquan Song <youquan.song@intel.com>
    Reviewed-by: Andrea Arcangeli <aarcange@redhat.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    mm/hugetlb.c | 1 +
    mm/page_alloc.c | 2 +-
    2 files changed, 2 insertions(+), 1 deletion(-)

    --- a/mm/hugetlb.c
    +++ b/mm/hugetlb.c
    @@ -575,6 +575,7 @@ static void prep_compound_gigantic_page(
    __SetPageHead(page);
    for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) {
    __SetPageTail(p);
    + set_page_count(p, 0);
    p->first_page = page;
    }
    }
    --- a/mm/page_alloc.c
    +++ b/mm/page_alloc.c
    @@ -355,8 +355,8 @@ void prep_compound_page(struct page *pag
    __SetPageHead(page);
    for (i = 1; i < nr_pages; i++) {
    struct page *p = page + i;
    -
    __SetPageTail(p);
    + set_page_count(p, 0);
    p->first_page = page;
    }
    }



    \
     
     \ /
      Last update: 2011-12-16 20:55    [W:7.006 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site