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


Groups > linux.kernel > #1560860 > unrolled thread

[PATCH 00/13] x86/microcode: 4.11 queue

Started byBorislav Petkov <bp@alien8.de>
First post2017-01-17 18:50 +0100
Last post2017-01-17 21:50 +0100
Articles 14 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 00/13] x86/microcode: 4.11 queue Borislav Petkov <bp@alien8.de> - 2017-01-17 18:50 +0100
    [PATCH 12/13] x86/microcode/AMD: Simplify saving from initrd Borislav Petkov <bp@alien8.de> - 2017-01-17 18:50 +0100
      Re: [PATCH 12/13] x86/microcode/AMD: Simplify saving from initrd Thomas Gleixner <tglx@linutronix.de> - 2017-01-17 22:20 +0100
    [PATCH 11/13] x86/microcode/AMD: Unify load_ucode_amd_ap() Borislav Petkov <bp@alien8.de> - 2017-01-17 18:50 +0100
      Re: [PATCH 11/13] x86/microcode/AMD: Unify load_ucode_amd_ap() Thomas Gleixner <tglx@linutronix.de> - 2017-01-17 22:00 +0100
        Re: [PATCH 11/13] x86/microcode/AMD: Unify load_ucode_amd_ap() Thomas Gleixner <tglx@linutronix.de> - 2017-01-17 22:20 +0100
    [PATCH 05/13] x86/microcode/AMD: Extend the container struct Borislav Petkov <bp@alien8.de> - 2017-01-17 18:50 +0100
      Re: [PATCH 05/13] x86/microcode/AMD: Extend the container struct Thomas Gleixner <tglx@linutronix.de> - 2017-01-17 21:50 +0100
    [PATCH 09/13] x86/microcode/AMD: Use find_microcode_in_initrd() Borislav Petkov <bp@alien8.de> - 2017-01-17 18:50 +0100
      Re: [PATCH 09/13] x86/microcode/AMD: Use  find_microcode_in_initrd() Thomas Gleixner <tglx@linutronix.de> - 2017-01-17 22:20 +0100
    [PATCH 04/13] x86/microcode/AMD: Shorten function parameter's name Borislav Petkov <bp@alien8.de> - 2017-01-17 18:50 +0100
      Re: [PATCH 04/13] x86/microcode/AMD: Shorten function parameter's  name Thomas Gleixner <tglx@linutronix.de> - 2017-01-17 21:10 +0100
    [PATCH 10/13] x86/microcode/AMD: Check patch level only on the BSP Borislav Petkov <bp@alien8.de> - 2017-01-17 18:50 +0100
      Re: [PATCH 10/13] x86/microcode/AMD: Check patch level only on the  BSP Thomas Gleixner <tglx@linutronix.de> - 2017-01-17 21:50 +0100

#1560860 — [PATCH 00/13] x86/microcode: 4.11 queue

FromBorislav Petkov <bp@alien8.de>
Date2017-01-17 18:50 +0100
Subject[PATCH 00/13] x86/microcode: 4.11 queue
Message-ID<t0FTI-1vq-27@gated-at.bofh.it>
From: Borislav Petkov <bp@suse.de>

Hi,

so this is more of a lessons-learned pile after the rewriting of the
whole patch loading method and not caching addresses. It largely
simplifies the loader - just look at the diffstat - without any
functionality loss (I hope :-)). The driver is also very much readable
now with unified, common paths where possible.

What is more, 6/13 reworks the whole AMD container parsing into much
more readable separation of functionality and functions doing only one
thing properly.

13/13 is also another nice simplification for the AP update path which
looks almost straightforward in comparison with what we had before.

All has been tested on a lot of boxes and in different configurations:

* builtin vs initrd microcode
* old microcode_ctl application method for Intel
* "echo 1 > /sys/devices/system/cpu/microcode/reload" late method
* CONFIG_RANDOMIZE_MEMORY

both on Intel and AMD machines.

Please queue for 4.11.

Thanks.

Borislav Petkov (13):
  x86/microcode/intel: Drop stashed AP patch pointer optimization
  x86/microcode: Use own MSR accessors
  x86/microcode/AMD: Clean up find_equiv_id()
  x86/microcode/AMD: Shorten function parameter's name
  x86/microcode/AMD: Extend the container struct
  x86/microcode/AMD: Rework container parsing
  x86/microcode: Decrease CPUID use
  x86/microcode/AMD: Get rid of global this_equiv_id
  x86/microcode/AMD: Use find_microcode_in_initrd()
  x86/microcode/AMD: Check patch level only on the BSP
  x86/microcode/AMD: Unify load_ucode_amd_ap()
  x86/microcode/AMD: Simplify saving from initrd
  x86/microcode/AMD: Remove AP scanning optimization

 arch/x86/include/asm/microcode.h       |  29 +-
 arch/x86/include/asm/microcode_amd.h   |   2 -
 arch/x86/include/asm/microcode_intel.h |   4 +-
 arch/x86/kernel/cpu/microcode/amd.c    | 501 +++++++++++----------------------
 arch/x86/kernel/cpu/microcode/core.c   |  81 ++++--
 arch/x86/kernel/cpu/microcode/intel.c  |  13 +-
 6 files changed, 248 insertions(+), 382 deletions(-)

