diff options
Diffstat (limited to 'arch/x86/kernel/cpu/mtrr/generic.c')
| -rw-r--r-- | arch/x86/kernel/cpu/mtrr/generic.c | 97 |
1 files changed, 52 insertions, 45 deletions
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 3a8317060732..67cf69f24b00 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -103,7 +103,7 @@ u32 phys_hi_rsvd; */ static inline void k8_check_syscfg_dram_mod_en(void) { - u32 lo, hi; + struct msr val; if (!((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && (boot_cpu_data.x86 >= 0x0f))) @@ -112,13 +112,13 @@ static inline void k8_check_syscfg_dram_mod_en(void) if (cc_platform_has(CC_ATTR_HOST_SEV_SNP)) return; - rdmsr(MSR_AMD64_SYSCFG, lo, hi); - if (lo & K8_MTRRFIXRANGE_DRAM_MODIFY) { + rdmsrq(MSR_AMD64_SYSCFG, val.q); + if (val.l & K8_MTRRFIXRANGE_DRAM_MODIFY) { pr_err(FW_WARN "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]" " not cleared by BIOS, clearing this bit\n", smp_processor_id()); - lo &= ~K8_MTRRFIXRANGE_DRAM_MODIFY; - mtrr_wrmsr(MSR_AMD64_SYSCFG, lo, hi); + val.l &= ~K8_MTRRFIXRANGE_DRAM_MODIFY; + mtrr_wrmsr(MSR_AMD64_SYSCFG, val.l, val.h); } } @@ -557,8 +557,14 @@ u8 mtrr_type_lookup(u64 start, u64 end, u8 *uniform) static void get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr) { - rdmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi); - rdmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi); + struct msr val; + + rdmsrq(MTRRphysBase_MSR(index), val.q); + vr->base_lo = val.l; + vr->base_hi = val.h; + rdmsrq(MTRRphysMask_MSR(index), val.q); + vr->mask_lo = val.l; + vr->mask_hi = val.h; } /* Fill the MSR pair relating to a var range */ @@ -577,17 +583,17 @@ void fill_mtrr_var_range(unsigned int index, static void get_fixed_ranges(mtrr_type *frs) { - unsigned int *p = (unsigned int *)frs; + u64 *p = (u64 *)frs; int i; k8_check_syscfg_dram_mod_en(); - rdmsr(MSR_MTRRfix64K_00000, p[0], p[1]); + rdmsrq(MSR_MTRRfix64K_00000, p[0]); for (i = 0; i < 2; i++) - rdmsr(MSR_MTRRfix16K_80000 + i, p[2 + i * 2], p[3 + i * 2]); + rdmsrq(MSR_MTRRfix16K_80000 + i, p[1 + i]); for (i = 0; i < 8; i++) - rdmsr(MSR_MTRRfix4K_C0000 + i, p[6 + i * 2], p[7 + i * 2]); + rdmsrq(MSR_MTRRfix4K_C0000 + i, p[3 + i]); } void mtrr_save_fixed_ranges(void *info) @@ -689,31 +695,26 @@ static void __init print_mtrr_state(void) bool __init get_mtrr_state(void) { struct mtrr_var_range *vrs; - unsigned lo, dummy; unsigned int i; + u64 q; vrs = mtrr_state.var_ranges; - rdmsr(MSR_MTRRcap, lo, dummy); - mtrr_state.have_fixed = lo & MTRR_CAP_FIX; + rdmsrq(MSR_MTRRcap, q); + mtrr_state.have_fixed = q & MTRR_CAP_FIX; for (i = 0; i < num_var_ranges; i++) get_mtrr_var_range(i, &vrs[i]); if (mtrr_state.have_fixed) get_fixed_ranges(mtrr_state.fixed_ranges); - rdmsr(MSR_MTRRdefType, lo, dummy); - mtrr_state.def_type = lo & MTRR_DEF_TYPE_TYPE; - mtrr_state.enabled = (lo & MTRR_DEF_TYPE_ENABLE) >> MTRR_STATE_SHIFT; + rdmsrq(MSR_MTRRdefType, q); + mtrr_state.def_type = q & MTRR_DEF_TYPE_TYPE; + mtrr_state.enabled = (q & MTRR_DEF_TYPE_ENABLE) >> MTRR_STATE_SHIFT; if (amd_special_default_mtrr()) { - unsigned low, high; - /* TOP_MEM2 */ - rdmsr(MSR_K8_TOP_MEM2, low, high); - mtrr_tom2 = high; - mtrr_tom2 <<= 32; - mtrr_tom2 |= low; + rdmsrq(MSR_K8_TOP_MEM2, mtrr_tom2); mtrr_tom2 &= 0xffffff800000ULL; } @@ -750,7 +751,9 @@ void __init mtrr_state_warn(void) */ void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b) { - if (wrmsr_safe(msr, a, b) < 0) { + struct msr val = { .l = a, .h = b }; + + if (wrmsrq_safe(msr, val.q) < 0) { pr_err("MTRR: CPU %u: Writing MSR %x to %x:%x failed\n", smp_processor_id(), msr, a, b); } @@ -765,11 +768,11 @@ void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b) */ static void set_fixed_range(int msr, bool *changed, unsigned int *msrwords) { - unsigned lo, hi; + struct msr val; - rdmsr(msr, lo, hi); + rdmsrq(msr, val.q); - if (lo != msrwords[0] || hi != msrwords[1]) { + if (val.l != msrwords[0] || val.h != msrwords[1]) { mtrr_wrmsr(msr, msrwords[0], msrwords[1]); *changed = true; } @@ -806,9 +809,8 @@ generic_get_free_region(unsigned long base, unsigned long size, int replace_reg) static void generic_get_mtrr(unsigned int reg, unsigned long *base, unsigned long *size, mtrr_type *type) { - u32 mask_lo, mask_hi, base_lo, base_hi; + u64 tmp, mask, base_msr; unsigned int hi; - u64 tmp, mask; /* * get_mtrr doesn't need to update mtrr_state, also it could be called @@ -816,9 +818,9 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, */ get_cpu(); - rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi); + rdmsrq(MTRRphysMask_MSR(reg), mask); - if (!(mask_lo & MTRR_PHYSMASK_V)) { + if (!(mask & MTRR_PHYSMASK_V)) { /* Invalid (i.e. free) range */ *base = 0; *size = 0; @@ -826,10 +828,10 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, goto out_put_cpu; } - rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi); + rdmsrq(MTRRphysBase_MSR(reg), base_msr); /* Work out the shifted address mask: */ - tmp = (u64)mask_hi << 32 | (mask_lo & PAGE_MASK); + tmp = mask & PAGE_MASK; mask = (u64)phys_hi_rsvd << 32 | tmp; /* Expand tmp with high bits to all 1s: */ @@ -849,8 +851,8 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, * contiguous range: */ *size = -mask >> PAGE_SHIFT; - *base = (u64)base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT; - *type = base_lo & MTRR_PHYSBASE_TYPE; + *base = base_msr >> PAGE_SHIFT; + *type = base_msr & MTRR_PHYSBASE_TYPE; out_put_cpu: put_cpu(); @@ -884,21 +886,21 @@ static int set_fixed_ranges(mtrr_type *frs) */ static bool set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr) { - unsigned int lo, hi; bool changed = false; + struct msr val; - rdmsr(MTRRphysBase_MSR(index), lo, hi); - if ((vr->base_lo & ~MTRR_PHYSBASE_RSVD) != (lo & ~MTRR_PHYSBASE_RSVD) - || (vr->base_hi & ~phys_hi_rsvd) != (hi & ~phys_hi_rsvd)) { + rdmsrq(MTRRphysBase_MSR(index), val.q); + if ((vr->base_lo & ~MTRR_PHYSBASE_RSVD) != (val.l & ~MTRR_PHYSBASE_RSVD) + || (vr->base_hi & ~phys_hi_rsvd) != (val.h & ~phys_hi_rsvd)) { mtrr_wrmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi); changed = true; } - rdmsr(MTRRphysMask_MSR(index), lo, hi); + rdmsrq(MTRRphysMask_MSR(index), val.q); - if ((vr->mask_lo & ~MTRR_PHYSMASK_RSVD) != (lo & ~MTRR_PHYSMASK_RSVD) - || (vr->mask_hi & ~phys_hi_rsvd) != (hi & ~phys_hi_rsvd)) { + if ((vr->mask_lo & ~MTRR_PHYSMASK_RSVD) != (val.l & ~MTRR_PHYSMASK_RSVD) + || (vr->mask_hi & ~phys_hi_rsvd) != (val.h & ~phys_hi_rsvd)) { mtrr_wrmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi); changed = true; } @@ -947,8 +949,12 @@ static unsigned long set_mtrr_state(void) void mtrr_disable(void) { + struct msr val; + /* Save MTRR state */ - rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); + rdmsrq(MSR_MTRRdefType, val.q); + deftype_lo = val.l; + deftype_hi = val.h; /* Disable MTRRs, and set the default type to uncached */ mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & MTRR_DEF_TYPE_DISABLE, deftype_hi); @@ -1057,8 +1063,9 @@ int generic_validate_add_page(unsigned long base, unsigned long size, static int generic_have_wrcomb(void) { - unsigned long config, dummy; - rdmsr(MSR_MTRRcap, config, dummy); + u64 config; + + rdmsrq(MSR_MTRRcap, config); return config & MTRR_CAP_WC; } |
