mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-09 05:31:17 -04:00
x86/cpu: Remove CPUID leaf 0x2 parsing loop
Leaf 0x2 output includes a "query count" byte where it was supposed to
specify the number of repeated CPUID leaf 0x2 subleaf 0 queries needed to
extract all of the CPU's cache and TLB descriptors.
Per current Intel manuals, all CPUs supporting this leaf "will always"
return an iteration count of 1.
Remove the leaf 0x2 query loop and just query the hardware once.
Note, as previously done in:
aec28d852ed2 ("x86/cpuid: Standardize on u32 in <asm/cpuid/api.h>")
standardize on using 'u32' and 'u8' types.
Suggested-by: Ingo Molnar <mingo@kernel.org>
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
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-2-darwi@linutronix.de
This commit is contained in:
committed by
Ingo Molnar
parent
0efb4dc3b0
commit
b5969494c8
@@ -6,6 +6,7 @@
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#include <linux/topology.h>
|
||||
@@ -777,28 +778,27 @@ static void intel_tlb_lookup(const unsigned char desc)
|
||||
|
||||
static void intel_detect_tlb(struct cpuinfo_x86 *c)
|
||||
{
|
||||
int i, j, n;
|
||||
unsigned int regs[4];
|
||||
unsigned char *desc = (unsigned char *)regs;
|
||||
u32 regs[4];
|
||||
u8 *desc = (u8 *)regs;
|
||||
|
||||
if (c->cpuid_level < 2)
|
||||
return;
|
||||
|
||||
/* Number of times to iterate */
|
||||
n = cpuid_eax(2) & 0xFF;
|
||||
cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]);
|
||||
|
||||
for (i = 0 ; i < n ; i++) {
|
||||
cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]);
|
||||
/* Intel CPUs must report an iteration count of 1 */
|
||||
if (desc[0] != 0x01)
|
||||
return;
|
||||
|
||||
/* If bit 31 is set, this is an unknown format */
|
||||
for (j = 0 ; j < 4 ; j++)
|
||||
if (regs[j] & (1 << 31))
|
||||
regs[j] = 0;
|
||||
|
||||
/* Byte 0 is level count, not a descriptor */
|
||||
for (j = 1 ; j < 16 ; j++)
|
||||
intel_tlb_lookup(desc[j]);
|
||||
/* If a register's bit 31 is set, it is an unknown format */
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (regs[i] & (1 << 31))
|
||||
regs[i] = 0;
|
||||
}
|
||||
|
||||
/* Skip the first byte as it is not a descriptor */
|
||||
for (int i = 1; i < 16; i++)
|
||||
intel_tlb_lookup(desc[i]);
|
||||
}
|
||||
|
||||
static const struct cpu_dev intel_cpu_dev = {
|
||||
|
||||
Reference in New Issue
Block a user