From nobody Thu Oct 2 00:00:47 2025 X-Original-To: dev-commits-src-all@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 4ccX4c1Yskz69gvP; Thu, 02 Oct 2025 00:00:48 +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 4ccX4b4y2mz3Skj; Thu, 02 Oct 2025 00:00:47 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1759363247; 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=0DlYubNYNfbXtawxKPTUVZPJn09gl47WaU5iIdG95z0=; b=LyUly5nBPSfSjLHCn2Bzt06Pb2Msy8ADPIu/A71KHgdNuvp1Bcw+wNl/9sDol0Zf7b2B0K ACWRxo5j8T7ZqoaYE/+xYXBQUo85Cjfo+3mAtsisbpn0vaeIBjaJXYkSxthbvBohfXsDLb CZrIXvOv/qytm8Rr/7A/3YTeC16CaGY7qXMz0pwLub4FaJBszuGwCOeKzJHWPAva2fjFWL iTMDCCZEOmx0dtFvydkSBBCVW6XDjhNjCgUiFwZ92s0ltHFsHlcM8ua4Gj7n3tA/ecI9cJ Eyl74/tOi4dNLtLkv6qNVLU412uBcWEx79XnpDCGjAwS0wzHeIi+3Ro4Hk/L/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1759363247; 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=0DlYubNYNfbXtawxKPTUVZPJn09gl47WaU5iIdG95z0=; b=dp4UJf60dq0nYXbO9+Z4Kk6h3UFl77SZR06mKTNciuqKV0UhJ68Z6OOZB6tV0Nj2jNS8rd NpBzTQBmCgbv1U2sv4zOFaYtA/xt/cf68SDkww+KWDBhU9tCPi3sgwChZZmEIk8L+Rt+Yl pCTR4jsMfcRYJfegCz7uMCYWa35ErZUAS/Tz2Lb4XFZA1D8suxBUcVxLrPW+S74Uo7uw+N DU6xqtCyow/RssDKSb+TkGHCHK44RTNyQtRdFQ6foUq+G64bERqgacuuFvZBXh3jY2ESeG VnICMsfuvTiIWkHJ9T+XFNMFIzB8gyZhiVPxCl5BuDllaRVTOx5sy/Ho+p8UWA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1759363247; a=rsa-sha256; cv=none; b=E0Exep7s/3980EM0b24MZZAynw4mU/7OwjYf1gx9n6X55w9TAqr+hVqF2o42NvTgsWUtfr ptZ9GWymbwUmOa0EwzjIZt0QBZGb3XufuBagOXA+2EdMJOvROkNWtGpMI+OCzxGQWPvcJ5 mZTNK6ko9mbZTTDbgA7zvU00yUR6EBiQ6kwCvYSFqw42Wryo9gCeaJS42YZc2X1MIPbIsZ peCsXWhgNmGU8ICUFO1OyUhUtZqMB90KHhCXD5Gxrv8MRMhjXyIgDBV/2JffgJiSVrUz0M SIgt7yAg2RRwqM076PqQhNMnNlg6w2r3w3aO/IoOJbXqi+AuWJJNhhtWOQAkDA== 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 4ccX4b4RX3zl8n; Thu, 02 Oct 2025 00:00:47 +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 59200lXF057549; Thu, 2 Oct 2025 00:00:47 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 59200lLf057546; Thu, 2 Oct 2025 00:00:47 GMT (envelope-from git) Date: Thu, 2 Oct 2025 00:00:47 GMT Message-Id: <202510020000.59200lLf057546@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Gleb Smirnoff Subject: git: b8975e052e80 - stable/15 - ucode: use wrmsr_early_safe() for early CPU microcode update List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@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/stable/15 X-Git-Reftype: branch X-Git-Commit: b8975e052e807054e2b9db5b67db45d288321ad1 Auto-Submitted: auto-generated The branch stable/15 has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=b8975e052e807054e2b9db5b67db45d288321ad1 commit b8975e052e807054e2b9db5b67db45d288321ad1 Author: Gleb Smirnoff AuthorDate: 2025-09-27 14:30:40 +0000 Commit: Gleb Smirnoff CommitDate: 2025-10-02 00:00:13 +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 (cherry picked from commit d9f03a43f2fec917c31d48b05d751e547c8775c7) --- 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;