All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jacob Shin <jacob.shin@amd.com>
To: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Andreas Herrmann <herrmann.der.user@googlemail.com>,
	"H. Peter Anvin" <hpa@zytor.com>, Ingo Molnar <mingo@redhat.com>,
	Thomas Gleixner <tglx@linutronix.de>, <x86@kernel.org>,
	Fenghua Yu <fenghua.yu@intel.com>, Borislav Petkov <bp@alien8.de>,
	Joe Perches <joe@perches.com>, <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH V3 4/4] microcode/x86/amd: early microcode patch loading support for AMD
Date: Fri, 31 May 2013 20:15:12 -0500	[thread overview]
Message-ID: <20130601011512.GA8532@jshin-Toonie> (raw)
In-Reply-To: <20130531213039.GA13307@khazad-dum.debian.net>

On Fri, May 31, 2013 at 06:30:39PM -0300, Henrique de Moraes Holschuh wrote:
> On Fri, 31 May 2013, Andreas Herrmann wrote:
> > On Fri, May 31, 2013 at 01:26:49AM -0300, Henrique de Moraes Holschuh wrote:
> > > On Thu, 30 May 2013, Jacob Shin wrote:
> > > >  mkdir initrd
> > > >  cd initrd
> > > > -mkdir kernel
> > > > -mkdir kernel/x86
> > > > -mkdir kernel/x86/microcode
> > > > -cp ../microcode.bin kernel/x86/microcode/GenuineIntel.bin
> > > > -find .|cpio -oc >../ucode.cpio
> > > > +mkdir -p kernel/x86/microcode
> > > > +cp ../microcode.bin kernel/x86/microcode/GenuineIntel.bin (or AuthenticAMD.bin)
> > > 
> > > Can I just 
> > > 'cat /lib/firmware/amd-ucode/*bin >kernel/x86/microcode/AuthenticAMD.bin' 
> > > to get a valid microcode container for all amd processors?
> > > 
> > > The answer for Intel is "yes".  I sure hope it is the same for AMD...
> > 
> > No, this doesn't work for AMD.
> > 
> > The container file includes a header section with information how to
> > map CPU F/M/S to microcode revisions provided with a container
> > file. Concatenating several container files will not create an
> > all-embracing header section.
> > 
> > More details were available on the amd64.org web pages.  But it seems
> > that the web site is not available anymore ...
> 
> Well, this is a problem for userspace.  Maybe the easier solution would be
> to make kernel/x86/microcode/AuthenticAMD a folder, and look for files there
> with names we can derivate from the ones used by the firmware interface (or
> even the same names)?
> 
> The early-initramfs API easily allows this to be implemented...

Yeah, but since that will break symmetry with Intel's GenuineIntel.bin
file path, so I decided to add some more logic to early loading code
to be able to parse through multiple containers files concatanated
together.

Any thoughts on this Boris?

Patch below:

---8<---

>From 40ba7f578e2abb83897f218e6577396a3852ad00 Mon Sep 17 00:00:00 2001
From: Jacob Shin <jacob.shin@amd.com>
Date: Fri, 31 May 2013 13:57:02 -0500
Subject: [PATCH 1/1] x86/microcode/amd: allow multiple family's bin files
 appended together

Add support for parsing through multiple family's microcode patch
container binary files appended together when early loading. This is
already supported on Intel.

Reported-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Jacob Shin <jacob.shin@amd.com>
---
 arch/x86/kernel/microcode_amd_early.c |   63 +++++++++++++++++++++++++++------
 1 file changed, 53 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kernel/microcode_amd_early.c b/arch/x86/kernel/microcode_amd_early.c
index 9618805..2426dab 100644
--- a/arch/x86/kernel/microcode_amd_early.c
+++ b/arch/x86/kernel/microcode_amd_early.c
@@ -16,6 +16,7 @@
 
 static bool ucode_loaded;
 static u32 ucode_new_rev;
+static int family_offset;
 
 /*
  * Microcode patch container file is prepended to the initrd in cpio format.
@@ -27,6 +28,7 @@ static struct cpio_data __cpuinit find_ucode_in_initrd(void)
 {
 	long offset = 0;
 	struct cpio_data cd;
+	int *fam_offset = &family_offset;
 
 #ifdef CONFIG_X86_32
 	/*
@@ -39,12 +41,18 @@ static struct cpio_data __cpuinit find_ucode_in_initrd(void)
 		cd = find_cpio_data((char *)__pa_nodebug(ucode_path),
 			(void *)p->hdr.ramdisk_image, p->hdr.ramdisk_size,
 			&offset);
+		fam_offset = (int *)__pa_nodebug(&family_offset);
 	} else
 #endif
 		cd = find_cpio_data(ucode_path,
 			(void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET),
 			boot_params.hdr.ramdisk_size, &offset);
 
+	if (*fam_offset) {
+		cd.data = (u8 *)cd.data + *fam_offset;
+		cd.size -= *fam_offset;
+	}
+
 	if (*(u32 *)cd.data != UCODE_MAGIC) {
 		cd.data = NULL;
 		cd.size = 0;
@@ -68,15 +76,18 @@ static void __cpuinit apply_ucode_in_initrd(void)
 	struct equiv_cpu_entry *eq;
 	u32 *header;
 	u8  *data;
-	u16 eq_id;
+	u16 eq_id = 0;
 	int offset, left;
-	u32 rev, dummy;
+	u32 rev, eax;
 	u32 *new_rev;
+	int *fam_off;
 
 #ifdef CONFIG_X86_32
 	new_rev = (u32 *)__pa_nodebug(&ucode_new_rev);
+	fam_off = (int *)__pa_nodebug(&family_offset);
 #else
 	new_rev = &ucode_new_rev;
+	fam_off = &family_offset;
 #endif
 	cd = find_ucode_in_initrd();
 	if (!cd.data)
@@ -92,18 +103,44 @@ static void __cpuinit apply_ucode_in_initrd(void)
 	    header[2] == 0)                            /* size */
 		return;
 
