#include <xen/err.h>
#include <xen/guest_access.h>
#include <xen/init.h>
+#include <xen/multiboot.h>
#include <xen/param.h>
#include <xen/spinlock.h>
#include <xen/stop_machine.h>
bootstrap_map(NULL);
}
}
-void __init microcode_grab_module(
+
+static void __init microcode_grab_module(
unsigned long *module_map,
const multiboot_info_t *mbi)
{
return microcode_update_cpu(NULL);
}
+static int __init early_update_cache(const void *data, size_t len)
+{
+ int rc = 0;
+ 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;
+}
+
+int __init microcode_init_cache(unsigned long *module_map,
+ const struct multiboot_info *mbi)
+{
+ int rc = 0;
+
+ if ( ucode_scan )
+ /* Need to rescan the modules because they might have been relocated */
+ microcode_scan_module(module_map, mbi);
+
+ if ( ucode_mod.mod_end )
+ rc = early_update_cache(bootstrap_map(&ucode_mod),
+ ucode_mod.mod_end);
+ else if ( ucode_blob.size )
+ rc = early_update_cache(ucode_blob.data, ucode_blob.size);
+
+ return rc;
+}
+
/* BSP calls this function to parse ucode blob and then apply an update. */
static int __init early_microcode_update_cpu(void)
{
- int rc = 0;
const void *data = NULL;
size_t len;
struct microcode_patch *patch;
if ( !data )
return -ENOMEM;
- patch = parse_blob(data, len);
+ patch = ucode_ops.cpu_request_microcode(data, len, false);
if ( IS_ERR(patch) )
{
printk(XENLOG_WARNING "Parsing microcode blob error %ld\n",
if ( !patch )
return -ENOENT;
- spin_lock(µcode_mutex);
- rc = microcode_update_cache(patch);
- spin_unlock(µcode_mutex);
- ASSERT(rc);
-
- return microcode_update_one();
+ return microcode_update_cpu(patch);
}
-int __init early_microcode_init(void)
+int __init early_microcode_init(unsigned long *module_map,
+ const struct multiboot_info *mbi)
{
const struct cpuinfo_x86 *c = &boot_cpu_data;
int rc = 0;
return -ENODEV;
}
- alternative_vcall(ucode_ops.collect_cpu_info);
+ microcode_grab_module(module_map, mbi);
+
+ ucode_ops.collect_cpu_info();
if ( ucode_mod.mod_end || ucode_blob.size )
rc = early_microcode_update_cpu();
#include <public/xen.h>
+struct multiboot_info;
+
struct cpu_signature {
/* CPU signature (CPUID.1.EAX). */
unsigned int 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 struct multiboot_info *mbi);
+int microcode_init_cache(unsigned long *module_map,
+ const struct multiboot_info *mbi);
int microcode_update_one(void);
#endif /* ASM_X86__MICROCODE_H */