• Yinghai Lu's avatar
    x86: Fix /proc/mtrr with base/size more than 44bits · b1851628
    Yinghai Lu authored
    commit d5c78673 upstream.
    
    On one sytem that mtrr range is more then 44bits, in dmesg we have
    [    0.000000] MTRR default type: write-back
    [    0.000000] MTRR fixed ranges enabled:
    [    0.000000]   00000-9FFFF write-back
    [    0.000000]   A0000-BFFFF uncachable
    [    0.000000]   C0000-DFFFF write-through
    [    0.000000]   E0000-FFFFF write-protect
    [    0.000000] MTRR variable ranges enabled:
    [    0.000000]   0 [000080000000-0000FFFFFFFF] mask 3FFF80000000 uncachable
    [    0.000000]   1 [380000000000-38FFFFFFFFFF] mask 3F0000000000 uncachable
    [    0.000000]   2 [000099000000-000099FFFFFF] mask 3FFFFF000000 write-through
    [    0.000000]   3 [00009A000000-00009AFFFFFF] mask 3FFFFF000000 write-through
    [    0.000000]   4 [381FFA000000-381FFBFFFFFF] mask 3FFFFE000000 write-through
    [    0.000000]   5 [381FFC000000-381FFC0FFFFF] mask 3FFFFFF00000 write-through
    [    0.000000]   6 [0000AD000000-0000ADFFFFFF] mask 3FFFFF000000 write-through
    [    0.000000]   7 [0000BD000000-0000BDFFFFFF] mask 3FFFFF000000 write-through
    [    0.000000]   8 disabled
    [    0.000000]   9 disabled
    
    but /proc/mtrr report wrong:
    reg00: base=0x080000000 ( 2048MB), size= 2048MB, count=1: uncachable
    reg01: base=0x80000000000 (8388608MB), size=1048576MB, count=1: uncachable
    reg02: base=0x099000000 ( 2448MB), size=   16MB, count=1: write-through
    reg03: base=0x09a000000 ( 2464MB), size=   16MB, count=1: write-through
    reg04: base=0x81ffa000000 (8519584MB), size=   32MB, count=1: write-through
    reg05: base=0x81ffc000000 (8519616MB), size=    1MB, count=1: write-through
    reg06: base=0x0ad000000 ( 2768MB), size=   16MB, count=1: write-through
    reg07: base=0x0bd000000 ( 3024MB), size=   16MB, count=1: write-through
    reg08: base=0x09b000000 ( 2480MB), size=   16MB, count=1: write-combining
    
    so bit 44 and bit 45 get cut off.
    
    We have problems in arch/x86/kernel/cpu/mtrr/generic.c::generic_get_mtrr().
    1. for base, we miss cast base_lo to 64bit before shifting.
    Fix that by adding u64 casting.
    
    2. for size, it only can handle 44 bits aka 32bits + page_shift
    Fix that with 64bit mask instead of 32bit mask_lo, then range could be
    more than 44bits.
    At the same time, we need to update size_or_mask for old cpus that does
    support cpuid 0x80000008 to get phys_addr. Need to set high 32bits
    to all 1s, otherwise will not get correct size for them.
    
    Also fix mtrr_add_page: it should check base and (base + size - 1)
    instead of base and size, as base and size could be small but
    base + size could bigger enough to be out of boundary. We can
    use boot_cpu_data.x86_phys_bits directly to avoid size_or_mask.
    
    So When are we going to have size more than 44bits? that is 16TiB.
    
    after patch we have right ouput:
    reg00: base=0x080000000 ( 2048MB), size= 2048MB, count=1: uncachable
    reg01: base=0x380000000000 (58720256MB), size=1048576MB, count=1: uncachable
    reg02: base=0x099000000 ( 2448MB), size=   16MB, count=1: write-through
    reg03: base=0x09a000000 ( 2464MB), size=   16MB, count=1: write-through
    reg04: base=0x381ffa000000 (58851232MB), size=   32MB, count=1: write-through
    reg05: base=0x381ffc000000 (58851264MB), size=    1MB, count=1: write-through
    reg06: base=0x0ad000000 ( 2768MB), size=   16MB, count=1: write-through
    reg07: base=0x0bd000000 ( 3024MB), size=   16MB, count=1: write-through
    reg08: base=0x09b000000 ( 2480MB), size=   16MB, count=1: write-combining
    
    -v2: simply checking in mtrr_add_page according to hpa.
    
    [ hpa: This probably wants to go into -stable only after having sat in
      mainline for a bit.  It is not a regression. ]
    Signed-off-by: default avatarYinghai Lu <yinghai@kernel.org>
    Link: http://lkml.kernel.org/r/1371162815-29931-1-git-send-email-yinghai@kernel.orgSigned-off-by: default avatarH. Peter Anvin <hpa@linux.intel.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    b1851628
generic.c 20.8 KB