Re: [BUG] 2.6.25-rc2-git8 fails to boot on 486 due to TSC breakage

From: Ingo Molnar
Date: Sun Feb 24 2008 - 12:53:44 EST



* Mikael Pettersson <mikpe@xxxxxxxx> wrote:

>
> That turned out to be very illuminating:
>
> --- dmesg-2.6.24-git7 2008-02-24 18:01:25.295851000 +0100
> +++ dmesg-2.6.24-git8 2008-02-24 18:01:25.530358000 +0100
> ...
> CPU: After generic identify, caps: 00000003 00000000 00000000 00000000 00000000 00000000 00000000 00000000
>
> CPU: After all inits, caps: 00000003 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> +CPU: After applying cleared_cpu_caps, caps: 00000013 00000000 00000000 00000000 00000000 00000000 00000000 00000000
>
> Notice how the TSC cap bit goes from Off to On.
>
> (The first two lines are printout loops from -git7 forward-ported
> to -git8, the third line is the same printout loop added just after
> the xor-with-cleared_cpu_caps[] loop.)
>
> Here's how the breakage occurs:
> 1. arch/x86/kernel/tsc_32.c:tsc_init() sees !cpu_has_tsc,
> so bails and calls setup_clear_cpu_cap(X86_FEATURE_TSC).
> 2. include/asm-x86/cpufeature.h:setup_clear_cpu_cap(bit) clears
> the bit in boot_cpu_data and sets it in cleared_cpu_caps
> 3. arch/x86/kernel/cpu/common.c:identify_cpu() XORs all caps
> in with cleared_cpu_caps
> HOWEVER, at this point c->x86_capability correctly has TSC
> Off, cleared_cpu_caps has TSC On, so the XOR incorrectly
> sets TSC to On in c->x86_capability, with disastrous results.
>
> The real bug is that clearing bits with XOR only works if the bits are
> known to be 1 prior to the XOR, and that's not true here.
>
> A simple fix is to convert the XOR to AND-NOT instead. The following
> patch does that, and allows my 486 to boot 2.6.25-rc kernels again.

thanks for the fix, i've queued it up. The breakage was introduced via:

commit 7d851c8d3db0f79b92c8b14361779ede8acd2488
Author: Andi Kleen <ak@xxxxxxx>
Date: Wed Jan 30 13:33:20 2008 +0100

x86: add framework to disable CPUID bits on the command line

There are already various options to disable specific cpuid bits
on the command line. They all use their own variable. Add a generic
mask to make this easier in the future.

Signed-off-by: Andi Kleen <ak@xxxxxxx>
Signed-off-by: Ingo Molnar <mingo@xxxxxxx>
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>

Ingo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/