summaryrefslogtreecommitdiff
path: root/arch/x86/kernel/cpu/mtrr/generic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu/mtrr/generic.c')
-rw-r--r--arch/x86/kernel/cpu/mtrr/generic.c97
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;
}