-- 
2.11.0

[toc] | [next] | [standalone]


#1560864 — [PATCH 12/13] x86/microcode/AMD: Simplify saving from initrd

FromBorislav Petkov <bp@alien8.de>
Date2017-01-17 18:50 +0100
Subject[PATCH 12/13] x86/microcode/AMD: Simplify saving from initrd
Message-ID<t0G3o-1zz-39@gated-at.bofh.it>
In reply to#1560860
From: Borislav Petkov <bp@suse.de>

No need to use the previously stashed info in the container - simply go
ahead and parse the initrd once more. It simplifies and streamlines the
code a whole lot.

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

diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index f1a61f181c9a..1ee33793c74a 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -379,43 +379,26 @@ load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size);
 
 int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)
 {
+	struct cont_desc desc;
 	enum ucode_state ret;
-	int retval = 0;
-
-	if (!cont.data) {
-		if (IS_ENABLED(CONFIG_X86_32) && (cont.size != -1)) {
-			struct cpio_data cp;
-
-			cp = find_microcode_in_initrd(ucode_path, false);
-			if (!(cp.data && cp.size)) {
-				cont.size = -1;
-				return -EINVAL;
-			}
+	struct cpio_data cp;
 
-			cont.cpuid_1_eax = cpuid_1_eax;
+	cp = find_microcode_in_initrd(ucode_path, false);
+	if (!(cp.data && cp.size))
+		return -EINVAL;
 
-			scan_containers(cp.data, cp.size, &cont);
-			if (!cont.eq_id) {
-				cont.size = -1;
-				return -EINVAL;
-			}
+	desc.cpuid_1_eax = cpuid_1_eax;
 
-		} else
-			return -EINVAL;
-	}
+	scan_containers(cp.data, cp.size, &desc);
+	if (!desc.eq_id)
+		return -EINVAL;
 
-	ret = load_microcode_amd(smp_processor_id(), x86_family(cpuid_1_eax), cont.data, cont.size);
+	ret = load_microcode_amd(smp_processor_id(), x86_family(cpuid_1_eax),
+				 desc.data, desc.size);
 	if (ret != UCODE_OK)
-		retval = -EINVAL;
-
-	/*
-	 * This will be freed any msec now, stash patches for the current
-	 * family and switch to patch cache for cpu hotplug, etc later.
-	 */
-	cont.data = NULL;
-	cont.size = 0;
+		return -EINVAL;
 
-	return retval;
+	return 0;
 }
 
 void reload_ucode_amd(void)
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1561025 — Re: [PATCH 12/13] x86/microcode/AMD: Simplify saving from initrd

FromThomas Gleixner <tglx@linutronix.de>
Date2017-01-17 22:20 +0100
SubjectRe: [PATCH 12/13] x86/microcode/AMD: Simplify saving from initrd
Message-ID<t0JkB-3Kd-7@gated-at.bofh.it>
In reply to#1560864
On Tue, 17 Jan 2017, Borislav Petkov wrote:

> From: Borislav Petkov <bp@suse.de>
> 
> No need to use the previously stashed info in the container - simply go
> ahead and parse the initrd once more. It simplifies and streamlines the
> code a whole lot.
> 
> Signed-off-by: Borislav Petkov <bp@suse.de>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

[toc] | [prev] | [next] | [standalone]


#1560865 — [PATCH 11/13] x86/microcode/AMD: Unify load_ucode_amd_ap()

FromBorislav Petkov <bp@alien8.de>
Date2017-01-17 18:50 +0100
Subject[PATCH 11/13] x86/microcode/AMD: Unify load_ucode_amd_ap()
Message-ID<t0G3o-1zz-37@gated-at.bofh.it>
In reply to#1560860
From: Borislav Petkov <bp@suse.de>

Use a version for both bitness by adding a helper which does the actual
container finding and parsing which can be used on any CPU - BSP or AP.
Streamlines the paths more.

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

diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 782e01311e4e..f1a61f181c9a 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -271,7 +271,7 @@ static bool get_builtin_microcode(struct cpio_data *cp, unsigned int family)
 #endif
 }
 
