mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-18 23:09:29 +02:00
Merge tag 'x86-msr-2026-08-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 MSR updates from Ingo Molnar: - Streamline the x86 MSR handling APIs along the 64-bit variants, simplifying the interfaces. Removal of the old APIs is planned for the next cycle, to reduce churn & integration pain (Juergen Gross) * tag 'x86-msr-2026-08-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (21 commits) x86/mce: Work around build warning after MSR-interface switch cpufreq: Stop using 32-bit MSR interfaces x86/featctl: Stop using 32-bit MSR interfaces KVM/x86: Stop using 32-bit MSR interfaces x86/mtrr: Stop using 32-bit MSR interfaces acpi: Stop using 32-bit MSR interfaces powercap: Stop using 32-bit MSR interfaces thermal/intel: Stop using 32-bit MSR interfaces x86/olpc: Stop using 32-bit MSR interfaces x86/hyperv: Stop using 32-bit MSR interfaces hwmon: Stop using 32-bit MSR interfaces EDAC: Stop using 32-bit MSR interfaces x86/cpu: Stop using 32-bit MSR interfaces x86/apic: Stop using 32-bit MSR interfaces x86/resctrl: Stop using 32-bit MSR interfaces x86/tsc: Stop using 32-bit MSR interfaces x86/amd: Stop using 32-bit MSR interfaces x86/pci: Stop using 32-bit MSR interfaces x86/hygon: Stop using 32-bit MSR interfaces x86/mce: Stop using 32-bit MSR interfaces ...
This commit is contained in:
@@ -60,17 +60,15 @@ void hv_enable_coco_interrupt(unsigned int cpu, unsigned int vector, bool set)
|
||||
|
||||
static u32 hv_apic_read(u32 reg)
|
||||
{
|
||||
u32 reg_val, hi;
|
||||
struct msr reg_val;
|
||||
|
||||
switch (reg) {
|
||||
case APIC_EOI:
|
||||
rdmsr(HV_X64_MSR_EOI, reg_val, hi);
|
||||
(void)hi;
|
||||
return reg_val;
|
||||
rdmsrq(HV_X64_MSR_EOI, reg_val.q);
|
||||
return reg_val.l;
|
||||
case APIC_TASKPRI:
|
||||
rdmsr(HV_X64_MSR_TPR, reg_val, hi);
|
||||
(void)hi;
|
||||
return reg_val;
|
||||
rdmsrq(HV_X64_MSR_TPR, reg_val.q);
|
||||
return reg_val.l;
|
||||
|
||||
default:
|
||||
return native_apic_mem_read(reg);
|
||||
|
||||
@@ -102,6 +102,7 @@ static inline void __resctrl_sched_in(struct task_struct *tsk)
|
||||
struct resctrl_pqr_state *state = this_cpu_ptr(&pqr_state);
|
||||
u32 closid = READ_ONCE(state->default_closid);
|
||||
u32 rmid = READ_ONCE(state->default_rmid);
|
||||
struct msr val;
|
||||
u32 tmp;
|
||||
|
||||
/*
|
||||
@@ -123,7 +124,9 @@ static inline void __resctrl_sched_in(struct task_struct *tsk)
|
||||
if (closid != state->cur_closid || rmid != state->cur_rmid) {
|
||||
state->cur_closid = closid;
|
||||
state->cur_rmid = rmid;
|
||||
wrmsr(MSR_IA32_PQR_ASSOC, rmid, closid);
|
||||
val.l = rmid;
|
||||
val.h = closid;
|
||||
wrmsrq(MSR_IA32_PQR_ASSOC, val.q);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ int x86_acpi_suspend_lowlevel(void)
|
||||
{
|
||||
struct wakeup_header *header =
|
||||
(struct wakeup_header *) __va(real_mode_header->wakeup_header);
|
||||
struct msr val;
|
||||
|
||||
if (header->signature != WAKEUP_HEADER_SIGNATURE) {
|
||||
printk(KERN_ERR "wakeup header does not match\n");
|
||||
@@ -82,13 +83,10 @@ int x86_acpi_suspend_lowlevel(void)
|
||||
* with 2-MB L2 Cache and Intel® Processor A100 and A110 on 90
|
||||
* nm process with 512-KB L2 Cache Specification Update".
|
||||
*/
|
||||
if (!rdmsr_safe(MSR_EFER,
|
||||
&header->pmode_efer_low,
|
||||
&header->pmode_efer_high) &&
|
||||
!wrmsr_safe(MSR_EFER,
|
||||
header->pmode_efer_low,
|
||||
header->pmode_efer_high))
|
||||
if (!rdmsrq_safe(MSR_EFER, &val.q) && !wrmsrq_safe(MSR_EFER, val.q))
|
||||
header->pmode_behavior |= (1 << WAKEUP_BEHAVIOR_RESTORE_EFER);
|
||||
header->pmode_efer_low = val.l;
|
||||
header->pmode_efer_high = val.h;
|
||||
#endif /* !CONFIG_64BIT */
|
||||
|
||||
header->pmode_cr0 = read_cr0();
|
||||
@@ -96,14 +94,12 @@ int x86_acpi_suspend_lowlevel(void)
|
||||
header->pmode_cr4 = __read_cr4();
|
||||
header->pmode_behavior |= (1 << WAKEUP_BEHAVIOR_RESTORE_CR4);
|
||||
}
|
||||
if (!rdmsr_safe(MSR_IA32_MISC_ENABLE,
|
||||
&header->pmode_misc_en_low,
|
||||
&header->pmode_misc_en_high) &&
|
||||
!wrmsr_safe(MSR_IA32_MISC_ENABLE,
|
||||
header->pmode_misc_en_low,
|
||||
header->pmode_misc_en_high))
|
||||
if (!rdmsrq_safe(MSR_IA32_MISC_ENABLE, &val.q) &&
|
||||
!wrmsrq_safe(MSR_IA32_MISC_ENABLE, val.q))
|
||||
header->pmode_behavior |=
|
||||
(1 << WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE);
|
||||
header->pmode_misc_en_low = val.l;
|
||||
header->pmode_misc_en_high = val.h;
|
||||
header->realmode_flags = acpi_realmode_flags;
|
||||
header->real_magic = 0x12345678;
|
||||
|
||||
|
||||
+20
-19
@@ -1191,11 +1191,11 @@ void disable_local_APIC(void)
|
||||
* restore the disabled state.
|
||||
*/
|
||||
if (enabled_via_apicbase) {
|
||||
unsigned int l, h;
|
||||
struct msr val;
|
||||
|
||||
rdmsr(MSR_IA32_APICBASE, l, h);
|
||||
l &= ~MSR_IA32_APICBASE_ENABLE;
|
||||
wrmsr(MSR_IA32_APICBASE, l, h);
|
||||
rdmsrq(MSR_IA32_APICBASE, val.q);
|
||||
val.l &= ~MSR_IA32_APICBASE_ENABLE;
|
||||
wrmsrq(MSR_IA32_APICBASE, val.q);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1960,7 +1960,8 @@ static bool __init detect_init_APIC(void)
|
||||
|
||||
static bool __init apic_verify(unsigned long addr)
|
||||
{
|
||||
u32 features, h, l;
|
||||
struct msr val;
|
||||
u32 features;
|
||||
|
||||
/*
|
||||
* The APIC feature bit should now be enabled
|
||||
@@ -1975,9 +1976,9 @@ static bool __init apic_verify(unsigned long addr)
|
||||
|
||||
/* The BIOS may have set up the APIC at some other address */
|
||||
if (boot_cpu_data.x86 >= 6) {
|
||||
rdmsr(MSR_IA32_APICBASE, l, h);
|
||||
if (l & MSR_IA32_APICBASE_ENABLE)
|
||||
addr = l & MSR_IA32_APICBASE_BASE;
|
||||
rdmsrq(MSR_IA32_APICBASE, val.q);
|
||||
if (val.l & MSR_IA32_APICBASE_ENABLE)
|
||||
addr = val.l & MSR_IA32_APICBASE_BASE;
|
||||
}
|
||||
|
||||
register_lapic_address(addr);
|
||||
@@ -1987,7 +1988,7 @@ static bool __init apic_verify(unsigned long addr)
|
||||
|
||||
bool __init apic_force_enable(unsigned long addr)
|
||||
{
|
||||
u32 h, l;
|
||||
struct msr val;
|
||||
|
||||
if (apic_is_disabled)
|
||||
return false;
|
||||
@@ -1998,12 +1999,12 @@ bool __init apic_force_enable(unsigned long addr)
|
||||
* and AMD K7 (Model > 1) or later.
|
||||
*/
|
||||
if (boot_cpu_data.x86 >= 6) {
|
||||
rdmsr(MSR_IA32_APICBASE, l, h);
|
||||
if (!(l & MSR_IA32_APICBASE_ENABLE)) {
|
||||
rdmsrq(MSR_IA32_APICBASE, val.q);
|
||||
if (!(val.l & MSR_IA32_APICBASE_ENABLE)) {
|
||||
pr_info("Local APIC disabled by BIOS -- reenabling.\n");
|
||||
l &= ~MSR_IA32_APICBASE_BASE;
|
||||
l |= MSR_IA32_APICBASE_ENABLE | addr;
|
||||
wrmsr(MSR_IA32_APICBASE, l, h);
|
||||
val.l &= ~MSR_IA32_APICBASE_BASE;
|
||||
val.l |= MSR_IA32_APICBASE_ENABLE | addr;
|
||||
wrmsrq(MSR_IA32_APICBASE, val.q);
|
||||
enabled_via_apicbase = 1;
|
||||
}
|
||||
}
|
||||
@@ -2442,7 +2443,7 @@ static int lapic_suspend(void *data)
|
||||
|
||||
static void lapic_resume(void *data)
|
||||
{
|
||||
unsigned int l, h;
|
||||
struct msr val;
|
||||
unsigned long flags;
|
||||
int maxlvt;
|
||||
|
||||
@@ -2475,10 +2476,10 @@ static void lapic_resume(void *data)
|
||||
* SMP! We'll need to do this as part of the CPU restore!
|
||||
*/
|
||||
if (boot_cpu_data.x86 >= 6) {
|
||||
rdmsr(MSR_IA32_APICBASE, l, h);
|
||||
l &= ~MSR_IA32_APICBASE_BASE;
|
||||
l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr;
|
||||
wrmsr(MSR_IA32_APICBASE, l, h);
|
||||
rdmsrq(MSR_IA32_APICBASE, val.q);
|
||||
val.l &= ~MSR_IA32_APICBASE_BASE;
|
||||
val.l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr;
|
||||
wrmsrq(MSR_IA32_APICBASE, val.q);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-16
@@ -113,7 +113,7 @@ static void init_amd_k5(struct cpuinfo_x86 *c)
|
||||
static void init_amd_k6(struct cpuinfo_x86 *c)
|
||||
{
|
||||
#ifdef CONFIG_X86_32
|
||||
u32 l, h;
|
||||
struct msr val;
|
||||
int mbytes = get_num_physpages() >> (20-PAGE_SHIFT);
|
||||
|
||||
if (c->x86_model < 6) {
|
||||
@@ -160,13 +160,13 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
|
||||
if (mbytes > 508)
|
||||
mbytes = 508;
|
||||
|
||||
rdmsr(MSR_K6_WHCR, l, h);
|
||||
if ((l&0x0000FFFF) == 0) {
|
||||
rdmsrq(MSR_K6_WHCR, val.q);
|
||||
if ((val.l & 0x0000FFFF) == 0) {
|
||||
unsigned long flags;
|
||||
l = (1<<0)|((mbytes/4)<<1);
|
||||
val.l = (1 << 0) | ((mbytes / 4) << 1);
|
||||
local_irq_save(flags);
|
||||
wbinvd();
|
||||
wrmsr(MSR_K6_WHCR, l, h);
|
||||
wrmsrq(MSR_K6_WHCR, val.q);
|
||||
local_irq_restore(flags);
|
||||
pr_info("Enabling old style K6 write allocation for %d Mb\n",
|
||||
mbytes);
|
||||
@@ -181,13 +181,13 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
|
||||
if (mbytes > 4092)
|
||||
mbytes = 4092;
|
||||
|
||||
rdmsr(MSR_K6_WHCR, l, h);
|
||||
if ((l&0xFFFF0000) == 0) {
|
||||
rdmsrq(MSR_K6_WHCR, val.q);
|
||||
if ((val.l & 0xFFFF0000) == 0) {
|
||||
unsigned long flags;
|
||||
l = ((mbytes>>2)<<22)|(1<<16);
|
||||
val.l = ((mbytes >> 2) << 22) | (1 << 16);
|
||||
local_irq_save(flags);
|
||||
wbinvd();
|
||||
wrmsr(MSR_K6_WHCR, l, h);
|
||||
wrmsrq(MSR_K6_WHCR, val.q);
|
||||
local_irq_restore(flags);
|
||||
pr_info("Enabling new style K6 write allocation for %d Mb\n",
|
||||
mbytes);
|
||||
@@ -207,7 +207,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
|
||||
static void init_amd_k7(struct cpuinfo_x86 *c)
|
||||
{
|
||||
#ifdef CONFIG_X86_32
|
||||
u32 l, h;
|
||||
struct msr val;
|
||||
|
||||
/*
|
||||
* Bit 15 of Athlon specific MSR 15, needs to be 0
|
||||
@@ -228,11 +228,12 @@ static void init_amd_k7(struct cpuinfo_x86 *c)
|
||||
* As per AMD technical note 27212 0.2
|
||||
*/
|
||||
if ((c->x86_model == 8 && c->x86_stepping >= 1) || (c->x86_model > 8)) {
|
||||
rdmsr(MSR_K7_CLK_CTL, l, h);
|
||||
if ((l & 0xfff00000) != 0x20000000) {
|
||||
rdmsrq(MSR_K7_CLK_CTL, val.q);
|
||||
if ((val.l & 0xfff00000) != 0x20000000) {
|
||||
pr_info("CPU: CLK_CTL MSR was %x. Reprogramming to %x\n",
|
||||
l, ((l & 0x000fffff)|0x20000000));
|
||||
wrmsr(MSR_K7_CLK_CTL, (l & 0x000fffff)|0x20000000, h);
|
||||
val.l, ((val.l & 0x000fffff) | 0x20000000));
|
||||
val.l = (val.l & 0x000fffff) | 0x20000000;
|
||||
wrmsrq(MSR_K7_CLK_CTL, val.q);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -616,12 +617,13 @@ clear_sev:
|
||||
|
||||
static void early_init_amd(struct cpuinfo_x86 *c)
|
||||
{
|
||||
u32 dummy;
|
||||
u64 val;
|
||||
|
||||
if (c->x86 >= 0xf)
|
||||
set_cpu_cap(c, X86_FEATURE_K8);
|
||||
|
||||
rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
|
||||
rdmsrq_safe(MSR_AMD64_PATCH_LEVEL, &val);
|
||||
c->microcode = (u32)val;
|
||||
|
||||
/*
|
||||
* c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
static void init_c3(struct cpuinfo_x86 *c)
|
||||
{
|
||||
u32 lo, hi;
|
||||
u64 msr;
|
||||
|
||||
/* Test for Centaur Extended Feature Flags presence */
|
||||
if (cpuid_eax(0xC0000000) >= 0xC0000001) {
|
||||
@@ -30,17 +30,17 @@ static void init_c3(struct cpuinfo_x86 *c)
|
||||
|
||||
/* enable ACE unit, if present and disabled */
|
||||
if ((tmp & (ACE_PRESENT | ACE_ENABLED)) == ACE_PRESENT) {
|
||||
rdmsr(MSR_VIA_FCR, lo, hi);
|
||||
lo |= ACE_FCR; /* enable ACE unit */
|
||||
wrmsr(MSR_VIA_FCR, lo, hi);
|
||||
rdmsrq(MSR_VIA_FCR, msr);
|
||||
/* enable ACE unit */
|
||||
wrmsrq(MSR_VIA_FCR, msr | ACE_FCR);
|
||||
pr_info("CPU: Enabled ACE h/w crypto\n");
|
||||
}
|
||||
|
||||
/* enable RNG unit, if present and disabled */
|
||||
if ((tmp & (RNG_PRESENT | RNG_ENABLED)) == RNG_PRESENT) {
|
||||
rdmsr(MSR_VIA_RNG, lo, hi);
|
||||
lo |= RNG_ENABLE; /* enable RNG unit */
|
||||
wrmsr(MSR_VIA_RNG, lo, hi);
|
||||
rdmsrq(MSR_VIA_RNG, msr);
|
||||
/* enable RNG unit */
|
||||
wrmsrq(MSR_VIA_RNG, msr | RNG_ENABLE);
|
||||
pr_info("CPU: Enabled h/w RNG\n");
|
||||
}
|
||||
|
||||
@@ -52,9 +52,8 @@ static void init_c3(struct cpuinfo_x86 *c)
|
||||
#ifdef CONFIG_X86_32
|
||||
/* Cyrix III family needs CX8 & PGE explicitly enabled. */
|
||||
if (c->x86_model >= 6 && c->x86_model <= 13) {
|
||||
rdmsr(MSR_VIA_FCR, lo, hi);
|
||||
lo |= (1<<1 | 1<<7);
|
||||
wrmsr(MSR_VIA_FCR, lo, hi);
|
||||
rdmsrq(MSR_VIA_FCR, msr);
|
||||
wrmsrq(MSR_VIA_FCR, msr | (1 << 1 | 1 << 7));
|
||||
set_cpu_cap(c, X86_FEATURE_CX8);
|
||||
}
|
||||
|
||||
@@ -115,8 +114,9 @@ static void init_centaur(struct cpuinfo_x86 *c)
|
||||
char *name;
|
||||
u32 fcr_set = 0;
|
||||
u32 fcr_clr = 0;
|
||||
u32 lo, hi, newlo;
|
||||
u32 newlo;
|
||||
u32 aa, bb, cc, dd;
|
||||
struct msr val;
|
||||
#endif
|
||||
early_init_centaur(c);
|
||||
init_intel_cacheinfo(c);
|
||||
@@ -169,15 +169,16 @@ static void init_centaur(struct cpuinfo_x86 *c)
|
||||
name = "??";
|
||||
}
|
||||
|
||||
rdmsr(MSR_IDT_FCR1, lo, hi);
|
||||
newlo = (lo|fcr_set) & (~fcr_clr);
|
||||
rdmsrq(MSR_IDT_FCR1, val.q);
|
||||
newlo = (val.l | fcr_set) & (~fcr_clr);
|
||||
|
||||
if (newlo != lo) {
|
||||
if (newlo != val.l) {
|
||||
pr_info("Centaur FCR was 0x%X now 0x%X\n",
|
||||
lo, newlo);
|
||||
wrmsr(MSR_IDT_FCR1, newlo, hi);
|
||||
val.l, newlo);
|
||||
val.l = newlo;
|
||||
wrmsrq(MSR_IDT_FCR1, val.q);
|
||||
} else {
|
||||
pr_info("Centaur FCR is 0x%X\n", lo);
|
||||
pr_info("Centaur FCR is 0x%X\n", val.l);
|
||||
}
|
||||
/* Emulate MTRRs using Centaur's MCR. */
|
||||
set_cpu_cap(c, X86_FEATURE_CENTAUR_MCR);
|
||||
|
||||
@@ -339,16 +339,16 @@ bool cpuid_feature(void)
|
||||
|
||||
static void squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
|
||||
{
|
||||
unsigned long lo, hi;
|
||||
struct msr val;
|
||||
|
||||
if (!cpu_has(c, X86_FEATURE_PN) || !disable_x86_serial_nr)
|
||||
return;
|
||||
|
||||
/* Disable processor serial number: */
|
||||
|
||||
rdmsr(MSR_IA32_BBL_CR_CTL, lo, hi);
|
||||
lo |= 0x200000;
|
||||
wrmsr(MSR_IA32_BBL_CR_CTL, lo, hi);
|
||||
rdmsrq(MSR_IA32_BBL_CR_CTL, val.q);
|
||||
val.l |= 0x200000;
|
||||
wrmsrq(MSR_IA32_BBL_CR_CTL, val.q);
|
||||
|
||||
pr_notice("CPU serial number disabled.\n");
|
||||
clear_cpu_cap(c, X86_FEATURE_PN);
|
||||
@@ -2299,8 +2299,10 @@ static inline void idt_syscall_init(void)
|
||||
/* May not be marked __init: used by software suspend */
|
||||
void syscall_init(void)
|
||||
{
|
||||
struct msr val = { .h = (__USER32_CS << 16) | __KERNEL_CS };
|
||||
|
||||
/* The default user and kernel segments */
|
||||
wrmsr(MSR_STAR, 0, (__USER32_CS << 16) | __KERNEL_CS);
|
||||
wrmsrq(MSR_STAR, val.q);
|
||||
|
||||
/*
|
||||
* Except the IA32_STAR MSR, there is NO need to setup SYSCALL and
|
||||
|
||||
@@ -25,7 +25,8 @@ enum vmx_feature_leafs {
|
||||
|
||||
static void init_vmx_capabilities(struct cpuinfo_x86 *c)
|
||||
{
|
||||
u32 supported, funcs, ept, vpid, ign, low, high;
|
||||
struct msr val;
|
||||
u32 supported, funcs, ept, vpid;
|
||||
|
||||
BUILD_BUG_ON(NVMXINTS != NR_VMX_FEATURE_WORDS);
|
||||
|
||||
@@ -39,25 +40,31 @@ static void init_vmx_capabilities(struct cpuinfo_x86 *c)
|
||||
* as they exist on any CPU that supports VMX, i.e. we want the WARN if
|
||||
* the RDMSR faults.
|
||||
*/
|
||||
rdmsr(MSR_IA32_VMX_PROCBASED_CTLS, ign, supported);
|
||||
rdmsrq(MSR_IA32_VMX_PROCBASED_CTLS, val.q);
|
||||
supported = val.h;
|
||||
c->vmx_capability[PRIMARY_CTLS] = supported;
|
||||
|
||||
rdmsr_safe(MSR_IA32_VMX_PROCBASED_CTLS2, &ign, &supported);
|
||||
rdmsrq_safe(MSR_IA32_VMX_PROCBASED_CTLS2, &val.q);
|
||||
supported = val.h;
|
||||
c->vmx_capability[SECONDARY_CTLS] = supported;
|
||||
|
||||
/* All 64 bits of tertiary controls MSR are allowed-1 settings. */
|
||||
rdmsr_safe(MSR_IA32_VMX_PROCBASED_CTLS3, &low, &high);
|
||||
c->vmx_capability[TERTIARY_CTLS_LOW] = low;
|
||||
c->vmx_capability[TERTIARY_CTLS_HIGH] = high;
|
||||
rdmsrq_safe(MSR_IA32_VMX_PROCBASED_CTLS3, &val.q);
|
||||
c->vmx_capability[TERTIARY_CTLS_LOW] = val.l;
|
||||
c->vmx_capability[TERTIARY_CTLS_HIGH] = val.h;
|
||||
|
||||
rdmsr(MSR_IA32_VMX_PINBASED_CTLS, ign, supported);
|
||||
rdmsr_safe(MSR_IA32_VMX_VMFUNC, &ign, &funcs);
|
||||
rdmsrq(MSR_IA32_VMX_PINBASED_CTLS, val.q);
|
||||
supported = val.h;
|
||||
rdmsrq_safe(MSR_IA32_VMX_VMFUNC, &val.q);
|
||||
funcs = val.h;
|
||||
|
||||
/*
|
||||
* Except for EPT+VPID, which enumerates support for both in a single
|
||||
* MSR, low for EPT, high for VPID.
|
||||
*/
|
||||
rdmsr_safe(MSR_IA32_VMX_EPT_VPID_CAP, &ept, &vpid);
|
||||
rdmsrq_safe(MSR_IA32_VMX_EPT_VPID_CAP, &val.q);
|
||||
ept = val.l;
|
||||
vpid = val.h;
|
||||
|
||||
/* Pin, EPT, VPID and VM-Func are merged into a single word. */
|
||||
WARN_ON_ONCE(supported >> 16);
|
||||
|
||||
@@ -125,11 +125,12 @@ static void bsp_init_hygon(struct cpuinfo_x86 *c)
|
||||
|
||||
static void early_init_hygon(struct cpuinfo_x86 *c)
|
||||
{
|
||||
u32 dummy;
|
||||
u64 val;
|
||||
|
||||
set_cpu_cap(c, X86_FEATURE_K8);
|
||||
|
||||
rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
|
||||
rdmsrq_safe(MSR_AMD64_PATCH_LEVEL, &val);
|
||||
c->microcode = (u32)val;
|
||||
|
||||
/*
|
||||
* c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate
|
||||
|
||||
@@ -542,12 +542,12 @@ static void init_intel(struct cpuinfo_x86 *c)
|
||||
set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_DS)) {
|
||||
unsigned int l1, l2;
|
||||
u64 l;
|
||||
|
||||
rdmsr(MSR_IA32_MISC_ENABLE, l1, l2);
|
||||
if (!(l1 & MSR_IA32_MISC_ENABLE_BTS_UNAVAIL))
|
||||
rdmsrq(MSR_IA32_MISC_ENABLE, l);
|
||||
if (!(l & MSR_IA32_MISC_ENABLE_BTS_UNAVAIL))
|
||||
set_cpu_cap(c, X86_FEATURE_BTS);
|
||||
if (!(l1 & MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL))
|
||||
if (!(l & MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL))
|
||||
set_cpu_cap(c, X86_FEATURE_PEBS);
|
||||
}
|
||||
|
||||
|
||||
@@ -280,11 +280,11 @@ static void smca_configure(unsigned int bank, unsigned int cpu)
|
||||
u8 *bank_counts = this_cpu_ptr(smca_bank_counts);
|
||||
const struct smca_hwid *s_hwid;
|
||||
unsigned int i, hwid_mcatype;
|
||||
u32 high, low;
|
||||
struct msr val;
|
||||
u32 smca_config = MSR_AMD64_SMCA_MCx_CONFIG(bank);
|
||||
|
||||
/* Set appropriate bits in MCA_CONFIG */
|
||||
if (!rdmsr_safe(smca_config, &low, &high)) {
|
||||
if (!rdmsrq_safe(smca_config, &val.q)) {
|
||||
/*
|
||||
* OS is required to set the MCAX bit to acknowledge that it is
|
||||
* now using the new MSR ranges and new registers under each
|
||||
@@ -294,7 +294,7 @@ static void smca_configure(unsigned int bank, unsigned int cpu)
|
||||
*
|
||||
* MCA_CONFIG[MCAX] is bit 32 (0 in the high portion of the MSR.)
|
||||
*/
|
||||
high |= BIT(0);
|
||||
val.h |= BIT(0);
|
||||
|
||||
/*
|
||||
* SMCA sets the Deferred Error Interrupt type per bank.
|
||||
@@ -307,9 +307,9 @@ static void smca_configure(unsigned int bank, unsigned int cpu)
|
||||
* APIC based interrupt. First, check that no interrupt has been
|
||||
* set.
|
||||
*/
|
||||
if ((low & BIT(5)) && !((high >> 5) & 0x3) && data->dfr_intr_en) {
|
||||
if ((val.l & BIT(5)) && !((val.h >> 5) & 0x3) && data->dfr_intr_en) {
|
||||
__set_bit(bank, data->dfr_intr_banks);
|
||||
high |= BIT(5);
|
||||
val.h |= BIT(5);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -324,33 +324,33 @@ static void smca_configure(unsigned int bank, unsigned int cpu)
|
||||
* The OS should set this to inform the platform that the OS is ready
|
||||
* to handle the MCA Thresholding interrupt.
|
||||
*/
|
||||
if ((low & BIT(10)) && data->thr_intr_en) {
|
||||
if ((val.l & BIT(10)) && data->thr_intr_en) {
|
||||
__set_bit(bank, data->thr_intr_banks);
|
||||
high |= BIT(8);
|
||||
val.h |= BIT(8);
|
||||
}
|
||||
|
||||
this_cpu_ptr(mce_banks_array)[bank].lsb_in_status = !!(low & BIT(8));
|
||||
this_cpu_ptr(mce_banks_array)[bank].lsb_in_status = !!(val.l & BIT(8));
|
||||
|
||||
if (low & MCI_CONFIG_PADDRV)
|
||||
if (val.l & MCI_CONFIG_PADDRV)
|
||||
this_cpu_ptr(smca_banks)[bank].paddrv = 1;
|
||||
|
||||
wrmsr(smca_config, low, high);
|
||||
wrmsrq(smca_config, val.q);
|
||||
}
|
||||
|
||||
if (rdmsr_safe(MSR_AMD64_SMCA_MCx_IPID(bank), &low, &high)) {
|
||||
if (rdmsrq_safe(MSR_AMD64_SMCA_MCx_IPID(bank), &val.q)) {
|
||||
pr_warn("Failed to read MCA_IPID for bank %d\n", bank);
|
||||
return;
|
||||
}
|
||||
|
||||
hwid_mcatype = HWID_MCATYPE(high & MCI_IPID_HWID,
|
||||
(high & MCI_IPID_MCATYPE) >> 16);
|
||||
hwid_mcatype = HWID_MCATYPE(val.h & MCI_IPID_HWID,
|
||||
(val.h & MCI_IPID_MCATYPE) >> 16);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(smca_hwid_mcatypes); i++) {
|
||||
s_hwid = &smca_hwid_mcatypes[i];
|
||||
|
||||
if (hwid_mcatype == s_hwid->hwid_mcatype) {
|
||||
this_cpu_ptr(smca_banks)[bank].hwid = s_hwid;
|
||||
this_cpu_ptr(smca_banks)[bank].id = low;
|
||||
this_cpu_ptr(smca_banks)[bank].id = val.l;
|
||||
this_cpu_ptr(smca_banks)[bank].sysfs_id = bank_counts[s_hwid->bank_type]++;
|
||||
break;
|
||||
}
|
||||
@@ -432,50 +432,50 @@ static bool lvt_off_valid(struct threshold_block *b, int apic, u32 lo, u32 hi)
|
||||
static void threshold_restart_block(void *_tr)
|
||||
{
|
||||
struct thresh_restart *tr = _tr;
|
||||
u32 hi, lo;
|
||||
struct msr val;
|
||||
|
||||
/* sysfs write might race against an offline operation */
|
||||
if (!this_cpu_read(threshold_banks) && !tr->set_lvt_off)
|
||||
return;
|
||||
|
||||
rdmsr(tr->b->address, lo, hi);
|
||||
rdmsrq(tr->b->address, val.q);
|
||||
|
||||
/*
|
||||
* Reset error count and overflow bit.
|
||||
* This is done during init or after handling an interrupt.
|
||||
*/
|
||||
if (hi & MASK_OVERFLOW_HI || tr->set_lvt_off) {
|
||||
hi &= ~(MASK_ERR_COUNT_HI | MASK_OVERFLOW_HI);
|
||||
hi |= THRESHOLD_MAX - tr->b->threshold_limit;
|
||||
if (val.h & MASK_OVERFLOW_HI || tr->set_lvt_off) {
|
||||
val.h &= ~(MASK_ERR_COUNT_HI | MASK_OVERFLOW_HI);
|
||||
val.h |= THRESHOLD_MAX - tr->b->threshold_limit;
|
||||
} else if (tr->old_limit) { /* change limit w/o reset */
|
||||
int new_count = (hi & THRESHOLD_MAX) +
|
||||
int new_count = (val.h & THRESHOLD_MAX) +
|
||||
(tr->old_limit - tr->b->threshold_limit);
|
||||
|
||||
hi = (hi & ~MASK_ERR_COUNT_HI) |
|
||||
val.h = (val.h & ~MASK_ERR_COUNT_HI) |
|
||||
(new_count & THRESHOLD_MAX);
|
||||
}
|
||||
|
||||
/* clear IntType */
|
||||
hi &= ~MASK_INT_TYPE_HI;
|
||||
val.h &= ~MASK_INT_TYPE_HI;
|
||||
|
||||
if (!tr->b->interrupt_capable)
|
||||
goto done;
|
||||
|
||||
if (tr->set_lvt_off) {
|
||||
if (lvt_off_valid(tr->b, tr->lvt_off, lo, hi)) {
|
||||
if (lvt_off_valid(tr->b, tr->lvt_off, val.l, val.h)) {
|
||||
/* set new lvt offset */
|
||||
hi &= ~MASK_LVTOFF_HI;
|
||||
hi |= tr->lvt_off << 20;
|
||||
val.h &= ~MASK_LVTOFF_HI;
|
||||
val.h |= tr->lvt_off << 20;
|
||||
}
|
||||
}
|
||||
|
||||
if (tr->b->interrupt_enable)
|
||||
hi |= INT_TYPE_APIC;
|
||||
val.h |= INT_TYPE_APIC;
|
||||
|
||||
done:
|
||||
|
||||
hi |= MASK_COUNT_EN_HI;
|
||||
wrmsr(tr->b->address, lo, hi);
|
||||
val.h |= MASK_COUNT_EN_HI;
|
||||
wrmsrq(tr->b->address, val.q);
|
||||
}
|
||||
|
||||
static void threshold_restart_bank(unsigned int bank, bool intr_en)
|
||||
@@ -726,7 +726,8 @@ static void smca_enable_interrupt_vectors(void)
|
||||
void mce_amd_feature_init(struct cpuinfo_x86 *c)
|
||||
{
|
||||
unsigned int bank, block, cpu = smp_processor_id();
|
||||
u32 low = 0, high = 0, address = 0;
|
||||
struct msr val = { .q = 0 };
|
||||
u32 address = 0;
|
||||
int offset = -1;
|
||||
|
||||
amd_apply_cpu_quirks(c);
|
||||
@@ -746,21 +747,21 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
|
||||
disable_err_thresholding(c, bank);
|
||||
|
||||
for (block = 0; block < NR_BLOCKS; ++block) {
|
||||
address = get_block_address(address, low, high, bank, block, cpu);
|
||||
address = get_block_address(address, val.l, val.h, bank, block, cpu);
|
||||
if (!address)
|
||||
break;
|
||||
|
||||
if (rdmsr_safe(address, &low, &high))
|
||||
if (rdmsrq_safe(address, &val.q))
|
||||
break;
|
||||
|
||||
if (!(high & MASK_VALID_HI))
|
||||
if (!(val.h & MASK_VALID_HI))
|
||||
continue;
|
||||
|
||||
if (!(high & MASK_CNTP_HI) ||
|
||||
(high & MASK_LOCKED_HI))
|
||||
if (!(val.h & MASK_CNTP_HI) ||
|
||||
(val.h & MASK_LOCKED_HI))
|
||||
continue;
|
||||
|
||||
offset = prepare_threshold_block(bank, block, address, offset, high);
|
||||
offset = prepare_threshold_block(bank, block, address, offset, val.h);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1083,24 +1084,24 @@ static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb
|
||||
u32 address)
|
||||
{
|
||||
struct threshold_block *b = NULL;
|
||||
u32 low, high;
|
||||
struct msr val;
|
||||
int err;
|
||||
|
||||
if ((bank >= this_cpu_read(mce_num_banks)) || (block >= NR_BLOCKS))
|
||||
return 0;
|
||||
|
||||
if (rdmsr_safe(address, &low, &high))
|
||||
if (rdmsrq_safe(address, &val.q))
|
||||
return 0;
|
||||
|
||||
if (!(high & MASK_VALID_HI)) {
|
||||
if (!(val.h & MASK_VALID_HI)) {
|
||||
if (block)
|
||||
goto recurse;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(high & MASK_CNTP_HI) ||
|
||||
(high & MASK_LOCKED_HI))
|
||||
if (!(val.h & MASK_CNTP_HI) ||
|
||||
(val.h & MASK_LOCKED_HI))
|
||||
goto recurse;
|
||||
|
||||
b = kzalloc_obj(struct threshold_block);
|
||||
@@ -1112,7 +1113,7 @@ static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb
|
||||
b->cpu = cpu;
|
||||
b->address = address;
|
||||
b->interrupt_enable = 0;
|
||||
b->interrupt_capable = lvt_interrupt_supported(bank, high);
|
||||
b->interrupt_capable = lvt_interrupt_supported(bank, val.h);
|
||||
b->threshold_limit = get_thr_limit();
|
||||
|
||||
if (b->interrupt_capable) {
|
||||
@@ -1124,13 +1125,13 @@ static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb
|
||||
|
||||
list_add(&b->miscj, &tb->miscj);
|
||||
|
||||
mce_threshold_block_init(b, (high & MASK_LVTOFF_HI) >> 20);
|
||||
mce_threshold_block_init(b, (val.h & MASK_LVTOFF_HI) >> 20);
|
||||
|
||||
err = kobject_init_and_add(&b->kobj, &threshold_ktype, tb->kobj, get_name(cpu, bank, b));
|
||||
if (err)
|
||||
goto out_free;
|
||||
recurse:
|
||||
address = get_block_address(address, low, high, bank, ++block, cpu);
|
||||
address = get_block_address(address, val.l, val.h, bank, ++block, cpu);
|
||||
if (!address)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -1866,7 +1866,7 @@ static void __mcheck_cpu_init_generic(void)
|
||||
|
||||
rdmsrq(MSR_IA32_MCG_CAP, cap);
|
||||
if (cap & MCG_CTL_P)
|
||||
wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
|
||||
wrmsrq(MSR_IA32_MCG_CTL, ~0ULL);
|
||||
}
|
||||
|
||||
static void __mcheck_cpu_init_prepare_banks(void)
|
||||
|
||||
@@ -23,16 +23,16 @@ int mce_p5_enabled __read_mostly;
|
||||
/* Machine check handler for Pentium class Intel CPUs: */
|
||||
noinstr void pentium_machine_check(struct pt_regs *regs)
|
||||
{
|
||||
u32 loaddr, hi, lotype;
|
||||
u64 addr, type;
|
||||
|
||||
instrumentation_begin();
|
||||
rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi);
|
||||
rdmsr(MSR_IA32_P5_MC_TYPE, lotype, hi);
|
||||
rdmsrq(MSR_IA32_P5_MC_ADDR, addr);
|
||||
rdmsrq(MSR_IA32_P5_MC_TYPE, type);
|
||||
|
||||
pr_emerg("CPU#%d: Machine Check Exception: 0x%8X (type 0x%8X).\n",
|
||||
smp_processor_id(), loaddr, lotype);
|
||||
smp_processor_id(), (u32)addr, (u32)type);
|
||||
|
||||
if (lotype & (1<<5)) {
|
||||
if (type & (1<<5)) {
|
||||
pr_emerg("CPU#%d: Possible thermal failure (CPU on fire ?).\n",
|
||||
smp_processor_id());
|
||||
}
|
||||
@@ -44,7 +44,7 @@ noinstr void pentium_machine_check(struct pt_regs *regs)
|
||||
/* Set up machine check reporting for processors with Intel style MCE: */
|
||||
void intel_p5_mcheck_init(struct cpuinfo_x86 *c)
|
||||
{
|
||||
u32 l, h;
|
||||
u64 __maybe_unused q;
|
||||
|
||||
/* Default P5 to off as its often misconnected: */
|
||||
if (!mce_p5_enabled)
|
||||
@@ -55,8 +55,8 @@ void intel_p5_mcheck_init(struct cpuinfo_x86 *c)
|
||||
return;
|
||||
|
||||
/* Read registers before enabling: */
|
||||
rdmsr(MSR_IA32_P5_MC_ADDR, l, h);
|
||||
rdmsr(MSR_IA32_P5_MC_TYPE, l, h);
|
||||
rdmsrq(MSR_IA32_P5_MC_ADDR, q);
|
||||
rdmsrq(MSR_IA32_P5_MC_TYPE, q);
|
||||
pr_info("Intel old style machine check architecture supported.\n");
|
||||
|
||||
/* Enable MCE: */
|
||||
|
||||
@@ -28,12 +28,12 @@ noinstr void winchip_machine_check(struct pt_regs *regs)
|
||||
/* Set up machine check reporting on the Winchip C6 series */
|
||||
void winchip_mcheck_init(struct cpuinfo_x86 *c)
|
||||
{
|
||||
u32 lo, hi;
|
||||
struct msr val;
|
||||
|
||||
rdmsr(MSR_IDT_FCR1, lo, hi);
|
||||
lo |= (1<<2); /* Enable EIERRINT (int 18 MCE) */
|
||||
lo &= ~(1<<4); /* Enable MCE */
|
||||
wrmsr(MSR_IDT_FCR1, lo, hi);
|
||||
rdmsrq(MSR_IDT_FCR1, val.q);
|
||||
val.l |= (1<<2); /* Enable EIERRINT (int 18 MCE) */
|
||||
val.l &= ~(1<<4); /* Enable MCE */
|
||||
wrmsrq(MSR_IDT_FCR1, val.q);
|
||||
|
||||
cr4_set_bits(X86_CR4_MCE);
|
||||
|
||||
|
||||
@@ -10,20 +10,23 @@ static void
|
||||
amd_get_mtrr(unsigned int reg, unsigned long *base,
|
||||
unsigned long *size, mtrr_type *type)
|
||||
{
|
||||
unsigned long low, high;
|
||||
unsigned long val;
|
||||
struct msr msr;
|
||||
|
||||
rdmsr(MSR_K6_UWCCR, low, high);
|
||||
rdmsrq(MSR_K6_UWCCR, msr.q);
|
||||
/* Upper dword is region 1, lower is region 0 */
|
||||
if (reg == 1)
|
||||
low = high;
|
||||
val = msr.h;
|
||||
else
|
||||
val = msr.l;
|
||||
/* The base masks off on the right alignment */
|
||||
*base = (low & 0xFFFE0000) >> PAGE_SHIFT;
|
||||
*base = (val & 0xFFFE0000) >> PAGE_SHIFT;
|
||||
*type = 0;
|
||||
if (low & 1)
|
||||
if (val & 1)
|
||||
*type = MTRR_TYPE_UNCACHABLE;
|
||||
if (low & 2)
|
||||
if (val & 2)
|
||||
*type = MTRR_TYPE_WRCOMB;
|
||||
if (!(low & 3)) {
|
||||
if (!(val & 3)) {
|
||||
*size = 0;
|
||||
return;
|
||||
}
|
||||
@@ -42,8 +45,8 @@ amd_get_mtrr(unsigned int reg, unsigned long *base,
|
||||
* +1 000 0000 0000 0100
|
||||
* *128K ...
|
||||
*/
|
||||
low = (~low) & 0x1FFFC;
|
||||
*size = (low + 4) << (15 - PAGE_SHIFT);
|
||||
val = (~val) & 0x1FFFC;
|
||||
*size = (val + 4) << (15 - PAGE_SHIFT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,12 +62,16 @@ amd_get_mtrr(unsigned int reg, unsigned long *base,
|
||||
static void
|
||||
amd_set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type type)
|
||||
{
|
||||
struct msr msr;
|
||||
u32 regs[2];
|
||||
|
||||
/*
|
||||
* Low is MTRR0, High MTRR 1
|
||||
*/
|
||||
rdmsr(MSR_K6_UWCCR, regs[0], regs[1]);
|
||||
rdmsrq(MSR_K6_UWCCR, msr.q);
|
||||
regs[0] = msr.l;
|
||||
regs[1] = msr.h;
|
||||
|
||||
/*
|
||||
* Blank to disable
|
||||
*/
|
||||
@@ -89,7 +96,9 @@ amd_set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type
|
||||
* disable local interrupts, write back the cache, set the mtrr
|
||||
*/
|
||||
wbinvd();
|
||||
wrmsr(MSR_K6_UWCCR, regs[0], regs[1]);
|
||||
msr.l = regs[0];
|
||||
msr.h = regs[1];
|
||||
wrmsrq(MSR_K6_UWCCR, msr.q);
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -65,26 +65,26 @@ static void
|
||||
centaur_set_mcr(unsigned int reg, unsigned long base,
|
||||
unsigned long size, mtrr_type type)
|
||||
{
|
||||
unsigned long low, high;
|
||||
struct msr val;
|
||||
|
||||
if (size == 0) {
|
||||
/* Disable */
|
||||
high = low = 0;
|
||||
val.q = 0;
|
||||
} else {
|
||||
high = base << PAGE_SHIFT;
|
||||
val.h = base << PAGE_SHIFT;
|
||||
if (centaur_mcr_type == 0) {
|
||||
/* Only support write-combining... */
|
||||
low = -size << PAGE_SHIFT | 0x1f;
|
||||
val.l = -size << PAGE_SHIFT | 0x1f;
|
||||
} else {
|
||||
if (type == MTRR_TYPE_UNCACHABLE)
|
||||
low = -size << PAGE_SHIFT | 0x02; /* NC */
|
||||
val.l = -size << PAGE_SHIFT | 0x02; /* NC */
|
||||
else
|
||||
low = -size << PAGE_SHIFT | 0x09; /* WWO, WC */
|
||||
val.l = -size << PAGE_SHIFT | 0x09; /* WWO, WC */
|
||||
}
|
||||
}
|
||||
centaur_mcr[reg].high = high;
|
||||
centaur_mcr[reg].low = low;
|
||||
wrmsr(MSR_IDT_MCR0 + reg, low, high);
|
||||
centaur_mcr[reg].high = val.h;
|
||||
centaur_mcr[reg].low = val.l;
|
||||
wrmsrq(MSR_IDT_MCR0 + reg, val.q);
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -658,8 +658,8 @@ static int __init mtrr_search_optimal_index(void)
|
||||
int __init mtrr_cleanup(void)
|
||||
{
|
||||
unsigned long x_remove_base, x_remove_size;
|
||||
unsigned long base, size, def, dummy;
|
||||
u64 chunk_size, gran_size;
|
||||
u64 def, chunk_size, gran_size;
|
||||
unsigned long base, size;
|
||||
mtrr_type type;
|
||||
int index_good;
|
||||
int i;
|
||||
@@ -670,7 +670,7 @@ int __init mtrr_cleanup(void)
|
||||
if (!cpu_feature_enabled(X86_FEATURE_MTRR) || enable_mtrr_cleanup < 1)
|
||||
return 0;
|
||||
|
||||
rdmsr(MSR_MTRRdefType, def, dummy);
|
||||
rdmsrq(MSR_MTRRdefType, def);
|
||||
def &= 0xff;
|
||||
if (def != MTRR_TYPE_UNCACHABLE)
|
||||
return 0;
|
||||
@@ -806,7 +806,7 @@ early_param("disable_mtrr_trim", disable_mtrr_trim_setup);
|
||||
|
||||
int __init amd_special_default_mtrr(void)
|
||||
{
|
||||
u32 l, h;
|
||||
u64 q;
|
||||
|
||||
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
|
||||
boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
|
||||
@@ -814,13 +814,13 @@ int __init amd_special_default_mtrr(void)
|
||||
if (boot_cpu_data.x86 < 0xf)
|
||||
return 0;
|
||||
/* In case some hypervisor doesn't pass SYSCFG through: */
|
||||
if (rdmsr_safe(MSR_AMD64_SYSCFG, &l, &h) < 0)
|
||||
if (rdmsrq_safe(MSR_AMD64_SYSCFG, &q) < 0)
|
||||
return 0;
|
||||
/*
|
||||
* Memory between 4GB and top of mem is forced WB by this magic bit.
|
||||
* Reserved before K8RevF, but should be zero there.
|
||||
*/
|
||||
if ((l & (Tom2Enabled | Tom2ForceMemTypeWB)) ==
|
||||
if ((q & (Tom2Enabled | Tom2ForceMemTypeWB)) ==
|
||||
(Tom2Enabled | Tom2ForceMemTypeWB))
|
||||
return 1;
|
||||
return 0;
|
||||
@@ -854,9 +854,9 @@ real_trim_memory(unsigned long start_pfn, unsigned long limit_pfn)
|
||||
*/
|
||||
int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
|
||||
{
|
||||
unsigned long i, base, size, highest_pfn = 0, def, dummy;
|
||||
unsigned long i, base, size, highest_pfn = 0;
|
||||
mtrr_type type;
|
||||
u64 total_trim_size;
|
||||
u64 def, total_trim_size;
|
||||
/* extra one for all 0 */
|
||||
int num[MTRR_NUM_TYPES + 1];
|
||||
|
||||
@@ -870,7 +870,7 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
|
||||
if (!cpu_feature_enabled(X86_FEATURE_MTRR) || disable_mtrr_trim)
|
||||
return 0;
|
||||
|
||||
rdmsr(MSR_MTRRdefType, def, dummy);
|
||||
rdmsrq(MSR_MTRRdefType, def);
|
||||
def &= MTRR_DEF_TYPE_TYPE;
|
||||
if (def != MTRR_TYPE_UNCACHABLE)
|
||||
return 0;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -547,7 +547,7 @@ void __init mtrr_bp_init(void)
|
||||
{
|
||||
bool generic_mtrrs = cpu_feature_enabled(X86_FEATURE_MTRR);
|
||||
const char *why = "(not available)";
|
||||
unsigned long config, dummy;
|
||||
unsigned long config;
|
||||
|
||||
phys_hi_rsvd = GENMASK(31, boot_cpu_data.x86_phys_bits - 32);
|
||||
|
||||
@@ -571,7 +571,7 @@ void __init mtrr_bp_init(void)
|
||||
if (mtrr_enabled()) {
|
||||
/* Get the number of variable MTRR ranges. */
|
||||
if (mtrr_if == &generic_mtrr_ops)
|
||||
rdmsr(MSR_MTRRcap, config, dummy);
|
||||
rdmsrq(MSR_MTRRcap, config);
|
||||
else
|
||||
config = mtrr_if->var_regs;
|
||||
num_var_ranges = config & MTRR_CAP_VCNT;
|
||||
|
||||
@@ -725,13 +725,16 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r)
|
||||
static void clear_closid_rmid(int cpu)
|
||||
{
|
||||
struct resctrl_pqr_state *state = this_cpu_ptr(&pqr_state);
|
||||
struct msr val = {
|
||||
.l = RESCTRL_RESERVED_RMID,
|
||||
.h = RESCTRL_RESERVED_CLOSID
|
||||
};
|
||||
|
||||
state->default_closid = RESCTRL_RESERVED_CLOSID;
|
||||
state->default_rmid = RESCTRL_RESERVED_RMID;
|
||||
state->cur_closid = RESCTRL_RESERVED_CLOSID;
|
||||
state->cur_rmid = RESCTRL_RESERVED_RMID;
|
||||
wrmsr(MSR_IA32_PQR_ASSOC, RESCTRL_RESERVED_RMID,
|
||||
RESCTRL_RESERVED_CLOSID);
|
||||
wrmsrq(MSR_IA32_PQR_ASSOC, val.q);
|
||||
}
|
||||
|
||||
static int resctrl_arch_online_cpu(unsigned int cpu)
|
||||
|
||||
@@ -136,7 +136,7 @@ static int logical_rmid_to_physical_rmid(int cpu, int lrmid)
|
||||
|
||||
static int __rmid_read_phys(u32 prmid, enum resctrl_event_id eventid, u64 *val)
|
||||
{
|
||||
u64 msr_val;
|
||||
struct msr msr_val = { .l = eventid, .h = prmid };
|
||||
|
||||
/*
|
||||
* As per the SDM, when IA32_QM_EVTSEL.EvtID (bits 7:0) is configured
|
||||
@@ -146,15 +146,15 @@ static int __rmid_read_phys(u32 prmid, enum resctrl_event_id eventid, u64 *val)
|
||||
* IA32_QM_CTR.Error (bit 63) and IA32_QM_CTR.Unavailable (bit 62)
|
||||
* are error bits.
|
||||
*/
|
||||
wrmsr(MSR_IA32_QM_EVTSEL, eventid, prmid);
|
||||
rdmsrq(MSR_IA32_QM_CTR, msr_val);
|
||||
wrmsrq(MSR_IA32_QM_EVTSEL, msr_val.q);
|
||||
rdmsrq(MSR_IA32_QM_CTR, msr_val.q);
|
||||
|
||||
if (msr_val & RMID_VAL_ERROR)
|
||||
if (msr_val.q & RMID_VAL_ERROR)
|
||||
return -EIO;
|
||||
if (msr_val & RMID_VAL_UNAVAIL)
|
||||
if (msr_val.q & RMID_VAL_UNAVAIL)
|
||||
return -EINVAL;
|
||||
|
||||
*val = msr_val;
|
||||
*val = msr_val.q;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -283,7 +283,10 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain_hdr *hdr,
|
||||
|
||||
static int __cntr_id_read(u32 cntr_id, u64 *val)
|
||||
{
|
||||
u64 msr_val;
|
||||
struct msr msr_val = {
|
||||
.l = ABMC_EXTENDED_EVT_ID | ABMC_EVT_ID,
|
||||
.h = cntr_id
|
||||
};
|
||||
|
||||
/*
|
||||
* QM_EVTSEL Register definition:
|
||||
@@ -306,15 +309,15 @@ static int __cntr_id_read(u32 cntr_id, u64 *val)
|
||||
* ID is set in the QM_EVTSEL.RMID field. The RMID_VAL_UNAVAIL bit
|
||||
* is set if the counter data is unavailable.
|
||||
*/
|
||||
wrmsr(MSR_IA32_QM_EVTSEL, ABMC_EXTENDED_EVT_ID | ABMC_EVT_ID, cntr_id);
|
||||
rdmsrq(MSR_IA32_QM_CTR, msr_val);
|
||||
wrmsrq(MSR_IA32_QM_EVTSEL, msr_val.q);
|
||||
rdmsrq(MSR_IA32_QM_CTR, msr_val.q);
|
||||
|
||||
if (msr_val & RMID_VAL_ERROR)
|
||||
if (msr_val.q & RMID_VAL_ERROR)
|
||||
return -EIO;
|
||||
if (msr_val & RMID_VAL_UNAVAIL)
|
||||
if (msr_val.q & RMID_VAL_UNAVAIL)
|
||||
return -EINVAL;
|
||||
|
||||
*val = msr_val;
|
||||
*val = msr_val.q;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -241,16 +241,16 @@ int resctrl_arch_pseudo_lock_fn(void *_plr)
|
||||
int resctrl_arch_measure_cycles_lat_fn(void *_plr)
|
||||
{
|
||||
struct pseudo_lock_region *plr = _plr;
|
||||
u32 saved_low, saved_high;
|
||||
unsigned long i;
|
||||
u64 start, end;
|
||||
void *mem_r;
|
||||
u64 saved;
|
||||
|
||||
local_irq_disable();
|
||||
/*
|
||||
* Disable hardware prefetchers.
|
||||
*/
|
||||
rdmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high);
|
||||
rdmsrq(MSR_MISC_FEATURE_CONTROL, saved);
|
||||
wrmsrq(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits);
|
||||
mem_r = READ_ONCE(plr->kmem);
|
||||
/*
|
||||
@@ -267,7 +267,7 @@ int resctrl_arch_measure_cycles_lat_fn(void *_plr)
|
||||
end = rdtsc_ordered();
|
||||
trace_pseudo_lock_mem_latency((u32)(end - start));
|
||||
}
|
||||
wrmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high);
|
||||
wrmsrq(MSR_MISC_FEATURE_CONTROL, saved);
|
||||
local_irq_enable();
|
||||
plr->thread_done = 1;
|
||||
wake_up_interruptible(&plr->lock_thread_wq);
|
||||
@@ -312,11 +312,11 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr,
|
||||
u64 hits_before = 0, hits_after = 0, miss_before = 0, miss_after = 0;
|
||||
struct perf_event *miss_event, *hit_event;
|
||||
int hit_pmcnum, miss_pmcnum;
|
||||
u32 saved_low, saved_high;
|
||||
unsigned int line_size;
|
||||
unsigned int size;
|
||||
unsigned long i;
|
||||
void *mem_r;
|
||||
u64 saved;
|
||||
u64 tmp;
|
||||
|
||||
miss_event = perf_event_create_kernel_counter(miss_attr, plr->cpu,
|
||||
@@ -346,7 +346,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr,
|
||||
/*
|
||||
* Disable hardware prefetchers.
|
||||
*/
|
||||
rdmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high);
|
||||
rdmsrq(MSR_MISC_FEATURE_CONTROL, saved);
|
||||
wrmsrq(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits);
|
||||
|
||||
/* Initialize rest of local variables */
|
||||
@@ -405,7 +405,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr,
|
||||
*/
|
||||
rmb();
|
||||
/* Re-enable hardware prefetchers */
|
||||
wrmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high);
|
||||
wrmsrq(MSR_MISC_FEATURE_CONTROL, saved);
|
||||
local_irq_enable();
|
||||
out_hit:
|
||||
perf_event_release_kernel(hit_event);
|
||||
|
||||
@@ -24,7 +24,8 @@ static void early_init_transmeta(struct cpuinfo_x86 *c)
|
||||
|
||||
static void init_transmeta(struct cpuinfo_x86 *c)
|
||||
{
|
||||
unsigned int cap_mask, uk, max, dummy;
|
||||
u64 msr;
|
||||
unsigned int max, dummy;
|
||||
unsigned int cms_rev1, cms_rev2;
|
||||
unsigned int cpu_rev, cpu_freq = 0, cpu_flags, new_cpu_rev;
|
||||
char cpu_info[65];
|
||||
@@ -86,10 +87,10 @@ static void init_transmeta(struct cpuinfo_x86 *c)
|
||||
}
|
||||
|
||||
/* Unhide possibly hidden capability flags */
|
||||
rdmsr(0x80860004, cap_mask, uk);
|
||||
wrmsr(0x80860004, ~0, uk);
|
||||
rdmsrq(0x80860004, msr);
|
||||
wrmsrq(0x80860004, msr | ~0U);
|
||||
c->x86_capability[CPUID_1_EDX] = cpuid_edx(0x00000001);
|
||||
wrmsr(0x80860004, cap_mask, uk);
|
||||
wrmsrq(0x80860004, msr);
|
||||
|
||||
/* All Transmeta CPUs have a constant TSC */
|
||||
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
static void init_zhaoxin_cap(struct cpuinfo_x86 *c)
|
||||
{
|
||||
u32 lo, hi;
|
||||
u64 msr;
|
||||
|
||||
/* Test for Extended Feature Flags presence */
|
||||
if (cpuid_eax(0xC0000000) >= 0xC0000001) {
|
||||
@@ -29,19 +29,17 @@ static void init_zhaoxin_cap(struct cpuinfo_x86 *c)
|
||||
|
||||
/* Enable ACE unit, if present and disabled */
|
||||
if ((tmp & (ACE_PRESENT | ACE_ENABLED)) == ACE_PRESENT) {
|
||||
rdmsr(MSR_ZHAOXIN_FCR57, lo, hi);
|
||||
rdmsrq(MSR_ZHAOXIN_FCR57, msr);
|
||||
/* Enable ACE unit */
|
||||
lo |= ACE_FCR;
|
||||
wrmsr(MSR_ZHAOXIN_FCR57, lo, hi);
|
||||
wrmsrq(MSR_ZHAOXIN_FCR57, msr | ACE_FCR);
|
||||
pr_info("CPU: Enabled ACE h/w crypto\n");
|
||||
}
|
||||
|
||||
/* Enable RNG unit, if present and disabled */
|
||||
if ((tmp & (RNG_PRESENT | RNG_ENABLED)) == RNG_PRESENT) {
|
||||
rdmsr(MSR_ZHAOXIN_FCR57, lo, hi);
|
||||
rdmsrq(MSR_ZHAOXIN_FCR57, msr);
|
||||
/* Enable RNG unit */
|
||||
lo |= RNG_ENABLE;
|
||||
wrmsr(MSR_ZHAOXIN_FCR57, lo, hi);
|
||||
wrmsrq(MSR_ZHAOXIN_FCR57, msr | RNG_ENABLE);
|
||||
pr_info("CPU: Enabled h/w RNG\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -1221,11 +1221,11 @@ static void __init check_system_tsc_reliable(void)
|
||||
if (is_geode_lx()) {
|
||||
/* RTSC counts during suspend */
|
||||
#define RTSC_SUSP 0x100
|
||||
unsigned long res_low, res_high;
|
||||
u64 res;
|
||||
|
||||
rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high);
|
||||
rdmsrq_safe(MSR_GEODE_BUSCONT_CONF0, &res);
|
||||
/* Geode_LX - the OLPC CPU has a very reliable TSC */
|
||||
if (res_low & RTSC_SUSP)
|
||||
if (res & RTSC_SUSP)
|
||||
tsc_clocksource_reliable = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -165,7 +165,8 @@ static const struct x86_cpu_id tsc_msr_cpu_ids[] = {
|
||||
*/
|
||||
unsigned long cpu_khz_from_msr(void)
|
||||
{
|
||||
u32 lo, hi, ratio, freq, tscref;
|
||||
u32 ratio, freq, tscref;
|
||||
struct msr val;
|
||||
const struct freq_desc *freq_desc;
|
||||
const struct x86_cpu_id *id;
|
||||
const struct muldiv *md;
|
||||
@@ -178,16 +179,16 @@ unsigned long cpu_khz_from_msr(void)
|
||||
|
||||
freq_desc = (struct freq_desc *)id->driver_data;
|
||||
if (freq_desc->use_msr_plat) {
|
||||
rdmsr(MSR_PLATFORM_INFO, lo, hi);
|
||||
ratio = (lo >> 8) & 0xff;
|
||||
rdmsrq(MSR_PLATFORM_INFO, val.q);
|
||||
ratio = (val.l >> 8) & 0xff;
|
||||
} else {
|
||||
rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
|
||||
ratio = (hi >> 8) & 0x1f;
|
||||
rdmsrq(MSR_IA32_PERF_STATUS, val.q);
|
||||
ratio = (val.h >> 8) & 0x1f;
|
||||
}
|
||||
|
||||
/* Get FSB FREQ ID */
|
||||
rdmsr(MSR_FSB_FREQ, lo, hi);
|
||||
index = lo & freq_desc->mask;
|
||||
rdmsrq(MSR_FSB_FREQ, val.q);
|
||||
index = val.l & freq_desc->mask;
|
||||
md = &freq_desc->muldiv[index];
|
||||
|
||||
/*
|
||||
|
||||
+13
-11
@@ -2675,13 +2675,13 @@ static bool cpu_has_sgx(void)
|
||||
|
||||
static int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, u32 msr, u32 *result)
|
||||
{
|
||||
u32 vmx_msr_low, vmx_msr_high;
|
||||
struct msr vmx_msr;
|
||||
u32 ctl = ctl_min | ctl_opt;
|
||||
|
||||
rdmsr(msr, vmx_msr_low, vmx_msr_high);
|
||||
rdmsrq(msr, vmx_msr.q);
|
||||
|
||||
ctl &= vmx_msr_high; /* bit == 0 in high word ==> must be zero */
|
||||
ctl |= vmx_msr_low; /* bit == 1 in low word ==> must be one */
|
||||
ctl &= vmx_msr.h; /* bit == 0 in high word ==> must be zero */
|
||||
ctl |= vmx_msr.l; /* bit == 1 in low word ==> must be one */
|
||||
|
||||
/* Ensure minimum (required) set of control bits are supported. */
|
||||
if (ctl_min & ~ctl)
|
||||
@@ -2737,6 +2737,7 @@ static int setup_vmcs_config(struct vmcs_config *vmcs_conf,
|
||||
u64 _cpu_based_3rd_exec_control = 0;
|
||||
u32 _vmexit_control = 0;
|
||||
u32 _vmentry_control = 0;
|
||||
struct msr val;
|
||||
u64 basic_msr;
|
||||
u64 misc_msr;
|
||||
|
||||
@@ -2786,8 +2787,9 @@ static int setup_vmcs_config(struct vmcs_config *vmcs_conf,
|
||||
SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
|
||||
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
|
||||
|
||||
rdmsr_safe(MSR_IA32_VMX_EPT_VPID_CAP,
|
||||
&vmx_cap->ept, &vmx_cap->vpid);
|
||||
rdmsrq_safe(MSR_IA32_VMX_EPT_VPID_CAP, &val.q);
|
||||
vmx_cap->ept = val.l;
|
||||
vmx_cap->vpid = val.h;
|
||||
|
||||
if (!(_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_EPT) &&
|
||||
vmx_cap->ept) {
|
||||
@@ -4434,7 +4436,7 @@ void vmx_deliver_interrupt(struct kvm_lapic *apic, int delivery_mode,
|
||||
*/
|
||||
void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
|
||||
{
|
||||
u32 low32, high32;
|
||||
struct msr val;
|
||||
unsigned long tmpl;
|
||||
unsigned long cr0, cr3, cr4;
|
||||
|
||||
@@ -4475,8 +4477,8 @@ void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
|
||||
|
||||
vmcs_writel(HOST_RIP, (unsigned long)vmx_vmexit); /* 22.2.5 */
|
||||
|
||||
rdmsr(MSR_IA32_SYSENTER_CS, low32, high32);
|
||||
vmcs_write32(HOST_IA32_SYSENTER_CS, low32);
|
||||
rdmsrq(MSR_IA32_SYSENTER_CS, val.q);
|
||||
vmcs_write32(HOST_IA32_SYSENTER_CS, val.l);
|
||||
|
||||
/*
|
||||
* SYSENTER is used for 32-bit system calls on either 32-bit or
|
||||
@@ -4491,8 +4493,8 @@ void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
|
||||
vmcs_writel(HOST_IA32_SYSENTER_EIP, tmpl); /* 22.2.3 */
|
||||
|
||||
if (vmcs_config.vmexit_ctrl & VM_EXIT_LOAD_IA32_PAT) {
|
||||
rdmsr(MSR_IA32_CR_PAT, low32, high32);
|
||||
vmcs_write64(HOST_IA32_PAT, low32 | ((u64) high32 << 32));
|
||||
rdmsrq(MSR_IA32_CR_PAT, val.q);
|
||||
vmcs_write64(HOST_IA32_PAT, val.q);
|
||||
}
|
||||
|
||||
if (cpu_has_load_ia32_efer())
|
||||
|
||||
+2
-2
@@ -7633,9 +7633,9 @@ static void kvm_probe_feature_msr(u32 msr_index)
|
||||
|
||||
static void kvm_probe_msr_to_save(u32 msr_index)
|
||||
{
|
||||
u32 dummy[2];
|
||||
u64 dummy;
|
||||
|
||||
if (rdmsr_safe(msr_index, &dummy[0], &dummy[1]))
|
||||
if (rdmsrq_safe(msr_index, &dummy))
|
||||
return;
|
||||
|
||||
/*
|
||||
|
||||
@@ -15,7 +15,7 @@ static void __rdmsr_on_cpu(void *info)
|
||||
else
|
||||
reg = &rv->reg;
|
||||
|
||||
rdmsr(rv->msr_no, reg->l, reg->h);
|
||||
rdmsrq(rv->msr_no, reg->q);
|
||||
}
|
||||
|
||||
static void __wrmsr_on_cpu(void *info)
|
||||
@@ -28,7 +28,7 @@ static void __wrmsr_on_cpu(void *info)
|
||||
else
|
||||
reg = &rv->reg;
|
||||
|
||||
wrmsr(rv->msr_no, reg->l, reg->h);
|
||||
wrmsrq(rv->msr_no, reg->q);
|
||||
}
|
||||
|
||||
int rdmsrq_on_cpu(unsigned int cpu, u32 msr_no, u64 *q)
|
||||
@@ -121,7 +121,7 @@ static void __rdmsr_safe_on_cpu(void *info)
|
||||
{
|
||||
struct msr_info_completion *rv = info;
|
||||
|
||||
rv->msr.err = rdmsr_safe(rv->msr.msr_no, &rv->msr.reg.l, &rv->msr.reg.h);
|
||||
rv->msr.err = rdmsrq_safe(rv->msr.msr_no, &rv->msr.reg.q);
|
||||
complete(&rv->done);
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ static void __wrmsr_safe_on_cpu(void *info)
|
||||
{
|
||||
struct msr_info *rv = info;
|
||||
|
||||
rv->err = wrmsr_safe(rv->msr_no, rv->reg.l, rv->reg.h);
|
||||
rv->err = wrmsrq_safe(rv->msr_no, rv->reg.q);
|
||||
}
|
||||
|
||||
int wrmsrq_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 q)
|
||||
|
||||
@@ -189,7 +189,7 @@ static const char *__init pci_mmcfg_intel_945(void)
|
||||
|
||||
static const char *__init pci_mmcfg_amd_fam10h(void)
|
||||
{
|
||||
u32 low, high, address;
|
||||
u32 address;
|
||||
u64 base, msr;
|
||||
int i;
|
||||
unsigned segnbits = 0, busnbits, end_bus;
|
||||
@@ -198,13 +198,9 @@ static const char *__init pci_mmcfg_amd_fam10h(void)
|
||||
return NULL;
|
||||
|
||||
address = MSR_FAM10H_MMIO_CONF_BASE;
|
||||
if (rdmsr_safe(address, &low, &high))
|
||||
if (rdmsrq_safe(address, &msr))
|
||||
return NULL;
|
||||
|
||||
msr = high;
|
||||
msr <<= 32;
|
||||
msr |= low;
|
||||
|
||||
/* ECAM is not enabled */
|
||||
if (!(msr & FAM10H_MMIO_CONF_ENABLE))
|
||||
return NULL;
|
||||
|
||||
@@ -311,12 +311,13 @@ static int xo1_sci_resume(struct platform_device *pdev)
|
||||
|
||||
static int setup_sci_interrupt(struct platform_device *pdev)
|
||||
{
|
||||
u32 lo, hi;
|
||||
u64 msr;
|
||||
u32 lo;
|
||||
u32 sts;
|
||||
int r;
|
||||
|
||||
rdmsr(0x51400020, lo, hi);
|
||||
sci_irq = (lo >> 20) & 15;
|
||||
rdmsrq(0x51400020, msr);
|
||||
sci_irq = (msr >> 20) & 15;
|
||||
|
||||
if (sci_irq) {
|
||||
dev_info(&pdev->dev, "SCI is mapped to IRQ %d\n", sci_irq);
|
||||
@@ -324,8 +325,8 @@ static int setup_sci_interrupt(struct platform_device *pdev)
|
||||
/* Zero means masked */
|
||||
dev_info(&pdev->dev, "SCI unmapped. Mapping to IRQ 3\n");
|
||||
sci_irq = 3;
|
||||
lo |= 0x00300000;
|
||||
wrmsrq(0x51400020, lo);
|
||||
msr |= 0x00300000;
|
||||
wrmsrq(0x51400020, msr);
|
||||
}
|
||||
|
||||
/* Select level triggered in PIC */
|
||||
|
||||
@@ -1430,6 +1430,7 @@ static __init int record_keyid_partitioning(u32 *tdx_keyid_start,
|
||||
u32 *nr_tdx_keyids)
|
||||
{
|
||||
u32 _nr_mktme_keyids, _tdx_keyid_start, _nr_tdx_keyids;
|
||||
struct msr val;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
@@ -1437,8 +1438,9 @@ static __init int record_keyid_partitioning(u32 *tdx_keyid_start,
|
||||
* Bit [31:0]: Number of MKTME KeyIDs.
|
||||
* Bit [63:32]: Number of TDX private KeyIDs.
|
||||
*/
|
||||
ret = rdmsr_safe(MSR_IA32_MKTME_KEYID_PARTITIONING, &_nr_mktme_keyids,
|
||||
&_nr_tdx_keyids);
|
||||
ret = rdmsrq_safe(MSR_IA32_MKTME_KEYID_PARTITIONING, &val.q);
|
||||
_nr_mktme_keyids = val.l;
|
||||
_nr_tdx_keyids = val.h;
|
||||
if (ret || !_nr_tdx_keyids)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -287,7 +287,8 @@ end:
|
||||
*/
|
||||
static void amd_fixup_frequency(struct acpi_processor_px *px, int i)
|
||||
{
|
||||
u32 hi, lo, fid, did;
|
||||
struct msr val;
|
||||
u32 fid, did;
|
||||
int index = px->control & 0x00000007;
|
||||
|
||||
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
|
||||
@@ -295,16 +296,16 @@ static void amd_fixup_frequency(struct acpi_processor_px *px, int i)
|
||||
|
||||
if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) ||
|
||||
boot_cpu_data.x86 == 0x11) {
|
||||
rdmsr(MSR_AMD_PSTATE_DEF_BASE + index, lo, hi);
|
||||
rdmsrq(MSR_AMD_PSTATE_DEF_BASE + index, val.q);
|
||||
/*
|
||||
* MSR C001_0064+:
|
||||
* Bit 63: PstateEn. Read-write. If set, the P-state is valid.
|
||||
*/
|
||||
if (!(hi & BIT(31)))
|
||||
if (!(val.h & BIT(31)))
|
||||
return;
|
||||
|
||||
fid = lo & 0x3f;
|
||||
did = (lo >> 6) & 7;
|
||||
fid = val.l & 0x3f;
|
||||
did = (val.l >> 6) & 7;
|
||||
if (boot_cpu_data.x86 == 0x10)
|
||||
px->core_frequency = (100 * (fid + 0x10)) >> did;
|
||||
else
|
||||
|
||||
@@ -698,20 +698,13 @@ static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr)
|
||||
#ifdef CONFIG_X86
|
||||
static int acpi_throttling_rdmsr(u64 *value)
|
||||
{
|
||||
u64 msr_high, msr_low;
|
||||
u64 msr = 0;
|
||||
int ret = -1;
|
||||
|
||||
if ((this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_INTEL) ||
|
||||
!this_cpu_has(X86_FEATURE_ACPI)) {
|
||||
pr_err("HARDWARE addr space,NOT supported yet\n");
|
||||
} else {
|
||||
msr_low = 0;
|
||||
msr_high = 0;
|
||||
rdmsr_safe(MSR_IA32_THERM_CONTROL,
|
||||
(u32 *)&msr_low, (u32 *) &msr_high);
|
||||
msr = (msr_high << 32) | msr_low;
|
||||
*value = (u64) msr;
|
||||
rdmsrq_safe(MSR_IA32_THERM_CONTROL, value);
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
@@ -720,15 +713,12 @@ static int acpi_throttling_rdmsr(u64 *value)
|
||||
static int acpi_throttling_wrmsr(u64 value)
|
||||
{
|
||||
int ret = -1;
|
||||
u64 msr;
|
||||
|
||||
if ((this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_INTEL) ||
|
||||
!this_cpu_has(X86_FEATURE_ACPI)) {
|
||||
pr_err("HARDWARE addr space,NOT supported yet\n");
|
||||
} else {
|
||||
msr = value;
|
||||
wrmsr_safe(MSR_IA32_THERM_CONTROL,
|
||||
msr & 0xffffffff, msr >> 32);
|
||||
wrmsrq_safe(MSR_IA32_THERM_CONTROL, value);
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -246,32 +246,32 @@ static unsigned extract_freq(struct cpufreq_policy *policy, u32 val)
|
||||
|
||||
static u32 cpu_freq_read_intel(struct acpi_pct_register *not_used)
|
||||
{
|
||||
u32 val, dummy __always_unused;
|
||||
u64 val;
|
||||
|
||||
rdmsr(MSR_IA32_PERF_CTL, val, dummy);
|
||||
return val;
|
||||
rdmsrq(MSR_IA32_PERF_CTL, val);
|
||||
return (u32)val;
|
||||
}
|
||||
|
||||
static void cpu_freq_write_intel(struct acpi_pct_register *not_used, u32 val)
|
||||
{
|
||||
u32 lo, hi;
|
||||
u64 msrval;
|
||||
|
||||
rdmsr(MSR_IA32_PERF_CTL, lo, hi);
|
||||
lo = (lo & ~INTEL_MSR_RANGE) | (val & INTEL_MSR_RANGE);
|
||||
wrmsr(MSR_IA32_PERF_CTL, lo, hi);
|
||||
rdmsrq(MSR_IA32_PERF_CTL, msrval);
|
||||
msrval = (msrval & ~(u64)INTEL_MSR_RANGE) | (val & INTEL_MSR_RANGE);
|
||||
wrmsrq(MSR_IA32_PERF_CTL, msrval);
|
||||
}
|
||||
|
||||
static u32 cpu_freq_read_amd(struct acpi_pct_register *not_used)
|
||||
{
|
||||
u32 val, dummy __always_unused;
|
||||
u64 val;
|
||||
|
||||
rdmsr(MSR_AMD_PERF_CTL, val, dummy);
|
||||
return val;
|
||||
rdmsrq(MSR_AMD_PERF_CTL, val);
|
||||
return (u32)val;
|
||||
}
|
||||
|
||||
static void cpu_freq_write_amd(struct acpi_pct_register *not_used, u32 val)
|
||||
{
|
||||
wrmsr(MSR_AMD_PERF_CTL, val, 0);
|
||||
wrmsrq(MSR_AMD_PERF_CTL, val);
|
||||
}
|
||||
|
||||
static u32 cpu_freq_read_io(struct acpi_pct_register *reg)
|
||||
|
||||
@@ -90,7 +90,7 @@ static int eps_acpi_exit(struct cpufreq_policy *policy)
|
||||
static unsigned int eps_get(unsigned int cpu)
|
||||
{
|
||||
struct eps_cpu_data *centaur;
|
||||
u32 lo, hi;
|
||||
u64 val;
|
||||
|
||||
if (cpu)
|
||||
return 0;
|
||||
@@ -99,50 +99,50 @@ static unsigned int eps_get(unsigned int cpu)
|
||||
return 0;
|
||||
|
||||
/* Return current frequency */
|
||||
rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
|
||||
return centaur->fsb * ((lo >> 8) & 0xff);
|
||||
rdmsrq(MSR_IA32_PERF_STATUS, val);
|
||||
return centaur->fsb * ((val >> 8) & 0xff);
|
||||
}
|
||||
|
||||
static int eps_set_state(struct eps_cpu_data *centaur,
|
||||
struct cpufreq_policy *policy,
|
||||
u32 dest_state)
|
||||
{
|
||||
u32 lo, hi;
|
||||
u64 val;
|
||||
int i;
|
||||
|
||||
/* Wait while CPU is busy */
|
||||
rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
|
||||
rdmsrq(MSR_IA32_PERF_STATUS, val);
|
||||
i = 0;
|
||||
while (lo & ((1 << 16) | (1 << 17))) {
|
||||
while (val & ((1 << 16) | (1 << 17))) {
|
||||
udelay(16);
|
||||
rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
|
||||
rdmsrq(MSR_IA32_PERF_STATUS, val);
|
||||
i++;
|
||||
if (unlikely(i > 64)) {
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
/* Set new multiplier and voltage */
|
||||
wrmsr(MSR_IA32_PERF_CTL, dest_state & 0xffff, 0);
|
||||
wrmsrq(MSR_IA32_PERF_CTL, dest_state & 0xffff);
|
||||
/* Wait until transition end */
|
||||
i = 0;
|
||||
do {
|
||||
udelay(16);
|
||||
rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
|
||||
rdmsrq(MSR_IA32_PERF_STATUS, val);
|
||||
i++;
|
||||
if (unlikely(i > 64)) {
|
||||
return -ENODEV;
|
||||
}
|
||||
} while (lo & ((1 << 16) | (1 << 17)));
|
||||
} while (val & ((1 << 16) | (1 << 17)));
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
u8 current_multiplier, current_voltage;
|
||||
|
||||
/* Print voltage and multiplier */
|
||||
rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
|
||||
current_voltage = lo & 0xff;
|
||||
rdmsrq(MSR_IA32_PERF_STATUS, val);
|
||||
current_voltage = val & 0xff;
|
||||
pr_info("Current voltage = %dmV\n", current_voltage * 16 + 700);
|
||||
current_multiplier = (lo >> 8) & 0xff;
|
||||
current_multiplier = (val >> 8) & 0xff;
|
||||
pr_info("Current multiplier = %d\n", current_multiplier);
|
||||
}
|
||||
#endif
|
||||
@@ -171,7 +171,6 @@ static int eps_target(struct cpufreq_policy *policy, unsigned int index)
|
||||
static int eps_cpu_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
unsigned int i;
|
||||
u32 lo, hi;
|
||||
u64 val;
|
||||
u8 current_multiplier, current_voltage;
|
||||
u8 max_multiplier, max_voltage;
|
||||
@@ -195,13 +194,13 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
|
||||
|
||||
switch (c->x86_model) {
|
||||
case 10:
|
||||
rdmsr(0x1153, lo, hi);
|
||||
brand = (((lo >> 2) ^ lo) >> 18) & 3;
|
||||
rdmsrq(0x1153, val);
|
||||
brand = (((val >> 2) ^ val) >> 18) & 3;
|
||||
pr_cont("Model A ");
|
||||
break;
|
||||
case 13:
|
||||
rdmsr(0x1154, lo, hi);
|
||||
brand = (((lo >> 4) ^ (lo >> 2))) & 0x000000ff;
|
||||
rdmsrq(0x1154, val);
|
||||
brand = (((val >> 4) ^ (val >> 2))) & 0x000000ff;
|
||||
pr_cont("Model D ");
|
||||
break;
|
||||
}
|
||||
@@ -237,20 +236,20 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
|
||||
}
|
||||
|
||||
/* Print voltage and multiplier */
|
||||
rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
|
||||
current_voltage = lo & 0xff;
|
||||
rdmsrq(MSR_IA32_PERF_STATUS, val);
|
||||
current_voltage = val & 0xff;
|
||||
pr_info("Current voltage = %dmV\n", current_voltage * 16 + 700);
|
||||
current_multiplier = (lo >> 8) & 0xff;
|
||||
current_multiplier = (val >> 8) & 0xff;
|
||||
pr_info("Current multiplier = %d\n", current_multiplier);
|
||||
|
||||
/* Print limits */
|
||||
max_voltage = hi & 0xff;
|
||||
max_voltage = (val >> 32) & 0xff;
|
||||
pr_info("Highest voltage = %dmV\n", max_voltage * 16 + 700);
|
||||
max_multiplier = (hi >> 8) & 0xff;
|
||||
max_multiplier = (val >> 40) & 0xff;
|
||||
pr_info("Highest multiplier = %d\n", max_multiplier);
|
||||
min_voltage = (hi >> 16) & 0xff;
|
||||
min_voltage = (val >> 48) & 0xff;
|
||||
pr_info("Lowest voltage = %dmV\n", min_voltage * 16 + 700);
|
||||
min_multiplier = (hi >> 24) & 0xff;
|
||||
min_multiplier = (val >> 56) & 0xff;
|
||||
pr_info("Lowest multiplier = %d\n", min_multiplier);
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
@@ -118,13 +118,14 @@ static unsigned int calc_speed(int mult)
|
||||
|
||||
static int longhaul_get_cpu_mult(void)
|
||||
{
|
||||
unsigned long invalue = 0, lo, hi;
|
||||
unsigned long invalue = 0;
|
||||
u64 val;
|
||||
|
||||
rdmsr(MSR_IA32_EBL_CR_POWERON, lo, hi);
|
||||
invalue = (lo & (1<<22|1<<23|1<<24|1<<25))>>22;
|
||||
rdmsrq(MSR_IA32_EBL_CR_POWERON, val);
|
||||
invalue = (val & (1<<22|1<<23|1<<24|1<<25))>>22;
|
||||
if (longhaul_version == TYPE_LONGHAUL_V2 ||
|
||||
longhaul_version == TYPE_POWERSAVER) {
|
||||
if (lo & (1<<27))
|
||||
if (val & (1<<27))
|
||||
invalue += 16;
|
||||
}
|
||||
return eblcr[invalue];
|
||||
@@ -761,7 +762,7 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy)
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
char *cpuname = NULL;
|
||||
int ret;
|
||||
u32 lo, hi;
|
||||
u64 val;
|
||||
|
||||
/* Check what we have on this motherboard */
|
||||
switch (c->x86_model) {
|
||||
@@ -835,8 +836,8 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy)
|
||||
}
|
||||
/* Check Longhaul ver. 2 */
|
||||
if (longhaul_version == TYPE_LONGHAUL_V2) {
|
||||
rdmsr(MSR_VIA_LONGHAUL, lo, hi);
|
||||
if (lo == 0 && hi == 0)
|
||||
rdmsrq(MSR_VIA_LONGHAUL, val);
|
||||
if (val == 0)
|
||||
/* Looks like MSR isn't present */
|
||||
longhaul_version = TYPE_LONGHAUL_V1;
|
||||
}
|
||||
|
||||
+39
-38
@@ -35,27 +35,27 @@ static unsigned int longrun_low_freq, longrun_high_freq;
|
||||
*/
|
||||
static void longrun_get_policy(struct cpufreq_policy *policy)
|
||||
{
|
||||
u32 msr_lo, msr_hi;
|
||||
struct msr msr;
|
||||
|
||||
rdmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi);
|
||||
pr_debug("longrun flags are %x - %x\n", msr_lo, msr_hi);
|
||||
if (msr_lo & 0x01)
|
||||
rdmsrq(MSR_TMTA_LONGRUN_FLAGS, msr.q);
|
||||
pr_debug("longrun flags are %x - %x\n", msr.l, msr.h);
|
||||
if (msr.l & 0x01)
|
||||
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
|
||||
else
|
||||
policy->policy = CPUFREQ_POLICY_POWERSAVE;
|
||||
|
||||
rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
|
||||
pr_debug("longrun ctrl is %x - %x\n", msr_lo, msr_hi);
|
||||
msr_lo &= 0x0000007F;
|
||||
msr_hi &= 0x0000007F;
|
||||
rdmsrq(MSR_TMTA_LONGRUN_CTRL, msr.q);
|
||||
pr_debug("longrun ctrl is %x - %x\n", msr.l, msr.h);
|
||||
msr.l &= 0x0000007F;
|
||||
msr.h &= 0x0000007F;
|
||||
|
||||
if (longrun_high_freq <= longrun_low_freq) {
|
||||
/* Assume degenerate Longrun table */
|
||||
policy->min = policy->max = longrun_high_freq;
|
||||
} else {
|
||||
policy->min = longrun_low_freq + msr_lo *
|
||||
policy->min = longrun_low_freq + msr.l *
|
||||
((longrun_high_freq - longrun_low_freq) / 100);
|
||||
policy->max = longrun_low_freq + msr_hi *
|
||||
policy->max = longrun_low_freq + msr.h *
|
||||
((longrun_high_freq - longrun_low_freq) / 100);
|
||||
}
|
||||
policy->cpu = 0;
|
||||
@@ -71,7 +71,7 @@ static void longrun_get_policy(struct cpufreq_policy *policy)
|
||||
*/
|
||||
static int longrun_set_policy(struct cpufreq_policy *policy)
|
||||
{
|
||||
u32 msr_lo, msr_hi;
|
||||
struct msr msr;
|
||||
u32 pctg_lo, pctg_hi;
|
||||
|
||||
if (!policy)
|
||||
@@ -93,24 +93,24 @@ static int longrun_set_policy(struct cpufreq_policy *policy)
|
||||
pctg_lo = pctg_hi;
|
||||
|
||||
/* performance or economy mode */
|
||||
rdmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi);
|
||||
msr_lo &= 0xFFFFFFFE;
|
||||
rdmsrq(MSR_TMTA_LONGRUN_FLAGS, msr.q);
|
||||
msr.l &= 0xFFFFFFFE;
|
||||
switch (policy->policy) {
|
||||
case CPUFREQ_POLICY_PERFORMANCE:
|
||||
msr_lo |= 0x00000001;
|
||||
msr.l |= 0x00000001;
|
||||
break;
|
||||
case CPUFREQ_POLICY_POWERSAVE:
|
||||
break;
|
||||
}
|
||||
wrmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi);
|
||||
wrmsrq(MSR_TMTA_LONGRUN_FLAGS, msr.q);
|
||||
|
||||
/* lower and upper boundary */
|
||||
rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
|
||||
msr_lo &= 0xFFFFFF80;
|
||||
msr_hi &= 0xFFFFFF80;
|
||||
msr_lo |= pctg_lo;
|
||||
msr_hi |= pctg_hi;
|
||||
wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
|
||||
rdmsrq(MSR_TMTA_LONGRUN_CTRL, msr.q);
|
||||
msr.l &= 0xFFFFFF80;
|
||||
msr.h &= 0xFFFFFF80;
|
||||
msr.l |= pctg_lo;
|
||||
msr.h |= pctg_hi;
|
||||
wrmsrq(MSR_TMTA_LONGRUN_CTRL, msr.q);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -160,8 +160,7 @@ static unsigned int longrun_get(unsigned int cpu)
|
||||
static int longrun_determine_freqs(unsigned int *low_freq,
|
||||
unsigned int *high_freq)
|
||||
{
|
||||
u32 msr_lo, msr_hi;
|
||||
u32 save_lo, save_hi;
|
||||
struct msr msr, save;
|
||||
u32 eax, ebx, ecx, edx;
|
||||
u32 try_hi;
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
@@ -178,15 +177,17 @@ static int longrun_determine_freqs(unsigned int *low_freq,
|
||||
* For maximum frequency, read out level zero.
|
||||
*/
|
||||
/* minimum */
|
||||
rdmsr(MSR_TMTA_LRTI_READOUT, msr_lo, msr_hi);
|
||||
wrmsr(MSR_TMTA_LRTI_READOUT, msr_hi, msr_hi);
|
||||
rdmsr(MSR_TMTA_LRTI_VOLT_MHZ, msr_lo, msr_hi);
|
||||
*low_freq = msr_lo * 1000; /* to kHz */
|
||||
rdmsrq(MSR_TMTA_LRTI_READOUT, msr.q);
|
||||
msr.l = msr.h;
|
||||
wrmsrq(MSR_TMTA_LRTI_READOUT, msr.q);
|
||||
rdmsrq(MSR_TMTA_LRTI_VOLT_MHZ, msr.q);
|
||||
*low_freq = msr.l * 1000; /* to kHz */
|
||||
|
||||
/* maximum */
|
||||
wrmsr(MSR_TMTA_LRTI_READOUT, 0, msr_hi);
|
||||
rdmsr(MSR_TMTA_LRTI_VOLT_MHZ, msr_lo, msr_hi);
|
||||
*high_freq = msr_lo * 1000; /* to kHz */
|
||||
msr.l = 0;
|
||||
wrmsrq(MSR_TMTA_LRTI_READOUT, msr.q);
|
||||
rdmsrq(MSR_TMTA_LRTI_VOLT_MHZ, msr.q);
|
||||
*high_freq = msr.l * 1000; /* to kHz */
|
||||
|
||||
pr_debug("longrun table interface told %u - %u kHz\n",
|
||||
*low_freq, *high_freq);
|
||||
@@ -202,9 +203,9 @@ static int longrun_determine_freqs(unsigned int *low_freq,
|
||||
pr_debug("high frequency is %u kHz\n", *high_freq);
|
||||
|
||||
/* get current borders */
|
||||
rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
|
||||
save_lo = msr_lo & 0x0000007F;
|
||||
save_hi = msr_hi & 0x0000007F;
|
||||
rdmsrq(MSR_TMTA_LONGRUN_CTRL, msr.q);
|
||||
save.l = msr.l & 0x0000007F;
|
||||
save.h = msr.h & 0x0000007F;
|
||||
|
||||
/* if current perf_pctg is larger than 90%, we need to decrease the
|
||||
* upper limit to make the calculation more accurate.
|
||||
@@ -214,16 +215,16 @@ static int longrun_determine_freqs(unsigned int *low_freq,
|
||||
* on some barrier values */
|
||||
for (try_hi = 80; try_hi > 0 && ecx > 90; try_hi -= 10) {
|
||||
/* set to 0 to try_hi perf_pctg */
|
||||
msr_lo &= 0xFFFFFF80;
|
||||
msr_hi &= 0xFFFFFF80;
|
||||
msr_hi |= try_hi;
|
||||
wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
|
||||
msr.l &= 0xFFFFFF80;
|
||||
msr.h &= 0xFFFFFF80;
|
||||
msr.h |= try_hi;
|
||||
wrmsrq(MSR_TMTA_LONGRUN_CTRL, msr.q);
|
||||
|
||||
/* read out current core MHz and current perf_pctg */
|
||||
cpuid(0x80860007, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
/* restore values */
|
||||
wrmsr(MSR_TMTA_LONGRUN_CTRL, save_lo, save_hi);
|
||||
wrmsrq(MSR_TMTA_LONGRUN_CTRL, save.q);
|
||||
}
|
||||
pr_debug("percentage is %u %%, freq is %u MHz\n", ecx, eax);
|
||||
|
||||
|
||||
@@ -83,15 +83,15 @@ static const struct {
|
||||
static int powernow_k6_get_cpu_multiplier(void)
|
||||
{
|
||||
unsigned long invalue = 0;
|
||||
u32 msrval;
|
||||
u64 msrval;
|
||||
|
||||
local_irq_disable();
|
||||
|
||||
msrval = POWERNOW_IOPORT + 0x1;
|
||||
wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
|
||||
wrmsrq(MSR_K6_EPMR, msrval); /* enable the PowerNow port */
|
||||
invalue = inl(POWERNOW_IOPORT + 0x8);
|
||||
msrval = POWERNOW_IOPORT + 0x0;
|
||||
wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
|
||||
wrmsrq(MSR_K6_EPMR, msrval); /* disable it again */
|
||||
|
||||
local_irq_enable();
|
||||
|
||||
@@ -101,8 +101,8 @@ static int powernow_k6_get_cpu_multiplier(void)
|
||||
static void powernow_k6_set_cpu_multiplier(unsigned int best_i)
|
||||
{
|
||||
unsigned long outvalue, invalue;
|
||||
unsigned long msrval;
|
||||
unsigned long cr0;
|
||||
u64 msrval;
|
||||
|
||||
/* we now need to transform best_i to the BVC format, see AMD#23446 */
|
||||
|
||||
@@ -118,13 +118,13 @@ static void powernow_k6_set_cpu_multiplier(unsigned int best_i)
|
||||
outvalue = (1<<12) | (1<<10) | (1<<9) | (index_to_register[best_i]<<5);
|
||||
|
||||
msrval = POWERNOW_IOPORT + 0x1;
|
||||
wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
|
||||
wrmsrq(MSR_K6_EPMR, msrval); /* enable the PowerNow port */
|
||||
invalue = inl(POWERNOW_IOPORT + 0x8);
|
||||
invalue = invalue & 0x1f;
|
||||
outvalue = outvalue | invalue;
|
||||
outl(outvalue, (POWERNOW_IOPORT + 0x8));
|
||||
msrval = POWERNOW_IOPORT + 0x0;
|
||||
wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
|
||||
wrmsrq(MSR_K6_EPMR, msrval); /* disable it again */
|
||||
|
||||
write_cr0(cr0);
|
||||
local_irq_enable();
|
||||
|
||||
@@ -87,10 +87,10 @@ static u32 convert_fid_to_vco_fid(u32 fid)
|
||||
*/
|
||||
static int pending_bit_stuck(void)
|
||||
{
|
||||
u32 lo, hi __always_unused;
|
||||
u64 msr;
|
||||
|
||||
rdmsr(MSR_FIDVID_STATUS, lo, hi);
|
||||
return lo & MSR_S_LO_CHANGE_PENDING ? 1 : 0;
|
||||
rdmsrq(MSR_FIDVID_STATUS, msr);
|
||||
return msr & MSR_S_LO_CHANGE_PENDING ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -99,7 +99,7 @@ static int pending_bit_stuck(void)
|
||||
*/
|
||||
static int query_current_values_with_pending_wait(struct powernow_k8_data *data)
|
||||
{
|
||||
u32 lo, hi;
|
||||
struct msr msr;
|
||||
u32 i = 0;
|
||||
|
||||
do {
|
||||
@@ -107,11 +107,11 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data)
|
||||
pr_debug("detected change pending stuck\n");
|
||||
return 1;
|
||||
}
|
||||
rdmsr(MSR_FIDVID_STATUS, lo, hi);
|
||||
} while (lo & MSR_S_LO_CHANGE_PENDING);
|
||||
rdmsrq(MSR_FIDVID_STATUS, msr.q);
|
||||
} while (msr.l & MSR_S_LO_CHANGE_PENDING);
|
||||
|
||||
data->currvid = hi & MSR_S_HI_CURRENT_VID;
|
||||
data->currfid = lo & MSR_S_LO_CURRENT_FID;
|
||||
data->currvid = msr.h & MSR_S_HI_CURRENT_VID;
|
||||
data->currfid = msr.l & MSR_S_LO_CURRENT_FID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -131,22 +131,22 @@ static void count_off_vst(struct powernow_k8_data *data)
|
||||
/* need to init the control msr to a safe value (for each cpu) */
|
||||
static void fidvid_msr_init(void)
|
||||
{
|
||||
u32 lo, hi;
|
||||
struct msr msr;
|
||||
u8 fid, vid;
|
||||
|
||||
rdmsr(MSR_FIDVID_STATUS, lo, hi);
|
||||
vid = hi & MSR_S_HI_CURRENT_VID;
|
||||
fid = lo & MSR_S_LO_CURRENT_FID;
|
||||
lo = fid | (vid << MSR_C_LO_VID_SHIFT);
|
||||
hi = MSR_C_HI_STP_GNT_BENIGN;
|
||||
pr_debug("cpu%d, init lo 0x%x, hi 0x%x\n", smp_processor_id(), lo, hi);
|
||||
wrmsr(MSR_FIDVID_CTL, lo, hi);
|
||||
rdmsrq(MSR_FIDVID_STATUS, msr.q);
|
||||
vid = msr.h & MSR_S_HI_CURRENT_VID;
|
||||
fid = msr.l & MSR_S_LO_CURRENT_FID;
|
||||
msr.l = fid | (vid << MSR_C_LO_VID_SHIFT);
|
||||
msr.h = MSR_C_HI_STP_GNT_BENIGN;
|
||||
pr_debug("cpu%d, init lo 0x%x, hi 0x%x\n", smp_processor_id(), msr.l, msr.h);
|
||||
wrmsrq(MSR_FIDVID_CTL, msr.q);
|
||||
}
|
||||
|
||||
/* write the new fid value along with the other control fields to the msr */
|
||||
static int write_new_fid(struct powernow_k8_data *data, u32 fid)
|
||||
{
|
||||
u32 lo;
|
||||
struct msr msr;
|
||||
u32 savevid = data->currvid;
|
||||
u32 i = 0;
|
||||
|
||||
@@ -155,15 +155,15 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid)
|
||||
return 1;
|
||||
}
|
||||
|
||||
lo = fid;
|
||||
lo |= (data->currvid << MSR_C_LO_VID_SHIFT);
|
||||
lo |= MSR_C_LO_INIT_FID_VID;
|
||||
msr.l = fid;
|
||||
msr.l |= (data->currvid << MSR_C_LO_VID_SHIFT);
|
||||
msr.l |= MSR_C_LO_INIT_FID_VID;
|
||||
msr.h = data->plllock * PLL_LOCK_CONVERSION;
|
||||
|
||||
pr_debug("writing fid 0x%x, lo 0x%x, hi 0x%x\n",
|
||||
fid, lo, data->plllock * PLL_LOCK_CONVERSION);
|
||||
pr_debug("writing fid 0x%x, lo 0x%x, hi 0x%x\n", fid, msr.l, msr.h);
|
||||
|
||||
do {
|
||||
wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION);
|
||||
wrmsrq(MSR_FIDVID_CTL, msr.q);
|
||||
if (i++ > 100) {
|
||||
pr_err("Hardware error - pending bit very stuck - no further pstate changes possible\n");
|
||||
return 1;
|
||||
@@ -190,7 +190,7 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid)
|
||||
/* Write a new vid to the hardware */
|
||||
static int write_new_vid(struct powernow_k8_data *data, u32 vid)
|
||||
{
|
||||
u32 lo;
|
||||
struct msr msr;
|
||||
u32 savefid = data->currfid;
|
||||
int i = 0;
|
||||
|
||||
@@ -199,15 +199,15 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid)
|
||||
return 1;
|
||||
}
|
||||
|
||||
lo = data->currfid;
|
||||
lo |= (vid << MSR_C_LO_VID_SHIFT);
|
||||
lo |= MSR_C_LO_INIT_FID_VID;
|
||||
msr.l = data->currfid;
|
||||
msr.l |= (vid << MSR_C_LO_VID_SHIFT);
|
||||
msr.l |= MSR_C_LO_INIT_FID_VID;
|
||||
msr.h = STOP_GRANT_5NS;
|
||||
|
||||
pr_debug("writing vid 0x%x, lo 0x%x, hi 0x%x\n",
|
||||
vid, lo, STOP_GRANT_5NS);
|
||||
pr_debug("writing vid 0x%x, lo 0x%x, hi 0x%x\n", vid, msr.l, msr.h);
|
||||
|
||||
do {
|
||||
wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
|
||||
wrmsrq(MSR_FIDVID_CTL, msr.q);
|
||||
if (i++ > 100) {
|
||||
pr_err("internal error - pending bit very stuck - no further pstate changes possible\n");
|
||||
return 1;
|
||||
@@ -281,9 +281,10 @@ static int transition_fid_vid(struct powernow_k8_data *data,
|
||||
static int core_voltage_pre_transition(struct powernow_k8_data *data,
|
||||
u32 reqvid, u32 reqfid)
|
||||
{
|
||||
struct msr msr;
|
||||
u32 rvosteps = data->rvo;
|
||||
u32 savefid = data->currfid;
|
||||
u32 maxvid, lo __always_unused, rvomult = 1;
|
||||
u32 maxvid, rvomult = 1;
|
||||
|
||||
pr_debug("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n",
|
||||
smp_processor_id(),
|
||||
@@ -292,8 +293,8 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data,
|
||||
if ((savefid < LO_FID_TABLE_TOP) && (reqfid < LO_FID_TABLE_TOP))
|
||||
rvomult = 2;
|
||||
rvosteps *= rvomult;
|
||||
rdmsr(MSR_FIDVID_STATUS, lo, maxvid);
|
||||
maxvid = 0x1f & (maxvid >> 16);
|
||||
rdmsrq(MSR_FIDVID_STATUS, msr.q);
|
||||
maxvid = 0x1f & (msr.h >> 16);
|
||||
pr_debug("ph1 maxvid=0x%x\n", maxvid);
|
||||
if (reqvid < maxvid) /* lower numbers are higher voltages */
|
||||
reqvid = maxvid;
|
||||
|
||||
@@ -345,7 +345,7 @@ static unsigned int get_cur_freq(unsigned int cpu)
|
||||
static int centrino_cpu_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu);
|
||||
unsigned l, h;
|
||||
u64 q;
|
||||
int i;
|
||||
|
||||
/* Only Intel makes Enhanced Speedstep-capable CPUs */
|
||||
@@ -378,16 +378,16 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
|
||||
|
||||
/* Check to see if Enhanced SpeedStep is enabled, and try to
|
||||
enable it if not. */
|
||||
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
|
||||
rdmsrq(MSR_IA32_MISC_ENABLE, q);
|
||||
|
||||
if (!(l & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
|
||||
l |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP;
|
||||
pr_debug("trying to enable Enhanced SpeedStep (%x)\n", l);
|
||||
wrmsr(MSR_IA32_MISC_ENABLE, l, h);
|
||||
if (!(q & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
|
||||
q |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP;
|
||||
pr_debug("trying to enable Enhanced SpeedStep (%x)\n", (u32)q);
|
||||
wrmsrq(MSR_IA32_MISC_ENABLE, q);
|
||||
|
||||
/* check to see if it stuck */
|
||||
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
|
||||
if (!(l & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
|
||||
rdmsrq(MSR_IA32_MISC_ENABLE, q);
|
||||
if (!(q & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
|
||||
pr_info("couldn't enable Enhanced SpeedStep\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -69,13 +69,14 @@ static unsigned int pentium3_get_frequency(enum speedstep_processor processor)
|
||||
{ 0, 0xff}
|
||||
};
|
||||
|
||||
struct msr msr;
|
||||
u32 msr_lo, msr_tmp;
|
||||
int i = 0, j = 0;
|
||||
|
||||
/* read MSR 0x2a - we only need the low 32 bits */
|
||||
rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
|
||||
pr_debug("P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
|
||||
msr_tmp = msr_lo;
|
||||
rdmsrq(MSR_IA32_EBL_CR_POWERON, msr.q);
|
||||
pr_debug("P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr.l, msr.h);
|
||||
msr_tmp = msr_lo = msr.l;
|
||||
|
||||
/* decode the FSB */
|
||||
msr_tmp &= 0x00c0000;
|
||||
@@ -108,19 +109,20 @@ static unsigned int pentium3_get_frequency(enum speedstep_processor processor)
|
||||
|
||||
static unsigned int pentiumM_get_frequency(void)
|
||||
{
|
||||
u32 msr_lo, msr_tmp;
|
||||
struct msr msr;
|
||||
u32 msr_tmp;
|
||||
|
||||
rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
|
||||
pr_debug("PM - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
|
||||
rdmsrq(MSR_IA32_EBL_CR_POWERON, msr.q);
|
||||
pr_debug("PM - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr.l, msr.h);
|
||||
|
||||
/* see table B-2 of 24547212.pdf */
|
||||
if (msr_lo & 0x00040000) {
|
||||
if (msr.l & 0x00040000) {
|
||||
printk(KERN_DEBUG PFX "PM - invalid FSB: 0x%x 0x%x\n",
|
||||
msr_lo, msr_tmp);
|
||||
msr.l, msr.h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
msr_tmp = (msr_lo >> 22) & 0x1f;
|
||||
msr_tmp = (msr.l >> 22) & 0x1f;
|
||||
pr_debug("bits 22-26 are 0x%x, speed is %u\n",
|
||||
msr_tmp, (msr_tmp * 100 * 1000));
|
||||
|
||||
@@ -129,13 +131,14 @@ static unsigned int pentiumM_get_frequency(void)
|
||||
|
||||
static unsigned int pentium_core_get_frequency(void)
|
||||
{
|
||||
struct msr msr;
|
||||
u32 fsb = 0;
|
||||
u32 msr_lo, msr_tmp;
|
||||
u32 msr_tmp;
|
||||
int ret;
|
||||
|
||||
rdmsr(MSR_FSB_FREQ, msr_lo, msr_tmp);
|
||||
rdmsrq(MSR_FSB_FREQ, msr.q);
|
||||
/* see table B-2 of 25366920.pdf */
|
||||
switch (msr_lo & 0x07) {
|
||||
switch (msr.l & 0x07) {
|
||||
case 5:
|
||||
fsb = 100000;
|
||||
break;
|
||||
@@ -158,11 +161,11 @@ static unsigned int pentium_core_get_frequency(void)
|
||||
pr_err("PCORE - MSR_FSB_FREQ undefined value\n");
|
||||
}
|
||||
|
||||
rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
|
||||
rdmsrq(MSR_IA32_EBL_CR_POWERON, msr.q);
|
||||
pr_debug("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n",
|
||||
msr_lo, msr_tmp);
|
||||
msr.l, msr.h);
|
||||
|
||||
msr_tmp = (msr_lo >> 22) & 0x1f;
|
||||
msr_tmp = (msr.l >> 22) & 0x1f;
|
||||
pr_debug("bits 22-26 are 0x%x, speed is %u\n",
|
||||
msr_tmp, (msr_tmp * fsb));
|
||||
|
||||
@@ -174,7 +177,8 @@ static unsigned int pentium_core_get_frequency(void)
|
||||
static unsigned int pentium4_get_frequency(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &boot_cpu_data;
|
||||
u32 msr_lo, msr_hi, mult;
|
||||
struct msr msr;
|
||||
u32 mult;
|
||||
unsigned int fsb = 0;
|
||||
unsigned int ret;
|
||||
u8 fsb_code;
|
||||
@@ -187,16 +191,16 @@ static unsigned int pentium4_get_frequency(void)
|
||||
if (c->x86_model < 2)
|
||||
return cpu_khz;
|
||||
|
||||
rdmsr(0x2c, msr_lo, msr_hi);
|
||||
rdmsrq(0x2c, msr.q);
|
||||
|
||||
pr_debug("P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi);
|
||||
pr_debug("P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr.l, msr.h);
|
||||
|
||||
/* decode the FSB: see IA-32 Intel (C) Architecture Software
|
||||
* Developer's Manual, Volume 3: System Prgramming Guide,
|
||||
* revision #12 in Table B-1: MSRs in the Pentium 4 and
|
||||
* Intel Xeon Processors, on page B-4 and B-5.
|
||||
*/
|
||||
fsb_code = (msr_lo >> 16) & 0x7;
|
||||
fsb_code = (msr.l >> 16) & 0x7;
|
||||
switch (fsb_code) {
|
||||
case 0:
|
||||
fsb = 100 * 1000;
|
||||
@@ -214,7 +218,7 @@ static unsigned int pentium4_get_frequency(void)
|
||||
"Please send an e-mail to <linux@brodo.de>\n");
|
||||
|
||||
/* Multiplier. */
|
||||
mult = msr_lo >> 24;
|
||||
mult = msr.l >> 24;
|
||||
|
||||
pr_debug("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n",
|
||||
fsb, mult, (fsb * mult));
|
||||
@@ -255,7 +259,8 @@ EXPORT_SYMBOL_GPL(speedstep_get_frequency);
|
||||
enum speedstep_processor speedstep_detect_processor(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
u32 ebx, msr_lo, msr_hi;
|
||||
struct msr msr;
|
||||
u32 ebx;
|
||||
|
||||
pr_debug("x86: %x, model: %x\n", c->x86, c->x86_model);
|
||||
|
||||
@@ -343,11 +348,11 @@ enum speedstep_processor speedstep_detect_processor(void)
|
||||
|
||||
/* all mobile PIII Coppermines have FSB 100 MHz
|
||||
* ==> sort out a few desktop PIIIs. */
|
||||
rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi);
|
||||
rdmsrq(MSR_IA32_EBL_CR_POWERON, msr.q);
|
||||
pr_debug("Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n",
|
||||
msr_lo, msr_hi);
|
||||
msr_lo &= 0x00c0000;
|
||||
if (msr_lo != 0x0080000)
|
||||
msr.l, msr.h);
|
||||
msr.l &= 0x00c0000;
|
||||
if (msr.l != 0x0080000)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@@ -356,11 +361,11 @@ enum speedstep_processor speedstep_detect_processor(void)
|
||||
* it has SpeedStep technology if either
|
||||
* bit 56 or 57 is set
|
||||
*/
|
||||
rdmsr(MSR_IA32_PLATFORM_ID, msr_lo, msr_hi);
|
||||
rdmsrq(MSR_IA32_PLATFORM_ID, msr.q);
|
||||
pr_debug("Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n",
|
||||
msr_lo, msr_hi);
|
||||
if ((msr_hi & (1<<18)) &&
|
||||
(relaxed_check ? 1 : (msr_hi & (3<<24)))) {
|
||||
msr.l, msr.h);
|
||||
if ((msr.h & (1<<18)) &&
|
||||
(relaxed_check ? 1 : (msr.h & (3<<24)))) {
|
||||
if (c->x86_stepping == 0x01) {
|
||||
pr_debug("early PIII version\n");
|
||||
return SPEEDSTEP_CPU_PIII_C_EARLY;
|
||||
|
||||
@@ -261,11 +261,11 @@ static void ie31200_clear_error_info(struct mem_ctl_info *mci)
|
||||
* the ECC error log registers in all memory controllers.
|
||||
*/
|
||||
if (cfg->msr_clear_eccerrlog_offset) {
|
||||
if (wrmsr_safe(cfg->msr_clear_eccerrlog_offset,
|
||||
cfg->reg_eccerrlog_ce_mask |
|
||||
cfg->reg_eccerrlog_ce_ovfl_mask |
|
||||
cfg->reg_eccerrlog_ue_mask |
|
||||
cfg->reg_eccerrlog_ue_ovfl_mask, 0) < 0)
|
||||
if (wrmsrq_safe(cfg->msr_clear_eccerrlog_offset,
|
||||
cfg->reg_eccerrlog_ce_mask |
|
||||
cfg->reg_eccerrlog_ce_ovfl_mask |
|
||||
cfg->reg_eccerrlog_ue_mask |
|
||||
cfg->reg_eccerrlog_ue_ovfl_mask) < 0)
|
||||
ie31200_printk(KERN_ERR, "Failed to wrmsr.\n");
|
||||
|
||||
return;
|
||||
|
||||
@@ -806,7 +806,7 @@ amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
|
||||
struct mce *m = (struct mce *)data;
|
||||
struct mce_hw_err *err = to_mce_hw_err(m);
|
||||
unsigned int fam = x86_family(m->cpuid);
|
||||
u32 mca_config_lo = 0, dummy;
|
||||
u64 mca_config = 0;
|
||||
int ecc;
|
||||
|
||||
if (m->kflags & MCE_HANDLED_CEC)
|
||||
@@ -826,9 +826,9 @@ amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
|
||||
((m->status & MCI_STATUS_PCC) ? "PCC" : "-"));
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_SMCA)) {
|
||||
rdmsr_safe(MSR_AMD64_SMCA_MCx_CONFIG(m->bank), &mca_config_lo, &dummy);
|
||||
rdmsrq_safe(MSR_AMD64_SMCA_MCx_CONFIG(m->bank), &mca_config);
|
||||
|
||||
if (mca_config_lo & MCI_CONFIG_MCAX)
|
||||
if (mca_config & MCI_CONFIG_MCAX)
|
||||
pr_cont("|%s", ((m->status & MCI_STATUS_TCC) ? "TCC" : "-"));
|
||||
|
||||
pr_cont("|%s", ((m->status & MCI_STATUS_SYNDV) ? "SyndV" : "-"));
|
||||
@@ -863,7 +863,7 @@ amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
|
||||
|
||||
if (m->status & MCI_STATUS_SYNDV) {
|
||||
pr_cont(", Syndrome: 0x%016llx\n", m->synd);
|
||||
if (mca_config_lo & MCI_CONFIG_FRUTEXT) {
|
||||
if (mca_config & MCI_CONFIG_FRUTEXT) {
|
||||
char frutext[17];
|
||||
|
||||
frutext[16] = '\0';
|
||||
|
||||
@@ -237,16 +237,17 @@ static struct vrm_model vrm_models[] = {
|
||||
*/
|
||||
static u8 get_via_model_d_vrm(void)
|
||||
{
|
||||
unsigned int vid, brand, __maybe_unused dummy;
|
||||
u64 msr;
|
||||
unsigned int vid, brand;
|
||||
static const char *brands[4] = {
|
||||
"C7-M", "C7", "Eden", "C7-D"
|
||||
};
|
||||
|
||||
rdmsr(0x198, dummy, vid);
|
||||
vid &= 0xff;
|
||||
rdmsrq(0x198, msr);
|
||||
vid = (msr >> 32) & 0xff;
|
||||
|
||||
rdmsr(0x1154, brand, dummy);
|
||||
brand = ((brand >> 4) ^ (brand >> 2)) & 0x03;
|
||||
rdmsrq(0x1154, msr);
|
||||
brand = ((msr >> 4) ^ (msr >> 2)) & 0x03;
|
||||
|
||||
if (vid > 0x3f) {
|
||||
pr_info("Using %d-bit VID table for VIA %s CPU\n",
|
||||
|
||||
@@ -752,17 +752,17 @@ EXPORT_SYMBOL_NS_GPL(rapl_default_check_unit, "INTEL_RAPL");
|
||||
|
||||
static void power_limit_irq_save_cpu(void *info)
|
||||
{
|
||||
u32 l, h = 0;
|
||||
struct msr val;
|
||||
struct rapl_package *rp = (struct rapl_package *)info;
|
||||
|
||||
/* save the state of PLN irq mask bit before disabling it */
|
||||
rdmsr_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, &l, &h);
|
||||
rdmsrq_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, &val.q);
|
||||
if (!(rp->power_limit_irq & PACKAGE_PLN_INT_SAVED)) {
|
||||
rp->power_limit_irq = l & PACKAGE_THERM_INT_PLN_ENABLE;
|
||||
rp->power_limit_irq = val.l & PACKAGE_THERM_INT_PLN_ENABLE;
|
||||
rp->power_limit_irq |= PACKAGE_PLN_INT_SAVED;
|
||||
}
|
||||
l &= ~PACKAGE_THERM_INT_PLN_ENABLE;
|
||||
wrmsr_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
|
||||
val.l &= ~PACKAGE_THERM_INT_PLN_ENABLE;
|
||||
wrmsrq_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, val.q);
|
||||
}
|
||||
|
||||
/* REVISIT:
|
||||
@@ -792,7 +792,7 @@ static void package_power_limit_irq_save(struct rapl_package *rp)
|
||||
*/
|
||||
static void package_power_limit_irq_restore(struct rapl_package *rp)
|
||||
{
|
||||
u32 l, h;
|
||||
struct msr val;
|
||||
|
||||
if (rp->lead_cpu < 0)
|
||||
return;
|
||||
@@ -804,14 +804,14 @@ static void package_power_limit_irq_restore(struct rapl_package *rp)
|
||||
if (!(rp->power_limit_irq & PACKAGE_PLN_INT_SAVED))
|
||||
return;
|
||||
|
||||
rdmsr_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, &l, &h);
|
||||
rdmsrq_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, &val.q);
|
||||
|
||||
if (rp->power_limit_irq & PACKAGE_THERM_INT_PLN_ENABLE)
|
||||
l |= PACKAGE_THERM_INT_PLN_ENABLE;
|
||||
val.l |= PACKAGE_THERM_INT_PLN_ENABLE;
|
||||
else
|
||||
l &= ~PACKAGE_THERM_INT_PLN_ENABLE;
|
||||
val.l &= ~PACKAGE_THERM_INT_PLN_ENABLE;
|
||||
|
||||
wrmsr_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
|
||||
wrmsrq_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, val.q);
|
||||
}
|
||||
|
||||
void rapl_default_set_floor_freq(struct rapl_domain *rd, bool mode)
|
||||
|
||||
@@ -185,7 +185,7 @@ int intel_tcc_get_tjmax(int cpu)
|
||||
int val, err;
|
||||
|
||||
if (cpu < 0)
|
||||
err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &msrval.l, &msrval.h);
|
||||
err = rdmsrq_safe(MSR_IA32_TEMPERATURE_TARGET, &msrval.q);
|
||||
else
|
||||
err = rdmsrq_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &msrval.q);
|
||||
if (err)
|
||||
@@ -212,7 +212,7 @@ int intel_tcc_get_offset(int cpu)
|
||||
int err;
|
||||
|
||||
if (cpu < 0)
|
||||
err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &val.l, &val.h);
|
||||
err = rdmsrq_safe(MSR_IA32_TEMPERATURE_TARGET, &val.q);
|
||||
else
|
||||
err = rdmsrq_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &val.q);
|
||||
if (err)
|
||||
@@ -245,7 +245,7 @@ int intel_tcc_set_offset(int cpu, int offset)
|
||||
return -EINVAL;
|
||||
|
||||
if (cpu < 0)
|
||||
err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &val.l, &val.h);
|
||||
err = rdmsrq_safe(MSR_IA32_TEMPERATURE_TARGET, &val.q);
|
||||
else
|
||||
err = rdmsrq_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &val.q);
|
||||
if (err)
|
||||
@@ -259,7 +259,7 @@ int intel_tcc_set_offset(int cpu, int offset)
|
||||
val.l |= offset << 24;
|
||||
|
||||
if (cpu < 0)
|
||||
return wrmsr_safe(MSR_IA32_TEMPERATURE_TARGET, val.l, val.h);
|
||||
return wrmsrq_safe(MSR_IA32_TEMPERATURE_TARGET, val.q);
|
||||
else
|
||||
return wrmsrq_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, val.q);
|
||||
}
|
||||
@@ -288,7 +288,7 @@ int intel_tcc_get_temp(int cpu, int *temp, bool pkg)
|
||||
return tjmax;
|
||||
|
||||
if (cpu < 0)
|
||||
err = rdmsr_safe(msr, &val.l, &val.h);
|
||||
err = rdmsrq_safe(msr, &val.q);
|
||||
else
|
||||
err = rdmsrq_safe_on_cpu(cpu, msr, &val.q);
|
||||
if (err)
|
||||
|
||||
@@ -993,8 +993,8 @@ void __init therm_lvt_init(void)
|
||||
void intel_init_thermal(struct cpuinfo_x86 *c)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
struct msr val;
|
||||
int tm2 = 0;
|
||||
u32 l, h;
|
||||
|
||||
if (!intel_thermal_supported(c))
|
||||
return;
|
||||
@@ -1004,9 +1004,9 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
|
||||
* be some SMM goo which handles it, so we can't even put a handler
|
||||
* since it might be delivered via SMI already:
|
||||
*/
|
||||
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
|
||||
rdmsrq(MSR_IA32_MISC_ENABLE, val.q);
|
||||
|
||||
h = lvtthmr_init;
|
||||
val.h = lvtthmr_init;
|
||||
/*
|
||||
* The initial value of thermal LVT entries on all APs always reads
|
||||
* 0x10000 because APs are woken up by BSP issuing INIT-SIPI-SIPI
|
||||
@@ -1017,11 +1017,11 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
|
||||
* BIOS has programmed on AP based on BSP's info we saved since BIOS
|
||||
* is always setting the same value for all threads/cores.
|
||||
*/
|
||||
if ((h & APIC_DM_FIXED_MASK) != APIC_DM_FIXED)
|
||||
if ((val.h & APIC_DM_FIXED_MASK) != APIC_DM_FIXED)
|
||||
apic_write(APIC_LVTTHMR, lvtthmr_init);
|
||||
|
||||
|
||||
if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) {
|
||||
if ((val.l & MSR_IA32_MISC_ENABLE_TM1) && (val.h & APIC_DM_SMI)) {
|
||||
if (system_state == SYSTEM_BOOTING)
|
||||
pr_debug("CPU%d: Thermal monitoring handled by SMI\n", cpu);
|
||||
return;
|
||||
@@ -1030,59 +1030,55 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
|
||||
/* early Pentium M models use different method for enabling TM2 */
|
||||
if (cpu_has(c, X86_FEATURE_TM2)) {
|
||||
if (c->x86 == 6 && (c->x86_model == 9 || c->x86_model == 13)) {
|
||||
rdmsr(MSR_THERM2_CTL, l, h);
|
||||
if (l & MSR_THERM2_CTL_TM_SELECT)
|
||||
rdmsrq(MSR_THERM2_CTL, val.q);
|
||||
if (val.l & MSR_THERM2_CTL_TM_SELECT)
|
||||
tm2 = 1;
|
||||
} else if (l & MSR_IA32_MISC_ENABLE_TM2)
|
||||
} else if (val.l & MSR_IA32_MISC_ENABLE_TM2)
|
||||
tm2 = 1;
|
||||
}
|
||||
|
||||
/* We'll mask the thermal vector in the lapic till we're ready: */
|
||||
h = THERMAL_APIC_VECTOR | APIC_DM_FIXED | APIC_LVT_MASKED;
|
||||
apic_write(APIC_LVTTHMR, h);
|
||||
val.h = THERMAL_APIC_VECTOR | APIC_DM_FIXED | APIC_LVT_MASKED;
|
||||
apic_write(APIC_LVTTHMR, val.h);
|
||||
|
||||
thermal_intr_init_core_clear_mask();
|
||||
thermal_intr_init_pkg_clear_mask();
|
||||
|
||||
rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
|
||||
if (cpu_has(c, X86_FEATURE_PLN) && !int_pln_enable)
|
||||
wrmsr(MSR_IA32_THERM_INTERRUPT,
|
||||
(l | (THERM_INT_LOW_ENABLE
|
||||
| THERM_INT_HIGH_ENABLE)) & ~THERM_INT_PLN_ENABLE, h);
|
||||
else if (cpu_has(c, X86_FEATURE_PLN) && int_pln_enable)
|
||||
wrmsr(MSR_IA32_THERM_INTERRUPT,
|
||||
l | (THERM_INT_LOW_ENABLE
|
||||
| THERM_INT_HIGH_ENABLE | THERM_INT_PLN_ENABLE), h);
|
||||
rdmsrq(MSR_IA32_THERM_INTERRUPT, val.q);
|
||||
if (cpu_has(c, X86_FEATURE_PLN) && !int_pln_enable) {
|
||||
val.l |= THERM_INT_LOW_ENABLE | THERM_INT_HIGH_ENABLE;
|
||||
val.l &= ~THERM_INT_PLN_ENABLE;
|
||||
} else if (cpu_has(c, X86_FEATURE_PLN) && int_pln_enable)
|
||||
val.l |= THERM_INT_LOW_ENABLE | THERM_INT_HIGH_ENABLE |
|
||||
THERM_INT_PLN_ENABLE;
|
||||
else
|
||||
wrmsr(MSR_IA32_THERM_INTERRUPT,
|
||||
l | (THERM_INT_LOW_ENABLE | THERM_INT_HIGH_ENABLE), h);
|
||||
val.l |= THERM_INT_LOW_ENABLE | THERM_INT_HIGH_ENABLE;
|
||||
wrmsrq(MSR_IA32_THERM_INTERRUPT, val.q);
|
||||
|
||||
if (cpu_has(c, X86_FEATURE_PTS)) {
|
||||
rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
|
||||
if (cpu_has(c, X86_FEATURE_PLN) && !int_pln_enable)
|
||||
wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT,
|
||||
(l | (PACKAGE_THERM_INT_LOW_ENABLE
|
||||
| PACKAGE_THERM_INT_HIGH_ENABLE))
|
||||
& ~PACKAGE_THERM_INT_PLN_ENABLE, h);
|
||||
else if (cpu_has(c, X86_FEATURE_PLN) && int_pln_enable)
|
||||
wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT,
|
||||
l | (PACKAGE_THERM_INT_LOW_ENABLE
|
||||
| PACKAGE_THERM_INT_HIGH_ENABLE
|
||||
| PACKAGE_THERM_INT_PLN_ENABLE), h);
|
||||
rdmsrq(MSR_IA32_PACKAGE_THERM_INTERRUPT, val.q);
|
||||
if (cpu_has(c, X86_FEATURE_PLN) && !int_pln_enable) {
|
||||
val.l |= PACKAGE_THERM_INT_LOW_ENABLE |
|
||||
PACKAGE_THERM_INT_HIGH_ENABLE;
|
||||
val.l &= ~PACKAGE_THERM_INT_PLN_ENABLE;
|
||||
} else if (cpu_has(c, X86_FEATURE_PLN) && int_pln_enable)
|
||||
val.l |= PACKAGE_THERM_INT_LOW_ENABLE |
|
||||
PACKAGE_THERM_INT_HIGH_ENABLE |
|
||||
PACKAGE_THERM_INT_PLN_ENABLE;
|
||||
else
|
||||
wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT,
|
||||
l | (PACKAGE_THERM_INT_LOW_ENABLE
|
||||
| PACKAGE_THERM_INT_HIGH_ENABLE), h);
|
||||
val.l |= PACKAGE_THERM_INT_LOW_ENABLE |
|
||||
PACKAGE_THERM_INT_HIGH_ENABLE;
|
||||
wrmsrq(MSR_IA32_PACKAGE_THERM_INTERRUPT, val.q);
|
||||
|
||||
if (cpu_has(c, X86_FEATURE_HFI)) {
|
||||
rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
|
||||
wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT,
|
||||
l | PACKAGE_THERM_INT_HFI_ENABLE, h);
|
||||
rdmsrq(MSR_IA32_PACKAGE_THERM_INTERRUPT, val.q);
|
||||
wrmsrq(MSR_IA32_PACKAGE_THERM_INTERRUPT,
|
||||
val.q | PACKAGE_THERM_INT_HFI_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
|
||||
wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h);
|
||||
rdmsrq(MSR_IA32_MISC_ENABLE, val.q);
|
||||
wrmsrq(MSR_IA32_MISC_ENABLE, val.q | MSR_IA32_MISC_ENABLE_TM1);
|
||||
|
||||
pr_info_once("CPU0: Thermal monitoring enabled (%s)\n",
|
||||
tm2 ? "TM2" : "TM1");
|
||||
|
||||
@@ -51,8 +51,7 @@ MODULE_PARM_DESC(notify_delay_ms,
|
||||
struct zone_device {
|
||||
int cpu;
|
||||
bool work_scheduled;
|
||||
u32 msr_pkg_therm_low;
|
||||
u32 msr_pkg_therm_high;
|
||||
u64 msr_pkg_therm;
|
||||
struct delayed_work work;
|
||||
struct thermal_zone_device *tzone;
|
||||
struct cpumask cpumask;
|
||||
@@ -186,28 +185,28 @@ static bool pkg_thermal_rate_control(void)
|
||||
static inline void enable_pkg_thres_interrupt(void)
|
||||
{
|
||||
u8 thres_0, thres_1;
|
||||
u32 l, h;
|
||||
struct msr val;
|
||||
|
||||
rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
|
||||
rdmsrq(MSR_IA32_PACKAGE_THERM_INTERRUPT, val.q);
|
||||
/* only enable/disable if it had valid threshold value */
|
||||
thres_0 = (l & THERM_MASK_THRESHOLD0) >> THERM_SHIFT_THRESHOLD0;
|
||||
thres_1 = (l & THERM_MASK_THRESHOLD1) >> THERM_SHIFT_THRESHOLD1;
|
||||
thres_0 = (val.l & THERM_MASK_THRESHOLD0) >> THERM_SHIFT_THRESHOLD0;
|
||||
thres_1 = (val.l & THERM_MASK_THRESHOLD1) >> THERM_SHIFT_THRESHOLD1;
|
||||
if (thres_0)
|
||||
l |= THERM_INT_THRESHOLD0_ENABLE;
|
||||
val.l |= THERM_INT_THRESHOLD0_ENABLE;
|
||||
if (thres_1)
|
||||
l |= THERM_INT_THRESHOLD1_ENABLE;
|
||||
wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
|
||||
val.l |= THERM_INT_THRESHOLD1_ENABLE;
|
||||
wrmsrq(MSR_IA32_PACKAGE_THERM_INTERRUPT, val.q);
|
||||
}
|
||||
|
||||
/* Disable threshold interrupt on local package/cpu */
|
||||
static inline void disable_pkg_thres_interrupt(void)
|
||||
{
|
||||
u32 l, h;
|
||||
struct msr val;
|
||||
|
||||
rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
|
||||
rdmsrq(MSR_IA32_PACKAGE_THERM_INTERRUPT, val.q);
|
||||
|
||||
l &= ~(THERM_INT_THRESHOLD0_ENABLE | THERM_INT_THRESHOLD1_ENABLE);
|
||||
wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
|
||||
val.l &= ~(THERM_INT_THRESHOLD0_ENABLE | THERM_INT_THRESHOLD1_ENABLE);
|
||||
wrmsrq(MSR_IA32_PACKAGE_THERM_INTERRUPT, val.q);
|
||||
}
|
||||
|
||||
static void pkg_temp_thermal_threshold_work_fn(struct work_struct *work)
|
||||
@@ -357,8 +356,7 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
|
||||
goto out_unregister_tz;
|
||||
|
||||
/* Store MSR value for package thermal interrupt, to restore at exit */
|
||||
rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, zonedev->msr_pkg_therm_low,
|
||||
zonedev->msr_pkg_therm_high);
|
||||
rdmsrq(MSR_IA32_PACKAGE_THERM_INTERRUPT, zonedev->msr_pkg_therm);
|
||||
|
||||
cpumask_set_cpu(cpu, &zonedev->cpumask);
|
||||
raw_spin_lock_irq(&pkg_temp_lock);
|
||||
@@ -426,8 +424,8 @@ static int pkg_thermal_cpu_offline(unsigned int cpu)
|
||||
if (lastcpu) {
|
||||
zones[topology_logical_die_id(cpu)] = NULL;
|
||||
/* After this point nothing touches the MSR anymore. */
|
||||
wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT,
|
||||
zonedev->msr_pkg_therm_low, zonedev->msr_pkg_therm_high);
|
||||
wrmsrq(MSR_IA32_PACKAGE_THERM_INTERRUPT,
|
||||
zonedev->msr_pkg_therm);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user