diff mbox series

[RFC,03/67] x86/cpu: Move get_builtin_firmware() common code (from microcode only)

Message ID 46d35ce06d84c55ff02a05610ca3fb6d51ee1a71.1605232743.git.isaku.yamahata@intel.com (mailing list archive)
State New, archived
Headers show
Series KVM: X86: TDX support | expand

Commit Message

Isaku Yamahata Nov. 16, 2020, 6:25 p.m. UTC
From: Zhang Chen <chen.zhang@intel.com>

Move get_builtin_firmware() to common.c so that it can be used to get
non-ucode firmware, e.g. Intel's SEAM modules, even if MICROCODE=n.

Require the consumers to select FW_LOADER, which is already true for
MICROCODE, instead of having dead code that returns false at runtime.

Signed-off-by: Zhang Chen <chen.zhang@intel.com>
Co-developed-by: Kai Huang <kai.huang@linux.intel.com>
Signed-off-by: Kai Huang <kai.huang@linux.intel.com>
Co-developed-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
---
 arch/x86/include/asm/cpu.h            |  5 +++++
 arch/x86/include/asm/microcode.h      |  3 ---
 arch/x86/kernel/cpu/common.c          | 20 ++++++++++++++++++++
 arch/x86/kernel/cpu/microcode/core.c  | 18 ------------------
 arch/x86/kernel/cpu/microcode/intel.c |  1 +
 5 files changed, 26 insertions(+), 21 deletions(-)

Comments

Borislav Petkov Nov. 25, 2020, 10:09 p.m. UTC | #1
On Mon, Nov 16, 2020 at 10:25:48AM -0800, isaku.yamahata@intel.com wrote:
> From: Zhang Chen <chen.zhang@intel.com>
> 
> Move get_builtin_firmware() to common.c so that it can be used to get
> non-ucode firmware, e.g. Intel's SEAM modules, even if MICROCODE=n.

What for?

This is used for microcode built in the kernel - a non-common use case.
Why is your thing built into the kernel and not a normal module object?
Sean Christopherson Nov. 26, 2020, 12:18 a.m. UTC | #2
On Wed, Nov 25, 2020, Borislav Petkov wrote:
> On Mon, Nov 16, 2020 at 10:25:48AM -0800, isaku.yamahata@intel.com wrote:
> > From: Zhang Chen <chen.zhang@intel.com>
> > 
> > Move get_builtin_firmware() to common.c so that it can be used to get
> > non-ucode firmware, e.g. Intel's SEAM modules, even if MICROCODE=n.
> 
> What for?
> 
> This is used for microcode built in the kernel - a non-common use case.
> Why is your thing built into the kernel and not a normal module object?

The SEAM module needs to be loaded during early boot, it can't be deferred to a
module, at least not without a lot more blood, sweat, and tears.

The SEAM Loader is an ACM that is invoked via GETSEC[EnterACCS], which requires
all APs to be in WFS.  SEAM Loader also returns control to the kernel with a
null IDT and NMIs unblocked, i.e. we're toast if there's a pending NMI.  And
unlike the run-time SEAMCALLs, boot-time SEAMCALLs do not have a strictly
bounded runtime.  Invoking configuration SEAMCALLs after the kernel is fully up
and running could cause instability as IRQ, NMI, and SMI are all blocked in SEAM
mode, e.g. a high priority IRQ/NMI/SMI could be blocked for 50+ usecs (it might
be far more than 50 usecs, I haven't seen real numbers for all SEAMCALLs).
Borislav Petkov Nov. 26, 2020, 10:12 a.m. UTC | #3
On Thu, Nov 26, 2020 at 12:18:12AM +0000, Sean Christopherson wrote:
> The SEAM module needs to be loaded during early boot, it can't be
> deferred to a module, at least not without a lot more blood, sweat,
> and tears.

Are you also planning to support builtin seam or only thru initrd loading?

In any case, this commit message needs to state intentions not me having
to plow all the way up to patch 62.

> The SEAM Loader is an ACM that is invoked via GETSEC[EnterACCS], which
> requires all APs to be in WFS.

Yah, this is the other thing that sprang at me from looking at that
"small" patchset briefly - I'm being killed by abbreviations. Whoever is
sending the next version, pls put a proper documentation as patch 1 of
the patchset just like the CET patchset does.

> SEAM Loader also returns control to the kernel with a null IDT and
> NMIs unblocked, i.e. we're toast if there's a pending NMI. And unlike
> the run-time SEAMCALLs, boot-time SEAMCALLs do not have a strictly
> bounded runtime. Invoking configuration SEAMCALLs after the kernel is
> fully up and running could cause instability as IRQ, NMI, and SMI are
> all blocked in SEAM mode, e.g. a high priority IRQ/NMI/SMI could be
> blocked for 50+ usecs (it might be far more than 50 usecs, I haven't
> seen real numbers for all SEAMCALLs).

Yah, I sure hope people have taken an ample amount of time to think
about all the implications of this thing because it sounds wonky to me.
amluto certainly has already gone deeper and will surely comment. :)

