Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 May 2019 20:01:09 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r347368 - head/sys/dev/cpuctl
Message-ID:  <201905082001.x48K19dR050922@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905082001.x48K19dR050922>