From nobody Sat Sep 27 14:31:00 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4cYqd02JRwz69Pj3; Sat, 27 Sep 2025 14:31:00 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4cYqd01PKyz3x2c; Sat, 27 Sep 2025 14:31:00 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1758983460; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=cRblOEPitYdab5aHeN+QQJ8ViRQyf4chLihJU3r1BfU=; b=AUQJYq15MSvUfwTokV5P4VFvorO6/t0m3oiiU21qA4WfzHTGJhh6ppcIP5PzXgvkU1t+mJ RSZje6mh3J2btex/QGF9goXL5C6T7VJ6z5mtqrCFE7M3008jeTdR3+U/z7z3GuXMryhFgM KtJLcclLb70V5ATNAIFs5R2GE+L2quv4MMtHb8AikNEwDeQTALVBhIL+e5EBiAdBOWZNmD VXDEpHx3LcuDYvVh87iKbemm1Y4ULDDBj3iY8iyTD3A76xbTBIceiMPRLybDAR0nL0aMli TgflVRtMzNR8PJGD2NBurHnU+oClwt7sdwnKNzT6t+KSjjdJx0OJHQp4Vo+3FQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1758983460; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=cRblOEPitYdab5aHeN+QQJ8ViRQyf4chLihJU3r1BfU=; b=eHKpkD06DEx+ucdBTs1OmkKlfD7AS7pnt3yt69+1jH5IVuWkmpUoCtDjLA/dRDcMU8ZiET BlSMrsAB7qQ3wsVS7L27+MWLA8Usy8NlSoO/sAQYLPPeLToG9CJ8sMiOhA863r8V2VaAm0 2PwmJOV2r779s8ZaHeC7u6l0CjFkuEde6Iy88wruHINtPw9fiuh2cRKcW0CWKTX6i2fNoK OuQoOZJ0hrKqsWI0Jj+IAxLCNvfkNt6tJhcgTUKzSF4Mb9TbfzcvDyjbKrx/FKxzmYf6mS oJuaz459rbyLHvZBigLcfnFph+xoL0Tlq60XJGcYrm+o8oDMZuSP0AWdJirBdA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1758983460; a=rsa-sha256; cv=none; b=LF9NPahMjFv+mGcQg3FpLPjQ41i5jvRTF65qckH0Ct4XCO48U1MLwAlfRu+mvRzs6EYQfr nlECW9H542QQClaam3NQSZkFJjzjSuQX0Mk0o3KUJ5EyAZsHrsEdQ/pt7pPtEe3zZYSJgB 2M/cg0ZmJTkpWZBMr+JD+snMEOH/VwsPP9YIuzBbvg8XOB0TnpcMeAeYawtSndX9BwTgfI MY+2am/PuQ9jCroXlvRME+HbmFQ4GuwHA4gpi+5hCa8R8nVnRnl2GThsp6LvrMqlA1cXtN J6ifQngNIUXzMJtVJV9M2yJ/5qWv31eYOkN2qPIshiaZRwrql6vfnbncZAlnzQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4cYqd00yBVzdry; Sat, 27 Sep 2025 14:31:00 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 58REV03j099295; Sat, 27 Sep 2025 14:31:00 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 58REV0as099292; Sat, 27 Sep 2025 14:31:00 GMT (envelope-from git) Date: Sat, 27 Sep 2025 14:31:00 GMT Message-Id: <202509271431.58REV0as099292@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Gleb Smirnoff Subject: git: d9f03a43f2fe - main - ucode: use wrmsr_early_safe() for early CPU microcode update List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: glebius X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: d9f03a43f2fec917c31d48b05d751e547c8775c7 Auto-Submitted: auto-generated The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=d9f03a43f2fec917c31d48b05d751e547c8775c7 commit d9f03a43f2fec917c31d48b05d751e547c8775c7 Author: Gleb Smirnoff AuthorDate: 2025-09-27 14:30:40 +0000 Commit: Gleb Smirnoff CommitDate: 2025-09-27 14:30:40 +0000 ucode: use wrmsr_early_safe() for early CPU microcode update Use the new method for wrmsr that is able to set up fault handler even at the very early stage of kernel boot. This prevents panic with new microcode for some new AMD EPYCs, that requires certain patchlevel of microcode to be already present in the CPU. If BSP patching failed, we print the message and we don't try to patch APs. This has been tested only on AMD booted in EFI mode. Reviewed by: stas, kib Differential Revision: https://reviews.freebsd.org/D52643 --- sys/dev/cpuctl/cpuctl.c | 2 +- sys/x86/include/ucode.h | 6 ++++-- sys/x86/x86/ucode.c | 56 +++++++++++++++++++++++++++++++++++++------------ 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/sys/dev/cpuctl/cpuctl.c b/sys/dev/cpuctl/cpuctl.c index b0ab3467df69..deaabaaaa1fc 100644 --- a/sys/dev/cpuctl/cpuctl.c +++ b/sys/dev/cpuctl/cpuctl.c @@ -344,7 +344,7 @@ ucode_intel_load_rv(void *arg) d = arg; if (PCPU_GET(cpuid) == d->cpu) - d->ret = ucode_intel_load(d->ptr, true, NULL, NULL); + d->ret = ucode_intel_load(d->ptr, SAFE, NULL, NULL); } static int diff --git a/sys/x86/include/ucode.h b/sys/x86/include/ucode.h index 75b9ff3afbd0..ea7cb07669a4 100644 --- a/sys/x86/include/ucode.h +++ b/sys/x86/include/ucode.h @@ -62,12 +62,14 @@ struct ucode_intel_extsig_table { } entries[0]; }; +typedef enum { SAFE, UNSAFE, EARLY } ucode_load_how; + const void *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); -int ucode_intel_load(const void *data, bool unsafe, +int ucode_intel_load(const void *data, ucode_load_how unsafe, uint64_t *nrevp, uint64_t *orevp); -int ucode_amd_load(const void *data, bool unsafe, +int ucode_amd_load(const void *data, ucode_load_how how, uint64_t *nrevp, uint64_t *orevp); size_t ucode_load_bsp(uintptr_t free); void ucode_load_ap(int cpu); diff --git a/sys/x86/x86/ucode.c b/sys/x86/x86/ucode.c index 1973047fafd1..72133de211f8 100644 --- a/sys/x86/x86/ucode.c +++ b/sys/x86/x86/ucode.c @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -58,7 +59,7 @@ static const void *ucode_amd_match(const uint8_t *data, size_t *len); static struct ucode_ops { const char *vendor; - int (*load)(const void *, bool, uint64_t *, uint64_t *); + int (*load)(const void *, ucode_load_how how, uint64_t *, uint64_t *); const void *(*match)(const uint8_t *, size_t *); } loaders[] = { { @@ -83,6 +84,7 @@ enum { NO_ERROR, NO_MATCH, VERIFICATION_FAILED, + LOAD_FAILED, } ucode_error = NO_ERROR; static uint64_t ucode_nrev, ucode_orev; @@ -103,6 +105,9 @@ log_msg(void *arg __unused) case VERIFICATION_FAILED: printf("CPU microcode: microcode verification failed\n"); break; + case LOAD_FAILED: + printf("CPU microcode load failed. BIOS update advised\n"); + break; default: break; } @@ -110,7 +115,8 @@ log_msg(void *arg __unused) SYSINIT(ucode_log, SI_SUB_CPU, SI_ORDER_FIRST, log_msg, NULL); int -ucode_intel_load(const void *data, bool unsafe, uint64_t *nrevp, uint64_t *orevp) +ucode_intel_load(const void *data, ucode_load_how how, uint64_t *nrevp, + uint64_t *orevp) { uint64_t nrev, orev; uint32_t cpuid[4]; @@ -122,10 +128,23 @@ ucode_intel_load(const void *data, bool unsafe, uint64_t *nrevp, uint64_t *orevp * undocumented errata applying to some Broadwell CPUs. */ wbinvd(); - if (unsafe) + switch (how) { + case SAFE: wrmsr_safe(MSR_BIOS_UPDT_TRIG, (uint64_t)(uintptr_t)data); - else + break; + case EARLY: +#ifdef __amd64__ + wrmsr_early_safe_start(); + if (wrmsr_early_safe(MSR_BIOS_UPDT_TRIG, + (uint64_t)(uintptr_t)data) != 0) + ucode_error = LOAD_FAILED; + wrmsr_early_safe_end(); + break; +#endif + case UNSAFE: wrmsr(MSR_BIOS_UPDT_TRIG, (uint64_t)(uintptr_t)data); + break; + } wrmsr(MSR_BIOS_SIGN, 0); /* @@ -233,20 +252,31 @@ ucode_intel_match(const uint8_t *data, size_t *len) } int -ucode_amd_load(const void *data, bool unsafe, uint64_t *nrevp, uint64_t *orevp) +ucode_amd_load(const void *data, ucode_load_how how, uint64_t *nrevp, + uint64_t *orevp) { uint64_t nrev, orev; uint32_t cpuid[4]; orev = rdmsr(MSR_BIOS_SIGN); - /* - * Perform update. - */ - if (unsafe) + switch (how) { + case SAFE: wrmsr_safe(MSR_K8_UCODE_UPDATE, (uint64_t)(uintptr_t)data); - else + break; + case EARLY: +#ifdef __amd64__ + wrmsr_early_safe_start(); + if (wrmsr_early_safe(MSR_K8_UCODE_UPDATE, + (uint64_t)(uintptr_t)data) != 0) + ucode_error = LOAD_FAILED; + wrmsr_early_safe_end(); + break; +#endif + case UNSAFE: wrmsr(MSR_K8_UCODE_UPDATE, (uint64_t)(uintptr_t)data); + break; + } /* * Serialize instruction flow. @@ -327,8 +357,8 @@ ucode_load_ap(int cpu) return; #endif - if (ucode_data != NULL) - (void)ucode_loader->load(ucode_data, false, NULL, NULL); + if (ucode_data != NULL && ucode_error != LOAD_FAILED) + (void)ucode_loader->load(ucode_data, UNSAFE, NULL, NULL); } static void * @@ -415,7 +445,7 @@ ucode_load_bsp(uintptr_t free) memcpy_early(addr, match, len); match = addr; - error = ucode_loader->load(match, false, &nrev, &orev); + error = ucode_loader->load(match, EARLY, &nrev, &orev); if (error == 0) { ucode_data = early_ucode_data = match; ucode_nrev = nrev;