-	eq     = (struct equiv_cpu_entry *)(data + CONTAINER_HDR_SZ);
-	offset = header[2] + CONTAINER_HDR_SZ;
-	data  += offset;
-	left  -= offset;
+	eax = cpuid_eax(0x00000001);
+
+	while (left > 0) {
+		eq = (struct equiv_cpu_entry *)(data + CONTAINER_HDR_SZ);
+
+		offset = header[2] + CONTAINER_HDR_SZ;
+		data  += offset;
+		left  -= offset;
+
+		eq_id = find_equiv_id(eq, eax);
+		if (eq_id)
+			break;
+
+		/*
+		 * support multiple container files appended together. if this
+		 * one does not have a matching equivalent cpu entry, we fast
+		 * forward to the next container file.
+		 */
+		while (left > 0) {
+			header = (u32 *)data;
+			if (header[0] == UCODE_MAGIC &&
+			    header[1] == UCODE_EQUIV_CPU_TABLE_TYPE)
+				break;
+
+			offset = header[1] + SECTION_HDR_SIZE;
+			data  += offset;
+			left  -= offset;
+		}
+
+		*fam_off = data - (u8 *)cd.data;
+	}
 
-	eq_id  = find_equiv_id(eq, cpuid_eax(0x00000001));
 	if (!eq_id)
 		return;
 
 	/* find ucode and update if needed */
 
-	rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
+	rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax);
 
 	while (left > 0) {
 		struct microcode_amd *mc;
@@ -116,8 +153,11 @@ static void __cpuinit apply_ucode_in_initrd(void)
 		mc = (struct microcode_amd *)(data + SECTION_HDR_SIZE);
 		if (eq_id == mc->hdr.processor_rev_id && rev < mc->hdr.patch_id)
 			if (__apply_microcode_amd(mc) == 0) {
-				if (!(*new_rev))
-					*new_rev = mc->hdr.patch_id;
+#ifdef CONFIG_X86_32
+				u8 *mpb = (u8  *)__pa_nodebug(&amd_bsp_mpb);
+				memcpy(mpb, mc, header[1]);
+#endif
+				*new_rev = mc->hdr.patch_id;
 				break;
 			}
 
@@ -182,6 +222,9 @@ void __cpuinit load_ucode_amd_ap(void)
 
 	if (cpu && !ucode_loaded) {
 		struct cpio_data cd = find_ucode_in_initrd();
+		if (!cd.data)
+			return;
+
 		if (load_microcode_amd(0, cd.data, cd.size) != UCODE_OK)
 			return;
 		ucode_loaded = true;
-- 
1.7.9.5



  reply	other threads:[~2013-06-01  1:15 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-30 19:09 [PATCH V3 0/4] x86/microcode: early microcode patch loading support on AMD Jacob Shin
2013-05-30 19:09 ` [PATCH V3 1/4] x86, microcode, intel: Correct typo in printk Jacob Shin
2013-05-31  3:26   ` [tip:x86/microcode] " tip-bot for Borislav Petkov
2013-05-30 19:09 ` [PATCH V3 2/4] x86/microcode: vendor abstract out save_microcode_in_initrd() Jacob Shin
2013-05-31  3:27   ` [tip:x86/microcode] x86, microcode: Vendor " tip-bot for Jacob Shin
2013-05-30 19:09 ` [PATCH V3 3/4] x86/microcode/amd: refactor functions to prepare for early loading Jacob Shin
2013-05-31  3:29   ` [tip:x86/microcode] x86, microcode, amd: Refactor " tip-bot for Jacob Shin
2013-05-30 19:09 ` [PATCH V3 4/4] microcode/x86/amd: early microcode patch loading support for AMD Jacob Shin
2013-05-31  3:31   ` [tip:x86/microcode] x86, microcode, amd: Early " tip-bot for Jacob Shin
2013-05-31  6:10     ` Yinghai Lu
2013-05-31  6:59       ` Jacob Shin
2013-05-31  8:41     ` Borislav Petkov
2013-05-31 15:02       ` Jacob Shin
2013-05-31 15:13         ` H. Peter Anvin
2013-05-31 15:17           ` Jacob Shin
2013-05-31 21:59         ` [tip:x86/microcode] x86, microcode, amd: Fix warnings and errors on with CONFIG_MICROCODE=m tip-bot for Jacob Shin
2013-06-01  9:30           ` Borislav Petkov
2013-06-04 21:02           ` Yinghai Lu
2013-06-04 21:36             ` Jacob Shin
2013-06-04 21:55               ` Jacob Shin
2013-06-04 22:05                 ` Yinghai Lu
2013-05-31  4:26   ` [PATCH V3 4/4] microcode/x86/amd: early microcode patch loading support for AMD Henrique de Moraes Holschuh
2013-05-31 15:54     ` Jacob Shin
2013-05-31 19:32     ` Andreas Herrmann
2013-05-31 21:30       ` Henrique de Moraes Holschuh
2013-06-01  1:15         ` Jacob Shin [this message]
2013-06-05 22:10           ` Borislav Petkov
2013-06-06 20:06             ` Jacob Shin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130601011512.GA8532@jshin-Toonie \
    --to=jacob.shin@amd.com \
    --cc=bp@alien8.de \
    --cc=fenghua.yu@intel.com \
    --cc=herrmann.der.user@googlemail.com \
    --cc=hmh@hmh.eng.br \
    --cc=hpa@zytor.com \
    --cc=joe@perches.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.