diff options
| -rw-r--r-- | arch/x86/kernel/cpu/microcode/amd.c | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index ce6f8381641b..6048d9dd1a15 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c | |||
| @@ -38,7 +38,9 @@ | |||
| 38 | #include <asm/cpu.h> | 38 | #include <asm/cpu.h> |
| 39 | #include <asm/msr.h> | 39 | #include <asm/msr.h> |
| 40 | 40 | ||
| 41 | static struct equiv_cpu_entry *equiv_cpu_table; | 41 | static struct equiv_cpu_table { |
| 42 | struct equiv_cpu_entry *entry; | ||
| 43 | } equiv_table; | ||
| 42 | 44 | ||
| 43 | /* | 45 | /* |
| 44 | * This points to the current valid container of microcode patches which we will | 46 | * This points to the current valid container of microcode patches which we will |
| @@ -63,11 +65,13 @@ static u8 amd_ucode_patch[PATCH_MAX_SIZE]; | |||
| 63 | static const char | 65 | static const char |
| 64 | ucode_path[] __maybe_unused = "kernel/x86/microcode/AuthenticAMD.bin"; | 66 | ucode_path[] __maybe_unused = "kernel/x86/microcode/AuthenticAMD.bin"; |
| 65 | 67 | ||
| 66 | static u16 find_equiv_id(struct equiv_cpu_entry *equiv_table, u32 sig) | 68 | static u16 find_equiv_id(struct equiv_cpu_table *et, u32 sig) |
| 67 | { | 69 | { |
| 68 | for (; equiv_table && equiv_table->installed_cpu; equiv_table++) { | 70 | struct equiv_cpu_entry *entry = et->entry; |
| 69 | if (sig == equiv_table->installed_cpu) | 71 | |
| 70 | return equiv_table->equiv_cpu; | 72 | for (; entry && entry->installed_cpu; entry++) { |
| 73 | if (sig == entry->installed_cpu) | ||
| 74 | return entry->equiv_cpu; | ||
| 71 | } | 75 | } |
| 72 | 76 | ||
| 73 | return 0; | 77 | return 0; |
| @@ -286,7 +290,7 @@ verify_patch(u8 family, const u8 *buf, size_t buf_size, u32 *patch_size, bool ea | |||
| 286 | */ | 290 | */ |
| 287 | static size_t parse_container(u8 *ucode, size_t size, struct cont_desc *desc) | 291 | static size_t parse_container(u8 *ucode, size_t size, struct cont_desc *desc) |
| 288 | { | 292 | { |
| 289 | struct equiv_cpu_entry *eq; | 293 | struct equiv_cpu_table table; |
| 290 | size_t orig_size = size; | 294 | size_t orig_size = size; |
| 291 | u32 *hdr = (u32 *)ucode; | 295 | u32 *hdr = (u32 *)ucode; |
| 292 | u16 eq_id; | 296 | u16 eq_id; |
| @@ -297,14 +301,14 @@ static size_t parse_container(u8 *ucode, size_t size, struct cont_desc *desc) | |||
| 297 | 301 | ||
| 298 | buf = ucode; | 302 | buf = ucode; |
| 299 | 303 | ||
| 300 | eq = (struct equiv_cpu_entry *)(buf + CONTAINER_HDR_SZ); | 304 | table.entry = (struct equiv_cpu_entry *)(buf + CONTAINER_HDR_SZ); |
| 301 | 305 | ||
| 302 | /* | 306 | /* |
| 303 | * Find the equivalence ID of our CPU in this table. Even if this table | 307 | * Find the equivalence ID of our CPU in this table. Even if this table |
| 304 | * doesn't contain a patch for the CPU, scan through the whole container | 308 | * doesn't contain a patch for the CPU, scan through the whole container |
| 305 | * so that it can be skipped in case there are other containers appended. | 309 | * so that it can be skipped in case there are other containers appended. |
| 306 | */ | 310 | */ |
| 307 | eq_id = find_equiv_id(eq, desc->cpuid_1_eax); | 311 | eq_id = find_equiv_id(&table, desc->cpuid_1_eax); |
| 308 | 312 | ||
| 309 | buf += hdr[2] + CONTAINER_HDR_SZ; | 313 | buf += hdr[2] + CONTAINER_HDR_SZ; |
| 310 | size -= hdr[2] + CONTAINER_HDR_SZ; | 314 | size -= hdr[2] + CONTAINER_HDR_SZ; |
| @@ -573,7 +577,7 @@ void reload_ucode_amd(void) | |||
| 573 | static u16 __find_equiv_id(unsigned int cpu) | 577 | static u16 __find_equiv_id(unsigned int cpu) |
| 574 | { | 578 | { |
| 575 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 579 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
| 576 | return find_equiv_id(equiv_cpu_table, uci->cpu_sig.sig); | 580 | return find_equiv_id(&equiv_table, uci->cpu_sig.sig); |
| 577 | } | 581 | } |
| 578 | 582 | ||
| 579 | /* | 583 | /* |
| @@ -717,13 +721,13 @@ static size_t install_equiv_cpu_table(const u8 *buf, size_t buf_size) | |||
| 717 | hdr = (const u32 *)buf; | 721 | hdr = (const u32 *)buf; |
| 718 | equiv_tbl_len = hdr[2]; | 722 | equiv_tbl_len = hdr[2]; |
| 719 | 723 | ||
| 720 | equiv_cpu_table = vmalloc(equiv_tbl_len); | 724 | equiv_table.entry = vmalloc(equiv_tbl_len); |
| 721 | if (!equiv_cpu_table) { | 725 | if (!equiv_table.entry) { |
| 722 | pr_err("failed to allocate equivalent CPU table\n"); | 726 | pr_err("failed to allocate equivalent CPU table\n"); |
| 723 | return 0; | 727 | return 0; |
| 724 | } | 728 | } |
| 725 | 729 | ||
| 726 | memcpy(equiv_cpu_table, buf + CONTAINER_HDR_SZ, equiv_tbl_len); | 730 | memcpy(equiv_table.entry, buf + CONTAINER_HDR_SZ, equiv_tbl_len); |
| 727 | 731 | ||
| 728 | /* add header length */ | 732 | /* add header length */ |
| 729 | return equiv_tbl_len + CONTAINER_HDR_SZ; | 733 | return equiv_tbl_len + CONTAINER_HDR_SZ; |
| @@ -731,8 +735,8 @@ static size_t install_equiv_cpu_table(const u8 *buf, size_t buf_size) | |||
| 731 | 735 | ||
| 732 | static void free_equiv_cpu_table(void) | 736 | static void free_equiv_cpu_table(void) |
| 733 | { | 737 | { |
| 734 | vfree(equiv_cpu_table); | 738 | vfree(equiv_table.entry); |
| 735 | equiv_cpu_table = NULL; | 739 | equiv_table.entry = NULL; |
| 736 | } | 740 | } |
| 737 | 741 | ||
| 738 | static void cleanup(void) | 742 | static void cleanup(void) |
