From: Philippe Elie Contributions from Zarakin Intel removed two msrs: MSR_P4_IQ_ESCR_0|1 (0x3ba/0x3bb), P4 model >= 3. See Intel documentation Vol. 3 System Programming Guide Appendix B. nmi_watchdog=2 oopsed at boot time and oprofile at driver load. Avoid touching them when model >= 3. Signed-off-by: Andrew Morton --- 25-akpm/arch/i386/kernel/nmi.c | 8 ++++++ 25-akpm/arch/i386/oprofile/op_model_p4.c | 36 ++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 4 deletions(-) diff -puN arch/i386/kernel/nmi.c~fix-oops-with-nmi_watchdog=2 arch/i386/kernel/nmi.c --- 25/arch/i386/kernel/nmi.c~fix-oops-with-nmi_watchdog=2 2004-08-28 14:36:27.265947120 -0700 +++ 25-akpm/arch/i386/kernel/nmi.c 2004-08-28 14:36:27.270946360 -0700 @@ -380,7 +380,13 @@ static int setup_p4_watchdog(void) clear_msr_range(0x3F1, 2); /* MSR 0x3F0 seems to have a default value of 0xFC00, but current docs doesn't fully define it, so leave it alone for now. */ - clear_msr_range(0x3A0, 31); + if (boot_cpu_data.x86_model >= 0x3) { + /* MSR_P4_IQ_ESCR0/1 (0x3ba/0x3bb) removed */ + clear_msr_range(0x3A0, 26); + clear_msr_range(0x3BC, 3); + } else { + clear_msr_range(0x3A0, 31); + } clear_msr_range(0x3C0, 6); clear_msr_range(0x3C8, 6); clear_msr_range(0x3E0, 2); diff -puN arch/i386/oprofile/op_model_p4.c~fix-oops-with-nmi_watchdog=2 arch/i386/oprofile/op_model_p4.c --- 25/arch/i386/oprofile/op_model_p4.c~fix-oops-with-nmi_watchdog=2 2004-08-28 14:36:27.266946968 -0700 +++ 25-akpm/arch/i386/oprofile/op_model_p4.c 2004-08-28 14:36:27.271946208 -0700 @@ -419,9 +419,28 @@ static void p4_fill_in_addresses(struct msrs->controls[i].addr = addr; } - /* 43 ESCR registers in three discontiguous group */ + /* 43 ESCR registers in three or four discontiguous group */ for (addr = MSR_P4_BSU_ESCR0 + stag; - addr <= MSR_P4_SSU_ESCR0; ++i, addr += addr_increment()) { + addr < MSR_P4_IQ_ESCR0; ++i, addr += addr_increment()) { + msrs->controls[i].addr = addr; + } + + /* no IQ_ESCR0/1 on some models, we save a seconde time BSU_ESCR0/1 + * to avoid special case in nmi_{save|restore}_registers() */ + if (boot_cpu_data.x86_model >= 0x3) { + for (addr = MSR_P4_BSU_ESCR0 + stag; + addr <= MSR_P4_BSU_ESCR1; ++i, addr += addr_increment()) { + msrs->controls[i].addr = addr; + } + } else { + for (addr = MSR_P4_IQ_ESCR0 + stag; + addr <= MSR_P4_IQ_ESCR1; ++i, addr += addr_increment()) { + msrs->controls[i].addr = addr; + } + } + + for (addr = MSR_P4_RAT_ESCR0 + stag; + addr <= MSR_P4_SSU_ESCR0; ++i, addr += addr_increment()) { msrs->controls[i].addr = addr; } @@ -553,7 +572,18 @@ static void p4_setup_ctrs(struct op_msrs /* clear all escrs (including those outside our concern) */ for (addr = MSR_P4_BSU_ESCR0 + stag; - addr <= MSR_P4_SSU_ESCR0; addr += addr_increment()) { + addr < MSR_P4_IQ_ESCR0; addr += addr_increment()) { + wrmsr(addr, 0, 0); + } + + /* On older models clear also MSR_P4_IQ_ESCR0/1 */ + if (boot_cpu_data.x86_model < 0x3) { + wrmsr(MSR_P4_IQ_ESCR0, 0, 0); + wrmsr(MSR_P4_IQ_ESCR1, 0, 0); + } + + for (addr = MSR_P4_RAT_ESCR0 + stag; + addr <= MSR_P4_SSU_ESCR0; ++i, addr += addr_increment()) { wrmsr(addr, 0, 0); } _