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.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Sergey Dyasli authored and Andrew Cooper committed 2022-12-20 19:33:04 +00:00
1 parent 1233294a8d
commit 44a6871a5b
4 files changed
+30 -14

No files matched your search

+9 -4
View File
@@ -300,7 +300,7 @@ static int scan_equiv_cpu_table(const struct container_equiv_table *et)
}
static struct microcode_patch *cf_check cpu_request_microcode(
const void *buf, size_t size)
const void *buf, size_t size, bool make_copy)
{
const struct microcode_patch *saved = NULL;
struct microcode_patch *patch = NULL;
@@ -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 = (struct microcode_patch *)saved;
}
if ( error && !patch )
+1 -1
View File
@@ -244,7 +244,7 @@ static 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)
+9 -4
View File
@@ -324,7 +324,7 @@ static int cf_check apply_microcode(const struct microcode_patch *patch)
}
static struct microcode_patch *cf_check cpu_request_microcode(
const void *buf, size_t size)
const void *buf, size_t size, bool make_copy)
{
int error = 0;
const struct microcode_patch *saved = NULL;
@@ -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 = (struct microcode_patch *)saved;
}
if ( error && !patch )
+11 -5
View File
@@ -23,15 +23,21 @@ 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);
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
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.