Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions include/cpu_features_cache_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,12 @@ typedef struct {
int partitioning; // number of lines per sector
} CacheLevelInfo;

// Increase this value if more cache levels are needed.
// This structure is CPU-agnostic; increase CPU_FEATURES_MAX_CACHE_LEVEL if a
// backend needs to report more cache levels. On x86 it must be at least 15 so
// that ParseLeaf2 cannot overflow CacheInfo::levels: a single CPUID leaf 2 can
// report up to 15 descriptors (the AL count byte is ignored).
#ifndef CPU_FEATURES_MAX_CACHE_LEVEL
#define CPU_FEATURES_MAX_CACHE_LEVEL 10
#define CPU_FEATURES_MAX_CACHE_LEVEL 16
#endif
typedef struct {
int size;
Expand Down
18 changes: 18 additions & 0 deletions test/cpuinfo_x86_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1398,6 +1398,24 @@ flags : fpu mmx sse sse2 pni ssse3 sse4_1 sse4_2
EXPECT_TRUE(info.features.sse4_2);
}

// Regression test: a CPUID leaf 2 advertising the maximum number of cache/TLB
// descriptors must not overflow CacheInfo::levels.
TEST_F(CpuidX86Test, Leaf2_TooManyDescriptors_DoesNotOverflow) {
cpu().SetLeaves({
{{0x00000000, 0}, Leaf{0x00000002, 0x756E6547, 0x6C65746E, 0x49656E69}},
{{0x00000001, 0}, Leaf{0x00000F0A, 0x00010808, 0x00000000, 0x3FEBFBFF}},
// Leaf 2 encodes one descriptor per byte across its four registers (16
// bytes total). AL, the low byte of EAX, is the ignored count byte, so
// these all-0x01 registers forge 15 non-zero descriptors -- more than the
// old 10-entry CacheInfo::levels array and exactly filling the new 16.
{{0x00000002, 0}, Leaf{0x01010101, 0x01010101, 0x01010101, 0x01010101}},
Comment thread
gchatelet marked this conversation as resolved.
});

const auto info = GetX86CacheInfo();
// All 15 descriptors are recorded, saturating the resized levels array.
EXPECT_EQ(info.size, 15);
}

// https://www.felixcloutier.com/x86/cpuid#example-3-1--example-of-cache-and-tlb-interpretation
TEST_F(CpuidX86Test, P4_CacheInfo) {
cpu().SetLeaves({
Expand Down
Loading