|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 1/2] x86/ucode: allow cpu_request_microcode() to skip memory allocation
This is a preparatory step in order to do earlier microcode loading on
the boot CPU when the domain heap has not been initialized yet and
xmalloc still unavailable.
Add make_copy argument which will allow to load microcode directly from
the blob bypassing microcode_cache. Add const qualifiers where required.
Signed-off-by: Sergey Dyasli <sergey.dyasli@xxxxxxxxxx>
---
xen/arch/x86/cpu/microcode/amd.c | 17 +++++++++++------
xen/arch/x86/cpu/microcode/core.c | 18 +++++++++---------
xen/arch/x86/cpu/microcode/intel.c | 17 +++++++++++------
xen/arch/x86/cpu/microcode/private.h | 18 ++++++++++++------
4 files changed, 43 insertions(+), 27 deletions(-)
diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c
index 8195707ee1..d4df3c4806 100644
--- a/xen/arch/x86/cpu/microcode/amd.c
+++ b/xen/arch/x86/cpu/microcode/amd.c
@@ -299,11 +299,11 @@ static int scan_equiv_cpu_table(const struct
container_equiv_table *et)
return -ESRCH;
}
-static struct microcode_patch *cf_check cpu_request_microcode(
- const void *buf, size_t size)
+static const struct microcode_patch *cf_check cpu_request_microcode(
+ const void *buf, size_t size, bool make_copy)
{
const struct microcode_patch *saved = NULL;
- struct microcode_patch *patch = NULL;
+ const struct microcode_patch *patch = NULL;
size_t saved_size = 0;
int error = 0;
@@ -411,9 +411,14 @@ static struct microcode_patch *cf_check
cpu_request_microcode(
if ( saved )
{
- patch = xmemdup_bytes(saved, saved_size);
- if ( !patch )
- error = -ENOMEM;
+ if ( make_copy )
+ {
+ patch = xmemdup_bytes(saved, saved_size);
+ if ( !patch )
+ error = -ENOMEM;
+ }
+ else
+ patch = saved;
}
if ( error && !patch )
diff --git a/xen/arch/x86/cpu/microcode/core.c
b/xen/arch/x86/cpu/microcode/core.c
index 452a7ca773..924a2bd7b5 100644
--- a/xen/arch/x86/cpu/microcode/core.c
+++ b/xen/arch/x86/cpu/microcode/core.c
@@ -99,7 +99,7 @@ static bool ucode_in_nmi = true;
bool __read_mostly opt_ucode_allow_same;
/* Protected by microcode_mutex */
-static struct microcode_patch *microcode_cache;
+static const struct microcode_patch *microcode_cache;
void __init microcode_set_module(unsigned int idx)
{
@@ -240,20 +240,20 @@ static const struct microcode_patch *nmi_patch =
ZERO_BLOCK_PTR;
* patch is found and an error occurs during the parsing process. Otherwise
* return NULL.
*/
-static struct microcode_patch *parse_blob(const char *buf, size_t len)
+static const struct microcode_patch *parse_blob(const char *buf, size_t len)
{
alternative_vcall(ucode_ops.collect_cpu_info);
- return alternative_call(ucode_ops.cpu_request_microcode, buf, len);
+ return alternative_call(ucode_ops.cpu_request_microcode, buf, len, true);
}
-static void microcode_free_patch(struct microcode_patch *patch)
+static void microcode_free_patch(const struct microcode_patch *patch)
{
- xfree(patch);
+ xfree((void *)patch);
}
/* Return true if cache gets updated. Otherwise, return false */
-static bool microcode_update_cache(struct microcode_patch *patch)
+static bool microcode_update_cache(const struct microcode_patch *patch)
{
ASSERT(spin_is_locked(µcode_mutex));
@@ -565,7 +565,7 @@ static long cf_check microcode_update_helper(void *data)
int ret;
struct ucode_buf *buffer = data;
unsigned int cpu, updated;
- struct microcode_patch *patch;
+ const struct microcode_patch *patch;
/* cpu_online_map must not change during update */
if ( !get_cpu_maps() )
@@ -648,7 +648,7 @@ static long cf_check microcode_update_helper(void *data)
* this requirement can be relaxed in the future. Right now, this is
* conservative and good.
*/
- ret = stop_machine_run(do_microcode_update, patch, NR_CPUS);
+ ret = stop_machine_run(do_microcode_update, (void *)patch, NR_CPUS);
updated = atomic_read(&cpu_updated);
if ( updated > 0 )
@@ -738,7 +738,7 @@ static int __init early_microcode_update_cpu(void)
int rc = 0;
const void *data = NULL;
size_t len;
- struct microcode_patch *patch;
+ const struct microcode_patch *patch;
if ( ucode_blob.size )
{
diff --git a/xen/arch/x86/cpu/microcode/intel.c
b/xen/arch/x86/cpu/microcode/intel.c
index f5ba6d76d7..017f37e43d 100644
--- a/xen/arch/x86/cpu/microcode/intel.c
+++ b/xen/arch/x86/cpu/microcode/intel.c
@@ -323,12 +323,12 @@ static int cf_check apply_microcode(const struct
microcode_patch *patch)
return 0;
}
-static struct microcode_patch *cf_check cpu_request_microcode(
- const void *buf, size_t size)
+static const struct microcode_patch *cf_check cpu_request_microcode(
+ const void *buf, size_t size, bool make_copy)
{
int error = 0;
const struct microcode_patch *saved = NULL;
- struct microcode_patch *patch = NULL;
+ const struct microcode_patch *patch = NULL;
while ( size )
{
@@ -364,10 +364,15 @@ static struct microcode_patch *cf_check
cpu_request_microcode(
if ( saved )
{
- patch = xmemdup_bytes(saved, get_totalsize(saved));
+ if ( make_copy )
+ {
+ patch = xmemdup_bytes(saved, get_totalsize(saved));
- if ( !patch )
- error = -ENOMEM;
+ if ( !patch )
+ error = -ENOMEM;
+ }
+ else
+ patch = saved;
}
if ( error && !patch )
diff --git a/xen/arch/x86/cpu/microcode/private.h
b/xen/arch/x86/cpu/microcode/private.h
index c085a10268..98657d39c3 100644
--- a/xen/arch/x86/cpu/microcode/private.h
+++ b/xen/arch/x86/cpu/microcode/private.h
@@ -23,16 +23,22 @@ struct microcode_ops {
* older that what is running in the CPU. This is a feature, to better
* cope with corner cases from buggy firmware.)
*
- * If one is found, allocate and return a struct microcode_patch
- * encapsulating the appropriate microcode patch. Does not alias the
- * original buffer. Must be suitable to be freed with a single xfree().
+ * If one is found, behaviour depends on the make_copy argument:
+ *
+ * true: allocate and return a struct microcode_patch encapsulating
+ * the appropriate microcode patch. Does not alias the original
+ * buffer. Must be suitable to be freed with a single xfree().
+ *
+ * false: return a pointer to the patch within the original buffer.
+ * This is useful for early microcode loading when xmalloc might
+ * not be available yet.
*
* If one is not found, (nothing matches the current CPU), return NULL.
* Also may return ERR_PTR(-err), e.g. bad container, out of memory.
*/
- struct microcode_patch *(*cpu_request_microcode)(const void *buf,
- size_t size);
-
+ const struct microcode_patch *(*cpu_request_microcode)(const void *buf,
+ size_t size,
+ bool make_copy);
/*
* Obtain microcode-relevant details for the current CPU. Results in
* per_cpu(cpu_sig).
--
2.17.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |