From d88b3516468de87f5b6a9ded28c0f7efc4f78196 Mon Sep 17 00:00:00 2001 From: cgoesche Date: Sat, 23 Aug 2025 20:25:36 -0400 Subject: [PATCH] lscpu: add 'microcode' information to the CPU summary The procfs provides microcode revision information on supported platforms (probably only x86 for now). It can be useful to show this in the output of lscpu for various use cases, e.g. applications that wish to make sure that a specific microcode version has been loaded. Addresses: #3050 Signed-off-by: Christian Goeschel Ndjomouo --- sys-utils/lscpu-cputype.c | 5 +++++ sys-utils/lscpu.1.adoc | 6 +++++- sys-utils/lscpu.c | 6 ++++-- sys-utils/lscpu.h | 1 + tests/expected/lscpu/lscpu-vbox-win | 1 + tests/expected/lscpu/lscpu-vmware_fpe | 1 + tests/expected/lscpu/lscpu-x86_64-64cpu-linux6.2 | 1 + tests/expected/lscpu/lscpu-x86_64-epyc_7451 | 1 + 8 files changed, 19 insertions(+), 3 deletions(-) diff --git a/sys-utils/lscpu-cputype.c b/sys-utils/lscpu-cputype.c index c3a4cbaa2..eda6bd100 100644 --- a/sys-utils/lscpu-cputype.c +++ b/sys-utils/lscpu-cputype.c @@ -91,6 +91,7 @@ void lscpu_unref_cputype(struct lscpu_cputype *ct) free(ct->bios_vendor); free(ct->machinetype); /* s390 */ free(ct->family); + free(ct->microcode); free(ct->model); free(ct->modelname); free(ct->bios_modelname); @@ -140,6 +141,8 @@ static void fprintf_cputypes(FILE *f, struct lscpu_cxt *cxt) fprintf(f, " machinetype: %s\n", ct->machinetype); if (ct->family) fprintf(f, " family: %s\n", ct->family); + if (ct->microcode) + fprintf(f, " microcode: %s\n", ct->microcode); if (ct->model) fprintf(f, " model: %s\n", ct->model); if (ct->modelname) @@ -183,6 +186,7 @@ enum { PAT_FLAGS, PAT_IMPLEMENTER, PAT_MAX_THREAD_ID, + PAT_MICROCODE, PAT_MHZ, PAT_MHZ_DYNAMIC, PAT_MHZ_STATIC, @@ -236,6 +240,7 @@ static const struct cpuinfo_pattern type_patterns[] = DEF_PAT_CPUTYPE( "isa", PAT_ISA, isa), /* riscv */ DEF_PAT_CPUTYPE( "marchid", PAT_FAMILY, family), /* riscv */ DEF_PAT_CPUTYPE( "max thread id", PAT_MAX_THREAD_ID, mtid), /* s390 */ + DEF_PAT_CPUTYPE( "microcode", PAT_MICROCODE, microcode), DEF_PAT_CPUTYPE( "mimpid", PAT_MODEL, model), /* riscv */ DEF_PAT_CPUTYPE( "model", PAT_MODEL, model), DEF_PAT_CPUTYPE( "model name", PAT_MODEL_NAME, modelname), diff --git a/sys-utils/lscpu.1.adoc b/sys-utils/lscpu.1.adoc index 795c3938b..c8694e767 100644 --- a/sys-utils/lscpu.1.adoc +++ b/sys-utils/lscpu.1.adoc @@ -16,7 +16,7 @@ lscpu - display information about the CPU architecture == DESCRIPTION -*lscpu* gathers CPU architecture information from _sysfs_, _/proc/cpuinfo_ and any applicable architecture-specific libraries (e.g. *librtas* on Powerpc). The command output can be optimized for parsing or for easy readability by humans. The information includes, for example, the number of CPUs, threads, cores, sockets, and Non-Uniform Memory Access (NUMA) nodes. There is also information about the CPU caches and cache sharing, family, model, bogoMIPS, byte order, and stepping. +*lscpu* gathers CPU architecture information from _sysfs_, _/proc/cpuinfo_ and any applicable architecture-specific libraries (e.g. *librtas* on Powerpc). The command output can be optimized for parsing or for easy readability by humans. The information includes, for example, the number of CPUs, threads, cores, sockets, and Non-Uniform Memory Access (NUMA) nodes. There is also information about the CPU caches and cache sharing, family, model, bogoMIPS, byte order, stepping and microcode. The default output formatting on a terminal is subject to change and may be optimized for better readability. The output for non-terminals (e.g., pipes) is never affected by this optimization and it is always in "Field: data\n" format. Use for example "*lscpu | less*" to see the default output without optimizations. @@ -106,6 +106,10 @@ The CPU logical numbers are not affected by this option. include::man-common/help-version.adoc[] +== COLUMNS + +A list of valid column labels can be viewed with the *--help* option. + == BUGS The basic overview of CPU models is based on heuristics, taking into account differences such as diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c index 117fd57e1..99799594e 100644 --- a/sys-utils/lscpu.c +++ b/sys-utils/lscpu.c @@ -924,6 +924,8 @@ print_summary_cputype(struct lscpu_cxt *cxt, if (ct->stepping) add_summary_s(tb, sec, _("Stepping:"), ct->stepping); + if (ct->microcode) + add_summary_s(tb, sec, _("Microcode version:"), ct->microcode); if (ct->freqboost >= 0) add_summary_s(tb, sec, _("Frequency boost:"), ct->freqboost ? _("enabled") : _("disabled")); @@ -1042,7 +1044,7 @@ static void print_summary(struct lscpu_cxt *cxt) */ set = cpuset_alloc(cxt->maxcpus, NULL, NULL); if (!set) - err(EXIT_FAILURE, _("failed to callocate cpu set")); + err(EXIT_FAILURE, _("failed to allocate cpu set")); CPU_ZERO_S(cxt->setsize, set); for (i = 0; i < cxt->npossibles; i++) { struct lscpu_cpu *cpu = cxt->cpus[i]; @@ -1067,7 +1069,7 @@ static void print_summary(struct lscpu_cxt *cxt) print_summary_cputype(cxt, cxt->cputypes[i], tb, sec); sec = NULL; - /* Section: vitualiazation */ + /* Section: virtualization */ if (cxt->virt) { sec = add_summary_e(tb, NULL, _("Virtualization features:")); if (cxt->virt->cpuflag && !strcmp(cxt->virt->cpuflag, "svm")) diff --git a/sys-utils/lscpu.h b/sys-utils/lscpu.h index bd7b64cc5..e1d86cbcd 100644 --- a/sys-utils/lscpu.h +++ b/sys-utils/lscpu.h @@ -74,6 +74,7 @@ struct lscpu_cputype { char *bios_vendor; /* aarch64 */ char *machinetype; /* s390 */ char *family; + char *microcode; char *model; char *modelname; char *bios_modelname; /* aarch64 */ diff --git a/tests/expected/lscpu/lscpu-vbox-win b/tests/expected/lscpu/lscpu-vbox-win index bc0ed4cb6..75cc7f3f6 100644 --- a/tests/expected/lscpu/lscpu-vbox-win +++ b/tests/expected/lscpu/lscpu-vbox-win @@ -10,6 +10,7 @@ Thread(s) per core: 1 Core(s) per socket: 2 Socket(s): 1 Stepping: 9 +Microcode version: 0x19 CPU(s) scaling MHz: 42% CPU max MHz: 3800.0000 CPU min MHz: 1600.0000 diff --git a/tests/expected/lscpu/lscpu-vmware_fpe b/tests/expected/lscpu/lscpu-vmware_fpe index 8fa54d2ee..808eb8c06 100644 --- a/tests/expected/lscpu/lscpu-vmware_fpe +++ b/tests/expected/lscpu/lscpu-vmware_fpe @@ -10,6 +10,7 @@ Thread(s) per core: 2 Core(s) per socket: 4 Socket(s): 2 Stepping: 0 +Microcode version: 0x6000852 Frequency boost: enabled CPU(s) scaling MHz: 52% CPU max MHz: 3200.0000 diff --git a/tests/expected/lscpu/lscpu-x86_64-64cpu-linux6.2 b/tests/expected/lscpu/lscpu-x86_64-64cpu-linux6.2 index 58ea109d9..935134bc7 100644 --- a/tests/expected/lscpu/lscpu-x86_64-64cpu-linux6.2 +++ b/tests/expected/lscpu/lscpu-x86_64-64cpu-linux6.2 @@ -11,6 +11,7 @@ Thread(s) per core: 2 Core(s) per socket: 4 Socket(s): 1 Stepping: 1 +Microcode version: 0xa6 CPU(s) scaling MHz: 45% CPU max MHz: 4700.0000 CPU min MHz: 400.0000 diff --git a/tests/expected/lscpu/lscpu-x86_64-epyc_7451 b/tests/expected/lscpu/lscpu-x86_64-epyc_7451 index c0548f97d..c24a0df27 100644 --- a/tests/expected/lscpu/lscpu-x86_64-epyc_7451 +++ b/tests/expected/lscpu/lscpu-x86_64-epyc_7451 @@ -10,6 +10,7 @@ Thread(s) per core: 2 Core(s) per socket: 24 Socket(s): 2 Stepping: 2 +Microcode version: 0x8001227 Frequency boost: enabled CPU(s) scaling MHz: 126% CPU max MHz: 2300.0000 -- 2.47.3