]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
mtrr, x86: fix MTRR state checks in mtrr_type_lookup()
authorToshi Kani <toshi.kani@hp.com>
Tue, 7 Apr 2015 23:57:07 +0000 (09:57 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Thu, 9 Apr 2015 09:07:13 +0000 (19:07 +1000)
'mtrr_state.enabled' contains the FE (fixed MTRRs enabled)
and E (MTRRs enabled) flags in MSR_MTRRdefType.  Intel SDM,
section 11.11.2.1, defines these flags as follows:
 - All MTRRs are disabled when the E flag is clear.
   The FE flag has no affect when the E flag is clear.
 - The default type is enabled when the E flag is set.
 - MTRR variable ranges are enabled when the E flag is set.
 - MTRR fixed ranges are enabled when both E and FE flags
   are set.

MTRR state checks in __mtrr_type_lookup() do not match with
SDM.  Hence, this patch makes the following changes:
 - The current code detects MTRRs disabled when both E and
   FE flags are clear in mtrr_state.enabled.  Fix to detect
   MTRRs disabled when the E flag is clear.
 - The current code does not check if the FE bit is set in
   mtrr_state.enabled when looking into the fixed entries.
   Fix to check the FE flag.
 - The current code returns the default type when the E flag
   is clear in mtrr_state.enabled.  However, the default type
   is also disabled when the E flag is clear.  Fix to remove
   the code as this case is handled as MTRR disabled with
   the 1st change.

In addition, this patch defines the E and FE flags in
mtrr_state.enabled as follows.
 - FE flag: MTRR_STATE_MTRR_FIXED_ENABLED
 - E  flag: MTRR_STATE_MTRR_ENABLED

print_mtrr_state() is also updated accordingly.

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Robert Elliott <Elliott@hp.com>
Cc: Paul Bolle <pebolle@tiscali.nl>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
arch/x86/include/uapi/asm/mtrr.h
arch/x86/kernel/cpu/mtrr/generic.c

index d0acb658c8f43950807dbf39a57e84c73bf34f06..66ba88dee38ebcbe8592ed92b4177c5b260ddb91 100644 (file)
@@ -88,6 +88,10 @@ struct mtrr_state_type {
        mtrr_type def_type;
 };
 
+/* Bit fields for enabled in struct mtrr_state_type */
+#define MTRR_STATE_MTRR_FIXED_ENABLED  0x01
+#define MTRR_STATE_MTRR_ENABLED                0x02
+
 #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
 #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
 
index c5be32701077cc5ff8c2f3b3eb96113422a46e16..4bff6db04fe80e85d5bd87a89afb2cb6e99757c5 100644 (file)
@@ -119,14 +119,16 @@ static u8 __mtrr_type_lookup(u64 start, u64 end, u64 *partial_end, int *repeat)
        if (!mtrr_state_set)
                return 0xFF;
 
-       if (!mtrr_state.enabled)
+       if (!(mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED))
                return 0xFF;
 
        /* Make end inclusive end, instead of exclusive */
        end--;
 
        /* Look in fixed ranges. Just return the type as per start */
-       if (mtrr_state.have_fixed && (start < 0x100000)) {
+       if ((start < 0x100000) &&
+           (mtrr_state.have_fixed) &&
+           (mtrr_state.enabled & MTRR_STATE_MTRR_FIXED_ENABLED)) {
                int idx;
 
                if (start < 0x80000) {
@@ -149,9 +151,6 @@ static u8 __mtrr_type_lookup(u64 start, u64 end, u64 *partial_end, int *repeat)
         * Look of multiple ranges matching this address and pick type
         * as per MTRR precedence
         */
-       if (!(mtrr_state.enabled & 2))
-               return mtrr_state.def_type;
-
        prev_match = 0xFF;
        for (i = 0; i < num_var_ranges; ++i) {
                unsigned short start_state, end_state, inclusive;
@@ -348,7 +347,9 @@ static void __init print_mtrr_state(void)
                 mtrr_attrib_to_str(mtrr_state.def_type));
        if (mtrr_state.have_fixed) {
                pr_debug("MTRR fixed ranges %sabled:\n",
-                        mtrr_state.enabled & 1 ? "en" : "dis");
+                       ((mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED) &&
+                        (mtrr_state.enabled & MTRR_STATE_MTRR_FIXED_ENABLED)) ?
+                        "en" : "dis");
                print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0);
                for (i = 0; i < 2; ++i)
                        print_fixed(0x80000 + i * 0x20000, 0x04000,
@@ -361,7 +362,7 @@ static void __init print_mtrr_state(void)
                print_fixed_last();
        }
        pr_debug("MTRR variable ranges %sabled:\n",
-                mtrr_state.enabled & 2 ? "en" : "dis");
+                mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED ? "en" : "dis");
        high_width = (__ffs64(size_or_mask) - (32 - PAGE_SHIFT) + 3) / 4;
 
        for (i = 0; i < num_var_ranges; ++i) {