x86/cpu: Use consolidated CPUID leaf 0x2 descriptor table

CPUID leaf 0x2 output is a stream of one-byte descriptors, each implying
certain details about the CPU's cache and TLB entries.

At previous commits, the mapping tables for such descriptors were merged
into one consolidated table.  The mapping was also transformed into a
hash lookup instead of a loop-based lookup for each descriptor.

Use the new consolidated table and its hash-based lookup through the
for_each_leaf_0x2_tlb_entry() accessor.

Remove the TLB-specific mapping, intel_tlb_table[], as it is now no
longer used.  Remove the <cpuid/types.h> macro, for_each_leaf_0x2_desc(),
since the converted code was its last user.

Signed-off-by: Ahmed S. Darwish <darwi@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/20250324133324.23458-23-darwi@linutronix.de
This commit is contained in:
Ahmed S. Darwish 2025-03-24 14:33:17 +01:00 committed by Ingo Molnar
parent da23a62598
commit 4772304ee6
2 changed files with 17 additions and 76 deletions

View File

@ -115,4 +115,14 @@ struct leaf_0x2_table {
extern const struct leaf_0x2_table cpuid_0x2_table[256];
/*
* All of leaf 0x2's one-byte TLB descriptors implies the same number of entries
* for their respective TLB types. TLB descriptor 0x63 is an exception: it
* implies 4 dTLB entries for 1GB pages and 32 dTLB entries for 2MB or 4MB pages.
*
* Encode that descriptor's dTLB entry count for 2MB/4MB pages here, as the entry
* count for dTLB 1GB pages is already encoded at the cpuid_0x2_table[]'s mapping.
*/
#define TLB_0x63_2M_4M_ENTRIES 32
#endif /* _ASM_X86_CPUID_TYPES_H */

View File

@ -626,81 +626,11 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 *c, unsigned int size)
}
#endif
/*
* All of leaf 0x2's one-byte TLB descriptors implies the same number of
* entries for their respective TLB types. The 0x63 descriptor is an
* exception: it implies 4 dTLB entries for 1GB pages 32 dTLB entries
* for 2MB or 4MB pages. Encode descriptor 0x63 dTLB entry count for
* 2MB/4MB pages here, as its count for dTLB 1GB pages is already at the
* intel_tlb_table[] mapping.
*/
#define TLB_0x63_2M_4M_ENTRIES 32
struct _tlb_table {
unsigned char descriptor;
enum _tlb_table_type type;
unsigned int entries;
};
static const struct _tlb_table intel_tlb_table[] = {
{ 0x01, TLB_INST_4K, 32}, /* TLB_INST 4 KByte pages, 4-way set associative */
{ 0x02, TLB_INST_4M, 2}, /* TLB_INST 4 MByte pages, full associative */
{ 0x03, TLB_DATA_4K, 64}, /* TLB_DATA 4 KByte pages, 4-way set associative */
{ 0x04, TLB_DATA_4M, 8}, /* TLB_DATA 4 MByte pages, 4-way set associative */
{ 0x05, TLB_DATA_4M, 32}, /* TLB_DATA 4 MByte pages, 4-way set associative */
{ 0x0b, TLB_INST_4M, 4}, /* TLB_INST 4 MByte pages, 4-way set associative */
{ 0x4f, TLB_INST_4K, 32}, /* TLB_INST 4 KByte pages */
{ 0x50, TLB_INST_ALL, 64}, /* TLB_INST 4 KByte and 2-MByte or 4-MByte pages */
{ 0x51, TLB_INST_ALL, 128}, /* TLB_INST 4 KByte and 2-MByte or 4-MByte pages */
{ 0x52, TLB_INST_ALL, 256}, /* TLB_INST 4 KByte and 2-MByte or 4-MByte pages */
{ 0x55, TLB_INST_2M_4M, 7}, /* TLB_INST 2-MByte or 4-MByte pages, fully associative */
{ 0x56, TLB_DATA0_4M, 16}, /* TLB_DATA0 4 MByte pages, 4-way set associative */
{ 0x57, TLB_DATA0_4K, 16}, /* TLB_DATA0 4 KByte pages, 4-way associative */
{ 0x59, TLB_DATA0_4K, 16}, /* TLB_DATA0 4 KByte pages, fully associative */
{ 0x5a, TLB_DATA0_2M_4M, 32}, /* TLB_DATA0 2-MByte or 4 MByte pages, 4-way set associative */
{ 0x5b, TLB_DATA_4K_4M, 64}, /* TLB_DATA 4 KByte and 4 MByte pages */
{ 0x5c, TLB_DATA_4K_4M, 128}, /* TLB_DATA 4 KByte and 4 MByte pages */
{ 0x5d, TLB_DATA_4K_4M, 256}, /* TLB_DATA 4 KByte and 4 MByte pages */
{ 0x61, TLB_INST_4K, 48}, /* TLB_INST 4 KByte pages, full associative */
{ 0x63, TLB_DATA_1G_2M_4M, 4}, /* TLB_DATA 1 GByte pages, 4-way set associative
* (plus 32 entries TLB_DATA 2 MByte or 4 MByte pages, not encoded here) */
{ 0x6b, TLB_DATA_4K, 256}, /* TLB_DATA 4 KByte pages, 8-way associative */
{ 0x6c, TLB_DATA_2M_4M, 128}, /* TLB_DATA 2 MByte or 4 MByte pages, 8-way associative */
{ 0x6d, TLB_DATA_1G, 16}, /* TLB_DATA 1 GByte pages, fully associative */
{ 0x76, TLB_INST_2M_4M, 8}, /* TLB_INST 2-MByte or 4-MByte pages, fully associative */
{ 0xb0, TLB_INST_4K, 128}, /* TLB_INST 4 KByte pages, 4-way set associative */
{ 0xb1, TLB_INST_2M_4M, 4}, /* TLB_INST 2M pages, 4-way, 8 entries or 4M pages, 4-way entries */
{ 0xb2, TLB_INST_4K, 64}, /* TLB_INST 4KByte pages, 4-way set associative */
{ 0xb3, TLB_DATA_4K, 128}, /* TLB_DATA 4 KByte pages, 4-way set associative */
{ 0xb4, TLB_DATA_4K, 256}, /* TLB_DATA 4 KByte pages, 4-way associative */
{ 0xb5, TLB_INST_4K, 64}, /* TLB_INST 4 KByte pages, 8-way set associative */
{ 0xb6, TLB_INST_4K, 128}, /* TLB_INST 4 KByte pages, 8-way set associative */
{ 0xba, TLB_DATA_4K, 64}, /* TLB_DATA 4 KByte pages, 4-way associative */
{ 0xc0, TLB_DATA_4K_4M, 8}, /* TLB_DATA 4 KByte and 4 MByte pages, 4-way associative */
{ 0xc1, STLB_4K_2M, 1024}, /* STLB 4 KByte and 2 MByte pages, 8-way associative */
{ 0xc2, TLB_DATA_2M_4M, 16}, /* TLB_DATA 2 MByte/4MByte pages, 4-way associative */
{ 0xca, STLB_4K, 512}, /* STLB 4 KByte pages, 4-way associative */
{ 0x00, 0, 0 }
};
static void intel_tlb_lookup(const unsigned char desc)
static void intel_tlb_lookup(const struct leaf_0x2_table *entry)
{
unsigned int entries;
unsigned char k;
short entries = entry->entries;
if (desc == 0)
return;
/* look up this descriptor in the table */
for (k = 0; intel_tlb_table[k].descriptor != desc &&
intel_tlb_table[k].descriptor != 0; k++)
;
if (intel_tlb_table[k].type == 0)
return;
entries = intel_tlb_table[k].entries;
switch (intel_tlb_table[k].type) {
switch (entry->t_type) {
case STLB_4K:
tlb_lli_4k = max(tlb_lli_4k, entries);
tlb_lld_4k = max(tlb_lld_4k, entries);
@ -757,15 +687,16 @@ static void intel_tlb_lookup(const unsigned char desc)
static void intel_detect_tlb(struct cpuinfo_x86 *c)
{
const struct leaf_0x2_table *entry;
union leaf_0x2_regs regs;
u8 *desc;
u8 *ptr;
if (c->cpuid_level < 2)
return;
cpuid_get_leaf_0x2_regs(&regs);
for_each_leaf_0x2_desc(regs, desc)
intel_tlb_lookup(*desc);
for_each_leaf_0x2_entry(regs, ptr, entry)
intel_tlb_lookup(entry);
}
static const struct cpu_dev intel_cpu_dev = {