git: 797e92944d11 - stable/15 - cpuctl: run amd_ucode_wrmsr only on one CPU and report if it failed
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 22 Sep 2025 16:11:56 UTC
The branch stable/15 has been updated by glebius:
URL: https://cgit.FreeBSD.org/src/commit/?id=797e92944d118c0fe7de20ae92a18066eaf9a194
commit 797e92944d118c0fe7de20ae92a18066eaf9a194
Author: Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2025-09-18 15:10:59 +0000
Commit: Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2025-09-22 16:11:33 +0000
cpuctl: run amd_ucode_wrmsr only on one CPU and report if it failed
The CPUCTL_UPDATE is supposed to be applied only to the CPU the ioctl(2)
was performed on. This is true for Intel CPUs, but for AMD the SMP
rendezvouz of amd_ucode_wrmsr() effectively executed it on all CPUs.
Also, the update failure was not reported.
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D52466
(cherry picked from commit 6683dcf61b3d0dfa8639c9e501eefb7709922ddf)
---
sys/dev/cpuctl/cpuctl.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/sys/dev/cpuctl/cpuctl.c b/sys/dev/cpuctl/cpuctl.c
index 9253b17a259d..b0ab3467df69 100644
--- a/sys/dev/cpuctl/cpuctl.c
+++ b/sys/dev/cpuctl/cpuctl.c
@@ -402,19 +402,20 @@ out:
* its workings.
*/
static void
-amd_ucode_wrmsr(void *ucode_ptr)
+amd_ucode_wrmsr(void *arg)
{
+ struct ucode_update_data *d = arg;
uint32_t tmp[4];
- wrmsr_safe(MSR_K8_UCODE_UPDATE, (uintptr_t)ucode_ptr);
+ if (PCPU_GET(cpuid) == d->cpu)
+ d->ret = wrmsr_safe(MSR_K8_UCODE_UPDATE, (uintptr_t)d->ptr);
do_cpuid(0, tmp);
}
static int
update_amd(int cpu, cpuctl_update_args_t *args, struct thread *td)
{
- void *ptr;
- int ret;
+ struct ucode_update_data d = { .cpu = cpu };
if (args->size == 0 || args->data == NULL) {
DPRINTF("[cpuctl,%d]: zero-sized firmware image", __LINE__);
@@ -430,18 +431,17 @@ update_amd(int cpu, cpuctl_update_args_t *args, struct thread *td)
* malloc(9) always returns the pointer aligned at least on
* the size of the allocation.
*/
- ptr = malloc(args->size + 16, M_CPUCTL, M_ZERO | M_WAITOK);
- if (copyin(args->data, ptr, args->size) != 0) {
+ d.ptr = malloc(args->size + 16, M_CPUCTL, M_ZERO | M_WAITOK);
+ if (copyin(args->data, d.ptr, args->size) != 0) {
DPRINTF("[cpuctl,%d]: copyin %p->%p of %zd bytes failed",
__LINE__, args->data, ptr, args->size);
- ret = EFAULT;
+ d.ret = EFAULT;
goto fail;
}
- smp_rendezvous(NULL, amd_ucode_wrmsr, NULL, ptr);
- ret = 0;
+ smp_rendezvous(NULL, amd_ucode_wrmsr, NULL, &d);
fail:
- free(ptr, M_CPUCTL);
- return (ret);
+ free(d.ptr, M_CPUCTL);
+ return (d.ret);
}
static int