linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/9] x86/microcode: Fixes for builtin vs initrd loading; cleanups
@ 2016-06-06 15:10 Borislav Petkov
  2016-06-06 15:10 ` [PATCH 1/9] x86/microcode: Fix loading precedence Borislav Petkov
                   ` (8 more replies)
  0 siblings, 9 replies; 19+ messages in thread
From: Borislav Petkov @ 2016-06-06 15:10 UTC (permalink / raw)
  To: X86 ML; +Cc: LKML

From: Borislav Petkov <bp@suse.de>

Hi,

the first two are fixes resulting from people enabling builtin microcode
and reporting issues. The result is a much more robust loading of early
microcode by checking for builtin microcode first and then the one
supplied by the initrd.

The rest are cleanups.

Pile has been tested on everything here and by the bug reporters.

@tip guys: 2/9 is CC:stable. Please route accordingly.

Please apply,
thanks.

Borislav Petkov (9):
  x86/microcode: Fix loading precedence
  x86/microcode: Fix suspend to RAM with builtin microcode
  lib/cpio: Make find_cpio_data()'s offset arg optional
  x86/microcode: Get rid of find_cpio_data()'s dummy offset arg
  x86/microcode: Propagate save_microcode_in_initrd() retval
  x86/microcode/intel: Rename load_microcode_early() to
    find_microcode_patch()
  x86/microcode/intel: Unexport save_mc_for_early()
  x86/microcode/AMD: Make amd_ucode_patch static
  Documentation/microcode: Document some aspects for more clarity

 Documentation/x86/early-microcode.txt  |   5 +-
 arch/x86/include/asm/microcode.h       |  26 ----
 arch/x86/include/asm/microcode_amd.h   |   1 -
 arch/x86/include/asm/microcode_intel.h |   5 -
 arch/x86/kernel/cpu/microcode/amd.c    |  33 ++---
 arch/x86/kernel/cpu/microcode/core.c   |   9 +-
 arch/x86/kernel/cpu/microcode/intel.c  | 227 ++++++++++++++++++++-------------
 arch/x86/mm/init.c                     |   7 -
 lib/earlycpio.c                        |   5 +-
 9 files changed, 169 insertions(+), 149 deletions(-)

-- 
2.7.3

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 1/9] x86/microcode: Fix loading precedence
  2016-06-06 15:10 [PATCH 0/9] x86/microcode: Fixes for builtin vs initrd loading; cleanups Borislav Petkov
@ 2016-06-06 15:10 ` Borislav Petkov
  2016-06-08  9:51   ` [tip:x86/microcode] " tip-bot for Borislav Petkov
  2016-06-06 15:10 ` [PATCH 2/9] x86/microcode: Fix suspend to RAM with builtin microcode Borislav Petkov
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Borislav Petkov @ 2016-06-06 15:10 UTC (permalink / raw)
  To: X86 ML; +Cc: LKML

From: Borislav Petkov <bp@suse.de>

So it can happen that even with builtin microcode,
CONFIG_BLK_DEV_INITRD=y gets forgotten enabled.

Or, even with that disabled, an initrd image gets supplied by the boot
loader, by omission or is simply forgotten there. And since we do look
at boot_params.hdr.ramdisk_* to know whether we have received an initrd,
we might get puzzled.

So let's just make the loader look for builtin microcode first and if
found, ignore the ramdisk image.

If no builtin found, it falls back to scanning the supplied initrd, of
course.

For that, we move all the initrd scanning in a separate
__scan_microcode_initrd() function and fall back to it only if
load_builtin_intel_microcode() has failed.

Reported-and-tested-by: Gabriel Craciunescu <nix.or.die@gmail.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/include/asm/microcode.h      |  24 -----
 arch/x86/kernel/cpu/microcode/amd.c   |  28 +++---
 arch/x86/kernel/cpu/microcode/intel.c | 183 ++++++++++++++++++++++------------
 3 files changed, 133 insertions(+), 102 deletions(-)

diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index 9d3a96c4da78..ca2af7ed6cbf 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -145,28 +145,4 @@ static inline bool
 get_builtin_firmware(struct cpio_data *cd, const char *name)	{ return false; }
 #endif
 
-static inline unsigned long get_initrd_start(void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-	return initrd_start;
-#else
-	return 0;
-#endif
-}
-
-static inline unsigned long get_initrd_start_addr(void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-#ifdef CONFIG_X86_32
-	unsigned long *initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start);
-
-	return (unsigned long)__pa_nodebug(*initrd_start_p);
-#else
-	return get_initrd_start();
-#endif
-#else /* CONFIG_BLK_DEV_INITRD */
-	return 0;
-#endif
-}
-
 #endif /* _ASM_X86_MICROCODE_H */
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 8581963894c7..11dd1cc8e444 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -61,19 +61,20 @@ static u16 this_equiv_id;
 
 static struct cpio_data ucode_cpio;
 
-/*
- * Microcode patch container file is prepended to the initrd in cpio format.
- * See Documentation/x86/early-microcode.txt
- */
-static __initdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin";
-
 static struct cpio_data __init find_ucode_in_initrd(void)
 {
+#ifdef CONFIG_BLK_DEV_INITRD
 	long offset = 0;
 	char *path;
 	void *start;
 	size_t size;
 
+	/*
+	 * Microcode patch container file is prepended to the initrd in cpio
+	 * format. See Documentation/x86/early-microcode.txt
+	 */
+	static __initdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin";
+
 #ifdef CONFIG_X86_32
 	struct boot_params *p;
 
@@ -89,9 +90,12 @@ static struct cpio_data __init find_ucode_in_initrd(void)
 	path    = ucode_path;
 	start   = (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET);
 	size    = boot_params.hdr.ramdisk_size;
-#endif
+#endif /* !CONFIG_X86_32 */
 
 	return find_cpio_data(path, start, size, &offset);
+#else
+	return (struct cpio_data){ NULL, 0, "" };
+#endif
 }
 
 static size_t compute_container_size(u8 *data, u32 total_size)
@@ -289,11 +293,11 @@ void __init load_ucode_amd_bsp(unsigned int family)
 	size = &ucode_cpio.size;
 #endif
 
-	cp = find_ucode_in_initrd();
-	if (!cp.data) {
-		if (!load_builtin_amd_microcode(&cp, family))
-			return;
-	}
+	if (!load_builtin_amd_microcode(&cp, family))
+		cp = find_ucode_in_initrd();
+
+	if (!(cp.data && cp.size))
+		return;
 
 	*data = cp.data;
 	*size = cp.size;
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 65cbbcd48fe4..5835d5b0db81 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -51,6 +51,12 @@ static struct mc_saved_data {
 	struct microcode_intel **mc_saved;
 } mc_saved_data;
 
+/* Microcode blobs within the initrd. 0 if builtin. */
+static struct ucode_blobs {
+	unsigned long start;
+	bool valid;
+} blobs;
+
 static enum ucode_state
 load_microcode_early(struct microcode_intel **saved,
 		     unsigned int num_saved, struct ucode_cpu_info *uci)
@@ -532,37 +538,6 @@ static bool __init load_builtin_intel_microcode(struct cpio_data *cp)
 #endif
 }
 
-static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin";
-static __init enum ucode_state
-scan_microcode(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
-	       unsigned long start, unsigned long size,
-	       struct ucode_cpu_info *uci)
-{
-	struct cpio_data cd;
-	long offset = 0;
-#ifdef CONFIG_X86_32
-	char *p = (char *)__pa_nodebug(ucode_name);
-#else
-	char *p = ucode_name;
-#endif
-
-	cd.data = NULL;
-	cd.size = 0;
-
-	/* try built-in microcode if no initrd */
-	if (!size) {
-		if (!load_builtin_intel_microcode(&cd))
-			return UCODE_ERROR;
-	} else {
-		cd = find_cpio_data(p, (void *)start, size, &offset);
-		if (!cd.data)
-			return UCODE_ERROR;
-	}
-
-	return get_matching_model_microcode(start, cd.data, cd.size,
-					    mcs, mc_ptrs, uci);
-}
-
 /*
  * Print ucode update info.
  */
@@ -680,14 +655,22 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)
  */
 int __init save_microcode_in_initrd_intel(void)
 {
-	unsigned int count = mc_saved_data.num_saved;
 	struct microcode_intel *mc_saved[MAX_UCODE_COUNT];
-	int ret = 0;
+	unsigned int count = mc_saved_data.num_saved;
+	unsigned long offset = 0;
+	int ret;
 
 	if (!count)
-		return ret;
+		return 0;
 
-	copy_ptrs(mc_saved, mc_tmp_ptrs, get_initrd_start(), count);
+	/*
+	 * We have found a valid initrd but it might've been relocated in the
+	 * meantime so get its updated address.
+	 */
+	if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && blobs.valid)
+		offset = initrd_start;
+
+	copy_ptrs(mc_saved, mc_tmp_ptrs, offset, count);
 
 	ret = save_microcode(&mc_saved_data, mc_saved, count);
 	if (ret)
@@ -698,20 +681,92 @@ int __init save_microcode_in_initrd_intel(void)
 	return ret;
 }
 
+static __init enum ucode_state
+__scan_microcode_initrd(struct cpio_data *cd, struct ucode_blobs *blbp)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	long offset = 0;
+	static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin";
+	char *p = IS_ENABLED(CONFIG_X86_32) ? (char *)__pa_nodebug(ucode_name)
+						    : ucode_name;
+# ifdef CONFIG_X86_32
+	unsigned long start = 0, size;
+	struct boot_params *params;
+
+	params = (struct boot_params *)__pa_nodebug(&boot_params);
+	size   = params->hdr.ramdisk_size;
+
+	/*
+	 * Set start only if we have an initrd image. We cannot use initrd_start
+	 * because it is not set that early yet.
+	 */
+	start = (size ? params->hdr.ramdisk_image : 0);
+
+# else /* CONFIG_X86_64 */
+	unsigned long start = 0, size;
+
+	size  = (u64)boot_params.ext_ramdisk_size << 32;
+	size |= boot_params.hdr.ramdisk_size;
+
+	if (size) {
+		start  = (u64)boot_params.ext_ramdisk_image << 32;
+		start |= boot_params.hdr.ramdisk_image;
+
+		start += PAGE_OFFSET;
+	}
+# endif
+
+	*cd = find_cpio_data(p, (void *)start, size, &offset);
+	if (cd->data) {
+		blbp->start = start;
+		blbp->valid = true;
+
+		return UCODE_OK;
+	} else
+#endif /* CONFIG_BLK_DEV_INITRD */
+		return UCODE_ERROR;
+}
+
+static __init enum ucode_state
+scan_microcode(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
+	       struct ucode_cpu_info *uci, struct ucode_blobs *blbp)
+{
+	struct cpio_data cd = { NULL, 0, "" };
+	enum ucode_state ret;
+
+	/* try built-in microcode first */
+	if (load_builtin_intel_microcode(&cd))
+		/*
+		 * Invalidate blobs as we might've gotten an initrd too,
+		 * supplied by the boot loader, by mistake or simply forgotten
+		 * there. That's fine, we ignore it since we've found builtin
+		 * microcode already.
+		 */
+		blbp->valid = false;
+	else {
+		ret = __scan_microcode_initrd(&cd, blbp);
+		if (ret != UCODE_OK)
+			return ret;
+	}
+
+	return get_matching_model_microcode(blbp->start, cd.data, cd.size,
+					    mcs, mc_ptrs, uci);
+}
+
 static void __init
 _load_ucode_intel_bsp(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
-		      unsigned long start, unsigned long size)
+		      struct ucode_blobs *blbp)
 {
 	struct ucode_cpu_info uci;
 	enum ucode_state ret;
 
 	collect_cpu_info_early(&uci);
 
-	ret = scan_microcode(mcs, mc_ptrs, start, size, &uci);
+	ret = scan_microcode(mcs, mc_ptrs, &uci, blbp);
 	if (ret != UCODE_OK)
 		return;
 
-	ret = load_microcode(mcs, mc_ptrs, start, &uci);
+	ret = load_microcode(mcs, mc_ptrs, blbp->start, &uci);
 	if (ret != UCODE_OK)
 		return;
 
@@ -720,54 +775,50 @@ _load_ucode_intel_bsp(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
 
 void __init load_ucode_intel_bsp(void)
 {
-	u64 start, size;
-#ifdef CONFIG_X86_32
-	struct boot_params *p;
-
-	p	= (struct boot_params *)__pa_nodebug(&boot_params);
-	size	= p->hdr.ramdisk_size;
-
-	/*
-	 * Set start only if we have an initrd image. We cannot use initrd_start
-	 * because it is not set that early yet.
-	 */
-	start	= (size ? p->hdr.ramdisk_image : 0);
+	struct ucode_blobs *blobs_p;
+	struct mc_saved_data *mcs;
+	unsigned long *ptrs;
 
-	_load_ucode_intel_bsp((struct mc_saved_data *)__pa_nodebug(&mc_saved_data),
-			      (unsigned long *)__pa_nodebug(&mc_tmp_ptrs),
-			      start, size);
+#ifdef CONFIG_X86_32
+	mcs	= (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
+	ptrs	= (unsigned long *)__pa_nodebug(&mc_tmp_ptrs);
+	blobs_p	= (struct ucode_blobs *)__pa_nodebug(&blobs);
 #else
-	size	= boot_params.hdr.ramdisk_size;
-	start	= (size ? boot_params.hdr.ramdisk_image + PAGE_OFFSET : 0);
-
-	_load_ucode_intel_bsp(&mc_saved_data, mc_tmp_ptrs, start, size);
+	mcs	= &mc_saved_data;
+	ptrs	= mc_tmp_ptrs;
+	blobs_p = &blobs;
 #endif
+
+	_load_ucode_intel_bsp(mcs, ptrs, blobs_p);
 }
 
 void load_ucode_intel_ap(void)
 {
-	unsigned long *mcs_tmp_p;
-	struct mc_saved_data *mcs_p;
+	struct ucode_blobs *blobs_p;
+	struct mc_saved_data *mcs;
 	struct ucode_cpu_info uci;
 	enum ucode_state ret;
-#ifdef CONFIG_X86_32
+	unsigned long *ptrs;
 
-	mcs_tmp_p = (unsigned long *)__pa_nodebug(mc_tmp_ptrs);
-	mcs_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
+#ifdef CONFIG_X86_32
+	mcs	= (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
+	ptrs	= (unsigned long *)__pa_nodebug(mc_tmp_ptrs);
+	blobs_p	= (struct ucode_blobs *)__pa_nodebug(&blobs);
 #else
-	mcs_tmp_p = mc_tmp_ptrs;
-	mcs_p = &mc_saved_data;
+	mcs	= &mc_saved_data;
+	ptrs	= mc_tmp_ptrs;
+	blobs_p = &blobs;
 #endif
 
 	/*
 	 * If there is no valid ucode previously saved in memory, no need to
 	 * update ucode on this AP.
 	 */
-	if (!mcs_p->num_saved)
+	if (!mcs->num_saved)
 		return;
 
 	collect_cpu_info_early(&uci);
-	ret = load_microcode(mcs_p, mcs_tmp_p, get_initrd_start_addr(), &uci);
+	ret = load_microcode(mcs, ptrs, blobs_p->start, &uci);
 	if (ret != UCODE_OK)
 		return;
 
-- 
2.7.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 2/9] x86/microcode: Fix suspend to RAM with builtin microcode
  2016-06-06 15:10 [PATCH 0/9] x86/microcode: Fixes for builtin vs initrd loading; cleanups Borislav Petkov
  2016-06-06 15:10 ` [PATCH 1/9] x86/microcode: Fix loading precedence Borislav Petkov
