NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

port-amd64/60619: L2 cache associativity not decoded properly on VIA/Zhaoxin CPUs, panic on Zhaoxin KX-7000



>Number:         60619
>Category:       port-amd64
>Synopsis:       L2 cache associativity not decoded properly on VIA/Zhaoxin CPUs, panic on Zhaoxin KX-7000
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    port-amd64-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Aug 18 21:35:00 +0000 2026
>Originator:     Andrius V
>Release:        NetBSD 11.0
>Organization:
>Environment:
>Description:
On a KX-7000 CPU I hit the panic:

"desired number of cache colors 21 is > 1, but not even!",

which revealed a couple of problems with cache detection on Centaur (VIA/Zhaoxin) CPUs:

First issue:
L2 cache associativity is not decoded correctly.

Current Centaur (VIA/Zhaoxin) cache probe reads cache parameters from cpuid function 0x80000006 (for Nehemiah and later CPUs). It is apparently using "AMD" way to encode parameters. The problem is that associativity bits hold the encoded value (cai->cai_associativity = VIA_L2N_ECX_C_ASSOC(descs[2]);), and need an AMD style table lookup  to decode an actual one in the same way AMD cpu probe does (defined by AMD_L2L3CACHE_INFO in https://nxr.netbsd.org/xref/src/sys/arch/x86/include/cacheinfo.h?r=1.31#344). Meaning, that it currently returns values like A for C7 and used directly as is, but actually means 32-way (not 10-way). In a same manner 8 for Nehemiah means 16-way (not 8-way). VIA datasheets state that actual decimal value is stored, but in reality it is not the case, which I can confirm from my own samples and InstLatx64 CPUID dumps. In KX-7000 case it was 6, which by AMD table is 8-way (matching CPU specs). 

The page color is counted as atop(cai_totalsize) / cai_associativity, so a wrong associativity yields a wrong color count (can be either bigger or smaller than the actual, depending on the model). Only by pure luck we didn't hit the panic before, since color calculation was still matching a power of two (just not the expected one). Wrong L2 associativity can be seen with using cpuctl utility (if L2 cache data is shown).

Second issue:
Newer CPU models support and prefer function 4 to get cache parameters.

With the more recent models, CPUID function 4 is the preferred way to get cache parameters which are stored in the "Intel" way instead. 
(https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/commit/?id=a2aa578fec8c29436bce5e6c15e1e31729d539a3). 

Looks like function 4 is supported from the CNQ generation VIA Nano CPUs (Nano/Eden 4xxx) or family 6 model F stepping C (6FC) models and all 7 family CPUs (used by Zhaoxin) based on InstLatx64 dumps, including KX-7000.

Additionally, L3 cache is reported by CPUID function 4 only. 0x80000006 always reports L3 as 0 KB on these CPUs. L3 only appeared in relatively recent Zhaoxin models (ignoring unreleased Centaur CNS CPUs).

Thus we need to map cache data for newer CPUs using CPUID function 4 to get more reliable data.
I believe probing it and verifying non-zero value is more preferred way in comparison to CPU family/stepping check.
>How-To-Repeat:
Panics during boot on KX-7000.
Silently miscalculate on others (Nehemiah (C3), Esther (C7), Isaiah (Nano)).
Wrong L2 associativity reported by cpuctl (if shown).
>Fix:
Use AMD_L2L3CACHE_INFO to map correct associativity value for Nehemiah and higher CPUs, same way as AMD probe does.

Use CPUID function 4 to query cache parameters and use intel way decoding it for more recent models where function 4 is available and contains non-zero value.

Map L3 value when available.

No patch yet...




Home | Main Index | Thread Index | Old Index