.. | .. |
---|
55 | 55 | }; |
---|
56 | 56 | |
---|
57 | 57 | static u32 ucode_new_rev; |
---|
58 | | -static u8 amd_ucode_patch[PATCH_MAX_SIZE]; |
---|
| 58 | + |
---|
| 59 | +/* One blob per node. */ |
---|
| 60 | +static u8 amd_ucode_patch[MAX_NUMNODES][PATCH_MAX_SIZE]; |
---|
59 | 61 | |
---|
60 | 62 | /* |
---|
61 | 63 | * Microcode patch container file is prepended to the initrd in cpio |
---|
.. | .. |
---|
429 | 431 | patch = (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch); |
---|
430 | 432 | #else |
---|
431 | 433 | new_rev = &ucode_new_rev; |
---|
432 | | - patch = &amd_ucode_patch; |
---|
| 434 | + patch = &amd_ucode_patch[0]; |
---|
433 | 435 | #endif |
---|
434 | 436 | |
---|
435 | 437 | desc.cpuid_1_eax = cpuid_1_eax; |
---|
.. | .. |
---|
548 | 550 | apply_microcode_early_amd(cpuid_1_eax, cp.data, cp.size, false); |
---|
549 | 551 | } |
---|
550 | 552 | |
---|
551 | | -static enum ucode_state |
---|
552 | | -load_microcode_amd(bool save, u8 family, const u8 *data, size_t size); |
---|
| 553 | +static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size); |
---|
553 | 554 | |
---|
554 | 555 | int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax) |
---|
555 | 556 | { |
---|
.. | .. |
---|
567 | 568 | if (!desc.mc) |
---|
568 | 569 | return -EINVAL; |
---|
569 | 570 | |
---|
570 | | - ret = load_microcode_amd(true, x86_family(cpuid_1_eax), desc.data, desc.size); |
---|
| 571 | + ret = load_microcode_amd(x86_family(cpuid_1_eax), desc.data, desc.size); |
---|
571 | 572 | if (ret > UCODE_UPDATED) |
---|
572 | 573 | return -EINVAL; |
---|
573 | 574 | |
---|
574 | 575 | return 0; |
---|
575 | 576 | } |
---|
576 | 577 | |
---|
577 | | -void reload_ucode_amd(void) |
---|
| 578 | +void reload_ucode_amd(unsigned int cpu) |
---|
578 | 579 | { |
---|
579 | | - struct microcode_amd *mc; |
---|
580 | 580 | u32 rev, dummy __always_unused; |
---|
| 581 | + struct microcode_amd *mc; |
---|
581 | 582 | |
---|
582 | | - mc = (struct microcode_amd *)amd_ucode_patch; |
---|
| 583 | + mc = (struct microcode_amd *)amd_ucode_patch[cpu_to_node(cpu)]; |
---|
583 | 584 | |
---|
584 | 585 | rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); |
---|
585 | 586 | |
---|
.. | .. |
---|
699 | 700 | rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); |
---|
700 | 701 | |
---|
701 | 702 | /* need to apply patch? */ |
---|
702 | | - if (rev >= mc_amd->hdr.patch_id) { |
---|
| 703 | + if (rev > mc_amd->hdr.patch_id) { |
---|
703 | 704 | ret = UCODE_OK; |
---|
704 | 705 | goto out; |
---|
705 | 706 | } |
---|
.. | .. |
---|
845 | 846 | return UCODE_OK; |
---|
846 | 847 | } |
---|
847 | 848 | |
---|
848 | | -static enum ucode_state |
---|
849 | | -load_microcode_amd(bool save, u8 family, const u8 *data, size_t size) |
---|
| 849 | +static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size) |
---|
850 | 850 | { |
---|
| 851 | + struct cpuinfo_x86 *c; |
---|
| 852 | + unsigned int nid, cpu; |
---|
851 | 853 | struct ucode_patch *p; |
---|
852 | 854 | enum ucode_state ret; |
---|
853 | 855 | |
---|
.. | .. |
---|
860 | 862 | return ret; |
---|
861 | 863 | } |
---|
862 | 864 | |
---|
863 | | - p = find_patch(0); |
---|
864 | | - if (!p) { |
---|
865 | | - return ret; |
---|
866 | | - } else { |
---|
867 | | - if (boot_cpu_data.microcode >= p->patch_id) |
---|
868 | | - return ret; |
---|
| 865 | + for_each_node(nid) { |
---|
| 866 | + cpu = cpumask_first(cpumask_of_node(nid)); |
---|
| 867 | + c = &cpu_data(cpu); |
---|
| 868 | + |
---|
| 869 | + p = find_patch(cpu); |
---|
| 870 | + if (!p) |
---|
| 871 | + continue; |
---|
| 872 | + |
---|
| 873 | + if (c->microcode >= p->patch_id) |
---|
| 874 | + continue; |
---|
869 | 875 | |
---|
870 | 876 | ret = UCODE_NEW; |
---|
| 877 | + |
---|
| 878 | + memset(&amd_ucode_patch[nid], 0, PATCH_MAX_SIZE); |
---|
| 879 | + memcpy(&amd_ucode_patch[nid], p->data, min_t(u32, p->size, PATCH_MAX_SIZE)); |
---|
871 | 880 | } |
---|
872 | | - |
---|
873 | | - /* save BSP's matching patch for early load */ |
---|
874 | | - if (!save) |
---|
875 | | - return ret; |
---|
876 | | - |
---|
877 | | - memset(amd_ucode_patch, 0, PATCH_MAX_SIZE); |
---|
878 | | - memcpy(amd_ucode_patch, p->data, min_t(u32, p->size, PATCH_MAX_SIZE)); |
---|
879 | 881 | |
---|
880 | 882 | return ret; |
---|
881 | 883 | } |
---|
.. | .. |
---|
901 | 903 | { |
---|
902 | 904 | char fw_name[36] = "amd-ucode/microcode_amd.bin"; |
---|
903 | 905 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
---|
904 | | - bool bsp = c->cpu_index == boot_cpu_data.cpu_index; |
---|
905 | 906 | enum ucode_state ret = UCODE_NFOUND; |
---|
906 | 907 | const struct firmware *fw; |
---|
907 | 908 | |
---|
908 | 909 | /* reload ucode container only on the boot cpu */ |
---|
909 | | - if (!refresh_fw || !bsp) |
---|
| 910 | + if (!refresh_fw) |
---|
910 | 911 | return UCODE_OK; |
---|
911 | 912 | |
---|
912 | 913 | if (c->x86 >= 0x15) |
---|
.. | .. |
---|
921 | 922 | if (!verify_container(fw->data, fw->size, false)) |
---|
922 | 923 | goto fw_release; |
---|
923 | 924 | |
---|
924 | | - ret = load_microcode_amd(bsp, c->x86, fw->data, fw->size); |
---|
| 925 | + ret = load_microcode_amd(c->x86, fw->data, fw->size); |
---|
925 | 926 | |
---|
926 | 927 | fw_release: |
---|
927 | 928 | release_firmware(fw); |
---|