svn commit: r347368 - head/sys/dev/cpuctl

Konstantin Belousov kib at FreeBSD.org
Wed May 8 20:01:10 UTC 2019


Author: kib
Date: Wed May  8 20:01:09 2019
New Revision: 347368
URL: https://svnweb.freebsd.org/changeset/base/347368

Log:
  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

Modified:
  head/sys/dev/cpuctl/cpuctl.c

Modified: head/sys/dev/cpuctl/cpuctl.c
==============================================================================
--- head/sys/dev/cpuctl/cpuctl.c	Wed May  8 19:42:00 2019	(r347367)
+++ head/sys/dev/cpuctl/cpuctl.c	Wed May  8 20:01:09 2019	(r347368)
@@ -330,9 +330,26 @@ cpuctl_do_update(int cpu, cpuctl_update_args_t *data, 
 	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, stru
 	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


More information about the svn-src-head mailing list