LCOV - code coverage report
Current view: top level - arch/x86/kernel/cpu/mtrr - generic.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 206 389 53.0 %
Date: 2022-04-01 14:58:12 Functions: 19 28 67.9 %
Branches: 71 190 37.4 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  * This only handles 32bit MTRR on 32bit hosts. This is strictly wrong
       4                 :            :  * because MTRRs can span up to 40 bits (36bits on most modern x86)
       5                 :            :  */
       6                 :            : #define DEBUG
       7                 :            : 
       8                 :            : #include <linux/export.h>
       9                 :            : #include <linux/init.h>
      10                 :            : #include <linux/io.h>
      11                 :            : #include <linux/mm.h>
      12                 :            : 
      13                 :            : #include <asm/processor-flags.h>
      14                 :            : #include <asm/cpufeature.h>
      15                 :            : #include <asm/tlbflush.h>
      16                 :            : #include <asm/mtrr.h>
      17                 :            : #include <asm/msr.h>
      18                 :            : #include <asm/memtype.h>
      19                 :            : 
      20                 :            : #include "mtrr.h"
      21                 :            : 
      22                 :            : struct fixed_range_block {
      23                 :            :         int base_msr;           /* start address of an MTRR block */
      24                 :            :         int ranges;             /* number of MTRRs in this block  */
      25                 :            : };
      26                 :            : 
      27                 :            : static struct fixed_range_block fixed_range_blocks[] = {
      28                 :            :         { MSR_MTRRfix64K_00000, 1 }, /* one   64k MTRR  */
      29                 :            :         { MSR_MTRRfix16K_80000, 2 }, /* two   16k MTRRs */
      30                 :            :         { MSR_MTRRfix4K_C0000,  8 }, /* eight  4k MTRRs */
      31                 :            :         {}
      32                 :            : };
      33                 :            : 
      34                 :            : static unsigned long smp_changes_mask;
      35                 :            : static int mtrr_state_set;
      36                 :            : u64 mtrr_tom2;
      37                 :            : 
      38                 :            : struct mtrr_state_type mtrr_state;
      39                 :            : EXPORT_SYMBOL_GPL(mtrr_state);
      40                 :            : 
      41                 :            : /*
      42                 :            :  * BIOS is expected to clear MtrrFixDramModEn bit, see for example
      43                 :            :  * "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
      44                 :            :  * Opteron Processors" (26094 Rev. 3.30 February 2006), section
      45                 :            :  * "13.2.1.2 SYSCFG Register": "The MtrrFixDramModEn bit should be set
      46                 :            :  * to 1 during BIOS initialization of the fixed MTRRs, then cleared to
      47                 :            :  * 0 for operation."
      48                 :            :  */
      49                 :          6 : static inline void k8_check_syscfg_dram_mod_en(void)
      50                 :            : {
      51                 :          6 :         u32 lo, hi;
      52                 :            : 
      53         [ +  - ]:          6 :         if (!((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
      54         [ -  + ]:          6 :               (boot_cpu_data.x86 >= 0x0f)))
      55                 :            :                 return;
      56                 :            : 
      57                 :          0 :         rdmsr(MSR_K8_SYSCFG, lo, hi);
      58         [ #  # ]:          0 :         if (lo & K8_MTRRFIXRANGE_DRAM_MODIFY) {
      59                 :          0 :                 pr_err(FW_WARN "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]"
      60                 :            :                        " not cleared by BIOS, clearing this bit\n",
      61                 :            :                        smp_processor_id());
      62                 :          0 :                 lo &= ~K8_MTRRFIXRANGE_DRAM_MODIFY;
      63                 :          0 :                 mtrr_wrmsr(MSR_K8_SYSCFG, lo, hi);
      64                 :            :         }
      65                 :            : }
      66                 :            : 
      67                 :            : /* Get the size of contiguous MTRR range */
      68                 :          0 : static u64 get_mtrr_size(u64 mask)
      69                 :            : {
      70                 :          0 :         u64 size;
      71                 :            : 
      72                 :          0 :         mask >>= PAGE_SHIFT;
      73                 :          0 :         mask |= size_or_mask;
      74                 :          0 :         size = -mask;
      75                 :          0 :         size <<= PAGE_SHIFT;
      76                 :          0 :         return size;
      77                 :            : }
      78                 :            : 
      79                 :            : /*
      80                 :            :  * Check and return the effective type for MTRR-MTRR type overlap.
      81                 :            :  * Returns 1 if the effective type is UNCACHEABLE, else returns 0
      82                 :            :  */
      83                 :          0 : static int check_type_overlap(u8 *prev, u8 *curr)
      84                 :            : {
      85   [ #  #  #  # ]:          0 :         if (*prev == MTRR_TYPE_UNCACHABLE || *curr == MTRR_TYPE_UNCACHABLE) {
      86                 :          0 :                 *prev = MTRR_TYPE_UNCACHABLE;
      87                 :          0 :                 *curr = MTRR_TYPE_UNCACHABLE;
      88                 :          0 :                 return 1;
      89                 :            :         }
      90                 :            : 
      91   [ #  #  #  #  :          0 :         if ((*prev == MTRR_TYPE_WRBACK && *curr == MTRR_TYPE_WRTHROUGH) ||
                   #  # ]
      92         [ #  # ]:          0 :             (*prev == MTRR_TYPE_WRTHROUGH && *curr == MTRR_TYPE_WRBACK)) {
      93                 :          0 :                 *prev = MTRR_TYPE_WRTHROUGH;
      94                 :          0 :                 *curr = MTRR_TYPE_WRTHROUGH;
      95                 :            :         }
      96                 :            : 
      97         [ #  # ]:          0 :         if (*prev != *curr) {
      98                 :          0 :                 *prev = MTRR_TYPE_UNCACHABLE;
      99                 :          0 :                 *curr = MTRR_TYPE_UNCACHABLE;
     100                 :          0 :                 return 1;
     101                 :            :         }
     102                 :            : 
     103                 :            :         return 0;
     104                 :            : }
     105                 :            : 
     106                 :            : /**
     107                 :            :  * mtrr_type_lookup_fixed - look up memory type in MTRR fixed entries
     108                 :            :  *
     109                 :            :  * Return the MTRR fixed memory type of 'start'.
     110                 :            :  *
     111                 :            :  * MTRR fixed entries are divided into the following ways:
     112                 :            :  *  0x00000 - 0x7FFFF : This range is divided into eight 64KB sub-ranges
     113                 :            :  *  0x80000 - 0xBFFFF : This range is divided into sixteen 16KB sub-ranges
     114                 :            :  *  0xC0000 - 0xFFFFF : This range is divided into sixty-four 4KB sub-ranges
     115                 :            :  *
     116                 :            :  * Return Values:
     117                 :            :  * MTRR_TYPE_(type)  - Matched memory type
     118                 :            :  * MTRR_TYPE_INVALID - Unmatched
     119                 :            :  */
     120                 :          0 : static u8 mtrr_type_lookup_fixed(u64 start, u64 end)
     121                 :            : {
     122                 :          0 :         int idx;
     123                 :            : 
     124                 :          0 :         if (start >= 0x100000)
     125                 :            :                 return MTRR_TYPE_INVALID;
     126                 :            : 
     127                 :            :         /* 0x0 - 0x7FFFF */
     128                 :          0 :         if (start < 0x80000) {
     129                 :          0 :                 idx = 0;
     130                 :          0 :                 idx += (start >> 16);
     131                 :          0 :                 return mtrr_state.fixed_ranges[idx];
     132                 :            :         /* 0x80000 - 0xBFFFF */
     133         [ #  # ]:          0 :         } else if (start < 0xC0000) {
     134                 :          0 :                 idx = 1 * 8;
     135                 :          0 :                 idx += ((start - 0x80000) >> 14);
     136                 :          0 :                 return mtrr_state.fixed_ranges[idx];
     137                 :            :         }
     138                 :            : 
     139                 :            :         /* 0xC0000 - 0xFFFFF */
     140                 :          0 :         idx = 3 * 8;
     141                 :          0 :         idx += ((start - 0xC0000) >> 12);
     142                 :          0 :         return mtrr_state.fixed_ranges[idx];
     143                 :            : }
     144                 :            : 
     145                 :            : /**
     146                 :            :  * mtrr_type_lookup_variable - look up memory type in MTRR variable entries
     147                 :            :  *
     148                 :            :  * Return Value:
     149                 :            :  * MTRR_TYPE_(type) - Matched memory type or default memory type (unmatched)
     150                 :            :  *
     151                 :            :  * Output Arguments:
     152                 :            :  * repeat - Set to 1 when [start:end] spanned across MTRR range and type
     153                 :            :  *          returned corresponds only to [start:*partial_end].  Caller has
     154                 :            :  *          to lookup again for [*partial_end:end].
     155                 :            :  *
     156                 :            :  * uniform - Set to 1 when an MTRR covers the region uniformly, i.e. the
     157                 :            :  *           region is fully covered by a single MTRR entry or the default
     158                 :            :  *           type.
     159                 :            :  */
     160                 :        219 : static u8 mtrr_type_lookup_variable(u64 start, u64 end, u64 *partial_end,
     161                 :            :                                     int *repeat, u8 *uniform)
     162                 :            : {
     163                 :        219 :         int i;
     164                 :        219 :         u64 base, mask;
     165                 :        219 :         u8 prev_match, curr_match;
     166                 :            : 
     167                 :        219 :         *repeat = 0;
     168                 :        219 :         *uniform = 1;
     169                 :            : 
     170                 :            :         /* Make end inclusive instead of exclusive */
     171                 :        219 :         end--;
     172                 :            : 
     173                 :        219 :         prev_match = MTRR_TYPE_INVALID;
     174         [ +  + ]:       1971 :         for (i = 0; i < num_var_ranges; ++i) {
     175                 :       1752 :                 unsigned short start_state, end_state, inclusive;
     176                 :            : 
     177         [ +  + ]:       1752 :                 if (!(mtrr_state.var_ranges[i].mask_lo & (1 << 11)))
     178                 :       1533 :                         continue;
     179                 :            : 
     180                 :        219 :                 base = (((u64)mtrr_state.var_ranges[i].base_hi) << 32) +
     181                 :        219 :                        (mtrr_state.var_ranges[i].base_lo & PAGE_MASK);
     182                 :        219 :                 mask = (((u64)mtrr_state.var_ranges[i].mask_hi) << 32) +
     183                 :        219 :                        (mtrr_state.var_ranges[i].mask_lo & PAGE_MASK);
     184                 :            : 
     185                 :        219 :                 start_state = ((start & mask) == (base & mask));
     186                 :        219 :                 end_state = ((end & mask) == (base & mask));
     187                 :        219 :                 inclusive = ((start < base) && (end > base));
     188                 :            : 
     189         [ -  + ]:        219 :                 if ((start_state != end_state) || inclusive) {
     190                 :            :                         /*
     191                 :            :                          * We have start:end spanning across an MTRR.
     192                 :            :                          * We split the region into either
     193                 :            :                          *
     194                 :            :                          * - start_state:1
     195                 :            :                          * (start:mtrr_end)(mtrr_end:end)
     196                 :            :                          * - end_state:1
     197                 :            :                          * (start:mtrr_start)(mtrr_start:end)
     198                 :            :                          * - inclusive:1
     199                 :            :                          * (start:mtrr_start)(mtrr_start:mtrr_end)(mtrr_end:end)
     200                 :            :                          *
     201                 :            :                          * depending on kind of overlap.
     202                 :            :                          *
     203                 :            :                          * Return the type of the first region and a pointer
     204                 :            :                          * to the start of next region so that caller will be
     205                 :            :                          * advised to lookup again after having adjusted start
     206                 :            :                          * and end.
     207                 :            :                          *
     208                 :            :                          * Note: This way we handle overlaps with multiple
     209                 :            :                          * entries and the default type properly.
     210                 :            :                          */
     211         [ #  # ]:          0 :                         if (start_state)
     212                 :          0 :                                 *partial_end = base + get_mtrr_size(mask);
     213                 :            :                         else
     214                 :          0 :                                 *partial_end = base;
     215                 :            : 
     216         [ #  # ]:          0 :                         if (unlikely(*partial_end <= start)) {
     217                 :          0 :                                 WARN_ON(1);
     218                 :          0 :                                 *partial_end = start + PAGE_SIZE;
     219                 :            :                         }
     220                 :            : 
     221                 :          0 :                         end = *partial_end - 1; /* end is inclusive */
     222                 :          0 :                         *repeat = 1;
     223                 :          0 :                         *uniform = 0;
     224                 :            :                 }
     225                 :            : 
     226         [ +  + ]:        219 :                 if ((start & mask) != (base & mask))
     227                 :        216 :                         continue;
     228                 :            : 
     229                 :          3 :                 curr_match = mtrr_state.var_ranges[i].base_lo & 0xff;
     230         [ +  - ]:          3 :                 if (prev_match == MTRR_TYPE_INVALID) {
     231                 :          3 :                         prev_match = curr_match;
     232                 :          3 :                         continue;
     233                 :            :                 }
     234                 :            : 
     235                 :          0 :                 *uniform = 0;
     236         [ #  # ]:          0 :                 if (check_type_overlap(&prev_match, &curr_match))
     237                 :          0 :                         return curr_match;
     238                 :            :         }
     239                 :            : 
     240         [ +  + ]:        219 :         if (prev_match != MTRR_TYPE_INVALID)
     241                 :            :                 return prev_match;
     242                 :            : 
     243                 :        216 :         return mtrr_state.def_type;
     244                 :            : }
     245                 :            : 
     246                 :            : /**
     247                 :            :  * mtrr_type_lookup - look up memory type in MTRR
     248                 :            :  *
     249                 :            :  * Return Values:
     250                 :            :  * MTRR_TYPE_(type)  - The effective MTRR type for the region
     251                 :            :  * MTRR_TYPE_INVALID - MTRR is disabled
     252                 :            :  *
     253                 :            :  * Output Argument:
     254                 :            :  * uniform - Set to 1 when an MTRR covers the region uniformly, i.e. the
     255                 :            :  *           region is fully covered by a single MTRR entry or the default
     256                 :            :  *           type.
     257                 :            :  */
     258                 :        219 : u8 mtrr_type_lookup(u64 start, u64 end, u8 *uniform)
     259                 :            : {
     260                 :        219 :         u8 type, prev_type, is_uniform = 1, dummy;
     261                 :        219 :         int repeat;
     262                 :        219 :         u64 partial_end;
     263                 :            : 
     264         [ +  - ]:        219 :         if (!mtrr_state_set)
     265                 :            :                 return MTRR_TYPE_INVALID;
     266                 :            : 
     267         [ +  - ]:        219 :         if (!(mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED))
     268                 :            :                 return MTRR_TYPE_INVALID;
     269                 :            : 
     270                 :            :         /*
     271                 :            :          * Look up the fixed ranges first, which take priority over
     272                 :            :          * the variable ranges.
     273                 :            :          */
     274         [ -  + ]:        219 :         if ((start < 0x100000) &&
     275   [ #  #  #  # ]:          0 :             (mtrr_state.have_fixed) &&
     276                 :            :             (mtrr_state.enabled & MTRR_STATE_MTRR_FIXED_ENABLED)) {
     277                 :          0 :                 is_uniform = 0;
     278         [ #  # ]:          0 :                 type = mtrr_type_lookup_fixed(start, end);
     279                 :          0 :                 goto out;
     280                 :            :         }
     281                 :            : 
     282                 :            :         /*
     283                 :            :          * Look up the variable ranges.  Look of multiple ranges matching
     284                 :            :          * this address and pick type as per MTRR precedence.
     285                 :            :          */
     286                 :        219 :         type = mtrr_type_lookup_variable(start, end, &partial_end,
     287                 :            :                                          &repeat, &is_uniform);
     288                 :            : 
     289                 :            :         /*
     290                 :            :          * Common path is with repeat = 0.
     291                 :            :          * However, we can have cases where [start:end] spans across some
     292                 :            :          * MTRR ranges and/or the default type.  Do repeated lookups for
     293                 :            :          * that case here.
     294                 :            :          */
     295         [ -  + ]:        219 :         while (repeat) {
     296                 :          0 :                 prev_type = type;
     297                 :          0 :                 start = partial_end;
     298                 :          0 :                 is_uniform = 0;
     299                 :          0 :                 type = mtrr_type_lookup_variable(start, end, &partial_end,
     300                 :            :                                                  &repeat, &dummy);
     301                 :            : 
     302         [ #  # ]:          0 :                 if (check_type_overlap(&prev_type, &type))
     303                 :          0 :                         goto out;
     304                 :            :         }
     305                 :            : 
     306   [ +  -  -  -  :        219 :         if (mtrr_tom2 && (start >= (1ULL<<32)) && (end < mtrr_tom2))
                   -  - ]
     307                 :          0 :                 type = MTRR_TYPE_WRBACK;
     308                 :            : 
     309                 :        219 : out:
     310                 :        219 :         *uniform = is_uniform;
     311                 :        219 :         return type;
     312                 :            : }
     313                 :            : 
     314                 :            : /* Get the MSR pair relating to a var range */
     315                 :            : static void
     316                 :         24 : get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr)
     317                 :            : {
     318                 :         24 :         rdmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi);
     319                 :         24 :         rdmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
     320                 :         24 : }
     321                 :            : 
     322                 :            : /* Fill the MSR pair relating to a var range */
     323                 :          0 : void fill_mtrr_var_range(unsigned int index,
     324                 :            :                 u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi)
     325                 :            : {
     326                 :          0 :         struct mtrr_var_range *vr;
     327                 :            : 
     328                 :          0 :         vr = mtrr_state.var_ranges;
     329                 :            : 
     330                 :          0 :         vr[index].base_lo = base_lo;
     331                 :          0 :         vr[index].base_hi = base_hi;
     332                 :          0 :         vr[index].mask_lo = mask_lo;
     333                 :          0 :         vr[index].mask_hi = mask_hi;
     334                 :          0 : }
     335                 :            : 
     336                 :          3 : static void get_fixed_ranges(mtrr_type *frs)
     337                 :            : {
     338                 :          3 :         unsigned int *p = (unsigned int *)frs;
     339                 :          3 :         int i;
     340                 :            : 
     341                 :          3 :         k8_check_syscfg_dram_mod_en();
     342                 :            : 
     343                 :          3 :         rdmsr(MSR_MTRRfix64K_00000, p[0], p[1]);
     344                 :            : 
     345         [ +  + ]:          9 :         for (i = 0; i < 2; i++)
     346                 :          6 :                 rdmsr(MSR_MTRRfix16K_80000 + i, p[2 + i * 2], p[3 + i * 2]);
     347         [ +  + ]:         27 :         for (i = 0; i < 8; i++)
     348                 :         24 :                 rdmsr(MSR_MTRRfix4K_C0000 + i, p[6 + i * 2], p[7 + i * 2]);
     349                 :          3 : }
     350                 :            : 
     351                 :          0 : void mtrr_save_fixed_ranges(void *info)
     352                 :            : {
     353         [ #  # ]:          0 :         if (boot_cpu_has(X86_FEATURE_MTRR))
     354                 :          0 :                 get_fixed_ranges(mtrr_state.fixed_ranges);
     355                 :          0 : }
     356                 :            : 
     357                 :            : static unsigned __initdata last_fixed_start;
     358                 :            : static unsigned __initdata last_fixed_end;
     359                 :            : static mtrr_type __initdata last_fixed_type;
     360                 :            : 
     361                 :          9 : static void __init print_fixed_last(void)
     362                 :            : {
     363         [ +  - ]:          9 :         if (!last_fixed_end)
     364                 :            :                 return;
     365                 :            : 
     366                 :          9 :         pr_debug("  %05X-%05X %s\n", last_fixed_start,
     367                 :            :                  last_fixed_end - 1, mtrr_attrib_to_str(last_fixed_type));
     368                 :            : 
     369                 :          9 :         last_fixed_end = 0;
     370                 :            : }
     371                 :            : 
     372                 :          9 : static void __init update_fixed_last(unsigned base, unsigned end,
     373                 :            :                                      mtrr_type type)
     374                 :            : {
     375                 :          9 :         last_fixed_start = base;
     376                 :          9 :         last_fixed_end = end;
     377                 :          9 :         last_fixed_type = type;
     378                 :          6 : }
     379                 :            : 
     380                 :            : static void __init
     381                 :         33 : print_fixed(unsigned base, unsigned step, const mtrr_type *types)
     382                 :            : {
     383                 :         33 :         unsigned i;
     384                 :            : 
     385         [ +  + ]:        297 :         for (i = 0; i < 8; ++i, ++types, base += step) {
     386         [ +  + ]:        264 :                 if (last_fixed_end == 0) {
     387                 :          3 :                         update_fixed_last(base, base + step, *types);
     388                 :          3 :                         continue;
     389                 :            :                 }
     390   [ +  -  +  + ]:        261 :                 if (last_fixed_end == base && last_fixed_type == *types) {
     391                 :        255 :                         last_fixed_end = base + step;
     392                 :        255 :                         continue;
     393                 :            :                 }
     394                 :            :                 /* new segments: gap or different type */
     395                 :          6 :                 print_fixed_last();
     396                 :          6 :                 update_fixed_last(base, base + step, *types);
     397                 :            :         }
     398                 :         33 : }
     399                 :            : 
     400                 :            : static void prepare_set(void);
     401                 :            : static void post_set(void);
     402                 :            : 
     403                 :          3 : static void __init print_mtrr_state(void)
     404                 :            : {
     405                 :          3 :         unsigned int i;
     406                 :          3 :         int high_width;
     407                 :            : 
     408                 :          3 :         pr_debug("MTRR default type: %s\n",
     409                 :            :                  mtrr_attrib_to_str(mtrr_state.def_type));
     410         [ +  - ]:          3 :         if (mtrr_state.have_fixed) {
     411         [ -  + ]:          3 :                 pr_debug("MTRR fixed ranges %sabled:\n",
     412                 :            :                         ((mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED) &&
     413                 :            :                          (mtrr_state.enabled & MTRR_STATE_MTRR_FIXED_ENABLED)) ?
     414                 :            :                          "en" : "dis");
     415                 :          3 :                 print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0);
     416         [ +  + ]:         12 :                 for (i = 0; i < 2; ++i)
     417                 :          6 :                         print_fixed(0x80000 + i * 0x20000, 0x04000,
     418                 :          6 :                                     mtrr_state.fixed_ranges + (i + 1) * 8);
     419         [ +  + ]:         27 :                 for (i = 0; i < 8; ++i)
     420                 :         24 :                         print_fixed(0xC0000 + i * 0x08000, 0x01000,
     421                 :         24 :                                     mtrr_state.fixed_ranges + (i + 3) * 8);
     422                 :            : 
     423                 :            :                 /* tail */
     424                 :          3 :                 print_fixed_last();
     425                 :            :         }
     426         [ -  + ]:          3 :         pr_debug("MTRR variable ranges %sabled:\n",
     427                 :            :                  mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED ? "en" : "dis");
     428                 :          3 :         high_width = (__ffs64(size_or_mask) - (32 - PAGE_SHIFT) + 3) / 4;
     429                 :            : 
     430         [ +  + ]:         27 :         for (i = 0; i < num_var_ranges; ++i) {
     431         [ +  + ]:         24 :                 if (mtrr_state.var_ranges[i].mask_lo & (1 << 11))
     432                 :          3 :                         pr_debug("  %u base %0*X%05X000 mask %0*X%05X000 %s\n",
     433                 :            :                                  i,
     434                 :            :                                  high_width,
     435                 :            :                                  mtrr_state.var_ranges[i].base_hi,
     436                 :            :                                  mtrr_state.var_ranges[i].base_lo >> 12,
     437                 :            :                                  high_width,
     438                 :            :                                  mtrr_state.var_ranges[i].mask_hi,
     439                 :            :                                  mtrr_state.var_ranges[i].mask_lo >> 12,
     440                 :            :                                  mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff));
     441                 :            :                 else
     442                 :         21 :                         pr_debug("  %u disabled\n", i);
     443                 :            :         }
     444         [ -  + ]:          3 :         if (mtrr_tom2)
     445                 :          0 :                 pr_debug("TOM2: %016llx aka %lldM\n", mtrr_tom2, mtrr_tom2>>20);
     446                 :          3 : }
     447                 :            : 
     448                 :            : /* PAT setup for BP. We need to go through sync steps here */
     449                 :          3 : void __init mtrr_bp_pat_init(void)
     450                 :            : {
     451                 :          3 :         unsigned long flags;
     452                 :            : 
     453                 :          3 :         local_irq_save(flags);
     454                 :          3 :         prepare_set();
     455                 :            : 
     456                 :          3 :         pat_init();
     457                 :            : 
     458                 :          3 :         post_set();
     459                 :          3 :         local_irq_restore(flags);
     460                 :          3 : }
     461                 :            : 
     462                 :            : /* Grab all of the MTRR state for this CPU into *state */
     463                 :          3 : bool __init get_mtrr_state(void)
     464                 :            : {
     465                 :          3 :         struct mtrr_var_range *vrs;
     466                 :          3 :         unsigned lo, dummy;
     467                 :          3 :         unsigned int i;
     468                 :            : 
     469                 :          3 :         vrs = mtrr_state.var_ranges;
     470                 :            : 
     471                 :          3 :         rdmsr(MSR_MTRRcap, lo, dummy);
     472                 :          3 :         mtrr_state.have_fixed = (lo >> 8) & 1;
     473                 :            : 
     474         [ +  + ]:         27 :         for (i = 0; i < num_var_ranges; i++)
     475                 :         24 :                 get_mtrr_var_range(i, &vrs[i]);
     476         [ +  - ]:          3 :         if (mtrr_state.have_fixed)
     477                 :          3 :                 get_fixed_ranges(mtrr_state.fixed_ranges);
     478                 :            : 
     479                 :          3 :         rdmsr(MSR_MTRRdefType, lo, dummy);
     480                 :          3 :         mtrr_state.def_type = (lo & 0xff);
     481                 :          3 :         mtrr_state.enabled = (lo & 0xc00) >> 10;
     482                 :            : 
     483         [ -  + ]:          3 :         if (amd_special_default_mtrr()) {
     484                 :          0 :                 unsigned low, high;
     485                 :            : 
     486                 :            :                 /* TOP_MEM2 */
     487                 :          0 :                 rdmsr(MSR_K8_TOP_MEM2, low, high);
     488                 :          0 :                 mtrr_tom2 = high;
     489                 :          0 :                 mtrr_tom2 <<= 32;
     490                 :          0 :                 mtrr_tom2 |= low;
     491                 :          0 :                 mtrr_tom2 &= 0xffffff800000ULL;
     492                 :            :         }
     493                 :            : 
     494                 :          3 :         print_mtrr_state();
     495                 :            : 
     496                 :          3 :         mtrr_state_set = 1;
     497                 :            : 
     498                 :          3 :         return !!(mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED);
     499                 :            : }
     500                 :            : 
     501                 :            : /* Some BIOS's are messed up and don't set all MTRRs the same! */
     502                 :          3 : void __init mtrr_state_warn(void)
     503                 :            : {
     504                 :          3 :         unsigned long mask = smp_changes_mask;
     505                 :            : 
     506         [ -  + ]:          3 :         if (!mask)
     507                 :            :                 return;
     508         [ #  # ]:          0 :         if (mask & MTRR_CHANGE_MASK_FIXED)
     509                 :          0 :                 pr_warn("mtrr: your CPUs had inconsistent fixed MTRR settings\n");
     510         [ #  # ]:          0 :         if (mask & MTRR_CHANGE_MASK_VARIABLE)
     511                 :          0 :                 pr_warn("mtrr: your CPUs had inconsistent variable MTRR settings\n");
     512         [ #  # ]:          0 :         if (mask & MTRR_CHANGE_MASK_DEFTYPE)
     513                 :          0 :                 pr_warn("mtrr: your CPUs had inconsistent MTRRdefType settings\n");
     514                 :            : 
     515                 :          0 :         pr_info("mtrr: probably your BIOS does not setup all CPUs.\n");
     516                 :          0 :         pr_info("mtrr: corrected configuration.\n");
     517                 :            : }
     518                 :            : 
     519                 :            : /*
     520                 :            :  * Doesn't attempt to pass an error out to MTRR users
     521                 :            :  * because it's quite complicated in some cases and probably not
     522                 :            :  * worth it because the best error handling is to ignore it.
     523                 :            :  */
     524                 :         12 : void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b)
     525                 :            : {
     526         [ -  + ]:         12 :         if (wrmsr_safe(msr, a, b) < 0) {
     527                 :          0 :                 pr_err("MTRR: CPU %u: Writing MSR %x to %x:%x failed\n",
     528                 :            :                         smp_processor_id(), msr, a, b);
     529                 :            :         }
     530                 :         12 : }
     531                 :            : 
     532                 :            : /**
     533                 :            :  * set_fixed_range - checks & updates a fixed-range MTRR if it
     534                 :            :  *                   differs from the value it should have
     535                 :            :  * @msr: MSR address of the MTTR which should be checked and updated
     536                 :            :  * @changed: pointer which indicates whether the MTRR needed to be changed
     537                 :            :  * @msrwords: pointer to the MSR values which the MSR should have
     538                 :            :  */
     539                 :         33 : static void set_fixed_range(int msr, bool *changed, unsigned int *msrwords)
     540                 :            : {
     541                 :         33 :         unsigned lo, hi;
     542                 :            : 
     543                 :         33 :         rdmsr(msr, lo, hi);
     544                 :            : 
     545   [ +  -  -  + ]:         33 :         if (lo != msrwords[0] || hi != msrwords[1]) {
     546                 :          0 :                 mtrr_wrmsr(msr, msrwords[0], msrwords[1]);
     547                 :          0 :                 *changed = true;
     548                 :            :         }
     549                 :         33 : }
     550                 :            : 
     551                 :            : /**
     552                 :            :  * generic_get_free_region - Get a free MTRR.
     553                 :            :  * @base: The starting (base) address of the region.
     554                 :            :  * @size: The size (in bytes) of the region.
     555                 :            :  * @replace_reg: mtrr index to be replaced; set to invalid value if none.
     556                 :            :  *
     557                 :            :  * Returns: The index of the region on success, else negative on error.
     558                 :            :  */
     559                 :            : int
     560                 :          0 : generic_get_free_region(unsigned long base, unsigned long size, int replace_reg)
     561                 :            : {
     562                 :          0 :         unsigned long lbase, lsize;
     563                 :          0 :         mtrr_type ltype;
     564                 :          0 :         int i, max;
     565                 :            : 
     566                 :          0 :         max = num_var_ranges;
     567         [ #  # ]:          0 :         if (replace_reg >= 0 && replace_reg < max)
     568                 :            :                 return replace_reg;
     569                 :            : 
     570         [ #  # ]:          0 :         for (i = 0; i < max; ++i) {
     571                 :          0 :                 mtrr_if->get(i, &lbase, &lsize, &ltype);
     572         [ #  # ]:          0 :                 if (lsize == 0)
     573                 :          0 :                         return i;
     574                 :            :         }
     575                 :            : 
     576                 :            :         return -ENOSPC;
     577                 :            : }
     578                 :            : 
     579                 :          0 : static void generic_get_mtrr(unsigned int reg, unsigned long *base,
     580                 :            :                              unsigned long *size, mtrr_type *type)
     581                 :            : {
     582                 :          0 :         u32 mask_lo, mask_hi, base_lo, base_hi;
     583                 :          0 :         unsigned int hi;
     584                 :          0 :         u64 tmp, mask;
     585                 :            : 
     586                 :            :         /*
     587                 :            :          * get_mtrr doesn't need to update mtrr_state, also it could be called
     588                 :            :          * from any cpu, so try to print it out directly.
     589                 :            :          */
     590                 :          0 :         get_cpu();
     591                 :            : 
     592                 :          0 :         rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi);
     593                 :            : 
     594         [ #  # ]:          0 :         if ((mask_lo & 0x800) == 0) {
     595                 :            :                 /*  Invalid (i.e. free) range */
     596                 :          0 :                 *base = 0;
     597                 :          0 :                 *size = 0;
     598                 :          0 :                 *type = 0;
     599                 :          0 :                 goto out_put_cpu;
     600                 :            :         }
     601                 :            : 
     602                 :          0 :         rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi);
     603                 :            : 
     604                 :            :         /* Work out the shifted address mask: */
     605                 :          0 :         tmp = (u64)mask_hi << (32 - PAGE_SHIFT) | mask_lo >> PAGE_SHIFT;
     606                 :          0 :         mask = size_or_mask | tmp;
     607                 :            : 
     608                 :            :         /* Expand tmp with high bits to all 1s: */
     609         [ #  # ]:          0 :         hi = fls64(tmp);
     610         [ #  # ]:          0 :         if (hi > 0) {
     611                 :          0 :                 tmp |= ~((1ULL<<(hi - 1)) - 1);
     612                 :            : 
     613         [ #  # ]:          0 :                 if (tmp != mask) {
     614                 :          0 :                         pr_warn("mtrr: your BIOS has configured an incorrect mask, fixing it.\n");
     615                 :          0 :                         add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
     616                 :          0 :                         mask = tmp;
     617                 :            :                 }
     618                 :            :         }
     619                 :            : 
     620                 :            :         /*
     621                 :            :          * This works correctly if size is a power of two, i.e. a
     622                 :            :          * contiguous range:
     623                 :            :          */
     624                 :          0 :         *size = -mask;
     625                 :          0 :         *base = (u64)base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT;
     626                 :          0 :         *type = base_lo & 0xff;
     627                 :            : 
     628                 :          0 : out_put_cpu:
     629                 :          0 :         put_cpu();
     630                 :          0 : }
     631                 :            : 
     632                 :            : /**
     633                 :            :  * set_fixed_ranges - checks & updates the fixed-range MTRRs if they
     634                 :            :  *                    differ from the saved set
     635                 :            :  * @frs: pointer to fixed-range MTRR values, saved by get_fixed_ranges()
     636                 :            :  */
     637                 :          3 : static int set_fixed_ranges(mtrr_type *frs)
     638                 :            : {
     639                 :          3 :         unsigned long long *saved = (unsigned long long *)frs;
     640                 :          3 :         bool changed = false;
     641                 :          3 :         int block = -1, range;
     642                 :            : 
     643                 :          3 :         k8_check_syscfg_dram_mod_en();
     644                 :            : 
     645         [ +  + ]:         12 :         while (fixed_range_blocks[++block].ranges) {
     646         [ +  + ]:         42 :                 for (range = 0; range < fixed_range_blocks[block].ranges; range++)
     647                 :         33 :                         set_fixed_range(fixed_range_blocks[block].base_msr + range,
     648                 :            :                                         &changed, (unsigned int *)saved++);
     649                 :            :         }
     650                 :            : 
     651                 :          3 :         return changed;
     652                 :            : }
     653                 :            : 
     654                 :            : /*
     655                 :            :  * Set the MSR pair relating to a var range.
     656                 :            :  * Returns true if changes are made.
     657                 :            :  */
     658                 :         24 : static bool set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr)
     659                 :            : {
     660                 :         24 :         unsigned int lo, hi;
     661                 :         24 :         bool changed = false;
     662                 :            : 
     663                 :         24 :         rdmsr(MTRRphysBase_MSR(index), lo, hi);
     664         [ +  - ]:         24 :         if ((vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL)
     665         [ -  + ]:         24 :             || (vr->base_hi & (size_and_mask >> (32 - PAGE_SHIFT))) !=
     666                 :            :                 (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) {
     667                 :            : 
     668                 :          0 :                 mtrr_wrmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi);
     669                 :          0 :                 changed = true;
     670                 :            :         }
     671                 :            : 
     672                 :         24 :         rdmsr(MTRRphysMask_MSR(index), lo, hi);
     673                 :            : 
     674         [ +  - ]:         24 :         if ((vr->mask_lo & 0xfffff800UL) != (lo & 0xfffff800UL)
     675         [ -  + ]:         24 :             || (vr->mask_hi & (size_and_mask >> (32 - PAGE_SHIFT))) !=
     676                 :            :                 (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) {
     677                 :          0 :                 mtrr_wrmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
     678                 :          0 :                 changed = true;
     679                 :            :         }
     680                 :         24 :         return changed;
     681                 :            : }
     682                 :            : 
     683                 :            : static u32 deftype_lo, deftype_hi;
     684                 :            : 
     685                 :            : /**
     686                 :            :  * set_mtrr_state - Set the MTRR state for this CPU.
     687                 :            :  *
     688                 :            :  * NOTE: The CPU must already be in a safe state for MTRR changes.
     689                 :            :  * RETURNS: 0 if no changes made, else a mask indicating what was changed.
     690                 :            :  */
     691                 :          3 : static unsigned long set_mtrr_state(void)
     692                 :            : {
     693                 :          3 :         unsigned long change_mask = 0;
     694                 :          3 :         unsigned int i;
     695                 :            : 
     696         [ +  + ]:         27 :         for (i = 0; i < num_var_ranges; i++) {
     697         [ -  + ]:         24 :                 if (set_mtrr_var_ranges(i, &mtrr_state.var_ranges[i]))
     698                 :          0 :                         change_mask |= MTRR_CHANGE_MASK_VARIABLE;
     699                 :            :         }
     700                 :            : 
     701   [ +  -  -  + ]:          3 :         if (mtrr_state.have_fixed && set_fixed_ranges(mtrr_state.fixed_ranges))
     702                 :          0 :                 change_mask |= MTRR_CHANGE_MASK_FIXED;
     703                 :            : 
     704                 :            :         /*
     705                 :            :          * Set_mtrr_restore restores the old value of MTRRdefType,
     706                 :            :          * so to set it we fiddle with the saved value:
     707                 :            :          */
     708         [ +  - ]:          3 :         if ((deftype_lo & 0xff) != mtrr_state.def_type
     709         [ -  + ]:          3 :             || ((deftype_lo & 0xc00) >> 10) != mtrr_state.enabled) {
     710                 :            : 
     711                 :          0 :                 deftype_lo = (deftype_lo & ~0xcff) | mtrr_state.def_type |
     712                 :          0 :                              (mtrr_state.enabled << 10);
     713                 :          0 :                 change_mask |= MTRR_CHANGE_MASK_DEFTYPE;
     714                 :            :         }
     715                 :            : 
     716                 :          3 :         return change_mask;
     717                 :            : }
     718                 :            : 
     719                 :            : 
     720                 :            : static unsigned long cr4;
     721                 :            : static DEFINE_RAW_SPINLOCK(set_atomicity_lock);
     722                 :            : 
     723                 :            : /*
     724                 :            :  * Since we are disabling the cache don't allow any interrupts,
     725                 :            :  * they would run extremely slow and would only increase the pain.
     726                 :            :  *
     727                 :            :  * The caller must ensure that local interrupts are disabled and
     728                 :            :  * are reenabled after post_set() has been called.
     729                 :            :  */
     730                 :          6 : static void prepare_set(void) __acquires(set_atomicity_lock)
     731                 :            : {
     732                 :          6 :         unsigned long cr0;
     733                 :            : 
     734                 :            :         /*
     735                 :            :          * Note that this is not ideal
     736                 :            :          * since the cache is only flushed/disabled for this CPU while the
     737                 :            :          * MTRRs are changed, but changing this requires more invasive
     738                 :            :          * changes to the way the kernel boots
     739                 :            :          */
     740                 :            : 
     741                 :          6 :         raw_spin_lock(&set_atomicity_lock);
     742                 :            : 
     743                 :            :         /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */
     744                 :          6 :         cr0 = read_cr0() | X86_CR0_CD;
     745                 :          6 :         write_cr0(cr0);
     746                 :            : 
     747                 :            :         /*
     748                 :            :          * Cache flushing is the most time-consuming step when programming
     749                 :            :          * the MTRRs. Fortunately, as per the Intel Software Development
     750                 :            :          * Manual, we can skip it if the processor supports cache self-
     751                 :            :          * snooping.
     752                 :            :          */
     753      [ -  +  - ]:          6 :         if (!static_cpu_has(X86_FEATURE_SELFSNOOP))
     754                 :          6 :                 wbinvd();
     755                 :            : 
     756                 :            :         /* Save value of CR4 and clear Page Global Enable (bit 7) */
     757         [ +  - ]:          6 :         if (boot_cpu_has(X86_FEATURE_PGE)) {
     758                 :          6 :                 cr4 = __read_cr4();
     759                 :          6 :                 __write_cr4(cr4 & ~X86_CR4_PGE);
     760                 :            :         }
     761                 :            : 
     762                 :            :         /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */
     763                 :          6 :         count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
     764                 :          6 :         __flush_tlb();
     765                 :            : 
     766                 :            :         /* Save MTRR state */
     767                 :          6 :         rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi);
     768                 :            : 
     769                 :            :         /* Disable MTRRs, and set the default type to uncached */
     770                 :          6 :         mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi);
     771                 :            : 
     772                 :            :         /* Again, only flush caches if we have to. */
     773      [ -  +  - ]:          6 :         if (!static_cpu_has(X86_FEATURE_SELFSNOOP))
     774                 :          6 :                 wbinvd();
     775                 :          6 : }
     776                 :            : 
     777                 :          6 : static void post_set(void) __releases(set_atomicity_lock)
     778                 :            : {
     779                 :            :         /* Flush TLBs (no need to flush caches - they are disabled) */
     780                 :          6 :         count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
     781                 :          6 :         __flush_tlb();
     782                 :            : 
     783                 :            :         /* Intel (P6) standard MTRRs */
     784                 :          6 :         mtrr_wrmsr(MSR_MTRRdefType, deftype_lo, deftype_hi);
     785                 :            : 
     786                 :            :         /* Enable caches */
     787                 :          6 :         write_cr0(read_cr0() & ~X86_CR0_CD);
     788                 :            : 
     789                 :            :         /* Restore value of CR4 */
     790         [ +  - ]:          6 :         if (boot_cpu_has(X86_FEATURE_PGE))
     791                 :          6 :                 __write_cr4(cr4);
     792                 :          6 :         raw_spin_unlock(&set_atomicity_lock);
     793                 :          6 : }
     794                 :            : 
     795                 :          3 : static void generic_set_all(void)
     796                 :            : {
     797                 :          3 :         unsigned long mask, count;
     798                 :          3 :         unsigned long flags;
     799                 :            : 
     800                 :          3 :         local_irq_save(flags);
     801                 :          3 :         prepare_set();
     802                 :            : 
     803                 :            :         /* Actually set the state */
     804                 :          3 :         mask = set_mtrr_state();
     805                 :            : 
     806                 :            :         /* also set PAT */
     807                 :          3 :         pat_init();
     808                 :            : 
     809                 :          3 :         post_set();
     810                 :          3 :         local_irq_restore(flags);
     811                 :            : 
     812                 :            :         /* Use the atomic bitops to update the global mask */
     813         [ +  + ]:        198 :         for (count = 0; count < sizeof(mask) * 8; ++count) {
     814         [ -  + ]:        192 :                 if (mask & 0x01)
     815                 :          0 :                         set_bit(count, &smp_changes_mask);
     816                 :        192 :                 mask >>= 1;
     817                 :            :         }
     818                 :            : 
     819                 :          3 : }
     820                 :            : 
     821                 :            : /**
     822                 :            :  * generic_set_mtrr - set variable MTRR register on the local CPU.
     823                 :            :  *
     824                 :            :  * @reg: The register to set.
     825                 :            :  * @base: The base address of the region.
     826                 :            :  * @size: The size of the region. If this is 0 the region is disabled.
     827                 :            :  * @type: The type of the region.
     828                 :            :  *
     829                 :            :  * Returns nothing.
     830                 :            :  */
     831                 :          0 : static void generic_set_mtrr(unsigned int reg, unsigned long base,
     832                 :            :                              unsigned long size, mtrr_type type)
     833                 :            : {
     834                 :          0 :         unsigned long flags;
     835                 :          0 :         struct mtrr_var_range *vr;
     836                 :            : 
     837                 :          0 :         vr = &mtrr_state.var_ranges[reg];
     838                 :            : 
     839                 :          0 :         local_irq_save(flags);
     840                 :          0 :         prepare_set();
     841                 :            : 
     842         [ #  # ]:          0 :         if (size == 0) {
     843                 :            :                 /*
     844                 :            :                  * The invalid bit is kept in the mask, so we simply
     845                 :            :                  * clear the relevant mask register to disable a range.
     846                 :            :                  */
     847                 :          0 :                 mtrr_wrmsr(MTRRphysMask_MSR(reg), 0, 0);
     848                 :          0 :                 memset(vr, 0, sizeof(struct mtrr_var_range));
     849                 :            :         } else {
     850                 :          0 :                 vr->base_lo = base << PAGE_SHIFT | type;
     851                 :          0 :                 vr->base_hi = (base & size_and_mask) >> (32 - PAGE_SHIFT);
     852                 :          0 :                 vr->mask_lo = -size << PAGE_SHIFT | 0x800;
     853                 :          0 :                 vr->mask_hi = (-size & size_and_mask) >> (32 - PAGE_SHIFT);
     854                 :            : 
     855                 :          0 :                 mtrr_wrmsr(MTRRphysBase_MSR(reg), vr->base_lo, vr->base_hi);
     856                 :          0 :                 mtrr_wrmsr(MTRRphysMask_MSR(reg), vr->mask_lo, vr->mask_hi);
     857                 :            :         }
     858                 :            : 
     859                 :          0 :         post_set();
     860                 :          0 :         local_irq_restore(flags);
     861                 :          0 : }
     862                 :            : 
     863                 :          0 : int generic_validate_add_page(unsigned long base, unsigned long size,
     864                 :            :                               unsigned int type)
     865                 :            : {
     866                 :          0 :         unsigned long lbase, last;
     867                 :            : 
     868                 :            :         /*
     869                 :            :          * For Intel PPro stepping <= 7
     870                 :            :          * must be 4 MiB aligned and not touch 0x70000000 -> 0x7003FFFF
     871                 :            :          */
     872   [ #  #  #  #  :          0 :         if (is_cpu(INTEL) && boot_cpu_data.x86 == 6 &&
                   #  # ]
     873                 :          0 :             boot_cpu_data.x86_model == 1 &&
     874         [ #  # ]:          0 :             boot_cpu_data.x86_stepping <= 7) {
     875         [ #  # ]:          0 :                 if (base & ((1 << (22 - PAGE_SHIFT)) - 1)) {
     876                 :          0 :                         pr_warn("mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
     877                 :          0 :                         return -EINVAL;
     878                 :            :                 }
     879   [ #  #  #  # ]:          0 :                 if (!(base + size < 0x70000 || base > 0x7003F) &&
     880                 :          0 :                     (type == MTRR_TYPE_WRCOMB
     881         [ #  # ]:          0 :                      || type == MTRR_TYPE_WRBACK)) {
     882                 :          0 :                         pr_warn("mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n");
     883                 :          0 :                         return -EINVAL;
     884                 :            :                 }
     885                 :            :         }
     886                 :            : 
     887                 :            :         /*
     888                 :            :          * Check upper bits of base and last are equal and lower bits are 0
     889                 :            :          * for base and 1 for last
     890                 :            :          */
     891                 :          0 :         last = base + size - 1;
     892   [ #  #  #  # ]:          0 :         for (lbase = base; !(lbase & 1) && (last & 1);
     893                 :          0 :              lbase = lbase >> 1, last = last >> 1)
     894                 :          0 :                 ;
     895         [ #  # ]:          0 :         if (lbase != last) {
     896                 :          0 :                 pr_warn("mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n", base, size);
     897                 :          0 :                 return -EINVAL;
     898                 :            :         }
     899                 :            :         return 0;
     900                 :            : }
     901                 :            : 
     902                 :          0 : static int generic_have_wrcomb(void)
     903                 :            : {
     904                 :          0 :         unsigned long config, dummy;
     905                 :          0 :         rdmsr(MSR_MTRRcap, config, dummy);
     906                 :          0 :         return config & (1 << 10);
     907                 :            : }
     908                 :            : 
     909                 :          0 : int positive_have_wrcomb(void)
     910                 :            : {
     911                 :          0 :         return 1;
     912                 :            : }
     913                 :            : 
     914                 :            : /*
     915                 :            :  * Generic structure...
     916                 :            :  */
     917                 :            : const struct mtrr_ops generic_mtrr_ops = {
     918                 :            :         .use_intel_if           = 1,
     919                 :            :         .set_all                = generic_set_all,
     920                 :            :         .get                    = generic_get_mtrr,
     921                 :            :         .get_free_region        = generic_get_free_region,
     922                 :            :         .set                    = generic_set_mtrr,
     923                 :            :         .validate_add_page      = generic_validate_add_page,
     924                 :            :         .have_wrcomb            = generic_have_wrcomb,
     925                 :            : };

Generated by: LCOV version 1.14