lkml.org 
[lkml]   [2021]   [Jan]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 38/38] x86/mtrr: Correct the range check before performing MTRR type lookups
    Date
    From: Ying-Tsun Huang <ying-tsun.huang@amd.com>

    commit cb7f4a8b1fb426a175d1708f05581939c61329d4 upstream.

    In mtrr_type_lookup(), if the input memory address region is not in the
    MTRR, over 4GB, and not over the top of memory, a write-back attribute
    is returned. These condition checks are for ensuring the input memory
    address region is actually mapped to the physical memory.

    However, if the end address is just aligned with the top of memory,
    the condition check treats the address is over the top of memory, and
    write-back attribute is not returned.

    And this hits in a real use case with NVDIMM: the nd_pmem module tries
    to map NVDIMMs as cacheable memories when NVDIMMs are connected. If a
    NVDIMM is the last of the DIMMs, the performance of this NVDIMM becomes
    very low since it is aligned with the top of memory and its memory type
    is uncached-minus.

    Move the input end address change to inclusive up into
    mtrr_type_lookup(), before checking for the top of memory in either
    mtrr_type_lookup_{variable,fixed}() helpers.

    [ bp: Massage commit message. ]

    Fixes: 0cc705f56e40 ("x86/mm/mtrr: Clean up mtrr_type_lookup()")
    Signed-off-by: Ying-Tsun Huang <ying-tsun.huang@amd.com>
    Signed-off-by: Borislav Petkov <bp@suse.de>
    Link: https://lkml.kernel.org/r/20201215070721.4349-1-ying-tsun.huang@amd.com
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/x86/kernel/cpu/mtrr/generic.c | 6 +++---
    1 file changed, 3 insertions(+), 3 deletions(-)

    --- a/arch/x86/kernel/cpu/mtrr/generic.c
    +++ b/arch/x86/kernel/cpu/mtrr/generic.c
    @@ -166,9 +166,6 @@ static u8 mtrr_type_lookup_variable(u64
    *repeat = 0;
    *uniform = 1;

    - /* Make end inclusive instead of exclusive */
    - end--;
    -
    prev_match = MTRR_TYPE_INVALID;
    for (i = 0; i < num_var_ranges; ++i) {
    unsigned short start_state, end_state, inclusive;
    @@ -260,6 +257,9 @@ u8 mtrr_type_lookup(u64 start, u64 end,
    int repeat;
    u64 partial_end;

    + /* Make end inclusive instead of exclusive */
    + end--;
    +
    if (!mtrr_state_set)
    return MTRR_TYPE_INVALID;


    \
     
     \ /
      Last update: 2021-01-11 14:04    [W:3.417 / U:0.056 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site