@ 2016-06-06 15:10 ` Borislav Petkov
  2016-06-08  9:52   ` [tip:x86/microcode] " tip-bot for Borislav Petkov
  2016-06-06 15:10 ` [PATCH 3/9] lib/cpio: Make find_cpio_data()'s offset arg optional Borislav Petkov
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Borislav Petkov @ 2016-06-06 15:10 UTC (permalink / raw)
  To: X86 ML; +Cc: LKML

From: Borislav Petkov <bp@suse.de>

Usually, after we have found the proper microcode blob for the current
machine, we stash it away for later use with save_microcode_in_initrd().

However, with builtin microcode which doesn't come from the initrd, we
don't call that function because CONFIG_BLK_DEV_INITRD=n and even if
set, we don't have a valid initrd.

In order to fix this, let's make save_microcode_in_initrd() an
fs_initcall which runs before rootfs_initcall() as this was the time it
was called previously through:

rootfs_initcall(populate_rootfs)
|-> free_initrd()
    |-> free_initrd_mem()
        |-> save_microcode_in_initrd()

Also, we make it run independently from initrd functionality being
present or not.

And since it is called in the microcode loader only now, we can also
make it static.

Reported-and-tested-by: Jim Bos <jim876@xs4all.nl>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: <stable@vger.kernel.org> # v4.6
---
 arch/x86/include/asm/microcode.h     | 2 --
 arch/x86/kernel/cpu/microcode/core.c | 3 ++-
 arch/x86/mm/init.c                   | 7 -------
 3 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index ca2af7ed6cbf..da0d81fa0b54 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -133,13 +133,11 @@ static inline unsigned int x86_cpuid_family(void)
 #ifdef CONFIG_MICROCODE
 extern void __init load_ucode_bsp(void);
 extern void load_ucode_ap(void);
-extern int __init save_microcode_in_initrd(void);
 void reload_early_microcode(void);
 extern bool get_builtin_firmware(struct cpio_data *cd, const char *name);
 #else
 static inline void __init load_ucode_bsp(void)			{ }
 static inline void load_ucode_ap(void)				{ }
-static inline int __init save_microcode_in_initrd(void)		{ return 0; }
 static inline void reload_early_microcode(void)			{ }
 static inline bool
 get_builtin_firmware(struct cpio_data *cd, const char *name)	{ return false; }
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index ac360bfbbdb6..12823b6ebd6d 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -175,7 +175,7 @@ void load_ucode_ap(void)
 	}
 }
 
-int __init save_microcode_in_initrd(void)
+static int __init save_microcode_in_initrd(void)
 {
 	struct cpuinfo_x86 *c = &boot_cpu_data;
 
@@ -691,4 +691,5 @@ int __init microcode_init(void)
 	return error;
 
 }
+fs_initcall(save_microcode_in_initrd);
 late_initcall(microcode_init);
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 372aad2b3291..dffd162db0a4 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -696,13 +696,6 @@ void free_initmem(void)
 void __init free_initrd_mem(unsigned long start, unsigned long end)
 {
 	/*
-	 * Remember, initrd memory may contain microcode or other useful things.
-	 * Before we lose initrd mem, we need to find a place to hold them
-	 * now that normal virtual memory is enabled.
-	 */
-	save_microcode_in_initrd();
-
-	/*
 	 * end could be not aligned, and We can not align that,
 	 * decompresser could be confused by aligned initrd_end
 	 * We already reserve the end partial page before in
-- 
2.7.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 3/9] lib/cpio: Make find_cpio_data()'s offset arg optional
  2016-06-06 15:10 [PATCH 0/9] x86/microcode: Fixes for builtin vs initrd loading; cleanups Borislav Petkov
  2016-06-06 15:10 ` [PATCH 1/9] x86/microcode: Fix loading precedence Borislav Petkov
  2016-06-06 15:10 ` [PATCH 2/9] x86/microcode: Fix suspend to RAM with builtin microcode Borislav Petkov
@ 2016-06-06 15:10 ` Borislav Petkov
  2016-06-08  9:52   ` [tip:x86/microcode] " tip-bot for Borislav Petkov
  2016-06-06 15:10 ` [PATCH 4/9] x86/microcode: Get rid of find_cpio_data()'s dummy offset arg Borislav Petkov
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Borislav Petkov @ 2016-06-06 15:10 UTC (permalink / raw)
  To: X86 ML; +Cc: LKML

