From nobody Thu Apr 2 20:21:29 2026 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 653023644A2 for ; Fri, 27 Mar 2026 02:19:51 +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=1774577992; cv=none; b=NSxq561iWaJsEUsifqVkPP1lzFMLRrrbGtVsUOn2k8V/BbMwr1oxBUrGzf66GDXw+wxm734DwLRlFwhEmFlkryHCJ2wruvJE5rXTktv7M0gae14+Y/k6Z37RRyq2/UEcSNsVd7K+dgKnb2GGLfoQ9UnrrGnwrNvSCfw855qTG4E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774577992; c=relaxed/simple; bh=1B5FsMesNAjF3SQIwWa7/TgWMtxwmmAnuAWxOyxEcO4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iaOMcpl9QQWTiKJWR1OhfERcTUc6oGuHEOR2RK7KEfO/UQ7eQT7lhWAOx3rWRF6qNdX1z5MBWnWUGY8GdYJcoXIPztxm2qbZBZWd7hmry5NXlDzt+B8XyyvctGBX3SRb4V4RbchrDIqAFNNIge0RtBR4z0Ns1ulGne9pb6+SjxA= 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=DQD+dnam; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=a+I2c3Fg; 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="DQD+dnam"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="a+I2c3Fg" From: "Ahmed S. Darwish" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1774577990; 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=fea5yNCkv7srikrGBIMhCHCtOJygc+9yvUVEcrDZioI=; b=DQD+dnam0Vp3LrwjJeu+wGq5+TKdbX5JKvaCH6rg/StWQ7YjDyFyfA7XUNtiyD6rwFUUE4 JslB8a83IHV9EQlIHK3FQrM4SMMyS06ziMq7LV9nThpI1pVbqeGg5pIyIpBlIRdrjtXeHZ IzJMjD4GDjYb47F/7O2k9OVq6ZBHcr1FWB0nV/a8/ocrSKfcQnhPd1MhaNNeiFhT07vRFf 0B5PtfDC/EhT60Klwh17JFT1hLJGhFTXJOb/C/Ruvv5dCjVVoEX6Y7bRgX2HCWF9NYS/fM acYpxzhNm6MuIzJohDUqTtMIRsanF8d1OhH10WdjfnQ8Bv7dOEH8gfpB3qcWlQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1774577990; 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=fea5yNCkv7srikrGBIMhCHCtOJygc+9yvUVEcrDZioI=; b=a+I2c3Fgm7II6gjMKu6OhU7BIZZ+59D/iSIm+Z/6KeDGd4T9aM5afl6wLxdyNNnB2OILcQ n9IsnfMWUECNReBQ== To: Borislav Petkov , Dave Hansen , Ingo Molnar Cc: Thomas Gleixner , Andrew Cooper , "H. Peter Anvin" , Sean Christopherson , David Woodhouse , Peter Zijlstra , Christian Ludloff , Sohil Mehta , John Ogness , x86@kernel.org, x86-cpuid@lists.linux.dev, LKML , "Ahmed S. Darwish" Subject: [PATCH v6 41/90] x86/cacheinfo: Use auto-generated data types Date: Fri, 27 Mar 2026 03:15:55 +0100 Message-ID: <20260327021645.555257-42-darwi@linutronix.de> In-Reply-To: <20260327021645.555257-1-darwi@linutronix.de> References: <20260327021645.555257-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 the auto-generated data type: struct leaf_0x4_n instead of the manually-defined: union _cpuid4_leaf_{eax,ebx,ecx} ones. Remove such unions entirely as they are no longer used. Signed-off-by: Ahmed S. Darwish Link: https://gitlab.com/x86-cpuid.org/x86-cpuid-db --- arch/x86/kernel/cpu/cacheinfo.c | 127 +++++++++++--------------------- 1 file changed, 42 insertions(+), 85 deletions(-) diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinf= o.c index 86a8e1dad935..209a0c708213 100644 --- a/arch/x86/kernel/cpu/cacheinfo.c +++ b/arch/x86/kernel/cpu/cacheinfo.c @@ -41,39 +41,8 @@ enum _cache_type { CTYPE_UNIFIED =3D 3 }; =20 -union _cpuid4_leaf_eax { - struct { - enum _cache_type type :5; - unsigned int level :3; - unsigned int is_self_initializing :1; - unsigned int is_fully_associative :1; - unsigned int reserved :4; - unsigned int num_threads_sharing :12; - unsigned int num_cores_on_die :6; - } split; - u32 full; -}; - -union _cpuid4_leaf_ebx { - struct { - unsigned int coherency_line_size :12; - unsigned int physical_line_partition :10; - unsigned int ways_of_associativity :10; - } split; - u32 full; -}; - -union _cpuid4_leaf_ecx { - struct { - unsigned int number_of_sets :32; - } split; - u32 full; -}; - struct _cpuid4_info { - union _cpuid4_leaf_eax eax; - union _cpuid4_leaf_ebx ebx; - union _cpuid4_leaf_ecx ecx; + struct leaf_0x4_n regs; unsigned int id; unsigned long size; }; @@ -148,17 +117,14 @@ 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, union _cpuid4_leaf_eax *eax, - union _cpuid4_leaf_ebx *ebx, union _cpuid4_leaf_ecx *ecx) +static void legacy_amd_cpuid4(int index, struct leaf_0x4_n *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; =20 - eax->full =3D 0; - ebx->full =3D 0; - ecx->full =3D 0; + *regs =3D (struct leaf_0x4_n){ }; =20 cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val); cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val); @@ -204,71 +170,62 @@ static void legacy_amd_cpuid4(int index, union _cpuid= 4_leaf_eax *eax, return; } =20 - eax->split.is_self_initializing =3D 1; - eax->split.type =3D types[index]; - eax->split.level =3D levels[index]; - eax->split.num_threads_sharing =3D 0; - eax->split.num_cores_on_die =3D topology_num_cores_per_package(); + regs->cache_self_init =3D 1; + regs->cache_type =3D types[index]; + regs->cache_level =3D levels[index]; + regs->num_threads_sharing =3D 0; + regs->num_cores_on_die =3D topology_num_cores_per_package(); =20 if (assoc =3D=3D AMD_CPUID4_FULLY_ASSOCIATIVE) - eax->split.is_fully_associative =3D 1; + regs->fully_associative =3D 1; =20 - ebx->split.coherency_line_size =3D line_size - 1; - ebx->split.ways_of_associativity =3D assoc - 1; - ebx->split.physical_line_partition =3D lines_per_tag - 1; - ecx->split.number_of_sets =3D (size_in_kb * 1024) / line_size / - (ebx->split.ways_of_associativity + 1) - 1; + regs->cache_linesize =3D line_size - 1; + regs->cache_nways =3D assoc - 1; + regs->cache_npartitions =3D lines_per_tag - 1; + regs->cache_nsets =3D (size_in_kb * 1024) / line_size / + (regs->cache_nways + 1) - 1; } =20 -static int cpuid4_info_fill_done(struct _cpuid4_info *id4, union _cpuid4_l= eaf_eax eax, - union _cpuid4_leaf_ebx ebx, union _cpuid4_leaf_ecx ecx) +static int cpuid4_info_fill_done(struct _cpuid4_info *id4, const struct le= af_0x4_n *regs) { - if (eax.split.type =3D=3D CTYPE_NULL) + if (regs->cache_type =3D=3D CTYPE_NULL) return -EIO; =20 - id4->eax =3D eax; - id4->ebx =3D ebx; - id4->ecx =3D ecx; - id4->size =3D (ecx.split.number_of_sets + 1) * - (ebx.split.coherency_line_size + 1) * - (ebx.split.physical_line_partition + 1) * - (ebx.split.ways_of_associativity + 1); + id4->regs =3D *regs; + id4->size =3D (regs->cache_nsets + 1) * + (regs->cache_linesize + 1) * + (regs->cache_npartitions + 1) * + (regs->cache_nways + 1); =20 return 0; } =20 static int amd_fill_cpuid4_info(struct cpuinfo_x86 *c, int index, struct _= cpuid4_info *id4) { - union _cpuid4_leaf_eax eax; - union _cpuid4_leaf_ebx ebx; - union _cpuid4_leaf_ecx ecx; + struct leaf_0x4_n l_0x4_regs; =20 if (boot_cpu_has(X86_FEATURE_TOPOEXT) || boot_cpu_data.x86_vendor =3D=3D = X86_VENDOR_HYGON) { - const struct cpuid_regs *regs =3D cpuid_subleaf_n_raw(c, 0x8000001d, ind= ex); + const struct leaf_0x8000001d_n *regs =3D cpuid_subleaf_n(c, 0x8000001d, = index); =20 if (!regs) return -EIO; =20 - eax.full =3D regs->eax; - ebx.full =3D regs->ebx; - ecx.full =3D regs->ecx; + /* CPUID(0x8000001d) and CPUID(0x4) have the same bitfields */ + l_0x4_regs =3D *(struct leaf_0x4_n *)regs; } else - legacy_amd_cpuid4(index, &eax, &ebx, &ecx); + legacy_amd_cpuid4(index, &l_0x4_regs); =20 - return cpuid4_info_fill_done(id4, eax, ebx, ecx); + return cpuid4_info_fill_done(id4, &l_0x4_regs); } =20 static int intel_fill_cpuid4_info(struct cpuinfo_x86 *c, int index, struct= _cpuid4_info *id4) { - const struct cpuid_regs *regs =3D cpuid_subleaf_n_raw(c, 0x4, index); + const struct leaf_0x4_n *regs =3D cpuid_subleaf_n(c, 0x4, index); =20 if (!regs) return -EIO; =20 - return cpuid4_info_fill_done(id4, - (union _cpuid4_leaf_eax)(regs->eax), - (union _cpuid4_leaf_ebx)(regs->ebx), - (union _cpuid4_leaf_ecx)(regs->ecx)); + return cpuid4_info_fill_done(id4, regs); } =20 static int fill_cpuid4_info(struct cpuinfo_x86 *c, int index, struct _cpui= d4_info *id4) @@ -290,7 +247,7 @@ static unsigned int get_cache_id(u32 apicid, const stru= ct _cpuid4_info *id4) unsigned long num_threads_sharing; int index_msb; =20 - num_threads_sharing =3D 1 + id4->eax.split.num_threads_sharing; + num_threads_sharing =3D 1 + id4->regs.num_threads_sharing; index_msb =3D get_count_order(num_threads_sharing); =20 return apicid >> index_msb; @@ -406,7 +363,7 @@ static unsigned int calc_cache_topo_id(struct cpuinfo_x= 86 *c, const struct _cpui unsigned int num_threads_sharing; int index_msb; =20 - num_threads_sharing =3D 1 + id4->eax.split.num_threads_sharing; + num_threads_sharing =3D 1 + id4->regs.num_threads_sharing; index_msb =3D get_count_order(num_threads_sharing); return c->topo.apicid & ~((1 << index_msb) - 1); } @@ -432,11 +389,11 @@ static bool intel_cacheinfo_0x4(struct cpuinfo_x86 *c) if (ret < 0) continue; =20 - switch (id4.eax.split.level) { + switch (id4.regs.cache_level) { case 1: - if (id4.eax.split.type =3D=3D CTYPE_DATA) + if (id4.regs.cache_type =3D=3D CTYPE_DATA) l1d =3D id4.size / 1024; - else if (id4.eax.split.type =3D=3D CTYPE_INST) + else if (id4.regs.cache_type =3D=3D CTYPE_INST) l1i =3D id4.size / 1024; break; case 2: @@ -497,7 +454,7 @@ static int __cache_amd_cpumap_setup(unsigned int cpu, i= nt index, } else if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { unsigned int apicid, nshared, first, last; =20 - nshared =3D id4->eax.split.num_threads_sharing + 1; + nshared =3D id4->regs.num_threads_sharing + 1; apicid =3D cpu_data(cpu).topo.apicid; first =3D apicid - (apicid % nshared); last =3D first + nshared - 1; @@ -544,7 +501,7 @@ static void __cache_cpumap_setup(unsigned int cpu, int = index, } =20 ci =3D this_cpu_ci->info_list + index; - num_threads_sharing =3D 1 + id4->eax.split.num_threads_sharing; + num_threads_sharing =3D 1 + id4->regs.num_threads_sharing; =20 cpumask_set_cpu(cpu, &ci->shared_cpu_map); if (num_threads_sharing =3D=3D 1) @@ -571,13 +528,13 @@ static void ci_info_init(struct cacheinfo *ci, const = struct _cpuid4_info *id4, { ci->id =3D id4->id; ci->attributes =3D CACHE_ID; - ci->level =3D id4->eax.split.level; - ci->type =3D cache_type_map[id4->eax.split.type]; - ci->coherency_line_size =3D id4->ebx.split.coherency_line_size + 1; - ci->ways_of_associativity =3D id4->ebx.split.ways_of_associativity + 1; + ci->level =3D id4->regs.cache_level; + ci->type =3D cache_type_map[id4->regs.cache_type]; + ci->coherency_line_size =3D id4->regs.cache_linesize + 1; + ci->ways_of_associativity =3D id4->regs.cache_nways + 1; ci->size =3D id4->size; - ci->number_of_sets =3D id4->ecx.split.number_of_sets + 1; - ci->physical_line_partition =3D id4->ebx.split.physical_line_partition + = 1; + ci->number_of_sets =3D id4->regs.cache_nsets + 1; + ci->physical_line_partition =3D id4->regs.cache_npartitions + 1; ci->priv =3D nb; } =20 --=20 2.53.0