From b339a18b81a1f6ca1455559594f5df872b9e59f4 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 22 Jul 2005 15:23:47 -0400 Subject: Fix up incorrect "unlikely()" on %gs reload in x86 __switch_to These days %gs is normally the TLS segment, so it's no longer zero. As a result, we shouldn't just assume that %fs/%gs tend to be zero together, but test them independently instead. Also, fix setting of debug registers to use the "next" pointer instead of "current". It so happens that the scheduler will have set the new current pointer before calling __switch_to(), but that's just an implementation detail. --- arch/i386/kernel/process.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index ba243a4cc119..d9492058aaf3 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -700,23 +700,27 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas /* * Restore %fs and %gs if needed. + * + * Glibc normally makes %fs be zero, and %gs is one of + * the TLS segments. */ - if (unlikely(prev->fs | prev->gs | next->fs | next->gs)) { + if (unlikely(prev->fs | next->fs)) loadsegment(fs, next->fs); + + if (prev->gs | next->gs) loadsegment(gs, next->gs); - } /* * Now maybe reload the debug registers */ if (unlikely(next->debugreg[7])) { - set_debugreg(current->thread.debugreg[0], 0); - set_debugreg(current->thread.debugreg[1], 1); - set_debugreg(current->thread.debugreg[2], 2); - set_debugreg(current->thread.debugreg[3], 3); + set_debugreg(next->debugreg[0], 0); + set_debugreg(next->debugreg[1], 1); + set_debugreg(next->debugreg[2], 2); + set_debugreg(next->debugreg[3], 3); /* no 4 and 5 */ - set_debugreg(current->thread.debugreg[6], 6); - set_debugreg(current->thread.debugreg[7], 7); + set_debugreg(next->debugreg[6], 6); + set_debugreg(next->debugreg[7], 7); } if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) -- cgit v1.2.2 From 8ed1383fb7b6685968588141d5934e0e6715e954 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 22 Jul 2005 16:06:16 -0400 Subject: x86: make restore_fpu() use alternative assembler instructions It's really just a single instruction, conditional on whether the CPU supports FXSR or not, so implement it as such instead of making it a function that queries FXSR dynamically. This means that the instruction just gets automatically rewritten to the correct one at boot-time. --- arch/i386/kernel/i387.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c index b817168d9c62..d75524758daf 100644 --- a/arch/i386/kernel/i387.c +++ b/arch/i386/kernel/i387.c @@ -82,17 +82,6 @@ void kernel_fpu_begin(void) } EXPORT_SYMBOL_GPL(kernel_fpu_begin); -void restore_fpu( struct task_struct *tsk ) -{ - if ( cpu_has_fxsr ) { - asm volatile( "fxrstor %0" - : : "m" (tsk->thread.i387.fxsave) ); - } else { - asm volatile( "frstor %0" - : : "m" (tsk->thread.i387.fsave) ); - } -} - /* * FPU tag word conversions. */ -- cgit v1.2.2 From 72538d8565b0205240d88591b72db3c7f3f1881a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 22 Jul 2005 18:29:40 -0400 Subject: Remove "noreplacement" kernel command line option. It is no longer valid to not replace instructions, since we depend on different behaviour depending on CPU capabilities. If you need to limit the capabilities of the replacements (because the boot CPU has features that non-boot CPU's do not have, for example), you need to explicitly disable those capabilities that are not shared across all CPU's. For example, if your boot CPU has FXSR, but other CPU's in your system do not, you need to use the "nofxsr" kernel command line, not disable instruction replacement per se. --- arch/i386/kernel/setup.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 7306353c520e..af4de58cab54 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -1414,7 +1414,7 @@ static struct nop { This runs before SMP is initialized to avoid SMP problems with self modifying code. This implies that assymetric systems where APs have less capabilities than the boot processor are not handled. - In this case boot with "noreplacement". */ + Tough. Make sure you disable such features by hand. */ void apply_alternatives(void *start, void *end) { struct alt_instr *a; @@ -1442,24 +1442,12 @@ void apply_alternatives(void *start, void *end) } } -static int no_replacement __initdata = 0; - void __init alternative_instructions(void) { extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; - if (no_replacement) - return; apply_alternatives(__alt_instructions, __alt_instructions_end); } -static int __init noreplacement_setup(char *s) -{ - no_replacement = 1; - return 0; -} - -__setup("noreplacement", noreplacement_setup); - static char * __init machine_specific_memory_setup(void); #ifdef CONFIG_MCA -- cgit v1.2.2 From 59586e5a262a29361c45c929ea3253d4aec830b0 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 26 Jul 2005 11:36:01 -0600 Subject: [PATCH] Don't export machine_restart, machine_halt, or machine_power_off. machine_restart, machine_halt and machine_power_off are machine specific hooks deep into the reboot logic, that modules have no business messing with. Usually code should be calling kernel_restart, kernel_halt, kernel_power_off, or emergency_restart. So don't export machine_restart, machine_halt, and machine_power_off so we can catch buggy users. Signed-off-by: Eric W. Biederman Signed-off-by: Linus Torvalds --- arch/i386/kernel/reboot.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c index b3e584849961..1b24bc7271af 100644 --- a/arch/i386/kernel/reboot.c +++ b/arch/i386/kernel/reboot.c @@ -337,14 +337,10 @@ void machine_restart(char * __unused) machine_real_restart(jump_to_bios, sizeof(jump_to_bios)); } -EXPORT_SYMBOL(machine_restart); - void machine_halt(void) { } -EXPORT_SYMBOL(machine_halt); - void machine_power_off(void) { lapic_shutdown(); @@ -355,5 +351,4 @@ void machine_power_off(void) pm_power_off(); } -EXPORT_SYMBOL(machine_power_off); -- cgit v1.2.2 From 4a1421f81b64e49ce932125e7222a2d7b7f87f13 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 26 Jul 2005 11:41:26 -0600 Subject: [PATCH] i386: Implement machine_emergency_reboot set_cpus_allowed is not safe in interrupt context and disabling apics is complicated code so don't call machine_shutdown on i386 from emergency_restart(). Signed-off-by: Eric W. Biederman Signed-off-by: Linus Torvalds --- arch/i386/kernel/reboot.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c index 1b24bc7271af..d473350aa055 100644 --- a/arch/i386/kernel/reboot.c +++ b/arch/i386/kernel/reboot.c @@ -311,10 +311,8 @@ void machine_shutdown(void) #endif } -void machine_restart(char * __unused) +void machine_emergency_restart(void) { - machine_shutdown(); - if (!reboot_thru_bios) { if (efi_enabled) { efi.reset_system(EFI_RESET_COLD, EFI_SUCCESS, 0, NULL); @@ -337,6 +335,12 @@ void machine_restart(char * __unused) machine_real_restart(jump_to_bios, sizeof(jump_to_bios)); } +void machine_restart(char * __unused) +{ + machine_shutdown(); + machine_emergency_restart(); +} + void machine_halt(void) { } -- cgit v1.2.2 From d8e392e7c8f019657ff3ebe70a45d234990831db Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 26 Jul 2005 12:07:01 -0600 Subject: [PATCH] machine_shutdown: Typo fix to actually allow specifying which cpu to reboot on This appears to be a typo I introduced when cleaning this code up earlier. Ooops. Signed-off-by: Eric W. Biederman Signed-off-by: Linus Torvalds --- arch/i386/kernel/reboot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c index d473350aa055..1049876702aa 100644 --- a/arch/i386/kernel/reboot.c +++ b/arch/i386/kernel/reboot.c @@ -284,7 +284,7 @@ void machine_shutdown(void) reboot_cpu_id = 0; /* See if there has been given a command line override */ - if ((reboot_cpu_id != -1) && (reboot_cpu < NR_CPUS) && + if ((reboot_cpu != -1) && (reboot_cpu < NR_CPUS) && cpu_isset(reboot_cpu, cpu_online_map)) { reboot_cpu_id = reboot_cpu; } -- cgit v1.2.2 From 4fa2564a6fde9815df969ef3547744a22f66ba9d Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 26 Jul 2005 12:08:53 -0600 Subject: [PATCH] i386 machine_power_off cleanup Call machine_shutdown() to move to the boot cpu and disable apics. Both acpi_power_off and apm_power_off want to move to the boot cpu. and we are already disabling the local apics so calling machine_shutdown simply reuses code. ia64 doesn't have a special path in power_off for efi so there is no reason i386 should. If we really need to call the efi power off path the efi driver can set pm_power_off like everyone else. Signed-off-by: Eric W. Biederman Signed-off-by: Linus Torvalds --- arch/i386/kernel/reboot.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c index 1049876702aa..c71fef31dc47 100644 --- a/arch/i386/kernel/reboot.c +++ b/arch/i386/kernel/reboot.c @@ -347,10 +347,8 @@ void machine_halt(void) void machine_power_off(void) { - lapic_shutdown(); + machine_shutdown(); - if (efi_enabled) - efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL); if (pm_power_off) pm_power_off(); } -- cgit v1.2.2 From 910de55c6653d76f90380c80f0b7a395f12019e3 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 26 Jul 2005 12:10:02 -0600 Subject: [PATCH] APM: Remove redundant call to set_cpus_allowed machine_power_off now always switches to the boot cpu so there is no reason for APM to also do that. Signed-off-by: Eric W. Biederman Signed-off-by: Linus Torvalds --- arch/i386/kernel/apm.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 064211d5f41b..d7811c4e8b50 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -911,14 +911,7 @@ static void apm_power_off(void) 0xcd, 0x15 /* int $0x15 */ }; - /* - * This may be called on an SMP machine. - */ -#ifdef CONFIG_SMP /* Some bioses don't like being called from CPU != 0 */ - set_cpus_allowed(current, cpumask_of_cpu(0)); - BUG_ON(smp_processor_id() != 0); -#endif if (apm_info.realmode_power_off) { (void)apm_save_cpus(); -- cgit v1.2.2 From 7657e20e46e26b198b24e2aefc696410bbe889c9 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 27 Jul 2005 11:43:57 -0700 Subject: [PATCH] Fix warning in powernow-k8.c powernow-k8.c: In function `query_current_values_with_pending_wait': powernow-k8.c:110: warning: `hi' may be used uninitialized in this function Signed-off-by: Brian Gerst Cc: Dave Jones Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 10cc096c0ade..31f65c8a4c24 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -110,14 +110,13 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data) u32 lo, hi; u32 i = 0; - lo = MSR_S_LO_CHANGE_PENDING; - while (lo & MSR_S_LO_CHANGE_PENDING) { + do { if (i++ > 0x1000000) { printk(KERN_ERR PFX "detected change pending stuck\n"); return 1; } rdmsr(MSR_FIDVID_STATUS, lo, hi); - } + } while (lo & MSR_S_LO_CHANGE_PENDING); data->currvid = hi & MSR_S_HI_CURRENT_VID; data->currfid = lo & MSR_S_LO_CURRENT_FID; -- cgit v1.2.2 From 71ae18ec690953e9ba7107c7cc44589c2cc0d9f1 Mon Sep 17 00:00:00 2001 From: Blaisorblade Date: Wed, 27 Jul 2005 11:45:18 -0700 Subject: [PATCH] sys_get_thread_area does not clear the returned argument sys_get_thread_area does not memset to 0 its struct user_desc info before copying it to user space... since sizeof(struct user_desc) is 16 while the actual datas which are filled are only 12 bytes + 9 bits (across the bitfields), there is a (small) information leak. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/process.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index d9492058aaf3..e3f362e8af5b 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -917,6 +917,8 @@ asmlinkage int sys_get_thread_area(struct user_desc __user *u_info) if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) return -EINVAL; + memset(&info, 0, sizeof(info)); + desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; info.entry_number = idx; -- cgit v1.2.2 From 03938c3f1062b0f279a0ef937a471d4db83702ed Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 28 Jul 2005 09:38:21 -0700 Subject: powernow-k8 requires that a data structure for each core be created in the _cpu_init function call. The cpufreq infrastructure doesn't call _cpu_init for the second core in each processor. Some systems crashed when _get was called with an odd-numbered core because it tried to dereference a NULL pointer since the data structure had not been created. The attached patch solves the problem by initializing data structures for all shared cores in the _cpu_init function. It should apply to 2.6.12-rc6 and has been tested by AMD and Sun. Signed-off-by: Mark Langsdorf Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 10cc096c0ade..9cf7b67b8afc 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -44,7 +44,7 @@ #define PFX "powernow-k8: " #define BFX PFX "BIOS error: " -#define VERSION "version 1.40.2" +#define VERSION "version 1.40.4" #include "powernow-k8.h" /* serialize freq changes */ @@ -978,7 +978,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) { struct powernow_k8_data *data; cpumask_t oldmask = CPU_MASK_ALL; - int rc; + int rc, i; if (!check_supported_cpu(pol->cpu)) return -ENODEV; @@ -1064,7 +1064,9 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) printk("cpu_init done, current fid 0x%x, vid 0x%x\n", data->currfid, data->currvid); - powernow_data[pol->cpu] = data; + for_each_cpu_mask(i, cpu_core_map[pol->cpu]) { + powernow_data[i] = data; + } return 0; -- cgit v1.2.2 From 841e40b380a70933e8dc1184e0f9ba1c6cac48af Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 28 Jul 2005 09:40:04 -0700 Subject: Opteron revision F will support higher frequencies than can be encoded in the current driver's 4 bit frequency field. This patch updates the driver to support Rev F including 6 bit FIDs and processor ID updates. This should apply cleanly whether or not the dual-core bugfix I sent out last week is applied. I'd prefer that both get applied, of course. Signed-off-by: David Keck Signed-off-by: Mark Langsdorf Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 29 +++++++++++++---------------- arch/i386/kernel/cpu/cpufreq/powernow-k8.h | 30 +++++++++++++++++------------- 2 files changed, 30 insertions(+), 29 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 9cf7b67b8afc..7fe5b2aaa209 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -1,5 +1,5 @@ /* - * (c) 2003, 2004 Advanced Micro Devices, Inc. + * (c) 2003, 2004, 2005 Advanced Micro Devices, Inc. * Your use of this code is subject to the terms and conditions of the * GNU general public license version 2. See "COPYING" or * http://www.gnu.org/licenses/gpl.html @@ -44,7 +44,7 @@ #define PFX "powernow-k8: " #define BFX PFX "BIOS error: " -#define VERSION "version 1.40.4" +#define VERSION "version 1.50.3" #include "powernow-k8.h" /* serialize freq changes */ @@ -232,7 +232,7 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid) /* * Reduce the vid by the max of step or reqvid. * Decreasing vid codes represent increasing voltages: - * vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of 0x1f is off. + * vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of VID_OFF is off. */ static int decrease_vid_code_by_step(struct powernow_k8_data *data, u32 reqvid, u32 step) { @@ -467,7 +467,7 @@ static int check_supported_cpu(unsigned int cpu) eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || ((eax & CPUID_XFAM) != CPUID_XFAM_K8) || - ((eax & CPUID_XMOD) > CPUID_XMOD_REV_E)) { + ((eax & CPUID_XMOD) > CPUID_XMOD_REV_F)) { printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); goto out; } @@ -696,6 +696,7 @@ static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK; data->rvo = (data->acpi_data.states[index].control >> RVO_SHIFT) & RVO_MASK; + data->exttype = (data->acpi_data.states[index].control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK; data->plllock = (data->acpi_data.states[index].control >> PLL_L_SHIFT) & PLL_L_MASK; data->vidmvs = 1 << ((data->acpi_data.states[index].control >> MVS_SHIFT) & MVS_MASK); data->vstable = (data->acpi_data.states[index].control >> VST_SHIFT) & VST_MASK; @@ -735,8 +736,13 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) } for (i = 0; i < data->acpi_data.state_count; i++) { - u32 fid = data->acpi_data.states[i].control & FID_MASK; - u32 vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK; + if (data->exttype) { + u32 fid = data->acpi_data.states[i].status & FID_MASK; + u32 vid = (data->acpi_data.states[i].status >> VID_SHIFT) & VID_MASK; + } else { + u32 fid = data->acpi_data.states[i].control & FID_MASK; + u32 vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK; + } dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid); @@ -753,7 +759,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) } /* verify voltage is OK - BIOSs are using "off" to indicate invalid */ - if (vid == 0x1f) { + if (vid == VID_OFF) { dprintk("invalid vid %u, ignoring\n", vid); powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; continue; @@ -930,15 +936,6 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi down(&fidvid_sem); - for_each_cpu_mask(i, cpu_core_map[pol->cpu]) { - /* make sure the sibling is initialized */ - if (!powernow_data[i]) { - ret = 0; - up(&fidvid_sem); - goto err_out; - } - } - powernow_k8_acpi_pst_values(data, newstate); if (transition_frequency(data, newstate)) { diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h index 9ed5bf221cb7..927e2dd6a69f 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h @@ -1,5 +1,5 @@ /* - * (c) 2003, 2004 Advanced Micro Devices, Inc. + * (c) 2003, 2004, 2005 Advanced Micro Devices, Inc. * Your use of this code is subject to the terms and conditions of the * GNU general public license version 2. See "COPYING" or * http://www.gnu.org/licenses/gpl.html @@ -19,6 +19,7 @@ struct powernow_k8_data { u32 vidmvs; /* usable value calculated from mvs */ u32 vstable; /* voltage stabilization time, units 20 us */ u32 plllock; /* pll lock time, units 1 us */ + u32 exttype; /* extended interface = 1 */ /* keep track of the current fid / vid */ u32 currvid, currfid; @@ -41,7 +42,7 @@ struct powernow_k8_data { #define CPUID_XFAM 0x0ff00000 /* extended family */ #define CPUID_XFAM_K8 0 #define CPUID_XMOD 0x000f0000 /* extended model */ -#define CPUID_XMOD_REV_E 0x00020000 +#define CPUID_XMOD_REV_F 0x00040000 #define CPUID_USE_XFAM_XMOD 0x00000f00 #define CPUID_GET_MAX_CAPABILITIES 0x80000000 #define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007 @@ -57,25 +58,26 @@ struct powernow_k8_data { /* Field definitions within the FID VID Low Control MSR : */ #define MSR_C_LO_INIT_FID_VID 0x00010000 -#define MSR_C_LO_NEW_VID 0x00001f00 -#define MSR_C_LO_NEW_FID 0x0000002f +#define MSR_C_LO_NEW_VID 0x00003f00 +#define MSR_C_LO_NEW_FID 0x0000003f #define MSR_C_LO_VID_SHIFT 8 /* Field definitions within the FID VID High Control MSR : */ -#define MSR_C_HI_STP_GNT_TO 0x000fffff +#define MSR_C_HI_STP_GNT_TO 0x000fffff /* Field definitions within the FID VID Low Status MSR : */ -#define MSR_S_LO_CHANGE_PENDING 0x80000000 /* cleared when completed */ -#define MSR_S_LO_MAX_RAMP_VID 0x1f000000 +#define MSR_S_LO_CHANGE_PENDING 0x80000000 /* cleared when completed */ +#define MSR_S_LO_MAX_RAMP_VID 0x3f000000 #define MSR_S_LO_MAX_FID 0x003f0000 #define MSR_S_LO_START_FID 0x00003f00 #define MSR_S_LO_CURRENT_FID 0x0000003f /* Field definitions within the FID VID High Status MSR : */ -#define MSR_S_HI_MAX_WORKING_VID 0x001f0000 -#define MSR_S_HI_START_VID 0x00001f00 -#define MSR_S_HI_CURRENT_VID 0x0000001f -#define MSR_C_HI_STP_GNT_BENIGN 0x00000001 +#define MSR_S_HI_MIN_WORKING_VID 0x3f000000 +#define MSR_S_HI_MAX_WORKING_VID 0x003f0000 +#define MSR_S_HI_START_VID 0x00003f00 +#define MSR_S_HI_CURRENT_VID 0x0000003f +#define MSR_C_HI_STP_GNT_BENIGN 0x00000001 /* * There are restrictions frequencies have to follow: @@ -99,13 +101,15 @@ struct powernow_k8_data { #define MIN_FREQ_RESOLUTION 200 /* fids jump by 2 matching freq jumps by 200 */ #define MAX_FID 0x2a /* Spec only gives FID values as far as 5 GHz */ -#define LEAST_VID 0x1e /* Lowest (numerically highest) useful vid value */ +#define LEAST_VID 0x3e /* Lowest (numerically highest) useful vid value */ #define MIN_FREQ 800 /* Min and max freqs, per spec */ #define MAX_FREQ 5000 #define INVALID_FID_MASK 0xffffffc1 /* not a valid fid if these bits are set */ -#define INVALID_VID_MASK 0xffffffe0 /* not a valid vid if these bits are set */ +#define INVALID_VID_MASK 0xffffffc0 /* not a valid vid if these bits are set */ + +#define VID_OFF 0x3f #define STOP_GRANT_5NS 1 /* min poss memory access latency for voltage change */ -- cgit v1.2.2 From 7153d9612fe5cefc29f9f17d7a6b9f0dcd07b20e Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 28 Jul 2005 09:45:10 -0700 Subject: powernow-k8.c: In function `query_current_values_with_pending_wait': powernow-k8.c:110: warning: `hi' may be used uninitialized in this function Signed-off-by: Brian Gerst Signed-off-by: Dave Jones Signed-off-by: Andrew Morton --- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 7fe5b2aaa209..de5deebc0154 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -110,14 +110,13 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data) u32 lo, hi; u32 i = 0; - lo = MSR_S_LO_CHANGE_PENDING; - while (lo & MSR_S_LO_CHANGE_PENDING) { + do { if (i++ > 0x1000000) { printk(KERN_ERR PFX "detected change pending stuck\n"); return 1; } rdmsr(MSR_FIDVID_STATUS, lo, hi); - } + } while (lo & MSR_S_LO_CHANGE_PENDING); data->currvid = hi & MSR_S_HI_CURRENT_VID; data->currfid = lo & MSR_S_LO_CURRENT_FID; -- cgit v1.2.2 From e2cac78935ff1705e1eb53be28da704d3482b4f5 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 28 Jul 2005 21:15:46 -0700 Subject: [PATCH] x86_64: When running cpuid4 need to run on the correct CPU Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/intel_cacheinfo.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index 1d768b263269..6c55b50cf048 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c @@ -128,7 +128,7 @@ static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_le cpuid_count(4, index, &eax, &ebx, &ecx, &edx); cache_eax.full = eax; if (cache_eax.split.type == CACHE_TYPE_NULL) - return -1; + return -EIO; /* better error ? */ this_leaf->eax.full = eax; this_leaf->ebx.full = ebx; @@ -334,6 +334,7 @@ static int __devinit detect_cache_attributes(unsigned int cpu) struct _cpuid4_info *this_leaf; unsigned long j; int retval; + cpumask_t oldmask; if (num_cache_leaves == 0) return -ENOENT; @@ -345,19 +346,26 @@ static int __devinit detect_cache_attributes(unsigned int cpu) memset(cpuid4_info[cpu], 0, sizeof(struct _cpuid4_info) * num_cache_leaves); + oldmask = current->cpus_allowed; + retval = set_cpus_allowed(current, cpumask_of_cpu(cpu)); + if (retval) + goto out; + /* Do cpuid and store the results */ + retval = 0; for (j = 0; j < num_cache_leaves; j++) { this_leaf = CPUID4_INFO_IDX(cpu, j); retval = cpuid4_cache_lookup(j, this_leaf); if (unlikely(retval < 0)) - goto err_out; + break; cache_shared_cpu_map_setup(cpu, j); } - return 0; + set_cpus_allowed(current, oldmask); -err_out: - free_cache_attributes(cpu); - return -ENOMEM; +out: + if (retval) + free_cache_attributes(cpu); + return retval; } #ifdef CONFIG_SYSFS -- cgit v1.2.2 From e1474e2d9dfb782e6c6517a180b5a8913c69dfad Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Thu, 28 Jul 2005 21:16:18 -0700 Subject: [PATCH] re-disable TSC on NUMAQ Somewhere recently, the TSC got re-enabled for timekeeping on NUMAQ machines. However, the hardware makes these get unsynchronized quite badly. So badly, in fact, that the code to fix up the skew can just hang on boot. This patch re-disables them. It's nicely confined to the numaq.c file. It would be great if this could make it into 2.6.13, I think it counts as a bugfix. Tested on a 16-proc 4-node NUMAQ. Signed-off-by: Dave Hansen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/numaq.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/numaq.c b/arch/i386/kernel/numaq.c index e51edf0a6564..5f5b075f860a 100644 --- a/arch/i386/kernel/numaq.c +++ b/arch/i386/kernel/numaq.c @@ -31,6 +31,7 @@ #include #include #include +#include #define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT)) @@ -77,3 +78,11 @@ int __init get_memcfg_numaq(void) smp_dump_qct(); return 1; } + +static int __init numaq_dsc_disable(void) +{ + printk(KERN_DEBUG "NUMAQ: disabling TSC\n"); + tsc_disable = 1; + return 0; +} +core_initcall(numaq_dsc_disable); -- cgit v1.2.2 From 2bcad935a3bb149833bf249e6b159f22a90d6218 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Fri, 29 Jul 2005 09:56:41 -0700 Subject: Fix up powernow-k8 compile. (Missing definitions). From: Mark Langsdorf Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k8.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h index 927e2dd6a69f..b1e85bb36396 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h @@ -125,12 +125,14 @@ struct powernow_k8_data { #define IRT_SHIFT 30 #define RVO_SHIFT 28 +#define EXT_TYPE_SHIFT 27 #define PLL_L_SHIFT 20 #define MVS_SHIFT 18 #define VST_SHIFT 11 #define VID_SHIFT 6 #define IRT_MASK 3 #define RVO_MASK 3 +#define EXT_TYPE_MASK 1 #define PLL_L_MASK 0x7f #define MVS_MASK 3 #define VST_MASK 0x7f -- cgit v1.2.2 From e7b47ccaf655cbaf336745a9b65cf7b22a536fca Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 29 Jul 2005 13:01:18 -0600 Subject: [PATCH] i386 machine_kexec: Cleanup inline assembly For some reason I was telling my inline assembly that the input argument was an output argument. Playing in the trampoline code I have seen a couple of instances where lgdt get the wrong size (because the trampolines run in 16bit mode) so use lgdtl and lidtl to be explicit. Additionally gcc-3.3 and gcc-3.4 want's an lvalue for a memory argument and it doesn't think an array of characters is an lvalue so use a packed structure instead. Signed-off-by: Eric W. Biederman Signed-off-by: Linus Torvalds --- arch/i386/kernel/machine_kexec.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c index 52ed18d8b511..cb699a2aa1f8 100644 --- a/arch/i386/kernel/machine_kexec.c +++ b/arch/i386/kernel/machine_kexec.c @@ -16,6 +16,7 @@ #include #include #include +#include static inline unsigned long read_cr3(void) { @@ -90,33 +91,32 @@ static void identity_map_page(unsigned long address) } #endif - static void set_idt(void *newidt, __u16 limit) { - unsigned char curidt[6]; + struct Xgt_desc_struct curidt; /* ia32 supports unaliged loads & stores */ - (*(__u16 *)(curidt)) = limit; - (*(__u32 *)(curidt +2)) = (unsigned long)(newidt); + curidt.size = limit; + curidt.address = (unsigned long)newidt; __asm__ __volatile__ ( - "lidt %0\n" - : "=m" (curidt) + "lidtl %0\n" + : : "m" (curidt) ); }; static void set_gdt(void *newgdt, __u16 limit) { - unsigned char curgdt[6]; + struct Xgt_desc_struct curgdt; /* ia32 supports unaligned loads & stores */ - (*(__u16 *)(curgdt)) = limit; - (*(__u32 *)(curgdt +2)) = (unsigned long)(newgdt); + curgdt.size = limit; + curgdt.address = (unsigned long)newgdt; __asm__ __volatile__ ( - "lgdt %0\n" - : "=m" (curgdt) + "lgdtl %0\n" + : : "m" (curgdt) ); }; -- cgit v1.2.2 From 094ce7fde493a1196b8152f9f9e73c20e24a2b05 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Fri, 29 Jul 2005 12:55:40 -0700 Subject: arch/i386/kernel/cpu/cpufreq/powernow-k8.c: In function `powernow_k8_cpu_init_acpi': arch/i386/kernel/cpu/cpufreq/powernow-k8.c:740: warning: unused variable `vid' arch/i386/kernel/cpu/cpufreq/powernow-k8.c:739: warning: unused variable `fid' arch/i386/kernel/cpu/cpufreq/powernow-k8.c:743: warning: unused variable `vid' arch/i386/kernel/cpu/cpufreq/powernow-k8.c:742: warning: unused variable `fid' arch/i386/kernel/cpu/cpufreq/powernow-k8.c:746: `fid' undeclared (first use in this function) arch/i386/kernel/cpu/cpufreq/powernow-k8.c:746: `vid' undeclared (first use in this function) Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index de5deebc0154..ab6e0611303d 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -735,12 +735,15 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) } for (i = 0; i < data->acpi_data.state_count; i++) { - if (data->exttype) { - u32 fid = data->acpi_data.states[i].status & FID_MASK; - u32 vid = (data->acpi_data.states[i].status >> VID_SHIFT) & VID_MASK; + u32 fid; + u32 vid; + + if (data->exttype) { + fid = data->acpi_data.states[i].status & FID_MASK; + vid = (data->acpi_data.states[i].status >> VID_SHIFT) & VID_MASK; } else { - u32 fid = data->acpi_data.states[i].control & FID_MASK; - u32 vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK; + fid = data->acpi_data.states[i].control & FID_MASK; + vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK; } dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid); -- cgit v1.2.2 From e1afc3f522ed088405fc8932110d338330db82bb Mon Sep 17 00:00:00 2001 From: "Natalie.Protasevich@unisys.com" Date: Fri, 29 Jul 2005 14:03:32 -0700 Subject: [PATCH] x86: avoid wasting IRQs patch update The patch addresses a problem with ACPI SCI interrupt entry, which gets re-used, and the IRQ is assigned to another unrelated device. The patch corrects the code such that SCI IRQ is skipped and duplicate entry is avoided. Second issue came up with VIA chipset, the problem was caused by original patch assigning IRQs starting 16 and up. The VIA chipset uses 4-bit IRQ register for internal interrupt routing, and therefore cannot handle IRQ numbers assigned to its devices. The patch corrects this problem by allowing PCI IRQs below 16. Signed-off by: Natalie Protasevich Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/mpparse.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index af917f609c7d..ce838abb27d8 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c @@ -1116,7 +1116,15 @@ int mp_register_gsi (u32 gsi, int edge_level, int active_high_low) */ int irq = gsi; if (gsi < MAX_GSI_NUM) { - gsi = pci_irq++; + if (gsi > 15) + gsi = pci_irq++; +#ifdef CONFIG_ACPI_BUS + /* + * Don't assign IRQ used by ACPI SCI + */ + if (gsi == acpi_fadt.sci_int) + gsi = pci_irq++; +#endif gsi_to_irq[irq] = gsi; } else { printk(KERN_ERR "GSI %u is too high\n", gsi); -- cgit v1.2.2