From: Borislav Petkov <bp@suse.de>

Some callers don't use it so make it optional.

Signed-off-by: Borislav Petkov <bp@suse.de>
---
 lib/earlycpio.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/earlycpio.c b/lib/earlycpio.c
index 3eb3e4722b8e..db283ba4d2c1 100644
--- a/lib/earlycpio.c
+++ b/lib/earlycpio.c
@@ -125,7 +125,10 @@ struct cpio_data find_cpio_data(const char *path, void *data,
 		if ((ch[C_MODE] & 0170000) == 0100000 &&
 		    ch[C_NAMESIZE] >= mypathsize &&
 		    !memcmp(p, path, mypathsize)) {
-			*nextoff = (long)nptr - (long)data;
+
+			if (nextoff)
+				*nextoff = (long)nptr - (long)data;
+
 			if (ch[C_NAMESIZE] - mypathsize >= MAX_CPIO_FILE_NAME) {
 				pr_warn(
 				"File %s exceeding MAX_CPIO_FILE_NAME [%d]\n",
-- 
2.7.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 4/9] x86/microcode: Get rid of find_cpio_data()'s dummy offset arg
  2016-06-06 15:10 [PATCH 0/9] x86/microcode: Fixes for builtin vs initrd loading; cleanups Borislav Petkov
                   ` (2 preceding siblings ...)
  2016-06-06 15:10 ` [PATCH 3/9] lib/cpio: Make find_cpio_data()'s offset arg optional Borislav Petkov
@ 2016-06-06 15:10 ` Borislav Petkov
  2016-06-08  9:53   ` [tip:x86/microcode] " tip-bot for Borislav Petkov
  2016-06-06 15:10 ` [PATCH 5/9] x86/microcode: Propagate save_microcode_in_initrd() retval Borislav Petkov
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Borislav Petkov @ 2016-06-06 15:10 UTC (permalink / raw)
  To: X86 ML; +Cc: LKML

From: Borislav Petkov <bp@suse.de>

The microcode loader doesn't use it and now that that arg has been made
optional in find_cpio_data(), get rid of it here.

No functionality change.

Signed-off-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/kernel/cpu/microcode/amd.c   | 3 +--
 arch/x86/kernel/cpu/microcode/intel.c | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 11dd1cc8e444..b1d1e345f5f5 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -64,7 +64,6 @@ static struct cpio_data ucode_cpio;
 static struct cpio_data __init find_ucode_in_initrd(void)
 {
 #ifdef CONFIG_BLK_DEV_INITRD
-	long offset = 0;
 	char *path;
 	void *start;
 	size_t size;
@@ -92,7 +91,7 @@ static struct cpio_data __init find_ucode_in_initrd(void)
 	size    = boot_params.hdr.ramdisk_size;
 #endif /* !CONFIG_X86_32 */
 
-	return find_cpio_data(path, start, size, &offset);
+	return find_cpio_data(path, start, size, NULL);
 #else
 	return (struct cpio_data){ NULL, 0, "" };
 #endif
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 5835d5b0db81..2ad40b73c8df 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -685,7 +685,6 @@ static __init enum ucode_state
 __scan_microcode_initrd(struct cpio_data *cd, struct ucode_blobs *blbp)
 {
 #ifdef CONFIG_BLK_DEV_INITRD
-	long offset = 0;
 	static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin";
 	char *p = IS_ENABLED(CONFIG_X86_32) ? (char *)__pa_nodebug(ucode_name)
 						    : ucode_name;
@@ -716,7 +715,7 @@ __scan_microcode_initrd(struct cpio_data *cd, struct ucode_blobs *blbp)
 	}
 # endif
 
-	*cd = find_cpio_data(p, (void *)start, size, &offset);
+	*cd = find_cpio_data(p, (void *)start, size, NULL);
 	if (cd->data) {
 		blbp->start = start;
 		blbp->valid = true;
-- 
2.7.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 5/9] x86/microcode: Propagate save_microcode_in_initrd() retval
  2016-06-06 15:10 [PATCH 0/9] x86/microcode: Fixes for builtin vs initrd loading; cleanups Borislav Petkov
                   ` (3 preceding siblings ...)
  2016-06-06 15:10 ` [PATCH 4/9] x86/microcode: Get rid of find_cpio_data()'s dummy offset arg Borislav Petkov
@ 2016-06-06 15:10 ` Borislav Petkov
  2016-06-08  9:53   ` [tip:x86/microcode] " tip-bot for Borislav Petkov
  2016-06-06 15:10 ` [PATCH 6/9] x86/microcode/intel: Rename load_microcode_early() to find_microcode_patch() Borislav Petkov
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Borislav Petkov @ 2016-06-06 15:10 UTC (permalink / raw)
  To: X86 ML; +Cc: LKML

From: Borislav Petkov <bp@suse.de>

Will be used in a later patch. No functionality change.

Signed-off-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/kernel/cpu/microcode/core.c  | 6 +++---
 arch/x86/kernel/cpu/microcode/intel.c | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index 12823b6ebd6d..9ae7fcac70ab 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -182,17 +182,17 @@ static int __init save_microcode_in_initrd(void)
 	switch (c->x86_vendor) {
 	case X86_VENDOR_INTEL:
 		if (c->x86 >= 6)
-			save_microcode_in_initrd_intel();
+			return save_microcode_in_initrd_intel();
 		break;
 	case X86_VENDOR_AMD:
 		if (c->x86 >= 0x10)
-			save_microcode_in_initrd_amd();
+			return save_microcode_in_initrd_amd();
 		break;
 	default:
 		break;
 	}
 
-	return 0;
+	return -EINVAL;
 }
 
 void reload_early_microcode(void)
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 2ad40b73c8df..d852ca984f87 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -675,8 +675,8 @@ int __init save_microcode_in_initrd_intel(void)
 	ret = save_microcode(&mc_saved_data, mc_saved, count);
 	if (ret)
 		pr_err("Cannot save microcode patches from initrd.\n");
-
-	show_saved_mc();
+	else
+		show_saved_mc();
 
 	return ret;
 }
-- 
2.7.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 6/9] x86/microcode/intel: Rename load_microcode_early() to find_microcode_patch()
  2016-06-06 15:10 [PATCH 0/9] x86/microcode: Fixes for builtin vs initrd loading; cleanups Borislav Petkov
                   ` (4 preceding siblings ...)
  2016-06-06 15:10 ` [PATCH 5/9] x86/microcode: Propagate save_microcode_in_initrd() retval Borislav Petkov
