|
34 | 34 | #include <asm/setup.h> |
35 | 35 | #include <asm/cpu.h> |
36 | 36 | #include <asm/msr.h> |
| 37 | +#include <asm/tlb.h> |
37 | 38 |
|
38 | 39 | #include "internal.h" |
39 | 40 |
|
@@ -483,11 +484,25 @@ static void scan_containers(u8 *ucode, size_t size, struct cont_desc *desc) |
483 | 484 | } |
484 | 485 | } |
485 | 486 |
|
486 | | -static int __apply_microcode_amd(struct microcode_amd *mc) |
| 487 | +static int __apply_microcode_amd(struct microcode_amd *mc, unsigned int psize) |
487 | 488 | { |
| 489 | + unsigned long p_addr = (unsigned long)&mc->hdr.data_code; |
488 | 490 | u32 rev, dummy; |
489 | 491 |
|
490 | | - native_wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc->hdr.data_code); |
| 492 | + native_wrmsrl(MSR_AMD64_PATCH_LOADER, p_addr); |
| 493 | + |
| 494 | + if (x86_family(bsp_cpuid_1_eax) == 0x17) { |
| 495 | + unsigned long p_addr_end = p_addr + psize - 1; |
| 496 | + |
| 497 | + invlpg(p_addr); |
| 498 | + |
| 499 | + /* |
| 500 | + * Flush next page too if patch image is crossing a page |
| 501 | + * boundary. |
| 502 | + */ |
| 503 | + if (p_addr >> PAGE_SHIFT != p_addr_end >> PAGE_SHIFT) |
| 504 | + invlpg(p_addr_end); |
| 505 | + } |
491 | 506 |
|
492 | 507 | /* verify patch application was successful */ |
493 | 508 | native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); |
@@ -529,7 +544,7 @@ static bool early_apply_microcode(u32 old_rev, void *ucode, size_t size) |
529 | 544 | if (old_rev > mc->hdr.patch_id) |
530 | 545 | return ret; |
531 | 546 |
|
532 | | - return !__apply_microcode_amd(mc); |
| 547 | + return !__apply_microcode_amd(mc, desc.psize); |
533 | 548 | } |
534 | 549 |
|
535 | 550 | static bool get_builtin_microcode(struct cpio_data *cp) |
@@ -745,7 +760,7 @@ void reload_ucode_amd(unsigned int cpu) |
745 | 760 | rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); |
746 | 761 |
|
747 | 762 | if (rev < mc->hdr.patch_id) { |
748 | | - if (!__apply_microcode_amd(mc)) |
| 763 | + if (!__apply_microcode_amd(mc, p->size)) |
749 | 764 | pr_info_once("reload revision: 0x%08x\n", mc->hdr.patch_id); |
750 | 765 | } |
751 | 766 | } |
@@ -798,7 +813,7 @@ static enum ucode_state apply_microcode_amd(int cpu) |
798 | 813 | goto out; |
799 | 814 | } |
800 | 815 |
|
801 | | - if (__apply_microcode_amd(mc_amd)) { |
| 816 | + if (__apply_microcode_amd(mc_amd, p->size)) { |
802 | 817 | pr_err("CPU%d: update failed for patch_level=0x%08x\n", |
803 | 818 | cpu, mc_amd->hdr.patch_id); |
804 | 819 | return UCODE_ERROR; |
|
0 commit comments