git: dbff73873577 - stable/15 - cpucontrol: return selected revision from ucode_amd_find()

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Mon, 22 Sep 2025 16:11:57 UTC
The branch stable/15 has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=dbff738735777dd16490e0fdebd743a48a7ca222

commit dbff738735777dd16490e0fdebd743a48a7ca222
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2025-09-18 15:11:03 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2025-09-22 16:11:33 +0000

    cpucontrol: return selected revision from ucode_amd_find()
    
    This fixes two printing bugs in cpucontrol(1).  First, the utility will
    now print "updating from rev X to rev Y", instead of incorrect "updating
    to revision X", where X is actually the old revision.  This also matches
    what Intel updater prints.  Second, the utility won't incorrectly warn
    that the update failed after reading the new revision post update.
    
    Reviewed by:            kib, markj
    Differential Revision:  https://reviews.freebsd.org/D52506
    
    (cherry picked from commit 83804499b72405475027e670690d4cdbada46090)
---
 sys/x86/include/ucode.h      |  2 +-
 sys/x86/x86/ucode.c          |  3 ++-
 sys/x86/x86/ucode_subr.c     | 10 +++++-----
 usr.sbin/cpucontrol/amd10h.c | 11 ++++++-----
 4 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/sys/x86/include/ucode.h b/sys/x86/include/ucode.h
index 0338d48a0832..75b9ff3afbd0 100644
--- a/sys/x86/include/ucode.h
+++ b/sys/x86/include/ucode.h
@@ -63,7 +63,7 @@ struct ucode_intel_extsig_table {
 };
 
 const void *ucode_amd_find(const char *path, uint32_t signature,
-	    uint32_t revision, const uint8_t *fw_data, size_t fw_size,
+	    uint32_t *revision, const uint8_t *fw_data, size_t fw_size,
 	    size_t *selected_sizep);
 int	ucode_intel_load(const void *data, bool unsafe,
 	    uint64_t *nrevp, uint64_t *orevp);
diff --git a/sys/x86/x86/ucode.c b/sys/x86/x86/ucode.c
index 0c153c0b656c..1973047fafd1 100644
--- a/sys/x86/x86/ucode.c
+++ b/sys/x86/x86/ucode.c
@@ -277,7 +277,8 @@ ucode_amd_match(const uint8_t *data, size_t *len)
 	signature = regs[0];
 	revision = rdmsr(MSR_BIOS_SIGN);
 
-	return (ucode_amd_find("loader blob", signature, revision, data, *len, len));
+	return (ucode_amd_find("loader blob", signature, &revision, data, *len,
+	    len));
 }
 
 /*
diff --git a/sys/x86/x86/ucode_subr.c b/sys/x86/x86/ucode_subr.c
index 9e128ad2bf04..53d7cfc06769 100644
--- a/sys/x86/x86/ucode_subr.c
+++ b/sys/x86/x86/ucode_subr.c
@@ -94,7 +94,7 @@ typedef struct container_header {
  * source code.
  */
 const void *
-ucode_amd_find(const char *path, uint32_t signature, uint32_t revision,
+ucode_amd_find(const char *path, uint32_t signature, uint32_t *revision,
     const uint8_t *fw_data, size_t fw_size, size_t *selected_sizep)
 {
 	const amd_10h_fw_header_t *fw_header;
@@ -112,7 +112,7 @@ ucode_amd_find(const char *path, uint32_t signature, uint32_t revision,
 	    (signature >> 4) & 0x0f,
 	    (signature >> 0) & 0x0f, (signature >> 20) & 0xff,
 	    (signature >> 16) & 0x0f);
-	WARNX(1, "microcode revision %#x", revision);
+	WARNX(1, "microcode revision %#x", *revision);
 
 nextfile:
 	WARNX(1, "checking %s for update.", path);
@@ -212,9 +212,9 @@ nextfile:
 			    fw_header->processor_rev_id, equiv_id);
 			continue; /* different cpu */
 		}
-		if (fw_header->patch_id <= revision) {
+		if (fw_header->patch_id <= *revision) {
 			WARNX(1, "patch_id %x, revision %x",
-			    fw_header->patch_id, revision);
+			    fw_header->patch_id, *revision);
 			continue; /* not newer revision */
 		}
 		if (fw_header->nb_dev_id != 0 || fw_header->sb_dev_id != 0) {
@@ -222,7 +222,7 @@ nextfile:
 		}
 
 		WARNX(3, "selecting revision: %x", fw_header->patch_id);
-		revision = fw_header->patch_id;
+		*revision = fw_header->patch_id;
 		selected_fw = fw_header;
 		selected_size = section_header->size;
 	}
diff --git a/usr.sbin/cpucontrol/amd10h.c b/usr.sbin/cpucontrol/amd10h.c
index 4fda44f0b797..9fc861fe5914 100644
--- a/usr.sbin/cpucontrol/amd10h.c
+++ b/usr.sbin/cpucontrol/amd10h.c
@@ -93,7 +93,7 @@ amd10h_update(const struct ucode_update_params *params)
 	size_t fw_size;
 	size_t selected_size;
 	uint32_t revision;
-	uint32_t new_rev;
+	uint32_t new_rev, old_rev;
 	uint32_t signature;
 	int devfd;
 	int error;
@@ -121,15 +121,16 @@ amd10h_update(const struct ucode_update_params *params)
 		WARN(0, "ioctl(%s)", dev);
 		goto done;
 	}
-	revision = (uint32_t)msrargs.data;
+	old_rev = revision = (uint32_t)msrargs.data;
 
-	selected_fw = ucode_amd_find(path, signature, revision, fw_image,
+	selected_fw = ucode_amd_find(path, signature, &revision, fw_image,
 	    fw_size, &selected_size);
 
 	if (selected_fw != NULL) {
 		WARNX(1, "selected ucode size is %zu", selected_size);
-		fprintf(stderr, "%s: updating cpu %s to revision %#x... ",
-		    path, dev, revision);
+		fprintf(stderr,
+		    "%s: updating cpu %s from rev %#x to rev %#x... ",
+		    path, dev, old_rev, revision);
 
 		args.data = __DECONST(void *, selected_fw);
 		args.size = selected_size;