@ 2016-06-06 15:10 ` Borislav Petkov
  2016-06-08  9:54   ` [tip:x86/microcode] " tip-bot for Borislav Petkov
  2016-06-06 15:10 ` [PATCH 7/9] x86/microcode/intel: Unexport save_mc_for_early() Borislav Petkov
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Borislav Petkov @ 2016-06-06 15:10 UTC (permalink / raw)
  To: X86 ML; +Cc: LKML

From: Borislav Petkov <bp@suse.de>

This function does exactly that: it goes through the previously saved
array of microcode blobs and finds the proper one for the current CPU.
Rename it accordingly.

No functionality change.

Signed-off-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/kernel/cpu/microcode/intel.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index d852ca984f87..b5759a3f0aa8 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -58,7 +58,7 @@ static struct ucode_blobs {
 } blobs;
 
 static enum ucode_state
-load_microcode_early(struct microcode_intel **saved,
+find_microcode_patch(struct microcode_intel **saved,
 		     unsigned int num_saved, struct ucode_cpu_info *uci)
 {
 	struct microcode_intel *ucode_ptr, *new_mc = NULL;
@@ -127,13 +127,13 @@ load_microcode(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
 	if (!mcs->mc_saved) {
 		copy_ptrs(mc_saved_tmp, mc_ptrs, offset, count);
 
-		return load_microcode_early(mc_saved_tmp, count, uci);
+		return find_microcode_patch(mc_saved_tmp, count, uci);
 	} else {
 #ifdef CONFIG_X86_32
 		microcode_phys(mc_saved_tmp, mcs);
-		return load_microcode_early(mc_saved_tmp, count, uci);
+		return find_microcode_patch(mc_saved_tmp, count, uci);
 #else
-		return load_microcode_early(mcs->mc_saved, count, uci);
+		return find_microcode_patch(mcs->mc_saved, count, uci);
 #endif
 	}
 }
@@ -834,7 +834,7 @@ void reload_ucode_intel(void)
 
 	collect_cpu_info_early(&uci);
 
-	ret = load_microcode_early(mc_saved_data.mc_saved,
+	ret = find_microcode_patch(mc_saved_data.mc_saved,
 				   mc_saved_data.num_saved, &uci);
 	if (ret != UCODE_OK)
 		return;
-- 
2.7.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 7/9] x86/microcode/intel: Unexport save_mc_for_early()
  2016-06-06 15:10 [PATCH 0/9] x86/microcode: Fixes for builtin vs initrd loading; cleanups Borislav Petkov
                   ` (5 preceding siblings ...)
  2016-06-06 15:10 ` [PATCH 6/9] x86/microcode/intel: Rename load_microcode_early() to find_microcode_patch() Borislav Petkov
@ 2016-06-06 15:10 ` Borislav Petkov
  2016-06-08  9:54   ` [tip:x86/microcode] " tip-bot for Borislav Petkov
  2016-06-06 15:10 ` [PATCH 8/9] x86/microcode/AMD: Make amd_ucode_patch static Borislav Petkov
  2016-06-06 15:10 ` [PATCH 9/9] Documentation/microcode: Document some aspects for more clarity Borislav Petkov
  8 siblings, 1 reply; 19+ messages in thread
From: Borislav Petkov @ 2016-06-06 15:10 UTC (permalink / raw)
  To: X86 ML; +Cc: LKML

From: Borislav Petkov <bp@suse.de>

It is used only in intel.c, drop the CONFIG_HOTPLUG_CPU ifdeffery from
the header and turn it into a void function because its return value
wasn't being used anyway.

No functionality change.

Signed-off-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/include/asm/microcode_intel.h |  5 -----
 arch/x86/kernel/cpu/microcode/intel.c  | 15 ++++++---------
 2 files changed, 6 insertions(+), 14 deletions(-)

diff --git a/arch/x86/include/asm/microcode_intel.h b/arch/x86/include/asm/microcode_intel.h
index 603417f8dd6c..5e69154c9f07 100644
--- a/arch/x86/include/asm/microcode_intel.h
+++ b/arch/x86/include/asm/microcode_intel.h
@@ -70,9 +70,4 @@ static inline int __init save_microcode_in_initrd_intel(void) { return -EINVAL;
 static inline void reload_ucode_intel(void) {}
 #endif
 
-#ifdef CONFIG_HOTPLUG_CPU
-extern int save_mc_for_early(u8 *mc);
-#else
-static inline int save_mc_for_early(u8 *mc) { return 0; }
-#endif
 #endif /* _ASM_X86_MICROCODE_INTEL_H */
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index b5759a3f0aa8..359e2034b558 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -456,8 +456,6 @@ static void show_saved_mc(void)
 #endif
 }
 
-#ifdef CONFIG_HOTPLUG_CPU
-static DEFINE_MUTEX(x86_cpu_microcode_mutex);
 /*
  * Save this mc into mc_saved_data. So it will be loaded early when a CPU is
  * hot added or resumes.
@@ -465,14 +463,16 @@ static DEFINE_MUTEX(x86_cpu_microcode_mutex);
  * Please make sure this mc should be a valid microcode patch before calling
  * this function.
  */
-int save_mc_for_early(u8 *mc)
+static void save_mc_for_early(u8 *mc)
 {
+#ifdef CONFIG_HOTPLUG_CPU
+	static DEFINE_MUTEX(x86_cpu_microcode_mutex);
+
 	struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
 	unsigned int mc_saved_count_init;
 	unsigned int num_saved;
 	struct microcode_intel **mc_saved;
-	int ret = 0;
-	int i;
+	int ret, i;
 
 	/*
 	 * Hold hotplug lock so mc_saved_data is not accessed by a CPU in
@@ -515,11 +515,8 @@ int save_mc_for_early(u8 *mc)
 
 out:
 	mutex_unlock(&x86_cpu_microcode_mutex);
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(save_mc_for_early);
 #endif
+}
 
 static bool __init load_builtin_intel_microcode(struct cpio_data *cp)
 {
-- 
2.7.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 8/9] x86/microcode/AMD: Make amd_ucode_patch static
  2016-06-06 15:10 [PATCH 0/9] x86/microcode: Fixes for builtin vs initrd loading; cleanups Borislav Petkov
                   ` (6 preceding siblings ...)
  2016-06-06 15:10 ` [PATCH 7/9] x86/microcode/intel: Unexport save_mc_for_early() Borislav Petkov
@ 2016-06-06 15:10 ` Borislav Petkov
  2016-06-08  9:55   ` [tip:x86/microcode] x86/microcode/AMD: Make amd_ucode_patch[] static tip-bot for Borislav Petkov
  2016-06-06 15:10 ` [PATCH 9/9] Documentation/microcode: Document some aspects for more clarity Borislav Petkov
  8 siblings, 1 reply; 19+ messages in thread
From: Borislav Petkov @ 2016-06-06 15:10 UTC (permalink / raw)
  To: X86 ML; +Cc: LKML

From: Borislav Petkov <bp@suse.de>

It is used only in amd.c now.

No functionality change.

Signed-off-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/include/asm/microcode_amd.h | 1 -
 arch/x86/kernel/cpu/microcode/amd.c  | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h
index adfc847a395e..15eb75484cc0 100644
--- a/arch/x86/include/asm/microcode_amd.h
+++ b/arch/x86/include/asm/microcode_amd.h
@@ -62,7 +62,6 @@ extern int apply_microcode_amd(int cpu);
 extern enum ucode_state load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size);
 
 #define PATCH_MAX_SIZE PAGE_SIZE
-extern u8 amd_ucode_patch[PATCH_MAX_SIZE];
 
 #ifdef CONFIG_MICROCODE_AMD
 extern void __init load_ucode_amd_bsp(unsigned int family);
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index b1d1e345f5f5..27a0228c9cae 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -56,7 +56,7 @@ static u8 *container;
 static size_t container_size;
 
 static u32 ucode_new_rev;
-u8 amd_ucode_patch[PATCH_MAX_SIZE];
+static u8 amd_ucode_patch[PATCH_MAX_SIZE];
 static u16 this_equiv_id;
 
 static struct cpio_data ucode_cpio;
-- 
2.7.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 9/9] Documentation/microcode: Document some aspects for more clarity
  2016-06-06 15:10 [PATCH 0/9] x86/microcode: Fixes for builtin vs initrd loading; cleanups Borislav Petkov
                   ` (7 preceding siblings ...)
  2016-06-06 15:10 ` [PATCH 8/9] x86/microcode/AMD: Make amd_ucode_patch static Borislav Petkov
@ 2016-06-06 15:10 ` Borislav Petkov
  2016-06-08  9:55   ` [tip:x86/microcode] " tip-bot for Borislav Petkov
  8 siblings, 1 reply; 19+ messages in thread
From: Borislav Petkov @ 2016-06-06 15:10 UTC (permalink / raw)
  To: X86 ML; +Cc: LKML

From: Borislav Petkov <bp@suse.de>

Document that builtin microcode is 64-bit only. Also, improve/add
comments to places.

Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: linux-doc@vger.kernel.org
---
 Documentation/x86/early-microcode.txt |  5 ++++-
 arch/x86/kernel/cpu/microcode/intel.c | 16 +++++++++-------
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/Documentation/x86/early-microcode.txt b/Documentation/x86/early-microcode.txt
index c956d99cf1de..07749e7f3d50 100644
--- a/Documentation/x86/early-microcode.txt
+++ b/Documentation/x86/early-microcode.txt
@@ -45,7 +45,10 @@ Builtin microcode
 =================
 
 We can also load builtin microcode supplied through the regular firmware
-builtin method CONFIG_FIRMWARE_IN_KERNEL. Here's an example:
+builtin method CONFIG_FIRMWARE_IN_KERNEL. Only 64-bit is currently
+supported.
+
+Here's an example:
 
 CONFIG_FIRMWARE_IN_KERNEL=y
 CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin"
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 359e2034b558..8962d6acee39 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -40,9 +40,13 @@
 #include <asm/msr.h>
 
 /*
- * Temporary microcode blobs pointers storage. We note here the pointers to
- * microcode blobs we've got from whatever storage (detached initrd, builtin).
- * Later on, we put those into final storage mc_saved_data.mc_saved.
+ * Temporary microcode blobs pointers storage. We note here during early load
+ * the pointers to microcode blobs we've got from whatever storage (detached
+ * initrd, builtin). Later on, we put those into final storage
+ * mc_saved_data.mc_saved.
+ *
+ * Important: those are offsets from the beginning of initrd or absolute
+ * addresses within the kernel image when built-in.
  */
 static unsigned long mc_tmp_ptrs[MAX_UCODE_COUNT];
 
@@ -57,6 +61,7 @@ static struct ucode_blobs {
 	bool valid;
 } blobs;
 
+/* Go through saved patches and find the one suitable for the current CPU. */
 static enum ucode_state
 find_microcode_patch(struct microcode_intel **saved,
 		     unsigned int num_saved, struct ucode_cpu_info *uci)
