From nobody Fri Oct 10 19:51:00 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 325D92E2EEA for ; Thu, 12 Jun 2025 23:42:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749771753; cv=none; b=PqJVQaWHlISZ+I1mx4JcpNr+bR/BoDP4coqR+RUZxcoZ1s3Ps01UwP+jrDb4WW7uJOgFt8n/QFaY3nks6aOC8B9Y5lm85yyqHxzmWyF/nL6/xXWcywSxuM94KicgZfXDMe44mbcwHPpbJHlWgBtb6MUBfWKlL4Btfp8alJRugYE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749771753; c=relaxed/simple; bh=0knIiJed+iM6apE2X1ooD/hv8cZ0HlCGEf+9pv5NZO0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=juiKSlmZfRYm3fdWvCzvakgBtAp7B44PnTWGlppOJrLhhGT5JDQbwCo59Z6QAyIPAKBvtRYmcbj03d+Dh6m5MhN3tZKP+gm+H/axBOW9zp9iRqAra5f9nBHSUI/kJ/pc+mXCAdUagcoA+DaQq4vVWTOl3UEaJ2mwHVjUyTD1/bs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Y5qVy9tp; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=xGhSosqj; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Y5qVy9tp"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="xGhSosqj" From: "Ahmed S. Darwish" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1749771749; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rJmOsBqP7pyCXVJh5L49zJK7w0MxhCEoQ8Qk5wVIKow=; b=Y5qVy9tpPkqfgjxssambEegRvhVITm3AUVQYbaPNRM5RrTDwSqwPUB2neppXqeInpN0YU6 lvIiI6bilLm7lt3WeMqyycef6dFMuGOKgxQC3mjwR9JWAIGabkww5pgk5l5KfWIL8UUHni shJrE2J7nil2Ss3o0ls0n+diP0avUVIvz/sN+r5jDLfEvhP86u8yWbHY/+/Ai9yCEIxA8+ g4zNSR4ibTXHtMzcAlmnkndr1YwqMUmhZS08hl2ynkAsSwkrBkzPT9cYKWfzmez/4Od0W8 HnMccCIYLv64L2Tq6Tb3i9mOCJF5SXW5hV3rMkbslLykmtmI39Kg0o/gOFIMeQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1749771749; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rJmOsBqP7pyCXVJh5L49zJK7w0MxhCEoQ8Qk5wVIKow=; b=xGhSosqjSpjnukJiRO1lfCO8+80QNQ2u7+5dGEzXXfV11ri4Z6W9+ehvTS3Ex8Xk80mVQN nmWO3zj7g5EsgUAw== To: Ingo Molnar , Borislav Petkov , Dave Hansen Cc: Thomas Gleixner , Andrew Cooper , "H. Peter Anvin" , Peter Zijlstra , Sean Christopherson , Sohil Mehta , Ard Biesheuvel , John Ogness , x86@kernel.org, x86-cpuid@lists.linux.dev, LKML , "Ahmed S. Darwish" Subject: [PATCH v3 39/44] x86/cacheinfo: Use parsed CPUID(0x80000005) and CPUID(0x80000006) Date: Fri, 13 Jun 2025 01:40:05 +0200 Message-ID: <20250612234010.572636-40-darwi@linutronix.de> In-Reply-To: <20250612234010.572636-1-darwi@linutronix.de> References: <20250612234010.572636-1-darwi@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" For the AMD CPUID(0x4)-emulation logic, use parsed CPUID(0x80000005) and CPUID(0x80000006) APID access instead of invoking direct CPUID queries. Beside centralizing CPUID access, this allows using the auto-generated 'struct leaf_0x80000005_0' and 'struct leaf_0x80000006_0' data types. Remove the 'union {l1,l2,l3}_cache' definitions as they are no longer needed. Note, the expression: ci->num_leaves =3D (cpuid_edx(0x80000006) & 0xf000) ? 4 : 3; is replaced with: ci->num_leaves =3D cpuid_leaf(c, 0x80000006)->l3_assoc ? 4 : 3; which is the same logic, since the 'l3_assoc' bitfield is 4 bits wide at EDX offset 12. Per AMD manuals, an L3 associativity of zero implies the absence of an L3 cache on the CPU. While at it, separate the 'Fallback AMD CPUID(0x4) emulation' comment from the '@AMD_L2_L3_INVALID_ASSOC' one, since the former acts as a source code section header. Signed-off-by: Ahmed S. Darwish --- arch/x86/kernel/cpu/cacheinfo.c | 105 ++++++++++++-------------------- 1 file changed, 40 insertions(+), 65 deletions(-) diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinf= o.c index f0540cba4bd4..de8e7125eedd 100644 --- a/arch/x86/kernel/cpu/cacheinfo.c +++ b/arch/x86/kernel/cpu/cacheinfo.c @@ -56,47 +56,17 @@ static const enum cache_type cache_type_map[] =3D { }; =20 /* - * Fallback AMD CPUID(0x4) emulation + * Fallback AMD CPUID(0x4) emulation: * AMD CPUs with TOPOEXT can just use CPUID(0x8000001d) - * + */ + +/* * @AMD_L2_L3_INVALID_ASSOC: cache info for the respective L2/L3 cache sho= uld * be determined from CPUID(0x8000001d) instead of CPUID(0x80000006). */ - #define AMD_CPUID4_FULLY_ASSOCIATIVE 0xffff #define AMD_L2_L3_INVALID_ASSOC 0x9 =20 -union l1_cache { - struct { - unsigned line_size :8; - unsigned lines_per_tag :8; - unsigned assoc :8; - unsigned size_in_kb :8; - }; - unsigned int val; -}; - -union l2_cache { - struct { - unsigned line_size :8; - unsigned lines_per_tag :4; - unsigned assoc :4; - unsigned size_in_kb :16; - }; - unsigned int val; -}; - -union l3_cache { - struct { - unsigned line_size :8; - unsigned lines_per_tag :4; - unsigned assoc :4; - unsigned res :2; - unsigned size_encoded :14; - }; - unsigned int val; -}; - /* L2/L3 associativity mapping */ static const unsigned short assocs[] =3D { [1] =3D 1, @@ -117,50 +87,52 @@ static const unsigned short assocs[] =3D { static const unsigned char levels[] =3D { 1, 1, 2, 3 }; static const unsigned char types[] =3D { 1, 2, 3, 3 }; =20 -static void legacy_amd_cpuid4(int index, struct leaf_0x4_0 *regs) +static void legacy_amd_cpuid4(struct cpuinfo_x86 *c, int index, struct lea= f_0x4_0 *regs) { - unsigned int dummy, line_size, lines_per_tag, assoc, size_in_kb; - union l1_cache l1i, l1d, *l1; - union l2_cache l2; - union l3_cache l3; + const struct leaf_0x80000005_0 *el5 =3D cpuid_leaf(c, 0x80000005); + const struct leaf_0x80000006_0 *el6 =3D cpuid_leaf(c, 0x80000006); + const struct cpuid_regs *el5_raw =3D (const struct cpuid_regs *)el5; + unsigned int line_size, lines_per_tag, assoc, size_in_kb; =20 *regs =3D (struct leaf_0x4_0){ }; =20 - cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val); - cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val); - - l1 =3D &l1d; switch (index) { - case 1: - l1 =3D &l1i; - fallthrough; case 0: - if (!l1->val) + if (!el5 || !el5_raw->ecx) return; =20 - assoc =3D (l1->assoc =3D=3D 0xff) ? AMD_CPUID4_FULLY_ASSOCIATIVE : l1->= assoc; - line_size =3D l1->line_size; - lines_per_tag =3D l1->lines_per_tag; - size_in_kb =3D l1->size_in_kb; + assoc =3D el5->l1_dcache_assoc; + line_size =3D el5->l1_dcache_line_size; + lines_per_tag =3D el5->l1_dcache_nlines; + size_in_kb =3D el5->l1_dcache_size_kb; + break; + case 1: + if (!el5 || !el5_raw->edx) + return; + + assoc =3D el5->l1_icache_assoc; + line_size =3D el5->l1_icache_line_size; + lines_per_tag =3D el5->l1_icache_nlines; + size_in_kb =3D el5->l1_icache_size_kb; break; case 2: - if (!l2.assoc || l2.assoc =3D=3D AMD_L2_L3_INVALID_ASSOC) + if (!el6 || !el6->l2_assoc || el6->l2_assoc =3D=3D AMD_L2_L3_INVALID_ASS= OC) return; =20 /* Use x86_cache_size as it might have K7 errata fixes */ - assoc =3D assocs[l2.assoc]; - line_size =3D l2.line_size; - lines_per_tag =3D l2.lines_per_tag; + assoc =3D assocs[el6->l2_assoc]; + line_size =3D el6->l2_line_size; + lines_per_tag =3D el6->l2_nlines; size_in_kb =3D __this_cpu_read(cpu_info.x86_cache_size); break; case 3: - if (!l3.assoc || l3.assoc =3D=3D AMD_L2_L3_INVALID_ASSOC) + if (!el6 || !el6->l3_assoc || el6->l3_assoc =3D=3D AMD_L2_L3_INVALID_ASS= OC) return; =20 - assoc =3D assocs[l3.assoc]; - line_size =3D l3.line_size; - lines_per_tag =3D l3.lines_per_tag; - size_in_kb =3D l3.size_encoded * 512; + assoc =3D assocs[el6->l3_assoc]; + line_size =3D el6->l3_line_size; + lines_per_tag =3D el6->l3_nlines; + size_in_kb =3D el6->l3_size_range * 512; if (boot_cpu_has(X86_FEATURE_AMD_DCM)) { size_in_kb =3D size_in_kb >> 1; assoc =3D assoc >> 1; @@ -170,6 +142,10 @@ static void legacy_amd_cpuid4(int index, struct leaf_0= x4_0 *regs) return; } =20 + /* For L1d and L1i caches, 0xff is the full associativity marker */ + if ((index =3D=3D 0 || index =3D=3D 1) && assoc =3D=3D 0xff) + assoc =3D AMD_CPUID4_FULLY_ASSOCIATIVE; + regs->cache_self_init =3D 1; regs->cache_type =3D types[index]; regs->cache_level =3D levels[index]; @@ -207,7 +183,7 @@ static int amd_fill_cpuid4_info(struct cpuinfo_x86 *c, = int index, struct _cpuid4 if (boot_cpu_has(X86_FEATURE_TOPOEXT) || boot_cpu_data.x86_vendor =3D=3D = X86_VENDOR_HYGON) regs =3D *(struct leaf_0x4_0 *)cpuid_subleaf_index(c, 0x8000001d, index); else - legacy_amd_cpuid4(index, ®s); + legacy_amd_cpuid4(c, index, ®s); =20 return cpuid4_info_fill_done(id4, ®s); } @@ -279,10 +255,9 @@ void init_amd_cacheinfo(struct cpuinfo_x86 *c) { struct cpu_cacheinfo *ci =3D get_cpu_cacheinfo(c->cpu_index); =20 - if (boot_cpu_has(X86_FEATURE_TOPOEXT)) - ci->num_leaves =3D cpuid_subleaf_count(c, 0x8000001d); - else if (c->extended_cpuid_level >=3D 0x80000006) - ci->num_leaves =3D (cpuid_edx(0x80000006) & 0xf000) ? 4 : 3; + ci->num_leaves =3D boot_cpu_has(X86_FEATURE_TOPOEXT) ? + cpuid_subleaf_count(c, 0x8000001d) : + cpuid_leaf(c, 0x80000006)->l3_assoc ? 4 : 3; } =20 void init_hygon_cacheinfo(struct cpuinfo_x86 *c) --=20 2.49.0