On Wed, Mar 18, 2015 at 11:02:27AM +0100, Borislav Petkov wrote:
> I don't like the ifdeffery in your solution and would like to try to fix
> it in a cleaner way. Unless you come up with a better solution first.

Ok, how about this below? It is more involved but finds and loads the
microcode built-in into the kernel in the early loader which is when
you want to load microcode anyway. Only AMD for now but that should be
enough for testing.

---
From: Borislav Petkov <[email protected]>
Date: Wed, 18 Mar 2015 19:28:56 +0100
Subject: [RFC PATCH] x86/microcode: Parse built-in microcode early

Only AMD for now, WIP.

Not-yet-signed-off-by: Borislav Petkov <[email protected]>
---
 arch/x86/include/asm/microcode.h           |  8 +++++++-
 arch/x86/include/asm/microcode_amd.h       |  4 ++--
 arch/x86/kernel/cpu/microcode/amd_early.c  | 13 ++++++++++---
 arch/x86/kernel/cpu/microcode/core_early.c | 23 ++++++++++++++++++++++-
 4 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index 2fb20d6f7e23..8924b9a65603 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -1,6 +1,8 @@
 #ifndef _ASM_X86_MICROCODE_H
 #define _ASM_X86_MICROCODE_H
 
+#include <linux/earlycpio.h>
+
 #define native_rdmsr(msr, val1, val2)                  \
 do {                                                   \
        u64 __val = native_read_msr((msr));             \
@@ -152,6 +154,7 @@ 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) {}
@@ -160,6 +163,9 @@ static inline int __init save_microcode_in_initrd(void)
        return 0;
 }
 static inline void reload_early_microcode(void) {}
+static bool get_builtin_firmware(struct cpio_data *cd, const char *name)
+{
+       return false;
+}
 #endif
-
 #endif /* _ASM_X86_MICROCODE_H */
diff --git a/arch/x86/include/asm/microcode_amd.h 
b/arch/x86/include/asm/microcode_amd.h
index af935397e053..b8438543f340 100644
--- a/arch/x86/include/asm/microcode_amd.h
+++ b/arch/x86/include/asm/microcode_amd.h
@@ -65,12 +65,12 @@ extern enum ucode_state load_microcode_amd(int cpu, u8 
family, const u8 *data, s
 extern u8 amd_ucode_patch[PATCH_MAX_SIZE];
 
 #ifdef CONFIG_MICROCODE_AMD_EARLY
-extern void __init load_ucode_amd_bsp(void);
+extern void __init load_ucode_amd_bsp(int family);
 extern void load_ucode_amd_ap(void);
 extern int __init save_microcode_in_initrd_amd(void);
 void reload_ucode_amd(void);
 #else
-static inline void __init load_ucode_amd_bsp(void) {}
+static inline void __init load_ucode_amd_bsp(int family) {}
 static inline void load_ucode_amd_ap(void) {}
 static inline int __init save_microcode_in_initrd_amd(void) { return -EINVAL; }
 void reload_ucode_amd(void) {}
diff --git a/arch/x86/kernel/cpu/microcode/amd_early.c 
b/arch/x86/kernel/cpu/microcode/amd_early.c
index 737737edbd1e..10d9068ca4f6 100644
--- a/arch/x86/kernel/cpu/microcode/amd_early.c
+++ b/arch/x86/kernel/cpu/microcode/amd_early.c
@@ -228,8 +228,9 @@ static void apply_ucode_in_initrd(void *ucode, size_t size, 
bool save_patch)
        }
 }
 
-void __init load_ucode_amd_bsp(void)
+void __init load_ucode_amd_bsp(int family)
 {
+       char fw_name[26] = "microcode_amd.bin";
        struct cpio_data cp;
        void **data;
        size_t *size;
@@ -243,8 +244,14 @@ void __init load_ucode_amd_bsp(void)
 #endif
 
        cp = find_ucode_in_initrd();
-       if (!cp.data)
-               return;
+       if (!cp.data) {
+               if (family >= 0x15)
+                       snprintf(fw_name, sizeof(fw_name),
+                                "microcode_amd_fam%.2xh.bin", family);
+
+               if (!get_builtin_firmware(&cp, fw_name))
+                       return;
+       }
 
        *data = cp.data;
        *size = cp.size;
diff --git a/arch/x86/kernel/cpu/microcode/core_early.c 
b/arch/x86/kernel/cpu/microcode/core_early.c
index a413a69cbd74..beda0ea2409e 100644
--- a/arch/x86/kernel/cpu/microcode/core_early.c
+++ b/arch/x86/kernel/cpu/microcode/core_early.c
@@ -3,6 +3,7 @@
  *
  *     Copyright (C) 2012 Fenghua Yu <[email protected]>
  *                        H Peter Anvin" <[email protected]>
+ *               (C) 2015 Borislav Petkov <[email protected]>
  *
  *     This driver allows to early upgrade microcode on Intel processors
  *     belonging to IA-32 family - PentiumPro, Pentium II,
@@ -17,6 +18,7 @@
  *     2 of the License, or (at your option) any later version.
  */
 #include <linux/module.h>
+#include <linux/firmware.h>
 #include <asm/microcode.h>
 #include <asm/microcode_intel.h>
 #include <asm/microcode_amd.h>
@@ -43,6 +45,25 @@ static bool __init check_loader_disabled_bsp(void)
        return *res;
 }
 
+extern struct builtin_fw __start_builtin_fw[];
+extern struct builtin_fw __end_builtin_fw[];
+
+bool get_builtin_firmware(struct cpio_data *cd, const char *name)
+{
+#ifdef CONFIG_FW_LOADER
+       struct builtin_fw *b_fw;
+
+       for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) {
+               if (!strcmp(name, b_fw->name)) {
+                       cd->size = b_fw->size;
+                       cd->data = b_fw->data;
+                       return true;
+               }
+       }
+#endif
+       return false;
+}
+
 void __init load_ucode_bsp(void)
 {
        int vendor, family;
@@ -63,7 +84,7 @@ void __init load_ucode_bsp(void)
                break;
        case X86_VENDOR_AMD:
                if (family >= 0x10)
-                       load_ucode_amd_bsp();
+                       load_ucode_amd_bsp(family);
                break;
        default:
                break;
-- 
2.3.3

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.
--
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to