Thx.
Sean Christopherson Nov. 30, 2020, 7:18 p.m. UTC | #4
On Thu, Nov 26, 2020, Borislav Petkov wrote:
> On Thu, Nov 26, 2020 at 12:18:12AM +0000, Sean Christopherson wrote:
> > The SEAM module needs to be loaded during early boot, it can't be
> > deferred to a module, at least not without a lot more blood, sweat,
> > and tears.
> 
> Are you also planning to support builtin seam or only thru initrd loading?

Yep, both built-in and initrd are supported.

> In any case, this commit message needs to state intentions not me having
> to plow all the way up to patch 62.

Yeah, most of the changelogs are in terrible shape.  This first RFC was intended
to get feedback on high level things like code organization and the KVM
shenanigans for VMX and TDX coexistence.
diff mbox series

Patch

diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index da78ccbd493b..0096ac7cad0a 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -7,6 +7,7 @@ 
 #include <linux/topology.h>
 #include <linux/nodemask.h>
 #include <linux/percpu.h>
+#include <linux/earlycpio.h>
 
 #ifdef CONFIG_SMP
 
@@ -37,6 +38,10 @@  extern int _debug_hotplug_cpu(int cpu, int action);
 
 int mwait_usable(const struct cpuinfo_x86 *);
 
+#if defined(CONFIG_MICROCODE) || defined(CONFIG_KVM_INTEL_TDX)
+bool get_builtin_firmware(struct cpio_data *cd, const char *name);
+#endif
+
 unsigned int x86_family(unsigned int sig);
 unsigned int x86_model(unsigned int sig);
 unsigned int x86_stepping(unsigned int sig);
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index 2b7cc5397f80..4f10089f30de 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -131,15 +131,12 @@  int __init microcode_init(void);
 extern void __init load_ucode_bsp(void);
 extern void load_ucode_ap(void);
 void reload_early_microcode(void);
-extern bool get_builtin_firmware(struct cpio_data *cd, const char *name);
 extern bool initrd_gone;
 #else
 static inline int __init microcode_init(void)			{ return 0; };
 static inline void __init load_ucode_bsp(void)			{ }
 static inline void load_ucode_ap(void)				{ }
 static inline void reload_early_microcode(void)			{ }
-static inline bool
-get_builtin_firmware(struct cpio_data *cd, const char *name)	{ return false; }
 #endif
 
 #endif /* _ASM_X86_MICROCODE_H */
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 35ad8480c464..87512c5854bb 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -22,6 +22,7 @@ 
 #include <linux/io.h>
 #include <linux/syscore_ops.h>
 #include <linux/pgtable.h>
+#include <linux/firmware.h>
 
 #include <asm/cmdline.h>
 #include <asm/stackprotector.h>
@@ -87,6 +88,25 @@  void __init setup_cpu_local_masks(void)
 	alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask);
 }
 
+#if defined(CONFIG_MICROCODE) || defined(CONFIG_KVM_INTEL_TDX)
+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)
+{
+	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;
+		}
+	}
+	return false;
+}
+#endif
+
 static void default_init(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_X86_64
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index ec6f0415bc6d..f877a9c19f42 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -22,7 +22,6 @@ 
 #include <linux/syscore_ops.h>
 #include <linux/miscdevice.h>
 #include <linux/capability.h>
-#include <linux/firmware.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
@@ -140,23 +139,6 @@  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)
-{
-	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;
-		}
-	}
-	return false;
-}
-
 void __init load_ucode_bsp(void)
 {
 	unsigned int cpuid_1_eax;
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 6a99535d7f37..50e69d6cb3d9 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -36,6 +36,7 @@ 
 #include <asm/tlbflush.h>
 #include <asm/setup.h>
 #include <asm/msr.h>
+#include <asm/cpu.h>
 
 static const char ucode_path[] = "kernel/x86/microcode/GenuineIntel.bin";