@@ -466,6 +471,7 @@ static void show_saved_mc(void)
 static void save_mc_for_early(u8 *mc)
 {
 #ifdef CONFIG_HOTPLUG_CPU
+	/* Synchronization during CPU hotplug. */
 	static DEFINE_MUTEX(x86_cpu_microcode_mutex);
 
 	struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
@@ -474,10 +480,6 @@ static void save_mc_for_early(u8 *mc)
 	struct microcode_intel **mc_saved;
 	int ret, i;
 
-	/*
-	 * Hold hotplug lock so mc_saved_data is not accessed by a CPU in
-	 * hotplug.
-	 */
 	mutex_lock(&x86_cpu_microcode_mutex);
 
 	mc_saved_count_init = mc_saved_data.num_saved;
-- 
2.7.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [tip:x86/microcode] x86/microcode: Fix loading precedence
  2016-06-06 15:10 ` [PATCH 1/9] x86/microcode: Fix loading precedence Borislav Petkov
@ 2016-06-08  9:51   ` tip-bot for Borislav Petkov
  0 siblings, 0 replies; 19+ messages in thread
From: tip-bot for Borislav Petkov @ 2016-06-08  9:51 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: brgerst, hpa, nix.or.die, bp, luto, tglx, peterz, mingo, bp,
	torvalds, linux-kernel, dvlasenk

Commit-ID:  6c5456474e7f0b63be66d44b0595001e2a8b44d5
Gitweb:     http://git.kernel.org/tip/6c5456474e7f0b63be66d44b0595001e2a8b44d5
Author:     Borislav Petkov <bp@suse.de>
AuthorDate: Mon, 6 Jun 2016 17:10:42 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 8 Jun 2016 11:04:19 +0200

x86/microcode: Fix loading precedence

So it can happen that even with builtin microcode,
CONFIG_BLK_DEV_INITRD=y gets forgotten enabled.

Or, even with that disabled, an initrd image gets supplied by the boot
loader, by omission or is simply forgotten there. And since we do look
at boot_params.hdr.ramdisk_* to know whether we have received an initrd,
we might get puzzled.

So let's just make the loader look for builtin microcode first and if
found, ignore the ramdisk image.

If no builtin found, it falls back to scanning the supplied initrd, of
course.

For that, we move all the initrd scanning in a separate
__scan_microcode_initrd() function and fall back to it only if
load_builtin_intel_microcode() has failed.

Reported-and-tested-by: Gabriel Craciunescu <nix.or.die@gmail.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1465225850-7352-2-git-send-email-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/microcode.h      |  24 -----
 arch/x86/kernel/cpu/microcode/amd.c   |  28 +++---
 arch/x86/kernel/cpu/microcode/intel.c | 183 ++++++++++++++++++++++------------
 3 files changed, 133 insertions(+), 102 deletions(-)

diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index 9d3a96c..ca2af7e 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -145,28 +145,4 @@ static inline bool
 get_builtin_firmware(struct cpio_data *cd, const char *name)	{ return false; }
 #endif
 
-static inline unsigned long get_initrd_start(void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-	return initrd_start;
-#else
-	return 0;
-#endif
-}
-
-static inline unsigned long get_initrd_start_addr(void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-#ifdef CONFIG_X86_32
-	unsigned long *initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start);
-
-	return (unsigned long)__pa_nodebug(*initrd_start_p);
-#else
-	return get_initrd_start();
-#endif
-#else /* CONFIG_BLK_DEV_INITRD */
-	return 0;
-#endif
-}
-
 #endif /* _ASM_X86_MICROCODE_H */
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 8581963..11dd1cc 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -61,19 +61,20 @@ static u16 this_equiv_id;
 
 static struct cpio_data ucode_cpio;
 
-/*
- * Microcode patch container file is prepended to the initrd in cpio format.
- * See Documentation/x86/early-microcode.txt
- */
-static __initdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin";
-
 static struct cpio_data __init find_ucode_in_initrd(void)
 {
+#ifdef CONFIG_BLK_DEV_INITRD
 	long offset = 0;
 	char *path;
 	void *start;
 	size_t size;
 
+	/*
+	 * Microcode patch container file is prepended to the initrd in cpio
+	 * format. See Documentation/x86/early-microcode.txt
+	 */
+	static __initdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin";
+
 #ifdef CONFIG_X86_32
 	struct boot_params *p;
 
@@ -89,9 +90,12 @@ static struct cpio_data __init find_ucode_in_initrd(void)
 	path    = ucode_path;
 	start   = (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET);
 	size    = boot_params.hdr.ramdisk_size;
-#endif
+#endif /* !CONFIG_X86_32 */
 
 	return find_cpio_data(path, start, size, &offset);
+#else
+	return (struct cpio_data){ NULL, 0, "" };
+#endif
 }
 
 static size_t compute_container_size(u8 *data, u32 total_size)
@@ -289,11 +293,11 @@ void __init load_ucode_amd_bsp(unsigned int family)
 	size = &ucode_cpio.size;
 #endif
 
-	cp = find_ucode_in_initrd();
-	if (!cp.data) {
-		if (!load_builtin_amd_microcode(&cp, family))
-			return;
-	}
+	if (!load_builtin_amd_microcode(&cp, family))
+		cp = find_ucode_in_initrd();
+
+	if (!(cp.data && cp.size))
+		return;
 
 	*data = cp.data;
 	*size = cp.size;
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 65cbbcd..5835d5b 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -51,6 +51,12 @@ static struct mc_saved_data {
 	struct microcode_intel **mc_saved;
 } mc_saved_data;
 
+/* Microcode blobs within the initrd. 0 if builtin. */
+static struct ucode_blobs {
+	unsigned long start;
+	bool valid;
+} blobs;
+
 static enum ucode_state
 load_microcode_early(struct microcode_intel **saved,
 		     unsigned int num_saved, struct ucode_cpu_info *uci)
@@ -532,37 +538,6 @@ static bool __init load_builtin_intel_microcode(struct cpio_data *cp)
 #endif
 }
 
-static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin";
-static __init enum ucode_state
-scan_microcode(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
-	       unsigned long start, unsigned long size,
-	       struct ucode_cpu_info *uci)
-{
-	struct cpio_data cd;
-	long offset = 0;
-#ifdef CONFIG_X86_32
-	char *p = (char *)__pa_nodebug(ucode_name);
-#else
-	char *p = ucode_name;
-#endif
-
-	cd.data = NULL;
-	cd.size = 0;
-
-	/* try built-in microcode if no initrd */
-	if (!size) {
-		if (!load_builtin_intel_microcode(&cd))
-			return UCODE_ERROR;
-	} else {
-		cd = find_cpio_data(p, (void *)start, size, &offset);
-		if (!cd.data)
-			return UCODE_ERROR;
-	}
-
-	return get_matching_model_microcode(start, cd.data, cd.size,
-					    mcs, mc_ptrs, uci);
-}
-
 /*
  * Print ucode update info.
  */
@@ -680,14 +655,22 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)
  */
 int __init save_microcode_in_initrd_intel(void)
 {
-	unsigned int count = mc_saved_data.num_saved;
 	struct microcode_intel *mc_saved[MAX_UCODE_COUNT];
-	int ret = 0;
+	unsigned int count = mc_saved_data.num_saved;
+	unsigned long offset = 0;
+	int ret;
 
 	if (!count)
-		return ret;
+		return 0;
 
-	copy_ptrs(mc_saved, mc_tmp_ptrs, get_initrd_start(), count);
+	/*
+	 * We have found a valid initrd but it might've been relocated in the
+	 * meantime so get its updated address.
+	 */
+	if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && blobs.valid)
+		offset = initrd_start;
+
+	copy_ptrs(mc_saved, mc_tmp_ptrs, offset, count);
 
 	ret = save_microcode(&mc_saved_data, mc_saved, count);
 	if (ret)
@@ -698,20 +681,92 @@ int __init save_microcode_in_initrd_intel(void)
 	return ret;
 }
 
