diff options
Diffstat (limited to 'arch/x86/kernel/cpu')
| -rw-r--r-- | arch/x86/kernel/cpu/amd.c | 12 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/microcode/amd.c | 18 |
2 files changed, 28 insertions, 2 deletions
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index f5c69d8974e1..b81fe2d63e15 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
| @@ -669,6 +669,17 @@ static void init_amd_gh(struct cpuinfo_x86 *c) | |||
| 669 | set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH); | 669 | set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH); |
| 670 | } | 670 | } |
| 671 | 671 | ||
| 672 | #define MSR_AMD64_DE_CFG 0xC0011029 | ||
| 673 | |||
| 674 | static void init_amd_ln(struct cpuinfo_x86 *c) | ||
| 675 | { | ||
| 676 | /* | ||
| 677 | * Apply erratum 665 fix unconditionally so machines without a BIOS | ||
| 678 | * fix work. | ||
| 679 | */ | ||
| 680 | msr_set_bit(MSR_AMD64_DE_CFG, 31); | ||
| 681 | } | ||
| 682 | |||
| 672 | static void init_amd_bd(struct cpuinfo_x86 *c) | 683 | static void init_amd_bd(struct cpuinfo_x86 *c) |
| 673 | { | 684 | { |
| 674 | u64 value; | 685 | u64 value; |
| @@ -726,6 +737,7 @@ static void init_amd(struct cpuinfo_x86 *c) | |||
| 726 | case 6: init_amd_k7(c); break; | 737 | case 6: init_amd_k7(c); break; |
| 727 | case 0xf: init_amd_k8(c); break; | 738 | case 0xf: init_amd_k8(c); break; |
| 728 | case 0x10: init_amd_gh(c); break; | 739 | case 0x10: init_amd_gh(c); break; |
| 740 | case 0x12: init_amd_ln(c); break; | ||
| 729 | case 0x15: init_amd_bd(c); break; | 741 | case 0x15: init_amd_bd(c); break; |
| 730 | } | 742 | } |
| 731 | 743 | ||
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 27a0228c9cae..620ab06bcf45 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c | |||
| @@ -54,6 +54,7 @@ static LIST_HEAD(pcache); | |||
| 54 | */ | 54 | */ |
| 55 | static u8 *container; | 55 | static u8 *container; |
| 56 | static size_t container_size; | 56 | static size_t container_size; |
| 57 | static bool ucode_builtin; | ||
| 57 | 58 | ||
| 58 | static u32 ucode_new_rev; | 59 | static u32 ucode_new_rev; |
| 59 | static u8 amd_ucode_patch[PATCH_MAX_SIZE]; | 60 | static u8 amd_ucode_patch[PATCH_MAX_SIZE]; |
| @@ -281,18 +282,22 @@ static bool __init load_builtin_amd_microcode(struct cpio_data *cp, | |||
| 281 | void __init load_ucode_amd_bsp(unsigned int family) | 282 | void __init load_ucode_amd_bsp(unsigned int family) |
| 282 | { | 283 | { |
| 283 | struct cpio_data cp; | 284 | struct cpio_data cp; |
| 285 | bool *builtin; | ||
| 284 | void **data; | 286 | void **data; |
| 285 | size_t *size; | 287 | size_t *size; |
| 286 | 288 | ||
| 287 | #ifdef CONFIG_X86_32 | 289 | #ifdef CONFIG_X86_32 |
| 288 | data = (void **)__pa_nodebug(&ucode_cpio.data); | 290 | data = (void **)__pa_nodebug(&ucode_cpio.data); |
| 289 | size = (size_t *)__pa_nodebug(&ucode_cpio.size); | 291 | size = (size_t *)__pa_nodebug(&ucode_cpio.size); |
| 292 | builtin = (bool *)__pa_nodebug(&ucode_builtin); | ||
| 290 | #else | 293 | #else |
| 291 | data = &ucode_cpio.data; | 294 | data = &ucode_cpio.data; |
| 292 | size = &ucode_cpio.size; | 295 | size = &ucode_cpio.size; |
| 296 | builtin = &ucode_builtin; | ||
| 293 | #endif | 297 | #endif |
| 294 | 298 | ||
| 295 | if (!load_builtin_amd_microcode(&cp, family)) | 299 | *builtin = load_builtin_amd_microcode(&cp, family); |
| 300 | if (!*builtin) | ||
| 296 | cp = find_ucode_in_initrd(); | 301 | cp = find_ucode_in_initrd(); |
| 297 | 302 | ||
| 298 | if (!(cp.data && cp.size)) | 303 | if (!(cp.data && cp.size)) |
| @@ -355,6 +360,7 @@ void load_ucode_amd_ap(void) | |||
| 355 | unsigned int cpu = smp_processor_id(); | 360 | unsigned int cpu = smp_processor_id(); |
| 356 | struct equiv_cpu_entry *eq; | 361 | struct equiv_cpu_entry *eq; |
| 357 | struct microcode_amd *mc; | 362 | struct microcode_amd *mc; |
| 363 | u8 *cont = container; | ||
| 358 | u32 rev, eax; | 364 | u32 rev, eax; |
| 359 | u16 eq_id; | 365 | u16 eq_id; |
| 360 | 366 | ||
| @@ -371,8 +377,12 @@ void load_ucode_amd_ap(void) | |||
| 371 | if (check_current_patch_level(&rev, false)) | 377 | if (check_current_patch_level(&rev, false)) |
| 372 | return; | 378 | return; |
| 373 | 379 | ||
| 380 | /* Add CONFIG_RANDOMIZE_MEMORY offset. */ | ||
| 381 | if (!ucode_builtin) | ||
| 382 | cont += PAGE_OFFSET - __PAGE_OFFSET_BASE; | ||
| 383 | |||
| 374 | eax = cpuid_eax(0x00000001); | 384 | eax = cpuid_eax(0x00000001); |
| 375 | eq = (struct equiv_cpu_entry *)(container + CONTAINER_HDR_SZ); | 385 | eq = (struct equiv_cpu_entry *)(cont + CONTAINER_HDR_SZ); |
| 376 | 386 | ||
| 377 | eq_id = find_equiv_id(eq, eax); | 387 | eq_id = find_equiv_id(eq, eax); |
| 378 | if (!eq_id) | 388 | if (!eq_id) |
| @@ -434,6 +444,10 @@ int __init save_microcode_in_initrd_amd(void) | |||
| 434 | else | 444 | else |
| 435 | container = cont_va; | 445 | container = cont_va; |
| 436 | 446 | ||
| 447 | /* Add CONFIG_RANDOMIZE_MEMORY offset. */ | ||
| 448 | if (!ucode_builtin) | ||
| 449 | container += PAGE_OFFSET - __PAGE_OFFSET_BASE; | ||
| 450 | |||
| 437 | eax = cpuid_eax(0x00000001); | 451 | eax = cpuid_eax(0x00000001); |
| 438 | eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); | 452 | eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); |
| 439 | 453 | ||