-void __init load_ucode_amd_bsp(unsigned int cpuid_1_eax)
+void __load_ucode_amd(unsigned int cpuid_1_eax, struct cpio_data *ret)
 {
 	struct ucode_cpu_info *uci;
 	struct cpio_data cp;
@@ -291,95 +291,74 @@ void __init load_ucode_amd_bsp(unsigned int cpuid_1_eax)
 	if (!get_builtin_microcode(&cp, x86_family(cpuid_1_eax)))
 		cp = find_microcode_in_initrd(path, use_pa);
 
-	if (!(cp.data && cp.size))
-		return;
-
 	/* Needed in load_microcode_amd() */
 	uci->cpu_sig.sig = cpuid_1_eax;
 
-	apply_microcode_early_amd(cpuid_1_eax, cp.data, cp.size, true, NULL);
+	*ret = cp;
 }
 
-#ifdef CONFIG_X86_32
-/*
- * On 32-bit, since AP's early load occurs before paging is turned on, we
- * cannot traverse cpu_equiv_table and microcode_cache in kernel heap memory.
- * So during cold boot, AP will apply_ucode_in_initrd() just like the BSP.
- * In save_microcode_in_initrd_amd() BSP's patch is copied to amd_ucode_patch,
- * which is used upon resume from suspend.
- */
-void load_ucode_amd_ap(unsigned int cpuid_1_eax)
+void __init load_ucode_amd_bsp(unsigned int cpuid_1_eax)
 {
-	struct microcode_amd *mc;
-	struct cpio_data cp;
-
-	mc = (struct microcode_amd *)__pa_nodebug(amd_ucode_patch);
-	if (mc->hdr.patch_id && mc->hdr.processor_rev_id) {
-		__apply_microcode_amd(mc);
-		return;
-	}
+	struct cpio_data cp = { };
 
-	if (!get_builtin_microcode(&cp, x86_family(cpuid_1_eax)))
-		cp = find_microcode_in_initrd((const char *)__pa_nodebug(ucode_path), true);
+	__load_ucode_amd(cpuid_1_eax, &cp);
 
 	if (!(cp.data && cp.size))
 		return;
 
-	/*
-	 * This would set amd_ucode_patch above so that the following APs can
-	 * use it directly instead of going down this path again.
-	 */
 	apply_microcode_early_amd(cpuid_1_eax, cp.data, cp.size, true, NULL);
 }
