[PATCH] x86/microcode/AMD: shrink the size of amd_ucode_patch array

From: Zeng Heng
Date: Mon Jun 05 2023 - 03:33:43 EST


About the commit <7ff6edf4fef3>, the amd_ucode_patch is expanded as
two-dimensional array. When CONFIG_MAXSMP is enabled or CONFIG_NODES_SHIFT
is set as 10, this array would occupy memory up to 12M.

Here we allocate amd_ucode_patch array dynamically in need instead of
static declaration.

Signed-off-by: Zeng Heng <zengheng4@xxxxxxxxxx>
---
arch/x86/kernel/cpu/microcode/amd.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index f5fdeb1e3606..b6cd6ce9c016 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -57,7 +57,8 @@ struct cont_desc {
static u32 ucode_new_rev;

/* One blob per node. */
-static u8 amd_ucode_patch[MAX_NUMNODES][PATCH_MAX_SIZE];
+static u8 amd_ucode_patch_0[PATCH_MAX_SIZE];
+static u8 *amd_ucode_patch[MAX_NUMNODES] = { amd_ucode_patch_0 };

/*
* Microcode patch container file is prepended to the initrd in cpio
@@ -420,17 +421,17 @@ static int __apply_microcode_amd(struct microcode_amd *mc)
static bool early_apply_microcode(u32 cpuid_1_eax, void *ucode, size_t size, bool save_patch)
{
struct cont_desc desc = { 0 };
- u8 (*patch)[PATCH_MAX_SIZE];
+ u8 *patch;
struct microcode_amd *mc;
u32 rev, dummy, *new_rev;
bool ret = false;

#ifdef CONFIG_X86_32
new_rev = (u32 *)__pa_nodebug(&ucode_new_rev);
- patch = (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch);
+ patch = (u8 *)__pa_nodebug(amd_ucode_patch_0);
#else
new_rev = &ucode_new_rev;
- patch = &amd_ucode_patch[0];
+ patch = amd_ucode_patch_0;
#endif

desc.cpuid_1_eax = cpuid_1_eax;
@@ -881,8 +882,11 @@ static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t siz

ret = UCODE_NEW;

- memset(&amd_ucode_patch[nid], 0, PATCH_MAX_SIZE);
- memcpy(&amd_ucode_patch[nid], p->data, min_t(u32, p->size, PATCH_MAX_SIZE));
+ if (!amd_ucode_patch[nid])
+ amd_ucode_patch[nid] = kmalloc(PATCH_MAX_SIZE, GFP_KERNEL);
+
+ memset(amd_ucode_patch[nid], 0, PATCH_MAX_SIZE);
+ memcpy(amd_ucode_patch[nid], p->data, min_t(u32, p->size, PATCH_MAX_SIZE));
}

return ret;
--
2.25.1