lkml.org 
[lkml]   [2016]   [Aug]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.6 26/56] x86/mtrr: Fix Xorg crashes in Qemu sessions
    Date
    4.6-stable review patch.  If anyone has any objections, please let me know.

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

    From: Toshi Kani <toshi.kani@hpe.com>

    commit edfe63ec97ed8d4496225f7ba54c9ce4207c5431 upstream.

    A Xorg failure on qemu32 was reported as a regression [1] caused by
    commit 9cd25aac1f44 ("x86/mm/pat: Emulate PAT when it is disabled").

    This patch fixes the Xorg crash.

    Negative effects of this regression were the following two failures [2]
    in Xorg on QEMU with QEMU CPU model "qemu32" (-cpu qemu32), which were
    triggered by the fact that its virtual CPU does not support MTRRs.

    #1. copy_process() failed in the check in reserve_pfn_range()

    copy_process
    copy_mm
    dup_mm
    dup_mmap
    copy_page_range
    track_pfn_copy
    reserve_pfn_range

    A WC map request was tracked as WC in memtype, which set a PTE as
    UC (pgprot) per __cachemode2pte_tbl[]. This led to this error in
    reserve_pfn_range() called from track_pfn_copy(), which obtained
    a pgprot from a PTE. It converts pgprot to page_cache_mode, which
    does not necessarily result in the original page_cache_mode since
    __cachemode2pte_tbl[] redirects multiple types to UC.

    #2. error path in copy_process() then hit WARN_ON_ONCE in
    untrack_pfn().

    x86/PAT: Xorg:509 map pfn expected mapping type uncached-
    minus for [mem 0xfd000000-0xfdffffff], got write-combining
    Call Trace:
    dump_stack
    warn_slowpath_common
    ? untrack_pfn
    ? untrack_pfn
    warn_slowpath_null
    untrack_pfn
    ? __kunmap_atomic
    unmap_single_vma
    ? pagevec_move_tail_fn
    unmap_vmas
    exit_mmap
    mmput
    copy_process.part.47
    _do_fork
    SyS_clone
    do_syscall_32_irqs_on
    entry_INT80_32

    These negative effects are caused by two separate bugs, but they
    can be addressed in separate patches. Fixing the pat_init() issue
    described below addresses the root cause, and avoids Xorg to hit
    these cases.

    When the CPU does not support MTRRs, MTRR does not call pat_init(),
    which leaves PAT enabled without initializing PAT. This pat_init()
    issue is a long-standing issue, but manifested as issue #1 (and then
    hit issue #2) with the above-mentioned commit because the memtype
    now tracks cache attribute with 'page_cache_mode'.

    This pat_init() issue existed before the commit, but we used pgprot
    in memtype. Hence, we did not have issue #1 before. But WC request
    resulted in WT in effect because WC pgrot is actually WT when PAT
    is not initialized. This is not how it was designed to work. When
    PAT is set to disable properly, WC is converted to UC. The use of
    WT can result in a system crash if the target range does not support
    WT. Fortunately, nobody ran into such issue before.

    To fix this pat_init() issue, PAT code has been enhanced to provide
    pat_disable() interface. Call this interface when MTRRs are disabled.
    By setting PAT to disable properly, PAT bypasses the memtype check,
    and avoids issue #1.

    [1]: https://lkml.org/lkml/2016/3/3/828
    [2]: https://lkml.org/lkml/2016/3/4/775

    Signed-off-by: Toshi Kani <toshi.kani@hpe.com>
    Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
    Cc: Andrew Morton <akpm@linux-foundation.org>
    Cc: Andy Lutomirski <luto@amacapital.net>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: Borislav Petkov <bp@suse.de>
    Cc: Brian Gerst <brgerst@gmail.com>
    Cc: Denys Vlasenko <dvlasenk@redhat.com>
    Cc: H. Peter Anvin <hpa@zytor.com>
    Cc: Juergen Gross <jgross@suse.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Luis R. Rodriguez <mcgrof@suse.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Toshi Kani <toshi.kani@hp.com>
    Cc: elliott@hpe.com
    Cc: konrad.wilk@oracle.com
    Cc: paul.gortmaker@windriver.com
    Cc: xen-devel@lists.xenproject.org
    Link: http://lkml.kernel.org/r/1458769323-24491-5-git-send-email-toshi.kani@hpe.com
    Signed-off-by: Ingo Molnar <mingo@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/x86/include/asm/mtrr.h | 6 +++++-
    arch/x86/kernel/cpu/mtrr/main.c | 10 +++++++++-
    2 files changed, 14 insertions(+), 2 deletions(-)

    --- a/arch/x86/include/asm/mtrr.h
    +++ b/arch/x86/include/asm/mtrr.h
    @@ -24,6 +24,7 @@
    #define _ASM_X86_MTRR_H

    #include <uapi/asm/mtrr.h>
    +#include <asm/pat.h>


    /*
    @@ -83,9 +84,12 @@ static inline int mtrr_trim_uncached_mem
    static inline void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
    {
    }
    +static inline void mtrr_bp_init(void)
    +{
    + pat_disable("MTRRs disabled, skipping PAT initialization too.");
    +}

    #define mtrr_ap_init() do {} while (0)
    -#define mtrr_bp_init() do {} while (0)
    #define set_mtrr_aps_delayed_init() do {} while (0)
    #define mtrr_aps_init() do {} while (0)
    #define mtrr_bp_restore() do {} while (0)
    --- a/arch/x86/kernel/cpu/mtrr/main.c
    +++ b/arch/x86/kernel/cpu/mtrr/main.c
    @@ -759,8 +759,16 @@ void __init mtrr_bp_init(void)
    }
    }

    - if (!mtrr_enabled())
    + if (!mtrr_enabled()) {
    pr_info("MTRR: Disabled\n");
    +
    + /*
    + * PAT initialization relies on MTRR's rendezvous handler.
    + * Skip PAT init until the handler can initialize both
    + * features independently.
    + */
    + pat_disable("MTRRs disabled, skipping PAT initialization too.");
    + }
    }

    void mtrr_ap_init(void)

    \
     
     \ /
      Last update: 2016-09-17 09:56    [W:2.879 / U:0.076 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site