+static __init enum ucode_state
+__scan_microcode_initrd(struct cpio_data *cd, struct ucode_blobs *blbp)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	long offset = 0;
+	static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin";
+	char *p = IS_ENABLED(CONFIG_X86_32) ? (char *)__pa_nodebug(ucode_name)
+						    : ucode_name;
+# ifdef CONFIG_X86_32
+	unsigned long start = 0, size;
+	struct boot_params *params;
+
+	params = (struct boot_params *)__pa_nodebug(&boot_params);
+	size   = params->hdr.ramdisk_size;
+
+	/*
+	 * Set start only if we have an initrd image. We cannot use initrd_start
+	 * because it is not set that early yet.
+	 */
+	start = (size ? params->hdr.ramdisk_image : 0);
+
+# else /* CONFIG_X86_64 */
+	unsigned long start = 0, size;
+
+	size  = (u64)boot_params.ext_ramdisk_size << 32;
+	size |= boot_params.hdr.ramdisk_size;
+
+	if (size) {
+		start  = (u64)boot_params.ext_ramdisk_image << 32;
+		start |= boot_params.hdr.ramdisk_image;
+
+		start += PAGE_OFFSET;
+	}
+# endif
+
+	*cd = find_cpio_data(p, (void *)start, size, &offset);
+	if (cd->data) {
+		blbp->start = start;
+		blbp->valid = true;
+
+		return UCODE_OK;
+	} else
+#endif /* CONFIG_BLK_DEV_INITRD */
+		return UCODE_ERROR;
+}
+
+static __init enum ucode_state
+scan_microcode(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
+	       struct ucode_cpu_info *uci, struct ucode_blobs *blbp)
+{
+	struct cpio_data cd = { NULL, 0, "" };
+	enum ucode_state ret;
+
+	/* try built-in microcode first */
+	if (load_builtin_intel_microcode(&cd))
+		/*
+		 * Invalidate blobs as we might've gotten an initrd too,
+		 * supplied by the boot loader, by mistake or simply forgotten
+		 * there. That's fine, we ignore it since we've found builtin
+		 * microcode already.
+		 */
+		blbp->valid = false;
+	else {
+		ret = __scan_microcode_initrd(&cd, blbp);
+		if (ret != UCODE_OK)
+			return ret;
+	}
+
+	return get_matching_model_microcode(blbp->start, cd.data, cd.size,
+					    mcs, mc_ptrs, uci);
+}
+
 static void __init
 _load_ucode_intel_bsp(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
-		      unsigned long start, unsigned long size)
+		      struct ucode_blobs *blbp)
 {
 	struct ucode_cpu_info uci;
 	enum ucode_state ret;
 
 	collect_cpu_info_early(&uci);
 
-	ret = scan_microcode(mcs, mc_ptrs, start, size, &uci);
+	ret = scan_microcode(mcs, mc_ptrs, &uci, blbp);
 	if (ret != UCODE_OK)
 		return;
 
-	ret = load_microcode(mcs, mc_ptrs, start, &uci);
+	ret = load_microcode(mcs, mc_ptrs, blbp->start, &uci);
 	if (ret != UCODE_OK)
 		return;
 
@@ -720,54 +775,50 @@ _load_ucode_intel_bsp(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
 
 void __init load_ucode_intel_bsp(void)
 {
-	u64 start, size;
-#ifdef CONFIG_X86_32
-	struct boot_params *p;
-
-	p	= (struct boot_params *)__pa_nodebug(&boot_params);
-	size	= p->hdr.ramdisk_size;
-
-	/*
-	 * Set start only if we have an initrd image. We cannot use initrd_start
-	 * because it is not set that early yet.
-	 */
-	start	= (size ? p->hdr.ramdisk_image : 0);
+	struct ucode_blobs *blobs_p;
+	struct mc_saved_data *mcs;
+	unsigned long *ptrs;
 
-	_load_ucode_intel_bsp((struct mc_saved_data *)__pa_nodebug(&mc_saved_data),
-			      (unsigned long *)__pa_nodebug(&mc_tmp_ptrs),
-			      start, size);
+#ifdef CONFIG_X86_32
+	mcs	= (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
+	ptrs	= (unsigned long *)__pa_nodebug(&mc_tmp_ptrs);
+	blobs_p	= (struct ucode_blobs *)__pa_nodebug(&blobs);
 #else
-	size	= boot_params.hdr.ramdisk_size;
-	start	= (size ? boot_params.hdr.ramdisk_image + PAGE_OFFSET : 0);
-
-	_load_ucode_intel_bsp(&mc_saved_data, mc_tmp_ptrs, start, size);
+	mcs	= &mc_saved_data;
+	ptrs	= mc_tmp_ptrs;
+	blobs_p = &blobs;
 #endif
+
+	_load_ucode_intel_bsp(mcs, ptrs, blobs_p);
 }
 
 void load_ucode_intel_ap(void)
 {
-	unsigned long *mcs_tmp_p;
-	struct mc_saved_data *mcs_p;
+	struct ucode_blobs *blobs_p;
+	struct mc_saved_data *mcs;
 	struct ucode_cpu_info uci;
 	enum ucode_state ret;
-#ifdef CONFIG_X86_32
+	unsigned long *ptrs;
 
-	mcs_tmp_p = (unsigned long *)__pa_nodebug(mc_tmp_ptrs);
-	mcs_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
+#ifdef CONFIG_X86_32
+	mcs	= (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
+	ptrs	= (unsigned long *)__pa_nodebug(mc_tmp_ptrs);
+	blobs_p	= (struct ucode_blobs *)__pa_nodebug(&blobs);
 #else
-	mcs_tmp_p = mc_tmp_ptrs;
-	mcs_p = &mc_saved_data;
+	mcs	= &mc_saved_data;
+	ptrs	= mc_tmp_ptrs;
+	blobs_p = &blobs;
 #endif
 
 	/*
 	 * If there is no valid ucode previously saved in memory, no need to
 	 * update ucode on this AP.
 	 */
-	if (!mcs_p->num_saved)
+	if (!mcs->num_saved)
 		return;
 
 	collect_cpu_info_early(&uci);
-	ret = load_microcode(mcs_p, mcs_tmp_p, get_initrd_start_addr(), &uci);
+	ret = load_microcode(mcs, ptrs, blobs_p->start, &uci);
 	if (ret != UCODE_OK)
 		return;
 

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [tip:x86/microcode] x86/microcode: Fix suspend to RAM with builtin microcode
  2016-06-06 15:10 ` [PATCH 2/9] x86/microcode: Fix suspend to RAM with builtin microcode Borislav Petkov
@ 2016-06-08  9:52   ` tip-bot for Borislav Petkov
  0 siblings, 0 replies; 19+ messages in thread
From: tip-bot for Borislav Petkov @ 2016-06-08  9:52 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: luto, brgerst, bp, linux-kernel, tglx, jim876, mingo, hpa,
	torvalds, dvlasenk, peterz, bp

Commit-ID:  4b703305d98bf7350d4b2953ee39a3aa2eeb1778
Gitweb:     http://git.kernel.org/tip/4b703305d98bf7350d4b2953ee39a3aa2eeb1778
Author:     Borislav Petkov <bp@suse.de>
AuthorDate: Mon, 6 Jun 2016 17:10:43 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 8 Jun 2016 11:04:19 +0200

x86/microcode: Fix suspend to RAM with builtin microcode

Usually, after we have found the proper microcode blob for the current
machine, we stash it away for later use with save_microcode_in_initrd().

However, with builtin microcode which doesn't come from the initrd, we
don't call that function because CONFIG_BLK_DEV_INITRD=n and even if
set, we don't have a valid initrd.

In order to fix this, let's make save_microcode_in_initrd() an
fs_initcall which runs before rootfs_initcall() as this was the time it
was called previously through:

 rootfs_initcall(populate_rootfs)
 |-> free_initrd()
     |-> free_initrd_mem()
         |-> save_microcode_in_initrd()

Also, we make it run independently from initrd functionality being
present or not.

And since it is called in the microcode loader only now, we can also
make it static.

Reported-and-tested-by: Jim Bos <jim876@xs4all.nl>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: <stable@vger.kernel.org> # v4.6
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1465225850-7352-3-git-send-email-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/microcode.h     | 2 --
 arch/x86/kernel/cpu/microcode/core.c | 3 ++-
 arch/x86/mm/init.c                   | 7 -------
 3 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index ca2af7e..da0d81f 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -133,13 +133,11 @@ static inline unsigned int x86_cpuid_family(void)
 #ifdef CONFIG_MICROCODE
 extern void __init load_ucode_bsp(void);
 extern void load_ucode_ap(void);
-extern int __init save_microcode_in_initrd(void);
 void reload_early_microcode(void);
 extern bool get_builtin_firmware(struct cpio_data *cd, const char *name);
 #else
 static inline void __init load_ucode_bsp(void)			{ }
 static inline void load_ucode_ap(void)				{ }
-static inline int __init save_microcode_in_initrd(void)		{ return 0; }
 static inline void reload_early_microcode(void)			{ }
 static inline bool
 get_builtin_firmware(struct cpio_data *cd, const char *name)	{ return false; }
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index ac360bf..12823b6 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -175,7 +175,7 @@ void load_ucode_ap(void)
 	}
 }
 
-int __init save_microcode_in_initrd(void)
+static int __init save_microcode_in_initrd(void)
 {
 	struct cpuinfo_x86 *c = &boot_cpu_data;
 
@@ -691,4 +691,5 @@ int __init microcode_init(void)
 	return error;
 
 }
+fs_initcall(save_microcode_in_initrd);
 late_initcall(microcode_init);
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 372aad2..dffd162 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -696,13 +696,6 @@ void free_initmem(void)
 void __init free_initrd_mem(unsigned long start, unsigned long end)
 {
 	/*
-	 * Remember, initrd memory may contain microcode or other useful things.
-	 * Before we lose initrd mem, we need to find a place to hold them
-	 * now that normal virtual memory is enabled.
-	 */
-	save_microcode_in_initrd();
-
-	/*
 	 * end could be not aligned, and We can not align that,
 	 * decompresser could be confused by aligned initrd_end
 	 * We already reserve the end partial page before in

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [tip:x86/microcode] lib/cpio: Make find_cpio_data()'s offset arg optional
  2016-06-06 15:10 ` [PATCH 3/9] lib/cpio: Make find_cpio_data()'s offset arg optional Borislav Petkov
@ 2016-06-08  9:52   ` tip-bot for Borislav Petkov
  0 siblings, 0 replies; 19+ messages in thread
From: tip-bot for Borislav Petkov @ 2016-06-08  9:52 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, brgerst, peterz, mingo, torvalds, bp, bp,
	dvlasenk, tglx, luto

Commit-ID:  7557933e6b99d381c19b196901ed537b00f6d121
Gitweb:     http://git.kernel.org/tip/7557933e6b99d381c19b196901ed537b00f6d121
Author:     Borislav Petkov <bp@suse.de>
AuthorDate: Mon, 6 Jun 2016 17:10:44 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 8 Jun 2016 11:04:19 +0200

lib/cpio: Make find_cpio_data()'s offset arg optional

Some callers don't use it so make it optional.

Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1465225850-7352-4-git-send-email-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 lib/earlycpio.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/earlycpio.c b/lib/earlycpio.c
index 3eb3e47..db283ba 100644
--- a/lib/earlycpio.c
+++ b/lib/earlycpio.c
@@ -125,7 +125,10 @@ struct cpio_data find_cpio_data(const char *path, void *data,
 		if ((ch[C_MODE] & 0170000) == 0100000 &&
 		    ch[C_NAMESIZE] >= mypathsize &&
 		    !memcmp(p, path, mypathsize)) {
-			*nextoff = (long)nptr - (long)data;
+
+			if (nextoff)
+				*nextoff = (long)nptr - (long)data;
+
 			if (ch[C_NAMESIZE] - mypathsize >= MAX_CPIO_FILE_NAME) {
 				pr_warn(
 				"File %s exceeding MAX_CPIO_FILE_NAME [%d]\n",

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [tip:x86/microcode] x86/microcode: Get rid of find_cpio_data()'s dummy offset arg
  2016-06-06 15:10 ` [PATCH 4/9] x86/microcode: Get rid of find_cpio_data()'s dummy offset arg Borislav Petkov
@ 2016-06-08  9:53   ` tip-bot for Borislav Petkov
  0 siblings, 0 replies; 19+ messages in thread
From: tip-bot for Borislav Petkov @ 2016-06-08  9:53 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: bp, mingo, linux-kernel, torvalds, peterz, dvlasenk, luto, tglx,
	bp, brgerst, hpa

Commit-ID:  852ad5b94524fd76d49944b9db0a93f7c9ee5814
Gitweb:     http://git.kernel.org/tip/852ad5b94524fd76d49944b9db0a93f7c9ee5814
Author:     Borislav Petkov <bp@suse.de>
AuthorDate: Mon, 6 Jun 2016 17:10:45 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 8 Jun 2016 11:04:19 +0200

x86/microcode: Get rid of find_cpio_data()'s dummy offset arg

The microcode loader doesn't use it and now that that arg has been made
optional in find_cpio_data(), get rid of it here.

No functionality change.

Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1465225850-7352-5-git-send-email-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/cpu/microcode/amd.c   | 3 +--
 arch/x86/kernel/cpu/microcode/intel.c | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 11dd1cc..b1d1e34 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -64,7 +64,6 @@ static struct cpio_data ucode_cpio;
 static struct cpio_data __init find_ucode_in_initrd(void)
 {
 #ifdef CONFIG_BLK_DEV_INITRD
-	long offset = 0;
 	char *path;
 	void *start;
 	size_t size;
@@ -92,7 +91,7 @@ static struct cpio_data __init find_ucode_in_initrd(void)
 	size    = boot_params.hdr.ramdisk_size;
 #endif /* !CONFIG_X86_32 */
 
-	return find_cpio_data(path, start, size, &offset);
+	return find_cpio_data(path, start, size, NULL);
 #else
 	return (struct cpio_data){ NULL, 0, "" };
 #endif
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 5835d5b..2ad40b7 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -685,7 +685,6 @@ static __init enum ucode_state
 __scan_microcode_initrd(struct cpio_data *cd, struct ucode_blobs *blbp)
 {
 #ifdef CONFIG_BLK_DEV_INITRD
-	long offset = 0;
 	static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin";
 	char *p = IS_ENABLED(CONFIG_X86_32) ? (char *)__pa_nodebug(ucode_name)
 						    : ucode_name;
@@ -716,7 +715,7 @@ __scan_microcode_initrd(struct cpio_data *cd, struct ucode_blobs *blbp)
 	}
 # endif
 
-	*cd = find_cpio_data(p, (void *)start, size, &offset);
+	*cd = find_cpio_data(p, (void *)start, size, NULL);
 	if (cd->data) {
 		blbp->start = start;
 		blbp->valid = true;

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [tip:x86/microcode] x86/microcode: Propagate save_microcode_in_initrd() retval
  2016-06-06 15:10 ` [PATCH 5/9] x86/microcode: Propagate save_microcode_in_initrd() retval Borislav Petkov
@ 2016-06-08  9:53   ` tip-bot for Borislav Petkov
  0 siblings, 0 replies; 19+ messages in thread
From: tip-bot for Borislav Petkov @ 2016-06-08  9:53 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: dvlasenk, torvalds, hpa, linux-kernel, mingo, tglx, brgerst,
	luto, bp, bp, peterz

Commit-ID:  fa6788b8c681ffe0a1bf9f99dddc2c447069241c
Gitweb:     http://git.kernel.org/tip/fa6788b8c681ffe0a1bf9f99dddc2c447069241c
Author:     Borislav Petkov <bp@suse.de>
AuthorDate: Mon, 6 Jun 2016 17:10:46 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 8 Jun 2016 11:04:20 +0200

x86/microcode: Propagate save_microcode_in_initrd() retval

Will be used in a later patch. No functionality change.

Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1465225850-7352-6-git-send-email-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/cpu/microcode/core.c  | 6 +++---
 arch/x86/kernel/cpu/microcode/intel.c | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index 12823b6..9ae7fca 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -182,17 +182,17 @@ static int __init save_microcode_in_initrd(void)
 	switch (c->x86_vendor) {
 	case X86_VENDOR_INTEL:
 		if (c->x86 >= 6)
-			save_microcode_in_initrd_intel();
+			return save_microcode_in_initrd_intel();
 		break;
 	case X86_VENDOR_AMD:
 		if (c->x86 >= 0x10)
-			save_microcode_in_initrd_amd();
+			return save_microcode_in_initrd_amd();
 		break;
 	default:
 		break;
 	}
 
-	return 0;
+	return -EINVAL;
 }
 
 void reload_early_microcode(void)
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 2ad40b7..d852ca9 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -675,8 +675,8 @@ int __init save_microcode_in_initrd_intel(void)
 	ret = save_microcode(&mc_saved_data, mc_saved, count);
 	if (ret)
 		pr_err("Cannot save microcode patches from initrd.\n");
-
-	show_saved_mc();
+	else
+		show_saved_mc();
 
 	return ret;
 }

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [tip:x86/microcode] x86/microcode/intel: Rename load_microcode_early() to find_microcode_patch()
  2016-06-06 15:10 ` [PATCH 6/9] x86/microcode/intel: Rename load_microcode_early() to find_microcode_patch() Borislav Petkov
@ 2016-06-08  9:54   ` tip-bot for Borislav Petkov
  0 siblings, 0 replies; 19+ messages in thread
From: tip-bot for Borislav Petkov @ 2016-06-08  9:54 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, brgerst, peterz, bp, dvlasenk, tglx, bp, torvalds,
	hpa, mingo, luto

Commit-ID:  9198251af1554c21fae8e43a940a8bed435ee1b3
Gitweb:     http://git.kernel.org/tip/9198251af1554c21fae8e43a940a8bed435ee1b3
Author:     Borislav Petkov <bp@suse.de>
AuthorDate: Mon, 6 Jun 2016 17:10:47 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 8 Jun 2016 11:04:20 +0200

x86/microcode/intel: Rename load_microcode_early() to find_microcode_patch()

This function does exactly that: it goes through the previously saved
array of microcode blobs and finds the proper one for the current CPU.
Rename it accordingly.

No functionality change.

Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1465225850-7352-7-git-send-email-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/cpu/microcode/intel.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index d852ca9..b5759a3 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -58,7 +58,7 @@ static struct ucode_blobs {
 } blobs;
 
 static enum ucode_state
-load_microcode_early(struct microcode_intel **saved,
+find_microcode_patch(struct microcode_intel **saved,
 		     unsigned int num_saved, struct ucode_cpu_info *uci)
 {
 	struct microcode_intel *ucode_ptr, *new_mc = NULL;
@@ -127,13 +127,13 @@ load_microcode(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
 	if (!mcs->mc_saved) {
 		copy_ptrs(mc_saved_tmp, mc_ptrs, offset, count);
 
-		return load_microcode_early(mc_saved_tmp, count, uci);
+		return find_microcode_patch(mc_saved_tmp, count, uci);
 	} else {
 #ifdef CONFIG_X86_32
 		microcode_phys(mc_saved_tmp, mcs);
-		return load_microcode_early(mc_saved_tmp, count, uci);
+		return find_microcode_patch(mc_saved_tmp, count, uci);
 #else
-		return load_microcode_early(mcs->mc_saved, count, uci);
+		return find_microcode_patch(mcs->mc_saved, count, uci);
 #endif
 	}
 }
@@ -834,7 +834,7 @@ void reload_ucode_intel(void)
 
 	collect_cpu_info_early(&uci);
 
-	ret = load_microcode_early(mc_saved_data.mc_saved,
+	ret = find_microcode_patch(mc_saved_data.mc_saved,
 				   mc_saved_data.num_saved, &uci);
 	if (ret != UCODE_OK)
 		return;

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [tip:x86/microcode] x86/microcode/intel: Unexport save_mc_for_early()
  2016-06-06 15:10 ` [PATCH 7/9] x86/microcode/intel: Unexport save_mc_for_early() Borislav Petkov
@ 2016-06-08  9:54   ` tip-bot for Borislav Petkov
  0 siblings, 0 replies; 19+ messages in thread
From: tip-bot for Borislav Petkov @ 2016-06-08  9:54 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, torvalds, brgerst, luto, mingo, dvlasenk, bp, tglx,
	bp, hpa, peterz

Commit-ID:  0c5fa827f1130d05858f158022c21e9e7e5cff92
Gitweb:     http://git.kernel.org/tip/0c5fa827f1130d05858f158022c21e9e7e5cff92
Author:     Borislav Petkov <bp@suse.de>
AuthorDate: Mon, 6 Jun 2016 17:10:48 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 8 Jun 2016 11:04:20 +0200

x86/microcode/intel: Unexport save_mc_for_early()

It is used only in intel.c, drop the CONFIG_HOTPLUG_CPU ifdeffery from
the header and turn it into a void function because its return value
wasn't being used anyway.

No functionality change.

Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1465225850-7352-8-git-send-email-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/microcode_intel.h |  5 -----
 arch/x86/kernel/cpu/microcode/intel.c  | 15 ++++++---------
 2 files changed, 6 insertions(+), 14 deletions(-)

diff --git a/arch/x86/include/asm/microcode_intel.h b/arch/x86/include/asm/microcode_intel.h
index 603417f..5e69154 100644
--- a/arch/x86/include/asm/microcode_intel.h
+++ b/arch/x86/include/asm/microcode_intel.h
@@ -70,9 +70,4 @@ static inline int __init save_microcode_in_initrd_intel(void) { return -EINVAL;
 static inline void reload_ucode_intel(void) {}
 #endif
 
-#ifdef CONFIG_HOTPLUG_CPU
-extern int save_mc_for_early(u8 *mc);
-#else
-static inline int save_mc_for_early(u8 *mc) { return 0; }
-#endif
 #endif /* _ASM_X86_MICROCODE_INTEL_H */
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index b5759a3..359e203 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -456,8 +456,6 @@ static void show_saved_mc(void)
 #endif
 }
 
-#ifdef CONFIG_HOTPLUG_CPU
-static DEFINE_MUTEX(x86_cpu_microcode_mutex);
 /*
  * Save this mc into mc_saved_data. So it will be loaded early when a CPU is
  * hot added or resumes.
@@ -465,14 +463,16 @@ static DEFINE_MUTEX(x86_cpu_microcode_mutex);
  * Please make sure this mc should be a valid microcode patch before calling
  * this function.
  */
-int save_mc_for_early(u8 *mc)
+static void save_mc_for_early(u8 *mc)
 {
+#ifdef CONFIG_HOTPLUG_CPU
+	static DEFINE_MUTEX(x86_cpu_microcode_mutex);
+
 	struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
 	unsigned int mc_saved_count_init;
 	unsigned int num_saved;
 	struct microcode_intel **mc_saved;
-	int ret = 0;
-	int i;
+	int ret, i;
 
 	/*
 	 * Hold hotplug lock so mc_saved_data is not accessed by a CPU in
@@ -515,11 +515,8 @@ int save_mc_for_early(u8 *mc)
 
 out:
 	mutex_unlock(&x86_cpu_microcode_mutex);
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(save_mc_for_early);
 #endif
+}
 
 static bool __init load_builtin_intel_microcode(struct cpio_data *cp)
 {

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [tip:x86/microcode] x86/microcode/AMD: Make amd_ucode_patch[] static
  2016-06-06 15:10 ` [PATCH 8/9] x86/microcode/AMD: Make amd_ucode_patch static Borislav Petkov
@ 2016-06-08  9:55   ` tip-bot for Borislav Petkov
  0 siblings, 0 replies; 19+ messages in thread
From: tip-bot for Borislav Petkov @ 2016-06-08  9:55 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, tglx, bp, hpa, mingo, linux-kernel, torvalds, dvlasenk,
	brgerst, bp, luto

Commit-ID:  a13004a2449c56a83d5816e81d850ea92b6837c2
Gitweb:     http://git.kernel.org/tip/a13004a2449c56a83d5816e81d850ea92b6837c2
Author:     Borislav Petkov <bp@suse.de>
AuthorDate: Mon, 6 Jun 2016 17:10:49 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 8 Jun 2016 11:04:20 +0200

x86/microcode/AMD: Make amd_ucode_patch[] static

It is used only in amd.c now.

No functionality change.

Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1465225850-7352-9-git-send-email-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/microcode_amd.h | 1 -
 arch/x86/kernel/cpu/microcode/amd.c  | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h
index adfc847..15eb754 100644
--- a/arch/x86/include/asm/microcode_amd.h
+++ b/arch/x86/include/asm/microcode_amd.h
@@ -62,7 +62,6 @@ extern int apply_microcode_amd(int cpu);
 extern enum ucode_state load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size);
 
 #define PATCH_MAX_SIZE PAGE_SIZE
-extern u8 amd_ucode_patch[PATCH_MAX_SIZE];
 
 #ifdef CONFIG_MICROCODE_AMD
 extern void __init load_ucode_amd_bsp(unsigned int family);
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index b1d1e34..27a0228 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -56,7 +56,7 @@ static u8 *container;
 static size_t container_size;
 
 static u32 ucode_new_rev;
-u8 amd_ucode_patch[PATCH_MAX_SIZE];
+static u8 amd_ucode_patch[PATCH_MAX_SIZE];
 static u16 this_equiv_id;
 
 static struct cpio_data ucode_cpio;

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [tip:x86/microcode] Documentation/microcode: Document some aspects for more clarity
  2016-06-06 15:10 ` [PATCH 9/9] Documentation/microcode: Document some aspects for more clarity Borislav Petkov
@ 2016-06-08  9:55   ` tip-bot for Borislav Petkov
  0 siblings, 0 replies; 19+ messages in thread
From: tip-bot for Borislav Petkov @ 2016-06-08  9:55 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: bp, brgerst, dvlasenk, torvalds, bp, luto, hpa, peterz, mingo,
	linux-kernel, tglx

Commit-ID:  9f3cc2a0772d7744d1d7195d39ac4794af622fe6
Gitweb:     http://git.kernel.org/tip/9f3cc2a0772d7744d1d7195d39ac4794af622fe6
Author:     Borislav Petkov <bp@suse.de>
AuthorDate: Mon, 6 Jun 2016 17:10:50 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 8 Jun 2016 11:04:20 +0200

Documentation/microcode: Document some aspects for more clarity

Document that builtin microcode is 64-bit only. Also, improve/add
comments to places.

Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-doc@vger.kernel.org
Link: http://lkml.kernel.org/r/1465225850-7352-10-git-send-email-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 Documentation/x86/early-microcode.txt |  5 ++++-
 arch/x86/kernel/cpu/microcode/intel.c | 16 +++++++++-------
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/Documentation/x86/early-microcode.txt b/Documentation/x86/early-microcode.txt
index c956d99..07749e7 100644
--- a/Documentation/x86/early-microcode.txt
+++ b/Documentation/x86/early-microcode.txt
@@ -45,7 +45,10 @@ Builtin microcode
 =================
 
 We can also load builtin microcode supplied through the regular firmware
-builtin method CONFIG_FIRMWARE_IN_KERNEL. Here's an example:
+builtin method CONFIG_FIRMWARE_IN_KERNEL. Only 64-bit is currently
+supported.
+
+Here's an example:
 
 CONFIG_FIRMWARE_IN_KERNEL=y
 CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin"
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 359e203..8962d6a 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -40,9 +40,13 @@
 #include <asm/msr.h>
 
 /*
- * Temporary microcode blobs pointers storage. We note here the pointers to
- * microcode blobs we've got from whatever storage (detached initrd, builtin).
- * Later on, we put those into final storage mc_saved_data.mc_saved.
+ * Temporary microcode blobs pointers storage. We note here during early load
+ * the pointers to microcode blobs we've got from whatever storage (detached
+ * initrd, builtin). Later on, we put those into final storage
+ * mc_saved_data.mc_saved.
+ *
+ * Important: those are offsets from the beginning of initrd or absolute
+ * addresses within the kernel image when built-in.
  */
 static unsigned long mc_tmp_ptrs[MAX_UCODE_COUNT];
 
@@ -57,6 +61,7 @@ static struct ucode_blobs {
 	bool valid;
 } blobs;
 
+/* Go through saved patches and find the one suitable for the current CPU. */
 static enum ucode_state
 find_microcode_patch(struct microcode_intel **saved,
 		     unsigned int num_saved, struct ucode_cpu_info *uci)
@@ -466,6 +471,7 @@ static void show_saved_mc(void)
 static void save_mc_for_early(u8 *mc)
 {
 #ifdef CONFIG_HOTPLUG_CPU
+	/* Synchronization during CPU hotplug. */
 	static DEFINE_MUTEX(x86_cpu_microcode_mutex);
 
 	struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
@@ -474,10 +480,6 @@ static void save_mc_for_early(u8 *mc)
 	struct microcode_intel **mc_saved;
 	int ret, i;
 
-	/*
-	 * Hold hotplug lock so mc_saved_data is not accessed by a CPU in
-	 * hotplug.
-	 */
 	mutex_lock(&x86_cpu_microcode_mutex);
 
 	mc_saved_count_init = mc_saved_data.num_saved;

^ permalink raw reply related	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2016-06-08  9:56 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-06 15:10 [PATCH 0/9] x86/microcode: Fixes for builtin vs initrd loading; cleanups Borislav Petkov
2016-06-06 15:10 ` [PATCH 1/9] x86/microcode: Fix loading precedence Borislav Petkov
2016-06-08  9:51   ` [tip:x86/microcode] " tip-bot for Borislav Petkov
2016-06-06 15:10 ` [PATCH 2/9] x86/microcode: Fix suspend to RAM with builtin microcode Borislav Petkov
2016-06-08  9:52   ` [tip:x86/microcode] " tip-bot for Borislav Petkov
2016-06-06 15:10 ` [PATCH 3/9] lib/cpio: Make find_cpio_data()'s offset arg optional Borislav Petkov
2016-06-08  9:52   ` [tip:x86/microcode] " tip-bot for Borislav Petkov
2016-06-06 15:10 ` [PATCH 4/9] x86/microcode: Get rid of find_cpio_data()'s dummy offset arg Borislav Petkov
2016-06-08  9:53   ` [tip:x86/microcode] " tip-bot for Borislav Petkov
2016-06-06 15:10 ` [PATCH 5/9] x86/microcode: Propagate save_microcode_in_initrd() retval Borislav Petkov
2016-06-08  9:53   ` [tip:x86/microcode] " tip-bot for Borislav Petkov
2016-06-06 15:10 ` [PATCH 6/9] x86/microcode/intel: Rename load_microcode_early() to find_microcode_patch() Borislav Petkov
2016-06-08  9:54   ` [tip:x86/microcode] " tip-bot for Borislav Petkov
2016-06-06 15:10 ` [PATCH 7/9] x86/microcode/intel: Unexport save_mc_for_early() Borislav Petkov
2016-06-08  9:54   ` [tip:x86/microcode] " tip-bot for Borislav Petkov
2016-06-06 15:10 ` [PATCH 8/9] x86/microcode/AMD: Make amd_ucode_patch static Borislav Petkov
2016-06-08  9:55   ` [tip:x86/microcode] x86/microcode/AMD: Make amd_ucode_patch[] static tip-bot for Borislav Petkov
2016-06-06 15:10 ` [PATCH 9/9] Documentation/microcode: Document some aspects for more clarity Borislav Petkov
2016-06-08  9:55   ` [tip:x86/microcode] " tip-bot for Borislav Petkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).