lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <174289539647.14745.12398405425285372043.tip-bot2@tip-bot2>
Date: Tue, 25 Mar 2025 09:36:36 -0000
From: "tip-bot2 for Ahmed S. Darwish" <tip-bot2@...utronix.de>
To: linux-tip-commits@...r.kernel.org
Cc: Ingo Molnar <mingo@...nel.org>, Thomas Gleixner <tglx@...utronix.de>,
 "Ahmed S. Darwish" <darwi@...utronix.de>, "H. Peter Anvin" <hpa@...or.com>,
 Linus Torvalds <torvalds@...ux-foundation.org>, x86@...nel.org,
 linux-kernel@...r.kernel.org
Subject: [tip: x86/cpu] x86/cacheinfo: Remove CPUID leaf 0x2 parsing loop

The following commit has been merged into the x86/cpu branch of tip:

Commit-ID:     09a1da4beb310420b720994f7b6599e8d0bce3e1
Gitweb:        https://git.kernel.org/tip/09a1da4beb310420b720994f7b6599e8d0bce3e1
Author:        Ahmed S. Darwish <darwi@...utronix.de>
AuthorDate:    Mon, 24 Mar 2025 14:32:57 +01:00
Committer:     Ingo Molnar <mingo@...nel.org>
CommitterDate: Tue, 25 Mar 2025 10:22:02 +01:00

x86/cacheinfo: 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 at commit aec28d852ed2 ("x86/cpuid: Standardize
on u32 in <asm/cpuid/api.h>"), standardize on using 'u32' and 'u8' types.

Suggested-by: Ingo Molnar <mingo@...nel.org>
Suggested-by: Thomas Gleixner <tglx@...utronix.de>
Signed-off-by: Ahmed S. Darwish <darwi@...utronix.de>
Signed-off-by: Ingo Molnar <mingo@...nel.org>
Cc: H. Peter Anvin <hpa@...or.com>
Cc: Linus Torvalds <torvalds@...ux-foundation.org>
Link: https://lore.kernel.org/r/20250324133324.23458-3-darwi@linutronix.de
---
 arch/x86/kernel/cpu/cacheinfo.c | 77 +++++++++++++++-----------------
 1 file changed, 37 insertions(+), 40 deletions(-)

diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c
index b3a5209..36782fd 100644
--- a/arch/x86/kernel/cpu/cacheinfo.c
+++ b/arch/x86/kernel/cpu/cacheinfo.c
@@ -42,7 +42,7 @@ static cpumask_var_t cpu_cacheinfo_mask;
 unsigned int memory_caching_control __ro_after_init;
 
 struct _cache_table {
-	unsigned char descriptor;
+	u8 descriptor;
 	char cache_type;
 	short size;
 };
@@ -783,50 +783,47 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c)
 
 	/* Don't use CPUID(2) if CPUID(4) is supported. */
 	if (!ci->num_leaves && c->cpuid_level > 1) {
-		/* supports eax=2  call */
-		int j, n;
-		unsigned int regs[4];
-		unsigned char *dp = (unsigned char *)regs;
-
-		/* Number of times to iterate */
-		n = cpuid_eax(2) & 0xFF;
-
-		for (i = 0 ; i < n ; i++) {
-			cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
-
-			/* 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++) {
-				unsigned char des = dp[j];
-				unsigned char k = 0;
-
-				/* look up this descriptor in the table */
-				while (cache_table[k].descriptor != 0) {
-					if (cache_table[k].descriptor == des) {
-						switch (cache_table[k].cache_type) {
-						case LVL_1_INST:
-							l1i += cache_table[k].size;
-							break;
-						case LVL_1_DATA:
-							l1d += cache_table[k].size;
-							break;
-						case LVL_2:
-							l2 += cache_table[k].size;
-							break;
-						case LVL_3:
-							l3 += cache_table[k].size;
-							break;
-						}
+		u32 regs[4];
+		u8 *desc = (u8 *)regs;
 
+		cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
+
+		/* Intel CPUs must report an iteration count of 1 */
+		if (desc[0] != 0x01)
+			return;
+
+		/* 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++) {
+			u8 des = desc[i];
+			u8 k = 0;
+
+			/* look up this descriptor in the table */
+			while (cache_table[k].descriptor != 0) {
+				if (cache_table[k].descriptor == des) {
+					switch (cache_table[k].cache_type) {
+					case LVL_1_INST:
+						l1i += cache_table[k].size;
+						break;
+					case LVL_1_DATA:
+						l1d += cache_table[k].size;
+						break;
+					case LVL_2:
+						l2 += cache_table[k].size;
+						break;
+					case LVL_3:
+						l3 += cache_table[k].size;
 						break;
 					}
 
-					k++;
+					break;
 				}
+				k++;
 			}
 		}
 	}

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