Messages in this thread Patch in this message | | | Date | Fri, 11 Jul 2003 21:01:23 -0400 (EDT) | From | "Nathaniel W. Filardo" <> | Subject | [BUG][PATCH] x86 cpu identify bug? |
| |
Hello all.
I have a Transmeta TM5800 in my laptop which some time ago stopped being able to do cpufreq stuff (/sys/devices/system/cpu/ stopped having the relevant files in it). I recently got time to look into the issue and believe I have found the relevant issue:
in arch/i386/kernel/cpu/common.c, identify_cpu contains:
if (this_cpu->c_identify) this_cpu->c_identify(c); else generic_identify(c);
At this point in the code, at least as far as I am able to tell, this_cpu is always default_cpu, which lacks an ->c_identify memeber, and as such, generic_identify is always called. That is correct behavior, I think... but a side effect of generic_identify is to set this_cpu. So I believe the correct fix is to make the flow of execution look like this:
generic_identify(c);
if (this_cpu->c_identify) this_cpu->c_identify(c);
The attached patch does that and adds some printk's that I seem to recall were in the kernel some time ago but are no longer.
Anyway, while this may not be the correct fix, it does fix my longrun issues, so I believe it to be correct, at least on uniprocessor systems. This bug probably has not bitten anybody except those people with CPUs that have CPUID bits beyond the first 64.
Keep up the good work! --nwf;--- linux-2.5.74-mm1/arch/i386/kernel/cpu/common.c.orig 2003-07-06 17:57:59.000000000 -0400 +++ linux-2.5.74-mm1/arch/i386/kernel/cpu/common.c 2003-07-06 18:06:24.000000000 -0400 @@ -288,10 +288,23 @@ c->x86 = 3; } - if (this_cpu->c_identify) + generic_identify(c); + + printk(KERN_DEBUG "CPU: After generic identify, caps: %08lx %08lx %08lx %08lx\n", + c->x86_capability[0], + c->x86_capability[1], + c->x86_capability[2], + c->x86_capability[3]); + + if (this_cpu->c_identify) { this_cpu->c_identify(c); - else - generic_identify(c); + + printk(KERN_DEBUG "CPU: After vendor identify, caps: %08lx %08lx %08lx %08lx\n", + c->x86_capability[0], + c->x86_capability[1], + c->x86_capability[2], + c->x86_capability[3]); + } /* * Vendor-specific initialization. In this section we @@ -341,7 +354,7 @@ /* Now the feature flags better reflect actual CPU features! */ - printk(KERN_DEBUG "CPU: After generic, caps: %08lx %08lx %08lx %08lx\n", + printk(KERN_DEBUG "CPU: After all inits, caps: %08lx %08lx %08lx %08lx\n", c->x86_capability[0], c->x86_capability[1], c->x86_capability[2],
| |