-#else
+
 void load_ucode_amd_ap(unsigned int cpuid_1_eax)
 {
 	struct equiv_cpu_entry *eq;
 	struct microcode_amd *mc;
+	struct cont_desc *desc;
 	u16 eq_id;
 
+	if (IS_ENABLED(CONFIG_X86_32)) {
+		mc   = (struct microcode_amd *)__pa_nodebug(amd_ucode_patch);
+		desc = (struct cont_desc *)__pa_nodebug(&cont);
+	} else {
+		mc   = (struct microcode_amd *)amd_ucode_patch;
+		desc = &cont;
+	}
+
 	/* First AP hasn't cached it yet, go through the blob. */
-	if (!cont.data) {
-		struct cpio_data cp;
+	if (!desc->data) {
+		struct cpio_data cp = { };
 
-		if (cont.size == -1)
+		if (desc->size == -1)
 			return;
 
 reget:
-		if (!get_builtin_microcode(&cp, x86_family(cpuid_1_eax))) {
-			cp = find_microcode_in_initrd(ucode_path, false);
-
-			if (!(cp.data && cp.size)) {
-				/*
-				 * Mark it so that other APs do not scan again
-				 * for no real reason and slow down boot
-				 * needlessly.
-				 */
-				cont.size = -1;
-				return;
-			}
+		__load_ucode_amd(cpuid_1_eax, &cp);
+		if (!(cp.data && cp.size)) {
+			/*
+			 * Mark it so that other APs do not scan again for no
+			 * real reason and slow down boot needlessly.
+			 */
+			desc->size = -1;
+			return;
 		}
 
-		if (!apply_microcode_early_amd(cpuid_1_eax, cp.data, cp.size, false, &cont)) {
-			cont.data = NULL;
-			cont.size = -1;
+		if (!apply_microcode_early_amd(cpuid_1_eax, cp.data, cp.size, false, desc)) {
+			desc->data = NULL;
+			desc->size = -1;
 			return;
 		}
 	}
 
-	eq  = (struct equiv_cpu_entry *)(cont.data + CONTAINER_HDR_SZ);
+	eq  = (struct equiv_cpu_entry *)(desc->data + CONTAINER_HDR_SZ);
 
 	eq_id = find_equiv_id(eq, cpuid_1_eax);
 	if (!eq_id)
 		return;
 
-	if (eq_id == cont.eq_id) {
+	if (eq_id == desc->eq_id) {
 		u32 rev, dummy;
 
 		microcode_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
-
-		mc = (struct microcode_amd *)amd_ucode_patch;
-
 		if (mc && rev < mc->hdr.patch_id) {
 			if (!__apply_microcode_amd(mc))
 				ucode_new_rev = mc->hdr.patch_id;
@@ -394,7 +373,6 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax)
 		goto reget;
 	}
 }
-#endif /* CONFIG_X86_32 */
 
 static enum ucode_state
 load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size);
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1561014 — Re: [PATCH 11/13] x86/microcode/AMD: Unify load_ucode_amd_ap()

FromThomas Gleixner <tglx@linutronix.de>
Date2017-01-17 22:00 +0100
SubjectRe: [PATCH 11/13] x86/microcode/AMD: Unify load_ucode_amd_ap()
Message-ID<t0J1g-3nu-3@gated-at.bofh.it>
In reply to#1560865
On Tue, 17 Jan 2017, Borislav Petkov wrote:
>  void load_ucode_amd_ap(unsigned int cpuid_1_eax)
>  {
>  	struct equiv_cpu_entry *eq;
>  	struct microcode_amd *mc;
> +	struct cont_desc *desc;
>  	u16 eq_id;
>  
> +	if (IS_ENABLED(CONFIG_X86_32)) {
> +		mc   = (struct microcode_amd *)__pa_nodebug(amd_ucode_patch);
> +		desc = (struct cont_desc *)__pa_nodebug(&cont);
> +	} else {
> +		mc   = (struct microcode_amd *)amd_ucode_patch;
> +		desc = &cont;

Bah! Now I realize that 'cont' is not a local variable as I assumed when
looking at the other patch. 'cont' is a pretty bad name for a (file) global
variable. Can we please use a more obvious name ?

While at it please make that thing static as there cant be a user outside
of that file.

> +	}
> +
>  	/* First AP hasn't cached it yet, go through the blob. */
> -	if (!cont.data) {
> -		struct cpio_data cp;
> +	if (!desc->data) {
> +		struct cpio_data cp = { };
>  
> -		if (cont.size == -1)
> +		if (desc->size == -1)
>  			return;

I'm not really fond of abusing the size member for this. And that '-1'
seems to have different meanings depending on other members. Really not
intuitive.

Please introduce a proper state member which tells what the descriptor
struct contains, i.e. EMPTY, VALID, INVALID ....

Thanks,

	tglx

[toc] | [prev] | [next] | [standalone]


#1561031 — Re: [PATCH 11/13] x86/microcode/AMD: Unify load_ucode_amd_ap()

FromThomas Gleixner <tglx@linutronix.de>
Date2017-01-17 22:20 +0100
SubjectRe: [PATCH 11/13] x86/microcode/AMD: Unify load_ucode_amd_ap()
Message-ID<t0JkB-3Kd-17@gated-at.bofh.it>
In reply to#1561014
On Tue, 17 Jan 2017, Thomas Gleixner wrote:

> On Tue, 17 Jan 2017, Borislav Petkov wrote:
> >  void load_ucode_amd_ap(unsigned int cpuid_1_eax)
> >  {
> >  	struct equiv_cpu_entry *eq;
> >  	struct microcode_amd *mc;
> > +	struct cont_desc *desc;
> >  	u16 eq_id;
> >  
> > +	if (IS_ENABLED(CONFIG_X86_32)) {
> > +		mc   = (struct microcode_amd *)__pa_nodebug(amd_ucode_patch);
> > +		desc = (struct cont_desc *)__pa_nodebug(&cont);
> > +	} else {
> > +		mc   = (struct microcode_amd *)amd_ucode_patch;
> > +		desc = &cont;
> 
> Bah! Now I realize that 'cont' is not a local variable as I assumed when
> looking at the other patch. 'cont' is a pretty bad name for a (file) global
> variable. Can we please use a more obvious name ?
> 
> While at it please make that thing static as there cant be a user outside
> of that file.
> 
> > +	}
> > +
> >  	/* First AP hasn't cached it yet, go through the blob. */
> > -	if (!cont.data) {
> > -		struct cpio_data cp;
> > +	if (!desc->data) {
> > +		struct cpio_data cp = { };
> >  
> > -		if (cont.size == -1)
> > +		if (desc->size == -1)
> >  			return;
> 
> I'm not really fond of abusing the size member for this. And that '-1'
> seems to have different meanings depending on other members. Really not
> intuitive.
> 
> Please introduce a proper state member which tells what the descriptor
> struct contains, i.e. EMPTY, VALID, INVALID ....

Reading further through the series I see that you remove all that cruft at
the end. Dammit, I never start reading books in the final chapter, maybe I
should do that with patch series :)

It might be nice nevertheless to have an initial patch which cleans up the
name of that 'cont' variable and that status thing, but it might not be
worth the trouble as you remove it at the end anyway, which makes a lot of
sense btw. Your call.

Thanks,

	tglx

[toc] | [prev] | [next] | [standalone]


#1560866 — [PATCH 05/13] x86/microcode/AMD: Extend the container struct

FromBorislav Petkov <bp@alien8.de>
Date2017-01-17 18:50 +0100
Subject[PATCH 05/13] x86/microcode/AMD: Extend the container struct
Message-ID<t0G3o-1zz-41@gated-at.bofh.it>
In reply to#1560860
From: Borislav Petkov <bp@suse.de>

Make it into a container descriptor which is being passed around and
stores important info like the matching container and the patch for the
current CPU.

Later patches will use this and thus get rid of a double container
parsing.

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

diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index ef36b613db62..7073588a2a09 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -42,9 +42,13 @@ static struct equiv_cpu_entry *equiv_cpu_table;
 
 /*
  * This points to the current valid container of microcode patches which we will
- * save from the initrd/builtin before jettisoning its contents.
+ * save from the initrd/builtin before jettisoning its contents. @mc is the
+ * microcode patch we found to match.
  */
-struct container {
+struct cont_desc {
+	struct microcode_amd *mc;
+	u32 psize;
+	u16 eq_id;
 	u8 *data;
 	size_t size;
 } cont;
@@ -119,9 +123,9 @@ static u16 find_equiv_id(struct equiv_cpu_entry *equiv_table, u32 sig)
  * table or 0 if none found.
  */
 static u16
-find_proper_container(u8 *ucode, size_t size, struct container *ret_cont)
+find_proper_container(u8 *ucode, size_t size, struct cont_desc *desc)
 {
-	struct container ret = { NULL, 0 };
+	struct cont_desc ret = { 0 };
 	u32 eax, ebx, ecx, edx;
 	struct equiv_cpu_entry *eq;
 	int offset, left;
@@ -164,7 +168,7 @@ find_proper_container(u8 *ucode, size_t size, struct container *ret_cont)
 			 */
 			left = ret.size - offset;
 
-			*ret_cont = ret;
+			*desc = ret;
 			return eq_id;
 		}
 
@@ -219,11 +223,11 @@ static int __apply_microcode_amd(struct microcode_amd *mc)
  * Returns true if container found (sets @ret_cont), false otherwise.
  */
 static bool apply_microcode_early_amd(void *ucode, size_t size, bool save_patch,
-				      struct container *ret_cont)
+				      struct cont_desc *desc)
 {
 	u8 (*patch)[PATCH_MAX_SIZE];
 	u32 rev, *header, *new_rev;
-	struct container ret;
+	struct cont_desc ret;
 	int offset, left;
 	u16 eq_id = 0;
 	u8  *data;
@@ -276,8 +280,8 @@ static bool apply_microcode_early_amd(void *ucode, size_t size, bool save_patch,
 		left   -= offset;
 	}
 
-	if (ret_cont)
-		*ret_cont = ret;
+	if (desc)
+		*desc = ret;
 
 	return true;
 }
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1561010 — Re: [PATCH 05/13] x86/microcode/AMD: Extend the container struct

FromThomas Gleixner <tglx@linutronix.de>
Date2017-01-17 21:50 +0100
SubjectRe: [PATCH 05/13] x86/microcode/AMD: Extend the container struct
Message-ID<t0IRz-3jt-17@gated-at.bofh.it>
In reply to#1560866
On Tue, 17 Jan 2017, Borislav Petkov wrote:
> -struct container {
> +struct cont_desc {
> +	struct microcode_amd *mc;
> +	u32 psize;
> +	u16 eq_id;
>  	u8 *data;
>  	size_t size;

While at it can you please structure the members in tabular fashion?

struct cont_desc {
	struct microcode_amd	*mc;
	u32			psize;
	...
	
Other than that:

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

[toc] | [prev] | [next] | [standalone]


#1560867 — [PATCH 09/13] x86/microcode/AMD: Use find_microcode_in_initrd()

FromBorislav Petkov <bp@alien8.de>
Date2017-01-17 18:50 +0100
Subject[PATCH 09/13] x86/microcode/AMD: Use find_microcode_in_initrd()
Message-ID<t0G3o-1zz-43@gated-at.bofh.it>
In reply to#1560860
From: Borislav Petkov <bp@suse.de>

Use the generic helper instead of semi-open-coding the procedure.

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

diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index e5cb7e73cb3b..340d636512c9 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -346,17 +346,15 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax)
 
 	/* First AP hasn't cached it yet, go through the blob. */
 	if (!cont.data) {
-		struct cpio_data cp = { NULL, 0, "" };
+		struct cpio_data cp;
 
 		if (cont.size == -1)
 			return;
 
 reget:
 		if (!get_builtin_microcode(&cp, x86_family(cpuid_1_eax))) {
-#ifdef CONFIG_BLK_DEV_INITRD
-			cp = find_cpio_data(ucode_path, (void *)initrd_start,
-					    initrd_end - initrd_start, NULL);
-#endif
+			cp = find_microcode_in_initrd(ucode_path, false);
+
 			if (!(cp.data && cp.size)) {
 				/*
 				 * Mark it so that other APs do not scan again
@@ -410,13 +408,9 @@ int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)
 
 	if (!cont.data) {
 		if (IS_ENABLED(CONFIG_X86_32) && (cont.size != -1)) {
-			struct cpio_data cp = { NULL, 0, "" };
-
-#ifdef CONFIG_BLK_DEV_INITRD
-			cp = find_cpio_data(ucode_path, (void *)initrd_start,
-					    initrd_end - initrd_start, NULL);
-#endif
+			struct cpio_data cp;
 
+			cp = find_microcode_in_initrd(ucode_path, false);
 			if (!(cp.data && cp.size)) {
 				cont.size = -1;
 				return -EINVAL;
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1561027 — Re: [PATCH 09/13] x86/microcode/AMD: Use find_microcode_in_initrd()

FromThomas Gleixner <tglx@linutronix.de>
Date2017-01-17 22:20 +0100
SubjectRe: [PATCH 09/13] x86/microcode/AMD: Use find_microcode_in_initrd()
Message-ID<t0JkB-3Kd-13@gated-at.bofh.it>
In reply to#1560867
On Tue, 17 Jan 2017, Borislav Petkov wrote:

> From: Borislav Petkov <bp@suse.de>
> 
> Use the generic helper instead of semi-open-coding the procedure.
> 
> Signed-off-by: Borislav Petkov <bp@suse.de>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

[toc] | [prev] | [next] | [standalone]


#1560868 — [PATCH 04/13] x86/microcode/AMD: Shorten function parameter's name

FromBorislav Petkov <bp@alien8.de>
Date2017-01-17 18:50 +0100
Subject[PATCH 04/13] x86/microcode/AMD: Shorten function parameter's name
Message-ID<t0G3o-1zz-45@gated-at.bofh.it>
In reply to#1560860
From: Borislav Petkov <bp@suse.de>

The whole driver calls this "mc", do that here too.

No functionality change.

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

diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 889fd61bc033..ef36b613db62 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -193,15 +193,15 @@ find_proper_container(u8 *ucode, size_t size, struct container *ret_cont)
 	return eq_id;
 }
 
-static int __apply_microcode_amd(struct microcode_amd *mc_amd)
+static int __apply_microcode_amd(struct microcode_amd *mc)
 {
 	u32 rev, dummy;
 
-	microcode_wrmsr(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc_amd->hdr.data_code);
+	microcode_wrmsr(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc->hdr.data_code);
 
 	/* verify patch application was successful */
 	microcode_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
-	if (rev != mc_amd->hdr.patch_id)
+	if (rev != mc->hdr.patch_id)
 		return -1;
 
 	return 0;
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1560973 — Re: [PATCH 04/13] x86/microcode/AMD: Shorten function parameter's name

FromThomas Gleixner <tglx@linutronix.de>
Date2017-01-17 21:10 +0100
SubjectRe: [PATCH 04/13] x86/microcode/AMD: Shorten function parameter's name
Message-ID<t0IeR-358-1@gated-at.bofh.it>
In reply to#1560868
On Tue, 17 Jan 2017, Borislav Petkov wrote:

> From: Borislav Petkov <bp@suse.de>
> 
> The whole driver calls this "mc", do that here too.
> 
> No functionality change.
> 
> Signed-off-by: Borislav Petkov <bp@suse.de>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

[toc] | [prev] | [next] | [standalone]


#1560870 — [PATCH 10/13] x86/microcode/AMD: Check patch level only on the BSP

FromBorislav Petkov <bp@alien8.de>
Date2017-01-17 18:50 +0100
Subject[PATCH 10/13] x86/microcode/AMD: Check patch level only on the BSP
Message-ID<t0G3p-1zz-49@gated-at.bofh.it>
In reply to#1560860
From: Borislav Petkov <bp@suse.de>

Check final patch levels for AMD only on the BSP. This way, we decide
early and only once whether to continue loading or to leave the loader
disabled on such systems.

Simplify a lot.

Signed-off-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/include/asm/microcode_amd.h |  2 -
 arch/x86/kernel/cpu/microcode/amd.c  | 77 ++++++------------------------------
 arch/x86/kernel/cpu/microcode/core.c | 51 +++++++++++++++++++++---
 3 files changed, 56 insertions(+), 74 deletions(-)

diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h
index 3e3e20be829a..3d57009e168b 100644
--- a/arch/x86/include/asm/microcode_amd.h
+++ b/arch/x86/include/asm/microcode_amd.h
@@ -54,6 +54,4 @@ static inline int __init
 save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; }
 void reload_ucode_amd(void) {}
 #endif
-
-extern bool check_current_patch_level(u32 *rev, bool early);
 #endif /* _ASM_X86_MICROCODE_AMD_H */
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 340d636512c9..782e01311e4e 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -216,7 +216,7 @@ apply_microcode_early_amd(u32 cpuid_1_eax, void *ucode, size_t size,
 	struct cont_desc desc = { 0 };
 	u8 (*patch)[PATCH_MAX_SIZE];
 	struct microcode_amd *mc;
-	u32 rev, *new_rev;
+	u32 rev, dummy, *new_rev;
 	bool ret = false;
 
 #ifdef CONFIG_X86_32
@@ -227,8 +227,7 @@ apply_microcode_early_amd(u32 cpuid_1_eax, void *ucode, size_t size,
 	patch	= &amd_ucode_patch;
 #endif
 
-	if (check_current_patch_level(&rev, true))
-		return ret;
+	microcode_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
 
 	desc.cpuid_1_eax = cpuid_1_eax;
 
@@ -337,13 +336,8 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax)
 {
 	struct equiv_cpu_entry *eq;
 	struct microcode_amd *mc;
-	u32 rev;
 	u16 eq_id;
 
-	/* 64-bit runs with paging enabled, thus early==false. */
-	if (check_current_patch_level(&rev, false))
-		return;
-
 	/* First AP hasn't cached it yet, go through the blob. */
 	if (!cont.data) {
 		struct cpio_data cp;
@@ -380,6 +374,10 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax)
 		return;
 
 	if (eq_id == cont.eq_id) {
+		u32 rev, dummy;
+
+		microcode_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
+
 		mc = (struct microcode_amd *)amd_ucode_patch;
 
 		if (mc && rev < mc->hdr.patch_id) {
@@ -445,19 +443,14 @@ int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)
 void reload_ucode_amd(void)
 {
 	struct microcode_amd *mc;
-	u32 rev;
-
-	/*
-	 * early==false because this is a syscore ->resume path and by
-	 * that time paging is long enabled.
-	 */
-	if (check_current_patch_level(&rev, false))
-		return;
+	u32 rev, dummy;
 
 	mc = (struct microcode_amd *)amd_ucode_patch;
 	if (!mc)
 		return;
 
+	rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
+
 	if (rev < mc->hdr.patch_id) {
 		if (!__apply_microcode_amd(mc)) {
 			ucode_new_rev = mc->hdr.patch_id;
@@ -595,60 +588,13 @@ static unsigned int verify_patch_size(u8 family, u32 patch_size,
 	return patch_size;
 }
 
-/*
- * Those patch levels cannot be updated to newer ones and thus should be final.
- */
-static u32 final_levels[] = {
-	0x01000098,
-	0x0100009f,
-	0x010000af,
-	0, /* T-101 terminator */
-};
-
-/*
- * Check the current patch level on this CPU.
- *
- * @rev: Use it to return the patch level. It is set to 0 in the case of
- * error.
- *
- * Returns:
- *  - true: if update should stop
- *  - false: otherwise
- */
-bool check_current_patch_level(u32 *rev, bool early)
-{
-	u32 lvl, dummy, i;
-	bool ret = false;
-	u32 *levels;
-
-	microcode_rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy);
-
-	if (IS_ENABLED(CONFIG_X86_32) && early)
-		levels = (u32 *)__pa_nodebug(&final_levels);
-	else
-		levels = final_levels;
-
-	for (i = 0; levels[i]; i++) {
-		if (lvl == levels[i]) {
-			lvl = 0;
-			ret = true;
-			break;
-		}
-	}
-
-	if (rev)
-		*rev = lvl;
-
-	return ret;
-}
-
 static int apply_microcode_amd(int cpu)
 {
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
 	struct microcode_amd *mc_amd;
 	struct ucode_cpu_info *uci;
 	struct ucode_patch *p;
-	u32 rev;
+	u32 rev, dummy;
 
 	BUG_ON(raw_smp_processor_id() != cpu);
 
@@ -661,8 +607,7 @@ static int apply_microcode_amd(int cpu)
 	mc_amd  = p->data;
 	uci->mc = p->data;
 
-	if (check_current_patch_level(&rev, false))
-		return -1;
+	rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
 
 	/* need to apply patch? */
 	if (rev >= mc_amd->hdr.patch_id) {
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index 437996c9be67..8650b58b4564 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -69,6 +69,42 @@ struct cpu_info_ctx {
 	int			err;
 };
 
+/*
+ * Those patch levels cannot be updated to newer ones and thus should be final.
+ */
+static u32 final_levels[] = {
+	0x01000098,
+	0x0100009f,
+	0x010000af,
+	0, /* T-101 terminator */
+};
+
+/*
+ * Check the current patch level on this CPU.
+ *
+ * Returns:
+ *  - true: if update should stop
+ *  - false: otherwise
+ */
+static bool amd_check_current_patch_level(void)
+{
+	u32 lvl, dummy, i;
+	u32 *levels;
+
+	microcode_rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy);
+
+	if (IS_ENABLED(CONFIG_X86_32))
+		levels = (u32 *)__pa_nodebug(&final_levels);
+	else
+		levels = final_levels;
+
+	for (i = 0; levels[i]; i++) {
+		if (lvl == levels[i])
+			return true;
+	}
+	return false;
+}
+
 static bool __init check_loader_disabled_bsp(void)
 {
 	static const char *__dis_opt_str = "dis_ucode_ldr";
@@ -95,6 +131,11 @@ static bool __init check_loader_disabled_bsp(void)
 	if (native_cpuid_ecx(1) & BIT(31))
 		return *res;
 
+	if (x86_cpuid_vendor() == X86_VENDOR_AMD) {
+		if (amd_check_current_patch_level())
+			return *res;
+	}
+
 	if (cmdline_find_option_bool(cmdline, option) <= 0)
 		*res = false;
 
@@ -122,15 +163,14 @@ bool get_builtin_firmware(struct cpio_data *cd, const char *name)
 
 void __init load_ucode_bsp(void)
 {
-	unsigned int vendor, cpuid_1_eax;
+	unsigned int cpuid_1_eax;
 
 	if (check_loader_disabled_bsp())
 		return;
 
-	vendor	    = x86_cpuid_vendor();
 	cpuid_1_eax = native_cpuid_eax(1);
 
-	switch (vendor) {
+	switch (x86_cpuid_vendor()) {
 	case X86_VENDOR_INTEL:
 		if (x86_family(cpuid_1_eax) >= 6)
 			load_ucode_intel_bsp();
@@ -155,15 +195,14 @@ static bool check_loader_disabled_ap(void)
 
 void load_ucode_ap(void)
 {
-	unsigned int vendor, cpuid_1_eax;
+	unsigned int cpuid_1_eax;
 
 	if (check_loader_disabled_ap())
 		return;
 
-	vendor	    = x86_cpuid_vendor();
 	cpuid_1_eax = native_cpuid_eax(1);
 
-	switch (vendor) {
+	switch (x86_cpuid_vendor()) {
 	case X86_VENDOR_INTEL:
 		if (x86_family(cpuid_1_eax) >= 6)
 			load_ucode_intel_ap();
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1561006 — Re: [PATCH 10/13] x86/microcode/AMD: Check patch level only on the BSP

FromThomas Gleixner <tglx@linutronix.de>
Date2017-01-17 21:50 +0100
SubjectRe: [PATCH 10/13] x86/microcode/AMD: Check patch level only on the BSP
Message-ID<t0IRz-3jt-3@gated-at.bofh.it>
In reply to#1560870
On Tue, 17 Jan 2017, Borislav Petkov wrote:

> From: Borislav Petkov <bp@suse.de>
> 
> Check final patch levels for AMD only on the BSP. This way, we decide
> early and only once whether to continue loading or to leave the loader
> disabled on such systems.
> 
> Simplify a lot.
> 
> Signed-off-by: Borislav Petkov <bp@suse.de>
>  void __init load_ucode_bsp(void)
>  {
> -	unsigned int vendor, cpuid_1_eax;
> +	unsigned int cpuid_1_eax;
>  
>  	if (check_loader_disabled_bsp())
>  		return;
>  
> -	vendor	    = x86_cpuid_vendor();
>  	cpuid_1_eax = native_cpuid_eax(1);
>  
> -	switch (vendor) {
> +	switch (x86_cpuid_vendor()) {
>  	case X86_VENDOR_INTEL:
>  		if (x86_family(cpuid_1_eax) >= 6)
>  			load_ucode_intel_bsp();
> @@ -155,15 +195,14 @@ static bool check_loader_disabled_ap(void)
>  
>  void load_ucode_ap(void)
>  {
> -	unsigned int vendor, cpuid_1_eax;
> +	unsigned int cpuid_1_eax;
>  
>  	if (check_loader_disabled_ap())
>  		return;
>  
> -	vendor	    = x86_cpuid_vendor();
>  	cpuid_1_eax = native_cpuid_eax(1);
>  
> -	switch (vendor) {
> +	switch (x86_cpuid_vendor()) {
>  	case X86_VENDOR_INTEL:
>  		if (x86_family(cpuid_1_eax) >= 6)
>  			load_ucode_intel_ap();

These two hunks look unrelated to $subject. Please seperate them out.

Thanks,

	tglx

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web