Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1665863

[PATCH 2/2] x86/microcode/intel: Save pointer to ucode patch for early AP loading

From Borislav Petkov <bp@alien8.de>
Newsgroups linux.kernel
Subject [PATCH 2/2] x86/microcode/intel: Save pointer to ucode patch for early AP loading
Date 2017-06-14 16:10 +0200
Message-ID <tSh9D-6aJ-7@gated-at.bofh.it> (permalink)
References <tSh9D-6aJ-9@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


From: Borislav Petkov <bp@suse.de>

Normally, when the initrd is gone, we can't search it for microcode
blobs to apply anymore. For that we need to stash away the patch in our
own storage.

And save_microcode_in_initrd_intel() looks like the proper place to
do that from. So in order for early loading to work, invalidate the
intel_ucode_patch pointer to the patch *before* scanning the initrd one
last time.

If the scanning code finds a microcode patch, it will assign that
pointer again, this time with our own storage's address.

This way, early microcode application during resume-from-RAM works too,
even after the initrd is long gone.

Signed-off-by: Borislav Petkov <bp@suse.de>
Tested-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
 arch/x86/kernel/cpu/microcode/intel.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index f522415bf9e5..d525a0bd7d28 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -166,7 +166,7 @@ static struct ucode_patch *__alloc_microcode_buf(void *data, unsigned int size)
 static void save_microcode_patch(void *data, unsigned int size)
 {
 	struct microcode_header_intel *mc_hdr, *mc_saved_hdr;
-	struct ucode_patch *iter, *tmp, *p;
+	struct ucode_patch *iter, *tmp, *p = NULL;
 	bool prev_found = false;
 	unsigned int sig, pf;
 
@@ -202,6 +202,18 @@ static void save_microcode_patch(void *data, unsigned int size)
 		else
 			list_add_tail(&p->plist, &microcode_cache);
 	}
+
+	/*
+	 * Save for early loading. On 32-bit, that needs to be a physical
+	 * address as the APs are running from physical addresses, before
+	 * paging has been enabled.
+	 */
+	if (p) {
+		if (IS_ENABLED(CONFIG_X86_32))
+			intel_ucode_patch = (struct microcode_intel *)__pa_nodebug(p->data);
+		else
+			intel_ucode_patch = p->data;
+	}
 }
 
 static int microcode_sanity_check(void *mc, int print_err)
@@ -607,6 +619,14 @@ int __init save_microcode_in_initrd_intel(void)
 	struct ucode_cpu_info uci;
 	struct cpio_data cp;
 
+	/*
+	 * initrd is going away, clear patch ptr. We will scan the microcode one
+	 * last time before jettisoning and save a patch, if found. Then we will
+	 * update that pointer too, with a stable patch address to use when
+	 * resuming the cores.
+	 */
+	intel_ucode_patch = NULL;
+
 	if (!load_builtin_intel_microcode(&cp))
 		cp = find_microcode_in_initrd(ucode_path, false);
 
@@ -619,9 +639,6 @@ int __init save_microcode_in_initrd_intel(void)
 
 	show_saved_mc();
 
-	/* initrd is going away, clear patch ptr. */
-	intel_ucode_patch = NULL;
-
 	return 0;
 }
 
-- 
2.13.0

Back to linux.kernel | Previous | Next | Find similar | Unroll thread


Thread

[PATCH 2/2] x86/microcode/intel: Save pointer to ucode patch for early AP loading Borislav Petkov <bp@alien8.de> - 2017-06-14 16:10 +0200

csiph-web