From 83cb39d44399ed24eb99ff80248a84bd34e2d28b Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 8 May 2019 20:01:09 +0000 Subject: [PATCH] x86: Put other CPUs into tight loop when updating Intel microcode from loaded OS. This should prevent at least some theoretical issues whith code execution on HT sibling of the core where the update is loaded. Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D20201 --- sys/dev/cpuctl/cpuctl.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/sys/dev/cpuctl/cpuctl.c b/sys/dev/cpuctl/cpuctl.c index 5890864b059b..94e67ad577b7 100644 --- a/sys/dev/cpuctl/cpuctl.c +++ b/sys/dev/cpuctl/cpuctl.c @@ -330,9 +330,26 @@ cpuctl_do_update(int cpu, cpuctl_update_args_t *data, struct thread *td) return (ret); } +struct ucode_update_data { + void *ptr; + int cpu; + int ret; +}; + +static void +ucode_intel_load_rv(void *arg) +{ + struct ucode_update_data *d; + + d = arg; + if (PCPU_GET(cpuid) == d->cpu) + d->ret = ucode_intel_load(d->ptr, true, NULL, NULL); +} + static int update_intel(int cpu, cpuctl_update_args_t *args, struct thread *td) { + struct ucode_update_data d; void *ptr; int is_bound, oldcpu, ret; @@ -360,12 +377,11 @@ update_intel(int cpu, cpuctl_update_args_t *args, struct thread *td) oldcpu = td->td_oncpu; is_bound = cpu_sched_is_bound(td); set_cpu(cpu, td); - critical_enter(); - - ret = ucode_intel_load(ptr, true, NULL, NULL); - - critical_exit(); + d.ptr = ptr; + d.cpu = cpu; + smp_rendezvous(NULL, ucode_intel_load_rv, NULL, &d); restore_cpu(oldcpu, is_bound, td); + ret = d.ret; /* * Replace any existing update. This ensures that the new update