Skip to content
Open
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.
// Increase this value if more cache levels are needed. It must be large enough
// to hold every descriptor a single CPUID leaf 2 can report (up to 15, since
// the AL count byte is ignored) so that ParseLeaf2 cannot overflow
// CacheInfo::levels.
#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 @@ -1399,6 +1399,24 @@ flags : fpu mmx sse sse2 pni ssse3 sse4_1 sse4_2
}

// https://www.felixcloutier.com/x86/cpuid#example-3-1--example-of-cache-and-tlb-interpretation

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line should stay next to its original test.

// 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}},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment below to indicate that we're forging 16 descriptors (one per byte). AL being discarded. so 15 descriptors.

});

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

TEST_F(CpuidX86Test, P4_CacheInfo) {
cpu().SetLeaves({
{{0x00000000, 0}, Leaf{0x00000002, 0x756E6547, 0x6C65746E, 0x49656E69}},
Expand Down