};
static unsigned long smp_changes_mask;
-struct mtrr_state mtrr_state = {};
-
+static struct mtrr_state mtrr_state = {};
/* Get the MSR pair relating to a var range */
static void __init
printk(KERN_INFO "mtrr: corrected configuration.\n");
}
+/* Doesn't attempt to pass an error out to MTRR users
+ because it's quite complicated in some cases and probably not
+ worth it because the best error handling is to ignore it. */
+void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b)
+{
+ if (wrmsr_safe(msr, a, b) < 0)
+ printk(KERN_ERR
+ "MTRR: CPU %u: Writing MSR %x to %x:%x failed\n",
+ smp_processor_id(), msr, a, b);
+}
int generic_get_free_region(unsigned long base, unsigned long size)
/* [SUMMARY] Get a free MTRR.
return -ENOSPC;
}
-void generic_get_mtrr(unsigned int reg, unsigned long *base,
- unsigned int *size, mtrr_type * type)
+static void generic_get_mtrr(unsigned int reg, unsigned long *base,
+ unsigned int *size, mtrr_type * type)
{
unsigned int mask_lo, mask_hi, base_lo, base_hi;
rdmsr(MTRRfix64K_00000_MSR, lo, hi);
if (p[0] != lo || p[1] != hi) {
- wrmsr(MTRRfix64K_00000_MSR, p[0], p[1]);
+ mtrr_wrmsr(MTRRfix64K_00000_MSR, p[0], p[1]);
changed = TRUE;
}
for (i = 0; i < 2; i++) {
rdmsr(MTRRfix16K_80000_MSR + i, lo, hi);
if (p[2 + i * 2] != lo || p[3 + i * 2] != hi) {
- wrmsr(MTRRfix16K_80000_MSR + i, p[2 + i * 2],
+ mtrr_wrmsr(MTRRfix16K_80000_MSR + i, p[2 + i * 2],
p[3 + i * 2]);
changed = TRUE;
}
for (i = 0; i < 8; i++) {
rdmsr(MTRRfix4K_C0000_MSR + i, lo, hi);
if (p[6 + i * 2] != lo || p[7 + i * 2] != hi) {
- wrmsr(MTRRfix4K_C0000_MSR + i, p[6 + i * 2],
+ mtrr_wrmsr(MTRRfix4K_C0000_MSR + i, p[6 + i * 2],
p[7 + i * 2]);
changed = TRUE;
}
rdmsr(MTRRphysBase_MSR(index), lo, hi);
if ((vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL)
- || (vr->base_hi & 0xfUL) != (hi & 0xfUL)) {
- wrmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi);
+ || (vr->base_hi & (size_and_mask >> (32 - PAGE_SHIFT))) !=
+ (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) {
+ mtrr_wrmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi);
changed = TRUE;
}
rdmsr(MTRRphysMask_MSR(index), lo, hi);
if ((vr->mask_lo & 0xfffff800UL) != (lo & 0xfffff800UL)
- || (vr->mask_hi & 0xfUL) != (hi & 0xfUL)) {
- wrmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
+ || (vr->mask_hi & (size_and_mask >> (32 - PAGE_SHIFT))) !=
+ (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) {
+ mtrr_wrmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
changed = TRUE;
}
return changed;
rdmsr(MTRRdefType_MSR, deftype_lo, deftype_hi);
/* Disable MTRRs, and set the default type to uncached */
- wrmsr(MTRRdefType_MSR, deftype_lo & 0xf300UL, deftype_hi);
+ mtrr_wrmsr(MTRRdefType_MSR, deftype_lo & 0xf300UL, deftype_hi);
}
static void post_set(void)
__flush_tlb();
/* Intel (P6) standard MTRRs */
- wrmsr(MTRRdefType_MSR, deftype_lo, deftype_hi);
+ mtrr_wrmsr(MTRRdefType_MSR, deftype_lo, deftype_hi);
/* Enable caches */
write_cr0(read_cr0() & 0xbfffffff);
if (size == 0) {
/* The invalid bit is kept in the mask, so we simply clear the
relevant mask register to disable a range. */
- wrmsr(MTRRphysMask_MSR(reg), 0, 0);
+ mtrr_wrmsr(MTRRphysMask_MSR(reg), 0, 0);
} else {
- wrmsr(MTRRphysBase_MSR(reg), base << PAGE_SHIFT | type,
+ mtrr_wrmsr(MTRRphysBase_MSR(reg), base << PAGE_SHIFT | type,
(base & size_and_mask) >> (32 - PAGE_SHIFT));
- wrmsr(MTRRphysMask_MSR(reg), -size << PAGE_SHIFT | 0x800,
+ mtrr_wrmsr(MTRRphysMask_MSR(reg), -size << PAGE_SHIFT | 0x800,
(-size & size_and_mask) >> (32 - PAGE_SHIFT));
}
}
-int generic_have_wrcomb(void)
+static int generic_have_wrcomb(void)
{
unsigned long config, dummy;
rdmsr(MTRRcap_MSR, config, dummy);