36 #include <linux/types.h>
39 #include <linux/kvm_para.h>
41 #include <linux/module.h>
46 #include <linux/pci.h>
50 #include <asm/processor.h>
63 static bool mtrr_aps_delayed_init;
69 static void set_mtrr(
unsigned int reg,
unsigned long base,
75 mtrr_ops[ops->
vendor] = ops;
93 pr_info(
"mtrr: Serverworks LE rev < 6 detected. Write-combining disabled.\n");
103 pr_info(
"mtrr: Intel 450NX MMC detected. Write-combining disabled.\n");
113 static void __init set_num_var_ranges(
void)
132 for (i = 0; i <
max; i++)
150 static int mtrr_rendezvous_handler(
void *
info)
227 stop_machine(mtrr_rendezvous_handler, &data, cpu_online_mask);
230 static void set_mtrr_from_inactive_cpu(
unsigned int reg,
unsigned long base,
239 stop_machine_from_inactive_cpu(mtrr_rendezvous_handler, &data,
279 unsigned int type,
bool increment)
281 unsigned long lbase, lsize;
299 pr_warning(
"mtrr: your processor doesn't support write-combining\n");
309 pr_warning(
"mtrr: base or size exceeds the MTRR width\n");
322 mtrr_if->
get(i, &lbase, &lsize, <ype);
323 if (!lsize || base > lbase + lsize - 1 ||
324 base + size - 1 < lbase)
330 if (base < lbase || base + size - 1 > lbase + lsize - 1) {
332 base + size - 1 >= lbase + lsize - 1) {
335 replace = replace == -1 ? i : -2;
337 }
else if (types_compatible(type, ltype))
340 pr_warning(
"mtrr: 0x%lx000,0x%lx000 overlaps existing"
341 " 0x%lx000,0x%lx000\n", base, size, lbase,
347 if (types_compatible(type, ltype))
349 pr_warning(
"mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
363 if (
likely(replace < 0)) {
375 pr_info(
"mtrr: no more MTRRs available\n");
384 static int mtrr_check(
unsigned long base,
unsigned long size)
387 pr_warning(
"mtrr: size and base must be multiples of 4 kiB\n");
388 pr_debug(
"mtrr: size: 0x%lx base: 0x%lx\n", size, base);
430 int mtrr_add(
unsigned long base,
unsigned long size,
unsigned int type,
433 if (mtrr_check(base, size))
458 unsigned long lbase, lsize;
470 for (i = 0; i <
max; ++
i) {
471 mtrr_if->
get(i, &lbase, &lsize, <ype);
472 if (lbase == base && lsize == size) {
478 pr_debug(
"mtrr: no MTRR for %lx000,%lx000 found\n",
484 pr_warning(
"mtrr: register: %d too big\n", reg);
487 mtrr_if->
get(reg, &lbase, &lsize, <ype);
493 pr_warning(
"mtrr: reg: %d has count=0\n", reg);
521 if (mtrr_check(base, size))
532 static void __init init_ifs(
void)
534 #ifndef CONFIG_X86_64
552 static int mtrr_save(
void)
564 static void mtrr_restore(
void)
580 .suspend = mtrr_save,
581 .resume = mtrr_restore,
612 if (cpuid_eax(0x80000000) >= 0x80000008) {
613 phys_addr = cpuid_eax(0x80000008) & 0xff;
637 if (cpu_has_k6_mtrr) {
645 if (cpu_has_centaur_mcr) {
652 if (cpu_has_cyrix_arr) {
664 set_num_var_ranges();
670 changed_by_mtrr_cleanup = 1;
679 if (!
use_intel() || mtrr_aps_delayed_init)
694 set_mtrr_from_inactive_cpu(~0
U, 0, 0, 0);
710 mtrr_aps_delayed_init =
true;
726 if (!mtrr_aps_delayed_init)
730 mtrr_aps_delayed_init =
false;
741 static int __init mtrr_init_finialize(
void)
747 if (!changed_by_mtrr_cleanup)