|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 2/2] x86/ucode: load microcode earlier on boot CPU
Call early_microcode_init() straight after multiboot modules become
accessible. Modify it to load the ucode directly from the blob bypassing
populating microcode_cache because xmalloc is still not available at
that point during Xen boot.
Introduce early_microcode_init_cache() for populating microcode_cache.
It needs to find the new virtual address of the ucode blob because it
changes during boot, e.g. from 0x00000000010802fc to 0xffff83204dac52fc.
Signed-off-by: Sergey Dyasli <sergey.dyasli@xxxxxxxxxx>
---
xen/arch/x86/cpu/microcode/core.c | 61 ++++++++++++++++++++++++----
xen/arch/x86/include/asm/microcode.h | 6 ++-
xen/arch/x86/include/asm/setup.h | 3 --
xen/arch/x86/setup.c | 10 +++--
4 files changed, 64 insertions(+), 16 deletions(-)
diff --git a/xen/arch/x86/cpu/microcode/core.c
b/xen/arch/x86/cpu/microcode/core.c
index 924a2bd7b5..b04b30ce5e 100644
--- a/xen/arch/x86/cpu/microcode/core.c
+++ b/xen/arch/x86/cpu/microcode/core.c
@@ -198,7 +198,7 @@ void __init microcode_scan_module(
bootstrap_map(NULL);
}
}
-void __init microcode_grab_module(
+static void __init microcode_grab_module(
unsigned long *module_map,
const multiboot_info_t *mbi)
{
@@ -733,9 +733,35 @@ int microcode_update_one(void)
}
/* BSP calls this function to parse ucode blob and then apply an update. */
-static int __init early_microcode_update_cpu(void)
+static int __init early_microcode_update_cache(const void *data, size_t len)
{
int rc = 0;
+ const struct microcode_patch *patch;
+
+ if ( !data )
+ return -ENOMEM;
+
+ patch = parse_blob(data, len);
+ if ( IS_ERR(patch) )
+ {
+ printk(XENLOG_WARNING "Parsing microcode blob error %ld\n",
+ PTR_ERR(patch));
+ return PTR_ERR(patch);
+ }
+
+ if ( !patch )
+ return -ENOENT;
+
+ spin_lock(µcode_mutex);
+ rc = microcode_update_cache(patch);
+ spin_unlock(µcode_mutex);
+ ASSERT(rc);
+
+ return rc;
+}
+
+static int __init early_microcode_update_cpu(void)
+{
const void *data = NULL;
size_t len;
const struct microcode_patch *patch;
@@ -754,7 +780,9 @@ static int __init early_microcode_update_cpu(void)
if ( !data )
return -ENOMEM;
- patch = parse_blob(data, len);
+ alternative_vcall(ucode_ops.collect_cpu_info);
+
+ patch = alternative_call(ucode_ops.cpu_request_microcode, data, len,
false);
if ( IS_ERR(patch) )
{
printk(XENLOG_WARNING "Parsing microcode blob error %ld\n",
@@ -765,15 +793,28 @@ static int __init early_microcode_update_cpu(void)
if ( !patch )
return -ENOENT;
- spin_lock(µcode_mutex);
- rc = microcode_update_cache(patch);
- spin_unlock(µcode_mutex);
- ASSERT(rc);
+ return microcode_update_cpu(patch);
+}
+
+int __init early_microcode_init_cache(unsigned long *module_map,
+ const multiboot_info_t *mbi)
+{
+ int rc = 0;
+
+ /* Need to rescan the modules because they might have been relocated */
+ microcode_grab_module(module_map, mbi);
+
+ if ( ucode_mod.mod_end )
+ rc = early_microcode_update_cache(bootstrap_map(&ucode_mod),
+ ucode_mod.mod_end);
+ else if ( ucode_blob.size )
+ rc = early_microcode_update_cache(ucode_blob.data, ucode_blob.size);
- return microcode_update_one();
+ return rc;
}
-int __init early_microcode_init(void)
+int __init early_microcode_init(unsigned long *module_map,
+ const multiboot_info_t *mbi)
{
const struct cpuinfo_x86 *c = &boot_cpu_data;
int rc = 0;
@@ -797,6 +838,8 @@ int __init early_microcode_init(void)
return -ENODEV;
}
+ microcode_grab_module(module_map, mbi);
+
alternative_vcall(ucode_ops.collect_cpu_info);
if ( ucode_mod.mod_end || ucode_blob.size )
diff --git a/xen/arch/x86/include/asm/microcode.h
b/xen/arch/x86/include/asm/microcode.h
index 3b0234e9fa..c5f9897535 100644
--- a/xen/arch/x86/include/asm/microcode.h
+++ b/xen/arch/x86/include/asm/microcode.h
@@ -3,6 +3,7 @@
#include <xen/types.h>
#include <xen/percpu.h>
+#include <xen/multiboot.h>
#include <public/xen.h>
@@ -21,7 +22,10 @@ DECLARE_PER_CPU(struct cpu_signature, cpu_sig);
void microcode_set_module(unsigned int idx);
int microcode_update(XEN_GUEST_HANDLE(const_void), unsigned long len);
-int early_microcode_init(void);
+int early_microcode_init(unsigned long *module_map,
+ const multiboot_info_t *mbi);
+int early_microcode_init_cache(unsigned long *module_map,
+ const multiboot_info_t *mbi);
int microcode_update_one(void);
#endif /* ASM_X86__MICROCODE_H */
diff --git a/xen/arch/x86/include/asm/setup.h b/xen/arch/x86/include/asm/setup.h
index 21037b7f31..82ee51c2dc 100644
--- a/xen/arch/x86/include/asm/setup.h
+++ b/xen/arch/x86/include/asm/setup.h
@@ -45,9 +45,6 @@ void *bootstrap_map(const module_t *mod);
int xen_in_range(unsigned long mfn);
-void microcode_grab_module(
- unsigned long *, const multiboot_info_t *);
-
extern uint8_t kbd_shift_flags;
#ifdef NDEBUG
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index e05189f649..9955e1e6fa 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1178,6 +1178,12 @@ void __init noreturn __start_xen(unsigned long mbi_p)
mod[i].reserved = 0;
}
+ /*
+ * TODO: load ucode earlier once multiboot modules become accessible
+ * at an earlier stage.
+ */
+ early_microcode_init(module_map, mbi);
+
if ( xen_phys_start )
{
relocated = true;
@@ -1774,11 +1780,9 @@ void __init noreturn __start_xen(unsigned long mbi_p)
init_IRQ();
- microcode_grab_module(module_map, mbi);
-
timer_init();
- early_microcode_init();
+ early_microcode_init_cache(module_map, mbi);
tsx_init(); /* Needs microcode. May change HLE/RTM feature bits. */
--
2.17.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |