diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2014-01-29 12:07:00 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2014-01-29 12:07:00 -0500 |
commit | 4064e0ea3c0e9427e6c22392c4b69b4bfa1b7125 (patch) | |
tree | 888b52771f540552a9dc85521d8dddf66eba9aeb /arch/x86/kernel/cpu | |
parent | 9b3965f7401b0cc3ed2c228085a4c13b1c9243b1 (diff) | |
parent | f4bcd8ccddb02833340652e9f46f5127828eb79d (diff) |
Merge commit 'f4bcd8ccddb02833340652e9f46f5127828eb79d' into x86/build
Bring in upstream merge of x86/kaslr for future patches.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/kernel/cpu')
25 files changed, 3758 insertions, 58 deletions
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 47b56a7e99cb..7fd54f09b011 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile | |||
@@ -36,12 +36,13 @@ obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd_iommu.o | |||
36 | endif | 36 | endif |
37 | obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_knc.o perf_event_p4.o | 37 | obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_knc.o perf_event_p4.o |
38 | obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o | 38 | obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o |
39 | obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore.o | 39 | obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore.o perf_event_intel_rapl.o |
40 | endif | 40 | endif |
41 | 41 | ||
42 | 42 | ||
43 | obj-$(CONFIG_X86_MCE) += mcheck/ | 43 | obj-$(CONFIG_X86_MCE) += mcheck/ |
44 | obj-$(CONFIG_MTRR) += mtrr/ | 44 | obj-$(CONFIG_MTRR) += mtrr/ |
45 | obj-$(CONFIG_MICROCODE) += microcode/ | ||
45 | 46 | ||
46 | obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o perf_event_amd_ibs.o | 47 | obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o perf_event_amd_ibs.o |
47 | 48 | ||
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index bca023bdd6b2..d3153e281d72 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -1,5 +1,4 @@ | |||
1 | #include <linux/export.h> | 1 | #include <linux/export.h> |
2 | #include <linux/init.h> | ||
3 | #include <linux/bitops.h> | 2 | #include <linux/bitops.h> |
4 | #include <linux/elf.h> | 3 | #include <linux/elf.h> |
5 | #include <linux/mm.h> | 4 | #include <linux/mm.h> |
@@ -487,7 +486,7 @@ static void early_init_amd(struct cpuinfo_x86 *c) | |||
487 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | 486 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); |
488 | set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC); | 487 | set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC); |
489 | if (!check_tsc_unstable()) | 488 | if (!check_tsc_unstable()) |
490 | sched_clock_stable = 1; | 489 | set_sched_clock_stable(); |
491 | } | 490 | } |
492 | 491 | ||
493 | #ifdef CONFIG_X86_64 | 492 | #ifdef CONFIG_X86_64 |
@@ -508,6 +507,16 @@ static void early_init_amd(struct cpuinfo_x86 *c) | |||
508 | set_cpu_cap(c, X86_FEATURE_EXTD_APICID); | 507 | set_cpu_cap(c, X86_FEATURE_EXTD_APICID); |
509 | } | 508 | } |
510 | #endif | 509 | #endif |
510 | |||
511 | /* F16h erratum 793, CVE-2013-6885 */ | ||
512 | if (c->x86 == 0x16 && c->x86_model <= 0xf) { | ||
513 | u64 val; | ||
514 | |||
515 | rdmsrl(MSR_AMD64_LS_CFG, val); | ||
516 | if (!(val & BIT(15))) | ||
517 | wrmsrl(MSR_AMD64_LS_CFG, val | BIT(15)); | ||
518 | } | ||
519 | |||
511 | } | 520 | } |
512 | 521 | ||
513 | static const int amd_erratum_383[]; | 522 | static const int amd_erratum_383[]; |
@@ -790,14 +799,10 @@ static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c) | |||
790 | } | 799 | } |
791 | 800 | ||
792 | /* Handle DTLB 2M and 4M sizes, fall back to L1 if L2 is disabled */ | 801 | /* Handle DTLB 2M and 4M sizes, fall back to L1 if L2 is disabled */ |
793 | if (!((eax >> 16) & mask)) { | 802 | if (!((eax >> 16) & mask)) |
794 | u32 a, b, c, d; | 803 | tlb_lld_2m[ENTRIES] = (cpuid_eax(0x80000005) >> 16) & 0xff; |
795 | 804 | else | |
796 | cpuid(0x80000005, &a, &b, &c, &d); | ||
797 | tlb_lld_2m[ENTRIES] = (a >> 16) & 0xff; | ||
798 | } else { | ||
799 | tlb_lld_2m[ENTRIES] = (eax >> 16) & mask; | 805 | tlb_lld_2m[ENTRIES] = (eax >> 16) & mask; |
800 | } | ||
801 | 806 | ||
802 | /* a 4M entry uses two 2M entries */ | 807 | /* a 4M entry uses two 2M entries */ |
803 | tlb_lld_4m[ENTRIES] = tlb_lld_2m[ENTRIES] >> 1; | 808 | tlb_lld_4m[ENTRIES] = tlb_lld_2m[ENTRIES] >> 1; |
diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c index 8d5652dc99dd..8779edab684e 100644 --- a/arch/x86/kernel/cpu/centaur.c +++ b/arch/x86/kernel/cpu/centaur.c | |||
@@ -1,6 +1,5 @@ | |||
1 | #include <linux/bitops.h> | 1 | #include <linux/bitops.h> |
2 | #include <linux/kernel.h> | 2 | #include <linux/kernel.h> |
3 | #include <linux/init.h> | ||
4 | 3 | ||
5 | #include <asm/processor.h> | 4 | #include <asm/processor.h> |
6 | #include <asm/e820.h> | 5 | #include <asm/e820.h> |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 6abc172b8258..24b6fd10625a 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -472,6 +472,7 @@ u16 __read_mostly tlb_lli_4m[NR_INFO]; | |||
472 | u16 __read_mostly tlb_lld_4k[NR_INFO]; | 472 | u16 __read_mostly tlb_lld_4k[NR_INFO]; |
473 | u16 __read_mostly tlb_lld_2m[NR_INFO]; | 473 | u16 __read_mostly tlb_lld_2m[NR_INFO]; |
474 | u16 __read_mostly tlb_lld_4m[NR_INFO]; | 474 | u16 __read_mostly tlb_lld_4m[NR_INFO]; |
475 | u16 __read_mostly tlb_lld_1g[NR_INFO]; | ||
475 | 476 | ||
476 | /* | 477 | /* |
477 | * tlb_flushall_shift shows the balance point in replacing cr3 write | 478 | * tlb_flushall_shift shows the balance point in replacing cr3 write |
@@ -486,13 +487,13 @@ void cpu_detect_tlb(struct cpuinfo_x86 *c) | |||
486 | if (this_cpu->c_detect_tlb) | 487 | if (this_cpu->c_detect_tlb) |
487 | this_cpu->c_detect_tlb(c); | 488 | this_cpu->c_detect_tlb(c); |
488 | 489 | ||
489 | printk(KERN_INFO "Last level iTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \ | 490 | printk(KERN_INFO "Last level iTLB entries: 4KB %d, 2MB %d, 4MB %d\n" |
490 | "Last level dTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \ | 491 | "Last level dTLB entries: 4KB %d, 2MB %d, 4MB %d, 1GB %d\n" |
491 | "tlb_flushall_shift: %d\n", | 492 | "tlb_flushall_shift: %d\n", |
492 | tlb_lli_4k[ENTRIES], tlb_lli_2m[ENTRIES], | 493 | tlb_lli_4k[ENTRIES], tlb_lli_2m[ENTRIES], |
493 | tlb_lli_4m[ENTRIES], tlb_lld_4k[ENTRIES], | 494 | tlb_lli_4m[ENTRIES], tlb_lld_4k[ENTRIES], |
494 | tlb_lld_2m[ENTRIES], tlb_lld_4m[ENTRIES], | 495 | tlb_lld_2m[ENTRIES], tlb_lld_4m[ENTRIES], |
495 | tlb_flushall_shift); | 496 | tlb_lld_1g[ENTRIES], tlb_flushall_shift); |
496 | } | 497 | } |
497 | 498 | ||
498 | void detect_ht(struct cpuinfo_x86 *c) | 499 | void detect_ht(struct cpuinfo_x86 *c) |
diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c index d0969c75ab54..aaf152e79637 100644 --- a/arch/x86/kernel/cpu/cyrix.c +++ b/arch/x86/kernel/cpu/cyrix.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/bitops.h> | 1 | #include <linux/bitops.h> |
3 | #include <linux/delay.h> | 2 | #include <linux/delay.h> |
4 | #include <linux/pci.h> | 3 | #include <linux/pci.h> |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index ea04b342c026..3db61c644e44 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/kernel.h> | 1 | #include <linux/kernel.h> |
3 | 2 | ||
4 | #include <linux/string.h> | 3 | #include <linux/string.h> |
@@ -93,7 +92,7 @@ static void early_init_intel(struct cpuinfo_x86 *c) | |||
93 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | 92 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); |
94 | set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC); | 93 | set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC); |
95 | if (!check_tsc_unstable()) | 94 | if (!check_tsc_unstable()) |
96 | sched_clock_stable = 1; | 95 | set_sched_clock_stable(); |
97 | } | 96 | } |
98 | 97 | ||
99 | /* Penwell and Cloverview have the TSC which doesn't sleep on S3 */ | 98 | /* Penwell and Cloverview have the TSC which doesn't sleep on S3 */ |
@@ -506,6 +505,7 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 *c, unsigned int size) | |||
506 | #define TLB_DATA0_2M_4M 0x23 | 505 | #define TLB_DATA0_2M_4M 0x23 |
507 | 506 | ||
508 | #define STLB_4K 0x41 | 507 | #define STLB_4K 0x41 |
508 | #define STLB_4K_2M 0x42 | ||
509 | 509 | ||
510 | static const struct _tlb_table intel_tlb_table[] = { | 510 | static const struct _tlb_table intel_tlb_table[] = { |
511 | { 0x01, TLB_INST_4K, 32, " TLB_INST 4 KByte pages, 4-way set associative" }, | 511 | { 0x01, TLB_INST_4K, 32, " TLB_INST 4 KByte pages, 4-way set associative" }, |
@@ -526,13 +526,20 @@ static const struct _tlb_table intel_tlb_table[] = { | |||
526 | { 0x5b, TLB_DATA_4K_4M, 64, " TLB_DATA 4 KByte and 4 MByte pages" }, | 526 | { 0x5b, TLB_DATA_4K_4M, 64, " TLB_DATA 4 KByte and 4 MByte pages" }, |
527 | { 0x5c, TLB_DATA_4K_4M, 128, " TLB_DATA 4 KByte and 4 MByte pages" }, | 527 | { 0x5c, TLB_DATA_4K_4M, 128, " TLB_DATA 4 KByte and 4 MByte pages" }, |
528 | { 0x5d, TLB_DATA_4K_4M, 256, " TLB_DATA 4 KByte and 4 MByte pages" }, | 528 | { 0x5d, TLB_DATA_4K_4M, 256, " TLB_DATA 4 KByte and 4 MByte pages" }, |
529 | { 0x61, TLB_INST_4K, 48, " TLB_INST 4 KByte pages, full associative" }, | ||
530 | { 0x63, TLB_DATA_1G, 4, " TLB_DATA 1 GByte pages, 4-way set associative" }, | ||
531 | { 0x76, TLB_INST_2M_4M, 8, " TLB_INST 2-MByte or 4-MByte pages, fully associative" }, | ||
529 | { 0xb0, TLB_INST_4K, 128, " TLB_INST 4 KByte pages, 4-way set associative" }, | 532 | { 0xb0, TLB_INST_4K, 128, " TLB_INST 4 KByte pages, 4-way set associative" }, |
530 | { 0xb1, TLB_INST_2M_4M, 4, " TLB_INST 2M pages, 4-way, 8 entries or 4M pages, 4-way entries" }, | 533 | { 0xb1, TLB_INST_2M_4M, 4, " TLB_INST 2M pages, 4-way, 8 entries or 4M pages, 4-way entries" }, |
531 | { 0xb2, TLB_INST_4K, 64, " TLB_INST 4KByte pages, 4-way set associative" }, | 534 | { 0xb2, TLB_INST_4K, 64, " TLB_INST 4KByte pages, 4-way set associative" }, |
532 | { 0xb3, TLB_DATA_4K, 128, " TLB_DATA 4 KByte pages, 4-way set associative" }, | 535 | { 0xb3, TLB_DATA_4K, 128, " TLB_DATA 4 KByte pages, 4-way set associative" }, |
533 | { 0xb4, TLB_DATA_4K, 256, " TLB_DATA 4 KByte pages, 4-way associative" }, | 536 | { 0xb4, TLB_DATA_4K, 256, " TLB_DATA 4 KByte pages, 4-way associative" }, |
537 | { 0xb5, TLB_INST_4K, 64, " TLB_INST 4 KByte pages, 8-way set ssociative" }, | ||
538 | { 0xb6, TLB_INST_4K, 128, " TLB_INST 4 KByte pages, 8-way set ssociative" }, | ||
534 | { 0xba, TLB_DATA_4K, 64, " TLB_DATA 4 KByte pages, 4-way associative" }, | 539 | { 0xba, TLB_DATA_4K, 64, " TLB_DATA 4 KByte pages, 4-way associative" }, |
535 | { 0xc0, TLB_DATA_4K_4M, 8, " TLB_DATA 4 KByte and 4 MByte pages, 4-way associative" }, | 540 | { 0xc0, TLB_DATA_4K_4M, 8, " TLB_DATA 4 KByte and 4 MByte pages, 4-way associative" }, |
541 | { 0xc1, STLB_4K_2M, 1024, " STLB 4 KByte and 2 MByte pages, 8-way associative" }, | ||
542 | { 0xc2, TLB_DATA_2M_4M, 16, " DTLB 2 MByte/4MByte pages, 4-way associative" }, | ||
536 | { 0xca, STLB_4K, 512, " STLB 4 KByte pages, 4-way associative" }, | 543 | { 0xca, STLB_4K, 512, " STLB 4 KByte pages, 4-way associative" }, |
537 | { 0x00, 0, 0 } | 544 | { 0x00, 0, 0 } |
538 | }; | 545 | }; |
@@ -558,6 +565,20 @@ static void intel_tlb_lookup(const unsigned char desc) | |||
558 | if (tlb_lld_4k[ENTRIES] < intel_tlb_table[k].entries) | 565 | if (tlb_lld_4k[ENTRIES] < intel_tlb_table[k].entries) |
559 | tlb_lld_4k[ENTRIES] = intel_tlb_table[k].entries; | 566 | tlb_lld_4k[ENTRIES] = intel_tlb_table[k].entries; |
560 | break; | 567 | break; |
568 | case STLB_4K_2M: | ||
569 | if (tlb_lli_4k[ENTRIES] < intel_tlb_table[k].entries) | ||
570 | tlb_lli_4k[ENTRIES] = intel_tlb_table[k].entries; | ||
571 | if (tlb_lld_4k[ENTRIES] < intel_tlb_table[k].entries) | ||
572 | tlb_lld_4k[ENTRIES] = intel_tlb_table[k].entries; | ||
573 | if (tlb_lli_2m[ENTRIES] < intel_tlb_table[k].entries) | ||
574 | tlb_lli_2m[ENTRIES] = intel_tlb_table[k].entries; | ||
575 | if (tlb_lld_2m[ENTRIES] < intel_tlb_table[k].entries) | ||
576 | tlb_lld_2m[ENTRIES] = intel_tlb_table[k].entries; | ||
577 | if (tlb_lli_4m[ENTRIES] < intel_tlb_table[k].entries) | ||
578 | tlb_lli_4m[ENTRIES] = intel_tlb_table[k].entries; | ||
579 | if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries) | ||
580 | tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries; | ||
581 | break; | ||
561 | case TLB_INST_ALL: | 582 | case TLB_INST_ALL: |
562 | if (tlb_lli_4k[ENTRIES] < intel_tlb_table[k].entries) | 583 | if (tlb_lli_4k[ENTRIES] < intel_tlb_table[k].entries) |
563 | tlb_lli_4k[ENTRIES] = intel_tlb_table[k].entries; | 584 | tlb_lli_4k[ENTRIES] = intel_tlb_table[k].entries; |
@@ -603,6 +624,10 @@ static void intel_tlb_lookup(const unsigned char desc) | |||
603 | if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries) | 624 | if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries) |
604 | tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries; | 625 | tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries; |
605 | break; | 626 | break; |
627 | case TLB_DATA_1G: | ||
628 | if (tlb_lld_1g[ENTRIES] < intel_tlb_table[k].entries) | ||
629 | tlb_lld_1g[ENTRIES] = intel_tlb_table[k].entries; | ||
630 | break; | ||
606 | } | 631 | } |
607 | } | 632 | } |
608 | 633 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce-apei.c b/arch/x86/kernel/cpu/mcheck/mce-apei.c index de8b60a53f69..a1aef9533154 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-apei.c +++ b/arch/x86/kernel/cpu/mcheck/mce-apei.c | |||
@@ -33,22 +33,28 @@ | |||
33 | #include <linux/acpi.h> | 33 | #include <linux/acpi.h> |
34 | #include <linux/cper.h> | 34 | #include <linux/cper.h> |
35 | #include <acpi/apei.h> | 35 | #include <acpi/apei.h> |
36 | #include <acpi/ghes.h> | ||
36 | #include <asm/mce.h> | 37 | #include <asm/mce.h> |
37 | 38 | ||
38 | #include "mce-internal.h" | 39 | #include "mce-internal.h" |
39 | 40 | ||
40 | void apei_mce_report_mem_error(int corrected, struct cper_sec_mem_err *mem_err) | 41 | void apei_mce_report_mem_error(int severity, struct cper_sec_mem_err *mem_err) |
41 | { | 42 | { |
42 | struct mce m; | 43 | struct mce m; |
43 | 44 | ||
44 | /* Only corrected MC is reported */ | 45 | if (!(mem_err->validation_bits & CPER_MEM_VALID_PA)) |
45 | if (!corrected || !(mem_err->validation_bits & CPER_MEM_VALID_PA)) | ||
46 | return; | 46 | return; |
47 | 47 | ||
48 | mce_setup(&m); | 48 | mce_setup(&m); |
49 | m.bank = 1; | 49 | m.bank = 1; |
50 | /* Fake a memory read corrected error with unknown channel */ | 50 | /* Fake a memory read error with unknown channel */ |
51 | m.status = MCI_STATUS_VAL | MCI_STATUS_EN | MCI_STATUS_ADDRV | 0x9f; | 51 | m.status = MCI_STATUS_VAL | MCI_STATUS_EN | MCI_STATUS_ADDRV | 0x9f; |
52 | |||
53 | if (severity >= GHES_SEV_RECOVERABLE) | ||
54 | m.status |= MCI_STATUS_UC; | ||
55 | if (severity >= GHES_SEV_PANIC) | ||
56 | m.status |= MCI_STATUS_PCC; | ||
57 | |||
52 | m.addr = mem_err->physical_addr; | 58 | m.addr = mem_err->physical_addr; |
53 | mce_log(&m); | 59 | mce_log(&m); |
54 | mce_notify_irq(); | 60 | mce_notify_irq(); |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index b3218cdee95f..4d5419b249da 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -1638,15 +1638,15 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c) | |||
1638 | 1638 | ||
1639 | static void mce_start_timer(unsigned int cpu, struct timer_list *t) | 1639 | static void mce_start_timer(unsigned int cpu, struct timer_list *t) |
1640 | { | 1640 | { |
1641 | unsigned long iv = mce_adjust_timer(check_interval * HZ); | 1641 | unsigned long iv = check_interval * HZ; |
1642 | |||
1643 | __this_cpu_write(mce_next_interval, iv); | ||
1644 | 1642 | ||
1645 | if (mca_cfg.ignore_ce || !iv) | 1643 | if (mca_cfg.ignore_ce || !iv) |
1646 | return; | 1644 | return; |
1647 | 1645 | ||
1646 | per_cpu(mce_next_interval, cpu) = iv; | ||
1647 | |||
1648 | t->expires = round_jiffies(jiffies + iv); | 1648 | t->expires = round_jiffies(jiffies + iv); |
1649 | add_timer_on(t, smp_processor_id()); | 1649 | add_timer_on(t, cpu); |
1650 | } | 1650 | } |
1651 | 1651 | ||
1652 | static void __mcheck_cpu_init_timer(void) | 1652 | static void __mcheck_cpu_init_timer(void) |
@@ -2272,8 +2272,10 @@ static int mce_device_create(unsigned int cpu) | |||
2272 | dev->release = &mce_device_release; | 2272 | dev->release = &mce_device_release; |
2273 | 2273 | ||
2274 | err = device_register(dev); | 2274 | err = device_register(dev); |
2275 | if (err) | 2275 | if (err) { |
2276 | put_device(dev); | ||
2276 | return err; | 2277 | return err; |
2278 | } | ||
2277 | 2279 | ||
2278 | for (i = 0; mce_device_attrs[i]; i++) { | 2280 | for (i = 0; mce_device_attrs[i]; i++) { |
2279 | err = device_create_file(dev, mce_device_attrs[i]); | 2281 | err = device_create_file(dev, mce_device_attrs[i]); |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c index 4cfe0458ca66..fb6156fee6f7 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c | |||
@@ -6,7 +6,6 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/gfp.h> | 8 | #include <linux/gfp.h> |
9 | #include <linux/init.h> | ||
10 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
11 | #include <linux/percpu.h> | 10 | #include <linux/percpu.h> |
12 | #include <linux/sched.h> | 11 | #include <linux/sched.h> |
diff --git a/arch/x86/kernel/cpu/mcheck/p5.c b/arch/x86/kernel/cpu/mcheck/p5.c index 1c044b1ccc59..a3042989398c 100644 --- a/arch/x86/kernel/cpu/mcheck/p5.c +++ b/arch/x86/kernel/cpu/mcheck/p5.c | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <linux/interrupt.h> | 5 | #include <linux/interrupt.h> |
6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <linux/init.h> | ||
9 | #include <linux/smp.h> | 8 | #include <linux/smp.h> |
10 | 9 | ||
11 | #include <asm/processor.h> | 10 | #include <asm/processor.h> |
diff --git a/arch/x86/kernel/cpu/mcheck/winchip.c b/arch/x86/kernel/cpu/mcheck/winchip.c index e9a701aecaa1..7dc5564d0cdf 100644 --- a/arch/x86/kernel/cpu/mcheck/winchip.c +++ b/arch/x86/kernel/cpu/mcheck/winchip.c | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <linux/interrupt.h> | 5 | #include <linux/interrupt.h> |
6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <linux/init.h> | ||
9 | 8 | ||
10 | #include <asm/processor.h> | 9 | #include <asm/processor.h> |
11 | #include <asm/mce.h> | 10 | #include <asm/mce.h> |
diff --git a/arch/x86/kernel/cpu/microcode/Makefile b/arch/x86/kernel/cpu/microcode/Makefile new file mode 100644 index 000000000000..285c85427c32 --- /dev/null +++ b/arch/x86/kernel/cpu/microcode/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | microcode-y := core.o | ||
2 | obj-$(CONFIG_MICROCODE) += microcode.o | ||
3 | microcode-$(CONFIG_MICROCODE_INTEL) += intel.o intel_lib.o | ||
4 | microcode-$(CONFIG_MICROCODE_AMD) += amd.o | ||
5 | obj-$(CONFIG_MICROCODE_EARLY) += core_early.o | ||
6 | obj-$(CONFIG_MICROCODE_INTEL_EARLY) += intel_early.o | ||
7 | obj-$(CONFIG_MICROCODE_AMD_EARLY) += amd_early.o | ||
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c new file mode 100644 index 000000000000..4a6ff747aaad --- /dev/null +++ b/arch/x86/kernel/cpu/microcode/amd.c | |||
@@ -0,0 +1,492 @@ | |||
1 | /* | ||
2 | * AMD CPU Microcode Update Driver for Linux | ||
3 | * Copyright (C) 2008-2011 Advanced Micro Devices Inc. | ||
4 | * | ||
5 | * Author: Peter Oruba <peter.oruba@amd.com> | ||
6 | * | ||
7 | * Based on work by: | ||
8 | * Tigran Aivazian <tigran@aivazian.fsnet.co.uk> | ||
9 | * | ||
10 | * Maintainers: | ||
11 | * Andreas Herrmann <herrmann.der.user@googlemail.com> | ||
12 | * Borislav Petkov <bp@alien8.de> | ||
13 | * | ||
14 | * This driver allows to upgrade microcode on F10h AMD | ||
15 | * CPUs and later. | ||
16 | * | ||
17 | * Licensed under the terms of the GNU General Public | ||
18 | * License version 2. See file COPYING for details. | ||
19 | */ | ||
20 | |||
21 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
22 | |||
23 | #include <linux/firmware.h> | ||
24 | #include <linux/pci_ids.h> | ||
25 | #include <linux/uaccess.h> | ||
26 | #include <linux/vmalloc.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/pci.h> | ||
30 | |||
31 | #include <asm/microcode.h> | ||
32 | #include <asm/processor.h> | ||
33 | #include <asm/msr.h> | ||
34 | #include <asm/microcode_amd.h> | ||
35 | |||
36 | MODULE_DESCRIPTION("AMD Microcode Update Driver"); | ||
37 | MODULE_AUTHOR("Peter Oruba"); | ||
38 | MODULE_LICENSE("GPL v2"); | ||
39 | |||
40 | static struct equiv_cpu_entry *equiv_cpu_table; | ||
41 | |||
42 | struct ucode_patch { | ||
43 | struct list_head plist; | ||
44 | void *data; | ||
45 | u32 patch_id; | ||
46 | u16 equiv_cpu; | ||
47 | }; | ||
48 | |||
49 | static LIST_HEAD(pcache); | ||
50 | |||
51 | static u16 __find_equiv_id(unsigned int cpu) | ||
52 | { | ||
53 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | ||
54 | return find_equiv_id(equiv_cpu_table, uci->cpu_sig.sig); | ||
55 | } | ||
56 | |||
57 | static u32 find_cpu_family_by_equiv_cpu(u16 equiv_cpu) | ||
58 | { | ||
59 | int i = 0; | ||
60 | |||
61 | BUG_ON(!equiv_cpu_table); | ||
62 | |||
63 | while (equiv_cpu_table[i].equiv_cpu != 0) { | ||
64 | if (equiv_cpu == equiv_cpu_table[i].equiv_cpu) | ||
65 | return equiv_cpu_table[i].installed_cpu; | ||
66 | i++; | ||
67 | } | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | /* | ||
72 | * a small, trivial cache of per-family ucode patches | ||
73 | */ | ||
74 | static struct ucode_patch *cache_find_patch(u16 equiv_cpu) | ||
75 | { | ||
76 | struct ucode_patch *p; | ||
77 | |||
78 | list_for_each_entry(p, &pcache, plist) | ||
79 | if (p->equiv_cpu == equiv_cpu) | ||
80 | return p; | ||
81 | return NULL; | ||
82 | } | ||
83 | |||
84 | static void update_cache(struct ucode_patch *new_patch) | ||
85 | { | ||
86 | struct ucode_patch *p; | ||
87 | |||
88 | list_for_each_entry(p, &pcache, plist) { | ||
89 | if (p->equiv_cpu == new_patch->equiv_cpu) { | ||
90 | if (p->patch_id >= new_patch->patch_id) | ||
91 | /* we already have the latest patch */ | ||
92 | return; | ||
93 | |||
94 | list_replace(&p->plist, &new_patch->plist); | ||
95 | kfree(p->data); | ||
96 | kfree(p); | ||
97 | return; | ||
98 | } | ||
99 | } | ||
100 | /* no patch found, add it */ | ||
101 | list_add_tail(&new_patch->plist, &pcache); | ||
102 | } | ||
103 | |||
104 | static void free_cache(void) | ||
105 | { | ||
106 | struct ucode_patch *p, *tmp; | ||
107 | |||
108 | list_for_each_entry_safe(p, tmp, &pcache, plist) { | ||
109 | __list_del(p->plist.prev, p->plist.next); | ||
110 | kfree(p->data); | ||
111 | kfree(p); | ||
112 | } | ||
113 | } | ||
114 | |||
115 | static struct ucode_patch *find_patch(unsigned int cpu) | ||
116 | { | ||
117 | u16 equiv_id; | ||
118 | |||
119 | equiv_id = __find_equiv_id(cpu); | ||
120 | if (!equiv_id) | ||
121 | return NULL; | ||
122 | |||
123 | return cache_find_patch(equiv_id); | ||
124 | } | ||
125 | |||
126 | static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) | ||
127 | { | ||
128 | struct cpuinfo_x86 *c = &cpu_data(cpu); | ||
129 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | ||
130 | struct ucode_patch *p; | ||
131 | |||
132 | csig->sig = cpuid_eax(0x00000001); | ||
133 | csig->rev = c->microcode; | ||
134 | |||
135 | /* | ||
136 | * a patch could have been loaded early, set uci->mc so that | ||
137 | * mc_bp_resume() can call apply_microcode() | ||
138 | */ | ||
139 | p = find_patch(cpu); | ||
140 | if (p && (p->patch_id == csig->rev)) | ||
141 | uci->mc = p->data; | ||
142 | |||
143 | pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev); | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static unsigned int verify_patch_size(u8 family, u32 patch_size, | ||
149 | unsigned int size) | ||
150 | { | ||
151 | u32 max_size; | ||
152 | |||
153 | #define F1XH_MPB_MAX_SIZE 2048 | ||
154 | #define F14H_MPB_MAX_SIZE 1824 | ||
155 | #define F15H_MPB_MAX_SIZE 4096 | ||
156 | #define F16H_MPB_MAX_SIZE 3458 | ||
157 | |||
158 | switch (family) { | ||
159 | case 0x14: | ||
160 | max_size = F14H_MPB_MAX_SIZE; | ||
161 | break; | ||
162 | case 0x15: | ||
163 | max_size = F15H_MPB_MAX_SIZE; | ||
164 | break; | ||
165 | case 0x16: | ||
166 | max_size = F16H_MPB_MAX_SIZE; | ||
167 | break; | ||
168 | default: | ||
169 | max_size = F1XH_MPB_MAX_SIZE; | ||
170 | break; | ||
171 | } | ||
172 | |||
173 | if (patch_size > min_t(u32, size, max_size)) { | ||
174 | pr_err("patch size mismatch\n"); | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | return patch_size; | ||
179 | } | ||
180 | |||
181 | int __apply_microcode_amd(struct microcode_amd *mc_amd) | ||
182 | { | ||
183 | u32 rev, dummy; | ||
184 | |||
185 | native_wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc_amd->hdr.data_code); | ||
186 | |||
187 | /* verify patch application was successful */ | ||
188 | native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); | ||
189 | if (rev != mc_amd->hdr.patch_id) | ||
190 | return -1; | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | int apply_microcode_amd(int cpu) | ||
196 | { | ||
197 | struct cpuinfo_x86 *c = &cpu_data(cpu); | ||
198 | struct microcode_amd *mc_amd; | ||
199 | struct ucode_cpu_info *uci; | ||
200 | struct ucode_patch *p; | ||
201 | u32 rev, dummy; | ||
202 | |||
203 | BUG_ON(raw_smp_processor_id() != cpu); | ||
204 | |||
205 | uci = ucode_cpu_info + cpu; | ||
206 | |||
207 | p = find_patch(cpu); | ||
208 | if (!p) | ||
209 | return 0; | ||
210 | |||
211 | mc_amd = p->data; | ||
212 | uci->mc = p->data; | ||
213 | |||
214 | rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); | ||
215 | |||
216 | /* need to apply patch? */ | ||
217 | if (rev >= mc_amd->hdr.patch_id) { | ||
218 | c->microcode = rev; | ||
219 | uci->cpu_sig.rev = rev; | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | if (__apply_microcode_amd(mc_amd)) { | ||
224 | pr_err("CPU%d: update failed for patch_level=0x%08x\n", | ||
225 | cpu, mc_amd->hdr.patch_id); | ||
226 | return -1; | ||
227 | } | ||
228 | pr_info("CPU%d: new patch_level=0x%08x\n", cpu, | ||
229 | mc_amd->hdr.patch_id); | ||
230 | |||
231 | uci->cpu_sig.rev = mc_amd->hdr.patch_id; | ||
232 | c->microcode = mc_amd->hdr.patch_id; | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static int install_equiv_cpu_table(const u8 *buf) | ||
238 | { | ||
239 | unsigned int *ibuf = (unsigned int *)buf; | ||
240 | unsigned int type = ibuf[1]; | ||
241 | unsigned int size = ibuf[2]; | ||
242 | |||
243 | if (type != UCODE_EQUIV_CPU_TABLE_TYPE || !size) { | ||
244 | pr_err("empty section/" | ||
245 | "invalid type field in container file section header\n"); | ||
246 | return -EINVAL; | ||
247 | } | ||
248 | |||
249 | equiv_cpu_table = vmalloc(size); | ||
250 | if (!equiv_cpu_table) { | ||
251 | pr_err("failed to allocate equivalent CPU table\n"); | ||
252 | return -ENOMEM; | ||
253 | } | ||
254 | |||
255 | memcpy(equiv_cpu_table, buf + CONTAINER_HDR_SZ, size); | ||
256 | |||
257 | /* add header length */ | ||
258 | return size + CONTAINER_HDR_SZ; | ||
259 | } | ||
260 | |||
261 | static void free_equiv_cpu_table(void) | ||
262 | { | ||
263 | vfree(equiv_cpu_table); | ||
264 | equiv_cpu_table = NULL; | ||
265 | } | ||
266 | |||
267 | static void cleanup(void) | ||
268 | { | ||
269 | free_equiv_cpu_table(); | ||
270 | free_cache(); | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * We return the current size even if some of the checks failed so that | ||
275 | * we can skip over the next patch. If we return a negative value, we | ||
276 | * signal a grave error like a memory allocation has failed and the | ||
277 | * driver cannot continue functioning normally. In such cases, we tear | ||
278 | * down everything we've used up so far and exit. | ||
279 | */ | ||
280 | static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover) | ||
281 | { | ||
282 | struct microcode_header_amd *mc_hdr; | ||
283 | struct ucode_patch *patch; | ||
284 | unsigned int patch_size, crnt_size, ret; | ||
285 | u32 proc_fam; | ||
286 | u16 proc_id; | ||
287 | |||
288 | patch_size = *(u32 *)(fw + 4); | ||
289 | crnt_size = patch_size + SECTION_HDR_SIZE; | ||
290 | mc_hdr = (struct microcode_header_amd *)(fw + SECTION_HDR_SIZE); | ||
291 | proc_id = mc_hdr->processor_rev_id; | ||
292 | |||
293 | proc_fam = find_cpu_family_by_equiv_cpu(proc_id); | ||
294 | if (!proc_fam) { | ||
295 | pr_err("No patch family for equiv ID: 0x%04x\n", proc_id); | ||
296 | return crnt_size; | ||
297 | } | ||
298 | |||
299 | /* check if patch is for the current family */ | ||
300 | proc_fam = ((proc_fam >> 8) & 0xf) + ((proc_fam >> 20) & 0xff); | ||
301 | if (proc_fam != family) | ||
302 | return crnt_size; | ||
303 | |||
304 | if (mc_hdr->nb_dev_id || mc_hdr->sb_dev_id) { | ||
305 | pr_err("Patch-ID 0x%08x: chipset-specific code unsupported.\n", | ||
306 | mc_hdr->patch_id); | ||
307 | return crnt_size; | ||
308 | } | ||
309 | |||
310 | ret = verify_patch_size(family, patch_size, leftover); | ||
311 | if (!ret) { | ||
312 | pr_err("Patch-ID 0x%08x: size mismatch.\n", mc_hdr->patch_id); | ||
313 | return crnt_size; | ||
314 | } | ||
315 | |||
316 | patch = kzalloc(sizeof(*patch), GFP_KERNEL); | ||
317 | if (!patch) { | ||
318 | pr_err("Patch allocation failure.\n"); | ||
319 | return -EINVAL; | ||
320 | } | ||
321 | |||
322 | patch->data = kzalloc(patch_size, GFP_KERNEL); | ||
323 | if (!patch->data) { | ||
324 | pr_err("Patch data allocation failure.\n"); | ||
325 | kfree(patch); | ||
326 | return -EINVAL; | ||
327 | } | ||
328 | |||
329 | /* All looks ok, copy patch... */ | ||
330 | memcpy(patch->data, fw + SECTION_HDR_SIZE, patch_size); | ||
331 | INIT_LIST_HEAD(&patch->plist); | ||
332 | patch->patch_id = mc_hdr->patch_id; | ||
333 | patch->equiv_cpu = proc_id; | ||
334 | |||
335 | pr_debug("%s: Added patch_id: 0x%08x, proc_id: 0x%04x\n", | ||
336 | __func__, patch->patch_id, proc_id); | ||
337 | |||
338 | /* ... and add to cache. */ | ||
339 | update_cache(patch); | ||
340 | |||
341 | return crnt_size; | ||
342 | } | ||
343 | |||
344 | static enum ucode_state __load_microcode_amd(u8 family, const u8 *data, | ||
345 | size_t size) | ||
346 | { | ||
347 | enum ucode_state ret = UCODE_ERROR; | ||
348 | unsigned int leftover; | ||
349 | u8 *fw = (u8 *)data; | ||
350 | int crnt_size = 0; | ||
351 | int offset; | ||
352 | |||
353 | offset = install_equiv_cpu_table(data); | ||
354 | if (offset < 0) { | ||
355 | pr_err("failed to create equivalent cpu table\n"); | ||
356 | return ret; | ||
357 | } | ||
358 | fw += offset; | ||
359 | leftover = size - offset; | ||
360 | |||
361 | if (*(u32 *)fw != UCODE_UCODE_TYPE) { | ||
362 | pr_err("invalid type field in container file section header\n"); | ||
363 | free_equiv_cpu_table(); | ||
364 | return ret; | ||
365 | } | ||
366 | |||
367 | while (leftover) { | ||
368 | crnt_size = verify_and_add_patch(family, fw, leftover); | ||
369 | if (crnt_size < 0) | ||
370 | return ret; | ||
371 | |||
372 | fw += crnt_size; | ||
373 | leftover -= crnt_size; | ||
374 | } | ||
375 | |||
376 | return UCODE_OK; | ||
377 | } | ||
378 | |||
379 | enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size) | ||
380 | { | ||
381 | enum ucode_state ret; | ||
382 | |||
383 | /* free old equiv table */ | ||
384 | free_equiv_cpu_table(); | ||
385 | |||
386 | ret = __load_microcode_amd(family, data, size); | ||
387 | |||
388 | if (ret != UCODE_OK) | ||
389 | cleanup(); | ||
390 | |||
391 | #if defined(CONFIG_MICROCODE_AMD_EARLY) && defined(CONFIG_X86_32) | ||
392 | /* save BSP's matching patch for early load */ | ||
393 | if (cpu_data(smp_processor_id()).cpu_index == boot_cpu_data.cpu_index) { | ||
394 | struct ucode_patch *p = find_patch(smp_processor_id()); | ||
395 | if (p) { | ||
396 | memset(amd_ucode_patch, 0, PATCH_MAX_SIZE); | ||
397 | memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), | ||
398 | PATCH_MAX_SIZE)); | ||
399 | } | ||
400 | } | ||
401 | #endif | ||
402 | return ret; | ||
403 | } | ||
404 | |||
405 | /* | ||
406 | * AMD microcode firmware naming convention, up to family 15h they are in | ||
407 | * the legacy file: | ||
408 | * | ||
409 | * amd-ucode/microcode_amd.bin | ||
410 | * | ||
411 | * This legacy file is always smaller than 2K in size. | ||
412 | * | ||
413 | * Beginning with family 15h, they are in family-specific firmware files: | ||
414 | * | ||
415 | * amd-ucode/microcode_amd_fam15h.bin | ||
416 | * amd-ucode/microcode_amd_fam16h.bin | ||
417 | * ... | ||
418 | * | ||
419 | * These might be larger than 2K. | ||
420 | */ | ||
421 | static enum ucode_state request_microcode_amd(int cpu, struct device *device, | ||
422 | bool refresh_fw) | ||
423 | { | ||
424 | char fw_name[36] = "amd-ucode/microcode_amd.bin"; | ||
425 | struct cpuinfo_x86 *c = &cpu_data(cpu); | ||
426 | enum ucode_state ret = UCODE_NFOUND; | ||
427 | const struct firmware *fw; | ||
428 | |||
429 | /* reload ucode container only on the boot cpu */ | ||
430 | if (!refresh_fw || c->cpu_index != boot_cpu_data.cpu_index) | ||
431 | return UCODE_OK; | ||
432 | |||
433 | if (c->x86 >= 0x15) | ||
434 | snprintf(fw_name, sizeof(fw_name), "amd-ucode/microcode_amd_fam%.2xh.bin", c->x86); | ||
435 | |||
436 | if (request_firmware(&fw, (const char *)fw_name, device)) { | ||
437 | pr_debug("failed to load file %s\n", fw_name); | ||
438 | goto out; | ||
439 | } | ||
440 | |||
441 | ret = UCODE_ERROR; | ||
442 | if (*(u32 *)fw->data != UCODE_MAGIC) { | ||
443 | pr_err("invalid magic value (0x%08x)\n", *(u32 *)fw->data); | ||
444 | goto fw_release; | ||
445 | } | ||
446 | |||
447 | ret = load_microcode_amd(c->x86, fw->data, fw->size); | ||
448 | |||
449 | fw_release: | ||
450 | release_firmware(fw); | ||
451 | |||
452 | out: | ||
453 | return ret; | ||
454 | } | ||
455 | |||
456 | static enum ucode_state | ||
457 | request_microcode_user(int cpu, const void __user *buf, size_t size) | ||
458 | { | ||
459 | return UCODE_ERROR; | ||
460 | } | ||
461 | |||
462 | static void microcode_fini_cpu_amd(int cpu) | ||
463 | { | ||
464 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | ||
465 | |||
466 | uci->mc = NULL; | ||
467 | } | ||
468 | |||
469 | static struct microcode_ops microcode_amd_ops = { | ||
470 | .request_microcode_user = request_microcode_user, | ||
471 | .request_microcode_fw = request_microcode_amd, | ||
472 | .collect_cpu_info = collect_cpu_info_amd, | ||
473 | .apply_microcode = apply_microcode_amd, | ||
474 | .microcode_fini_cpu = microcode_fini_cpu_amd, | ||
475 | }; | ||
476 | |||
477 | struct microcode_ops * __init init_amd_microcode(void) | ||
478 | { | ||
479 | struct cpuinfo_x86 *c = &cpu_data(0); | ||
480 | |||
481 | if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) { | ||
482 | pr_warning("AMD CPU family 0x%x not supported\n", c->x86); | ||
483 | return NULL; | ||
484 | } | ||
485 | |||
486 | return µcode_amd_ops; | ||
487 | } | ||
488 | |||
489 | void __exit exit_amd_microcode(void) | ||
490 | { | ||
491 | cleanup(); | ||
492 | } | ||
diff --git a/arch/x86/kernel/cpu/microcode/amd_early.c b/arch/x86/kernel/cpu/microcode/amd_early.c new file mode 100644 index 000000000000..8384c0fa206f --- /dev/null +++ b/arch/x86/kernel/cpu/microcode/amd_early.c | |||
@@ -0,0 +1,380 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Author: Jacob Shin <jacob.shin@amd.com> | ||
5 | * Fixes: Borislav Petkov <bp@suse.de> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/earlycpio.h> | ||
13 | #include <linux/initrd.h> | ||
14 | |||
15 | #include <asm/cpu.h> | ||
16 | #include <asm/setup.h> | ||
17 | #include <asm/microcode_amd.h> | ||
18 | |||
19 | /* | ||
20 | * This points to the current valid container of microcode patches which we will | ||
21 | * save from the initrd before jettisoning its contents. | ||
22 | */ | ||
23 | static u8 *container; | ||
24 | static size_t container_size; | ||
25 | |||
26 | static u32 ucode_new_rev; | ||
27 | u8 amd_ucode_patch[PATCH_MAX_SIZE]; | ||
28 | static u16 this_equiv_id; | ||
29 | |||
30 | struct cpio_data ucode_cpio; | ||
31 | |||
32 | /* | ||
33 | * Microcode patch container file is prepended to the initrd in cpio format. | ||
34 | * See Documentation/x86/early-microcode.txt | ||
35 | */ | ||
36 | static __initdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin"; | ||
37 | |||
38 | static struct cpio_data __init find_ucode_in_initrd(void) | ||
39 | { | ||
40 | long offset = 0; | ||
41 | char *path; | ||
42 | void *start; | ||
43 | size_t size; | ||
44 | |||
45 | #ifdef CONFIG_X86_32 | ||
46 | struct boot_params *p; | ||
47 | |||
48 | /* | ||
49 | * On 32-bit, early load occurs before paging is turned on so we need | ||
50 | * to use physical addresses. | ||
51 | */ | ||
52 | p = (struct boot_params *)__pa_nodebug(&boot_params); | ||
53 | path = (char *)__pa_nodebug(ucode_path); | ||
54 | start = (void *)p->hdr.ramdisk_image; | ||
55 | size = p->hdr.ramdisk_size; | ||
56 | #else | ||
57 | path = ucode_path; | ||
58 | start = (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET); | ||
59 | size = boot_params.hdr.ramdisk_size; | ||
60 | #endif | ||
61 | |||
62 | return find_cpio_data(path, start, size, &offset); | ||
63 | } | ||
64 | |||
65 | static size_t compute_container_size(u8 *data, u32 total_size) | ||
66 | { | ||
67 | size_t size = 0; | ||
68 | u32 *header = (u32 *)data; | ||
69 | |||
70 | if (header[0] != UCODE_MAGIC || | ||
71 | header[1] != UCODE_EQUIV_CPU_TABLE_TYPE || /* type */ | ||
72 | header[2] == 0) /* size */ | ||
73 | return size; | ||
74 | |||
75 | size = header[2] + CONTAINER_HDR_SZ; | ||
76 | total_size -= size; | ||
77 | data += size; | ||
78 | |||
79 | while (total_size) { | ||
80 | u16 patch_size; | ||
81 | |||
82 | header = (u32 *)data; | ||
83 | |||
84 | if (header[0] != UCODE_UCODE_TYPE) | ||
85 | break; | ||
86 | |||
87 | /* | ||
88 | * Sanity-check patch size. | ||
89 | */ | ||
90 | patch_size = header[1]; | ||
91 | if (patch_size > PATCH_MAX_SIZE) | ||
92 | break; | ||
93 | |||
94 | size += patch_size + SECTION_HDR_SIZE; | ||
95 | data += patch_size + SECTION_HDR_SIZE; | ||
96 | total_size -= patch_size + SECTION_HDR_SIZE; | ||
97 | } | ||
98 | |||
99 | return size; | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * Early load occurs before we can vmalloc(). So we look for the microcode | ||
104 | * patch container file in initrd, traverse equivalent cpu table, look for a | ||
105 | * matching microcode patch, and update, all in initrd memory in place. | ||
106 | * When vmalloc() is available for use later -- on 64-bit during first AP load, | ||
107 | * and on 32-bit during save_microcode_in_initrd_amd() -- we can call | ||
108 | * load_microcode_amd() to save equivalent cpu table and microcode patches in | ||
109 | * kernel heap memory. | ||
110 | */ | ||
111 | static void apply_ucode_in_initrd(void *ucode, size_t size) | ||
112 | { | ||
113 | struct equiv_cpu_entry *eq; | ||
114 | size_t *cont_sz; | ||
115 | u32 *header; | ||
116 | u8 *data, **cont; | ||
117 | u16 eq_id = 0; | ||
118 | int offset, left; | ||
119 | u32 rev, eax, ebx, ecx, edx; | ||
120 | u32 *new_rev; | ||
121 | |||
122 | #ifdef CONFIG_X86_32 | ||
123 | new_rev = (u32 *)__pa_nodebug(&ucode_new_rev); | ||
124 | cont_sz = (size_t *)__pa_nodebug(&container_size); | ||
125 | cont = (u8 **)__pa_nodebug(&container); | ||
126 | #else | ||
127 | new_rev = &ucode_new_rev; | ||
128 | cont_sz = &container_size; | ||
129 | cont = &container; | ||
130 | #endif | ||
131 | |||
132 | data = ucode; | ||
133 | left = size; | ||
134 | header = (u32 *)data; | ||
135 | |||
136 | /* find equiv cpu table */ | ||
137 | if (header[0] != UCODE_MAGIC || | ||
138 | header[1] != UCODE_EQUIV_CPU_TABLE_TYPE || /* type */ | ||
139 | header[2] == 0) /* size */ | ||
140 | return; | ||
141 | |||
142 | eax = 0x00000001; | ||
143 | ecx = 0; | ||
144 | native_cpuid(&eax, &ebx, &ecx, &edx); | ||
145 | |||
146 | while (left > 0) { | ||
147 | eq = (struct equiv_cpu_entry *)(data + CONTAINER_HDR_SZ); | ||
148 | |||
149 | *cont = data; | ||
150 | |||
151 | /* Advance past the container header */ | ||
152 | offset = header[2] + CONTAINER_HDR_SZ; | ||
153 | data += offset; | ||
154 | left -= offset; | ||
155 | |||
156 | eq_id = find_equiv_id(eq, eax); | ||
157 | if (eq_id) { | ||
158 | this_equiv_id = eq_id; | ||
159 | *cont_sz = compute_container_size(*cont, left + offset); | ||
160 | |||
161 | /* | ||
162 | * truncate how much we need to iterate over in the | ||
163 | * ucode update loop below | ||
164 | */ | ||
165 | left = *cont_sz - offset; | ||
166 | break; | ||
167 | } | ||
168 | |||
169 | /* | ||
170 | * support multiple container files appended together. if this | ||
171 | * one does not have a matching equivalent cpu entry, we fast | ||
172 | * forward to the next container file. | ||
173 | */ | ||
174 | while (left > 0) { | ||
175 | header = (u32 *)data; | ||
176 | if (header[0] == UCODE_MAGIC && | ||
177 | header[1] == UCODE_EQUIV_CPU_TABLE_TYPE) | ||
178 | break; | ||
179 | |||
180 | offset = header[1] + SECTION_HDR_SIZE; | ||
181 | data += offset; | ||
182 | left -= offset; | ||
183 | } | ||
184 | |||
185 | /* mark where the next microcode container file starts */ | ||
186 | offset = data - (u8 *)ucode; | ||
187 | ucode = data; | ||
188 | } | ||
189 | |||
190 | if (!eq_id) { | ||
191 | *cont = NULL; | ||
192 | *cont_sz = 0; | ||
193 | return; | ||
194 | } | ||
195 | |||
196 | /* find ucode and update if needed */ | ||
197 | |||
198 | native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax); | ||
199 | |||
200 | while (left > 0) { | ||
201 | struct microcode_amd *mc; | ||
202 | |||
203 | header = (u32 *)data; | ||
204 | if (header[0] != UCODE_UCODE_TYPE || /* type */ | ||
205 | header[1] == 0) /* size */ | ||
206 | break; | ||
207 | |||
208 | mc = (struct microcode_amd *)(data + SECTION_HDR_SIZE); | ||
209 | |||
210 | if (eq_id == mc->hdr.processor_rev_id && rev < mc->hdr.patch_id) { | ||
211 | |||
212 | if (!__apply_microcode_amd(mc)) { | ||
213 | rev = mc->hdr.patch_id; | ||
214 | *new_rev = rev; | ||
215 | |||
216 | /* save ucode patch */ | ||
217 | memcpy(amd_ucode_patch, mc, | ||
218 | min_t(u32, header[1], PATCH_MAX_SIZE)); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | offset = header[1] + SECTION_HDR_SIZE; | ||
223 | data += offset; | ||
224 | left -= offset; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | void __init load_ucode_amd_bsp(void) | ||
229 | { | ||
230 | struct cpio_data cp; | ||
231 | void **data; | ||
232 | size_t *size; | ||
233 | |||
234 | #ifdef CONFIG_X86_32 | ||
235 | data = (void **)__pa_nodebug(&ucode_cpio.data); | ||
236 | size = (size_t *)__pa_nodebug(&ucode_cpio.size); | ||
237 | #else | ||
238 | data = &ucode_cpio.data; | ||
239 | size = &ucode_cpio.size; | ||
240 | #endif | ||
241 | |||
242 | cp = find_ucode_in_initrd(); | ||
243 | if (!cp.data) | ||
244 | return; | ||
245 | |||
246 | *data = cp.data; | ||
247 | *size = cp.size; | ||
248 | |||
249 | apply_ucode_in_initrd(cp.data, cp.size); | ||
250 | } | ||
251 | |||
252 | #ifdef CONFIG_X86_32 | ||
253 | /* | ||
254 | * On 32-bit, since AP's early load occurs before paging is turned on, we | ||
255 | * cannot traverse cpu_equiv_table and pcache in kernel heap memory. So during | ||
256 | * cold boot, AP will apply_ucode_in_initrd() just like the BSP. During | ||
257 | * save_microcode_in_initrd_amd() BSP's patch is copied to amd_ucode_patch, | ||
258 | * which is used upon resume from suspend. | ||
259 | */ | ||
260 | void load_ucode_amd_ap(void) | ||
261 | { | ||
262 | struct microcode_amd *mc; | ||
263 | size_t *usize; | ||
264 | void **ucode; | ||
265 | |||
266 | mc = (struct microcode_amd *)__pa(amd_ucode_patch); | ||
267 | if (mc->hdr.patch_id && mc->hdr.processor_rev_id) { | ||
268 | __apply_microcode_amd(mc); | ||
269 | return; | ||
270 | } | ||
271 | |||
272 | ucode = (void *)__pa_nodebug(&container); | ||
273 | usize = (size_t *)__pa_nodebug(&container_size); | ||
274 | |||
275 | if (!*ucode || !*usize) | ||
276 | return; | ||
277 | |||
278 | apply_ucode_in_initrd(*ucode, *usize); | ||
279 | } | ||
280 | |||
281 | static void __init collect_cpu_sig_on_bsp(void *arg) | ||
282 | { | ||
283 | unsigned int cpu = smp_processor_id(); | ||
284 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | ||
285 | |||
286 | uci->cpu_sig.sig = cpuid_eax(0x00000001); | ||
287 | } | ||
288 | #else | ||
289 | void load_ucode_amd_ap(void) | ||
290 | { | ||
291 | unsigned int cpu = smp_processor_id(); | ||
292 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | ||
293 | struct equiv_cpu_entry *eq; | ||
294 | struct microcode_amd *mc; | ||
295 | u32 rev, eax; | ||
296 | u16 eq_id; | ||
297 | |||
298 | /* Exit if called on the BSP. */ | ||
299 | if (!cpu) | ||
300 | return; | ||
301 | |||
302 | if (!container) | ||
303 | return; | ||
304 | |||
305 | rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax); | ||
306 | |||
307 | uci->cpu_sig.rev = rev; | ||
308 | uci->cpu_sig.sig = eax; | ||
309 | |||
310 | eax = cpuid_eax(0x00000001); | ||
311 | eq = (struct equiv_cpu_entry *)(container + CONTAINER_HDR_SZ); | ||
312 | |||
313 | eq_id = find_equiv_id(eq, eax); | ||
314 | if (!eq_id) | ||
315 | return; | ||
316 | |||
317 | if (eq_id == this_equiv_id) { | ||
318 | mc = (struct microcode_amd *)amd_ucode_patch; | ||
319 | |||
320 | if (mc && rev < mc->hdr.patch_id) { | ||
321 | if (!__apply_microcode_amd(mc)) | ||
322 | ucode_new_rev = mc->hdr.patch_id; | ||
323 | } | ||
324 | |||
325 | } else { | ||
326 | if (!ucode_cpio.data) | ||
327 | return; | ||
328 | |||
329 | /* | ||
330 | * AP has a different equivalence ID than BSP, looks like | ||
331 | * mixed-steppings silicon so go through the ucode blob anew. | ||
332 | */ | ||
333 | apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size); | ||
334 | } | ||
335 | } | ||
336 | #endif | ||
337 | |||
338 | int __init save_microcode_in_initrd_amd(void) | ||
339 | { | ||
340 | enum ucode_state ret; | ||
341 | u32 eax; | ||
342 | |||
343 | #ifdef CONFIG_X86_32 | ||
344 | unsigned int bsp = boot_cpu_data.cpu_index; | ||
345 | struct ucode_cpu_info *uci = ucode_cpu_info + bsp; | ||
346 | |||
347 | if (!uci->cpu_sig.sig) | ||
348 | smp_call_function_single(bsp, collect_cpu_sig_on_bsp, NULL, 1); | ||
349 | |||
350 | /* | ||
351 | * Take into account the fact that the ramdisk might get relocated | ||
352 | * and therefore we need to recompute the container's position in | ||
353 | * virtual memory space. | ||
354 | */ | ||
355 | container = (u8 *)(__va((u32)relocated_ramdisk) + | ||
356 | ((u32)container - boot_params.hdr.ramdisk_image)); | ||
357 | #endif | ||
358 | if (ucode_new_rev) | ||
359 | pr_info("microcode: updated early to new patch_level=0x%08x\n", | ||
360 | ucode_new_rev); | ||
361 | |||
362 | if (!container) | ||
363 | return -EINVAL; | ||
364 | |||
365 | eax = cpuid_eax(0x00000001); | ||
366 | eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); | ||
367 | |||
368 | ret = load_microcode_amd(eax, container, container_size); | ||
369 | if (ret != UCODE_OK) | ||
370 | return -EINVAL; | ||
371 | |||
372 | /* | ||
373 | * This will be freed any msec now, stash patches for the current | ||
374 | * family and switch to patch cache for cpu hotplug, etc later. | ||
375 | */ | ||
376 | container = NULL; | ||
377 | container_size = 0; | ||
378 | |||
379 | return 0; | ||
380 | } | ||
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c new file mode 100644 index 000000000000..15c987698b0f --- /dev/null +++ b/arch/x86/kernel/cpu/microcode/core.c | |||
@@ -0,0 +1,645 @@ | |||
1 | /* | ||
2 | * Intel CPU Microcode Update Driver for Linux | ||
3 | * | ||
4 | * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk> | ||
5 | * 2006 Shaohua Li <shaohua.li@intel.com> | ||
6 | * | ||
7 | * This driver allows to upgrade microcode on Intel processors | ||
8 | * belonging to IA-32 family - PentiumPro, Pentium II, | ||
9 | * Pentium III, Xeon, Pentium 4, etc. | ||
10 | * | ||
11 | * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture | ||
12 | * Software Developer's Manual | ||
13 | * Order Number 253668 or free download from: | ||
14 | * | ||
15 | * http://developer.intel.com/Assets/PDF/manual/253668.pdf | ||
16 | * | ||
17 | * For more information, go to http://www.urbanmyth.org/microcode | ||
18 | * | ||
19 | * This program is free software; you can redistribute it and/or | ||
20 | * modify it under the terms of the GNU General Public License | ||
21 | * as published by the Free Software Foundation; either version | ||
22 | * 2 of the License, or (at your option) any later version. | ||
23 | * | ||
24 | * 1.0 16 Feb 2000, Tigran Aivazian <tigran@sco.com> | ||
25 | * Initial release. | ||
26 | * 1.01 18 Feb 2000, Tigran Aivazian <tigran@sco.com> | ||
27 | * Added read() support + cleanups. | ||
28 | * 1.02 21 Feb 2000, Tigran Aivazian <tigran@sco.com> | ||
29 | * Added 'device trimming' support. open(O_WRONLY) zeroes | ||
30 | * and frees the saved copy of applied microcode. | ||
31 | * 1.03 29 Feb 2000, Tigran Aivazian <tigran@sco.com> | ||
32 | * Made to use devfs (/dev/cpu/microcode) + cleanups. | ||
33 | * 1.04 06 Jun 2000, Simon Trimmer <simon@veritas.com> | ||
34 | * Added misc device support (now uses both devfs and misc). | ||
35 | * Added MICROCODE_IOCFREE ioctl to clear memory. | ||
36 | * 1.05 09 Jun 2000, Simon Trimmer <simon@veritas.com> | ||
37 | * Messages for error cases (non Intel & no suitable microcode). | ||
38 | * 1.06 03 Aug 2000, Tigran Aivazian <tigran@veritas.com> | ||
39 | * Removed ->release(). Removed exclusive open and status bitmap. | ||
40 | * Added microcode_rwsem to serialize read()/write()/ioctl(). | ||
41 | * Removed global kernel lock usage. | ||
42 | * 1.07 07 Sep 2000, Tigran Aivazian <tigran@veritas.com> | ||
43 | * Write 0 to 0x8B msr and then cpuid before reading revision, | ||
44 | * so that it works even if there were no update done by the | ||
45 | * BIOS. Otherwise, reading from 0x8B gives junk (which happened | ||
46 | * to be 0 on my machine which is why it worked even when I | ||
47 | * disabled update by the BIOS) | ||
48 | * Thanks to Eric W. Biederman <ebiederman@lnxi.com> for the fix. | ||
49 | * 1.08 11 Dec 2000, Richard Schaal <richard.schaal@intel.com> and | ||
50 | * Tigran Aivazian <tigran@veritas.com> | ||
51 | * Intel Pentium 4 processor support and bugfixes. | ||
52 | * 1.09 30 Oct 2001, Tigran Aivazian <tigran@veritas.com> | ||
53 | * Bugfix for HT (Hyper-Threading) enabled processors | ||
54 | * whereby processor resources are shared by all logical processors | ||
55 | * in a single CPU package. | ||
56 | * 1.10 28 Feb 2002 Asit K Mallick <asit.k.mallick@intel.com> and | ||
57 | * Tigran Aivazian <tigran@veritas.com>, | ||
58 | * Serialize updates as required on HT processors due to | ||
59 | * speculative nature of implementation. | ||
60 | * 1.11 22 Mar 2002 Tigran Aivazian <tigran@veritas.com> | ||
61 | * Fix the panic when writing zero-length microcode chunk. | ||
62 | * 1.12 29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>, | ||
63 | * Jun Nakajima <jun.nakajima@intel.com> | ||
64 | * Support for the microcode updates in the new format. | ||
65 | * 1.13 10 Oct 2003 Tigran Aivazian <tigran@veritas.com> | ||
66 | * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl | ||
67 | * because we no longer hold a copy of applied microcode | ||
68 | * in kernel memory. | ||
69 | * 1.14 25 Jun 2004 Tigran Aivazian <tigran@veritas.com> | ||
70 | * Fix sigmatch() macro to handle old CPUs with pf == 0. | ||
71 | * Thanks to Stuart Swales for pointing out this bug. | ||
72 | */ | ||
73 | |||
74 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
75 | |||
76 | #include <linux/platform_device.h> | ||
77 | #include <linux/miscdevice.h> | ||
78 | #include <linux/capability.h> | ||
79 | #include <linux/kernel.h> | ||
80 | #include <linux/module.h> | ||
81 | #include <linux/mutex.h> | ||
82 | #include <linux/cpu.h> | ||
83 | #include <linux/fs.h> | ||
84 | #include <linux/mm.h> | ||
85 | #include <linux/syscore_ops.h> | ||
86 | |||
87 | #include <asm/microcode.h> | ||
88 | #include <asm/processor.h> | ||
89 | #include <asm/cpu_device_id.h> | ||
90 | #include <asm/perf_event.h> | ||
91 | |||
92 | MODULE_DESCRIPTION("Microcode Update Driver"); | ||
93 | MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); | ||
94 | MODULE_LICENSE("GPL"); | ||
95 | |||
96 | #define MICROCODE_VERSION "2.00" | ||
97 | |||
98 | static struct microcode_ops *microcode_ops; | ||
99 | |||
100 | /* | ||
101 | * Synchronization. | ||
102 | * | ||
103 | * All non cpu-hotplug-callback call sites use: | ||
104 | * | ||
105 | * - microcode_mutex to synchronize with each other; | ||
106 | * - get/put_online_cpus() to synchronize with | ||
107 | * the cpu-hotplug-callback call sites. | ||
108 | * | ||
109 | * We guarantee that only a single cpu is being | ||
110 | * updated at any particular moment of time. | ||
111 | */ | ||
112 | static DEFINE_MUTEX(microcode_mutex); | ||
113 | |||
114 | struct ucode_cpu_info ucode_cpu_info[NR_CPUS]; | ||
115 | EXPORT_SYMBOL_GPL(ucode_cpu_info); | ||
116 | |||
117 | /* | ||
118 | * Operations that are run on a target cpu: | ||
119 | */ | ||
120 | |||
121 | struct cpu_info_ctx { | ||
122 | struct cpu_signature *cpu_sig; | ||
123 | int err; | ||
124 | }; | ||
125 | |||
126 | static void collect_cpu_info_local(void *arg) | ||
127 | { | ||
128 | struct cpu_info_ctx *ctx = arg; | ||
129 | |||
130 | ctx->err = microcode_ops->collect_cpu_info(smp_processor_id(), | ||
131 | ctx->cpu_sig); | ||
132 | } | ||
133 | |||
134 | static int collect_cpu_info_on_target(int cpu, struct cpu_signature *cpu_sig) | ||
135 | { | ||
136 | struct cpu_info_ctx ctx = { .cpu_sig = cpu_sig, .err = 0 }; | ||
137 | int ret; | ||
138 | |||
139 | ret = smp_call_function_single(cpu, collect_cpu_info_local, &ctx, 1); | ||
140 | if (!ret) | ||
141 | ret = ctx.err; | ||
142 | |||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | static int collect_cpu_info(int cpu) | ||
147 | { | ||
148 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | ||
149 | int ret; | ||
150 | |||
151 | memset(uci, 0, sizeof(*uci)); | ||
152 | |||
153 | ret = collect_cpu_info_on_target(cpu, &uci->cpu_sig); | ||
154 | if (!ret) | ||
155 | uci->valid = 1; | ||
156 | |||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | struct apply_microcode_ctx { | ||
161 | int err; | ||
162 | }; | ||
163 | |||
164 | static void apply_microcode_local(void *arg) | ||
165 | { | ||
166 | struct apply_microcode_ctx *ctx = arg; | ||
167 | |||
168 | ctx->err = microcode_ops->apply_microcode(smp_processor_id()); | ||
169 | } | ||
170 | |||
171 | static int apply_microcode_on_target(int cpu) | ||
172 | { | ||
173 | struct apply_microcode_ctx ctx = { .err = 0 }; | ||
174 | int ret; | ||
175 | |||
176 | ret = smp_call_function_single(cpu, apply_microcode_local, &ctx, 1); | ||
177 | if (!ret) | ||
178 | ret = ctx.err; | ||
179 | |||
180 | return ret; | ||
181 | } | ||
182 | |||
183 | #ifdef CONFIG_MICROCODE_OLD_INTERFACE | ||
184 | static int do_microcode_update(const void __user *buf, size_t size) | ||
185 | { | ||
186 | int error = 0; | ||
187 | int cpu; | ||
188 | |||
189 | for_each_online_cpu(cpu) { | ||
190 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | ||
191 | enum ucode_state ustate; | ||
192 | |||
193 | if (!uci->valid) | ||
194 | continue; | ||
195 | |||
196 | ustate = microcode_ops->request_microcode_user(cpu, buf, size); | ||
197 | if (ustate == UCODE_ERROR) { | ||
198 | error = -1; | ||
199 | break; | ||
200 | } else if (ustate == UCODE_OK) | ||
201 | apply_microcode_on_target(cpu); | ||
202 | } | ||
203 | |||
204 | return error; | ||
205 | } | ||
206 | |||
207 | static int microcode_open(struct inode *inode, struct file *file) | ||
208 | { | ||
209 | return capable(CAP_SYS_RAWIO) ? nonseekable_open(inode, file) : -EPERM; | ||
210 | } | ||
211 | |||
212 | static ssize_t microcode_write(struct file *file, const char __user *buf, | ||
213 | size_t len, loff_t *ppos) | ||
214 | { | ||
215 | ssize_t ret = -EINVAL; | ||
216 | |||
217 | if ((len >> PAGE_SHIFT) > totalram_pages) { | ||
218 | pr_err("too much data (max %ld pages)\n", totalram_pages); | ||
219 | return ret; | ||
220 | } | ||
221 | |||
222 | get_online_cpus(); | ||
223 | mutex_lock(µcode_mutex); | ||
224 | |||
225 | if (do_microcode_update(buf, len) == 0) | ||
226 | ret = (ssize_t)len; | ||
227 | |||
228 | if (ret > 0) | ||
229 | perf_check_microcode(); | ||
230 | |||
231 | mutex_unlock(µcode_mutex); | ||
232 | put_online_cpus(); | ||
233 | |||
234 | return ret; | ||
235 | } | ||
236 | |||
237 | static const struct file_operations microcode_fops = { | ||
238 | .owner = THIS_MODULE, | ||
239 | .write = microcode_write, | ||
240 | .open = microcode_open, | ||
241 | .llseek = no_llseek, | ||
242 | }; | ||
243 | |||
244 | static struct miscdevice microcode_dev = { | ||
245 | .minor = MICROCODE_MINOR, | ||
246 | .name = "microcode", | ||
247 | .nodename = "cpu/microcode", | ||
248 | .fops = µcode_fops, | ||
249 | }; | ||
250 | |||
251 | static int __init microcode_dev_init(void) | ||
252 | { | ||
253 | int error; | ||
254 | |||
255 | error = misc_register(µcode_dev); | ||
256 | if (error) { | ||
257 | pr_err("can't misc_register on minor=%d\n", MICROCODE_MINOR); | ||
258 | return error; | ||
259 | } | ||
260 | |||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static void __exit microcode_dev_exit(void) | ||
265 | { | ||
266 | misc_deregister(µcode_dev); | ||
267 | } | ||
268 | |||
269 | MODULE_ALIAS_MISCDEV(MICROCODE_MINOR); | ||
270 | MODULE_ALIAS("devname:cpu/microcode"); | ||
271 | #else | ||
272 | #define microcode_dev_init() 0 | ||
273 | #define microcode_dev_exit() do { } while (0) | ||
274 | #endif | ||
275 | |||
276 | /* fake device for request_firmware */ | ||
277 | static struct platform_device *microcode_pdev; | ||
278 | |||
279 | static int reload_for_cpu(int cpu) | ||
280 | { | ||
281 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | ||
282 | enum ucode_state ustate; | ||
283 | int err = 0; | ||
284 | |||
285 | if (!uci->valid) | ||
286 | return err; | ||
287 | |||
288 | ustate = microcode_ops->request_microcode_fw(cpu, µcode_pdev->dev, true); | ||
289 | if (ustate == UCODE_OK) | ||
290 | apply_microcode_on_target(cpu); | ||
291 | else | ||
292 | if (ustate == UCODE_ERROR) | ||
293 | err = -EINVAL; | ||
294 | return err; | ||
295 | } | ||
296 | |||
297 | static ssize_t reload_store(struct device *dev, | ||
298 | struct device_attribute *attr, | ||
299 | const char *buf, size_t size) | ||
300 | { | ||
301 | unsigned long val; | ||
302 | int cpu; | ||
303 | ssize_t ret = 0, tmp_ret; | ||
304 | |||
305 | ret = kstrtoul(buf, 0, &val); | ||
306 | if (ret) | ||
307 | return ret; | ||
308 | |||
309 | if (val != 1) | ||
310 | return size; | ||
311 | |||
312 | get_online_cpus(); | ||
313 | mutex_lock(µcode_mutex); | ||
314 | for_each_online_cpu(cpu) { | ||
315 | tmp_ret = reload_for_cpu(cpu); | ||
316 | if (tmp_ret != 0) | ||
317 | pr_warn("Error reloading microcode on CPU %d\n", cpu); | ||
318 | |||
319 | /* save retval of the first encountered reload error */ | ||
320 | if (!ret) | ||
321 | ret = tmp_ret; | ||
322 | } | ||
323 | if (!ret) | ||
324 | perf_check_microcode(); | ||
325 | mutex_unlock(µcode_mutex); | ||
326 | put_online_cpus(); | ||
327 | |||
328 | if (!ret) | ||
329 | ret = size; | ||
330 | |||
331 | return ret; | ||
332 | } | ||
333 | |||
334 | static ssize_t version_show(struct device *dev, | ||
335 | struct device_attribute *attr, char *buf) | ||
336 | { | ||
337 | struct ucode_cpu_info *uci = ucode_cpu_info + dev->id; | ||
338 | |||
339 | return sprintf(buf, "0x%x\n", uci->cpu_sig.rev); | ||
340 | } | ||
341 | |||
342 | static ssize_t pf_show(struct device *dev, | ||
343 | struct device_attribute *attr, char *buf) | ||
344 | { | ||
345 | struct ucode_cpu_info *uci = ucode_cpu_info + dev->id; | ||
346 | |||
347 | return sprintf(buf, "0x%x\n", uci->cpu_sig.pf); | ||
348 | } | ||
349 | |||
350 | static DEVICE_ATTR(reload, 0200, NULL, reload_store); | ||
351 | static DEVICE_ATTR(version, 0400, version_show, NULL); | ||
352 | static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL); | ||
353 | |||
354 | static struct attribute *mc_default_attrs[] = { | ||
355 | &dev_attr_version.attr, | ||
356 | &dev_attr_processor_flags.attr, | ||
357 | NULL | ||
358 | }; | ||
359 | |||
360 | static struct attribute_group mc_attr_group = { | ||
361 | .attrs = mc_default_attrs, | ||
362 | .name = "microcode", | ||
363 | }; | ||
364 | |||
365 | static void microcode_fini_cpu(int cpu) | ||
366 | { | ||
367 | microcode_ops->microcode_fini_cpu(cpu); | ||
368 | } | ||
369 | |||
370 | static enum ucode_state microcode_resume_cpu(int cpu) | ||
371 | { | ||
372 | pr_debug("CPU%d updated upon resume\n", cpu); | ||
373 | |||
374 | if (apply_microcode_on_target(cpu)) | ||
375 | return UCODE_ERROR; | ||
376 | |||
377 | return UCODE_OK; | ||
378 | } | ||
379 | |||
380 | static enum ucode_state microcode_init_cpu(int cpu, bool refresh_fw) | ||
381 | { | ||
382 | enum ucode_state ustate; | ||
383 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | ||
384 | |||
385 | if (uci && uci->valid) | ||
386 | return UCODE_OK; | ||
387 | |||
388 | if (collect_cpu_info(cpu)) | ||
389 | return UCODE_ERROR; | ||
390 | |||
391 | /* --dimm. Trigger a delayed update? */ | ||
392 | if (system_state != SYSTEM_RUNNING) | ||
393 | return UCODE_NFOUND; | ||
394 | |||
395 | ustate = microcode_ops->request_microcode_fw(cpu, µcode_pdev->dev, | ||
396 | refresh_fw); | ||
397 | |||
398 | if (ustate == UCODE_OK) { | ||
399 | pr_debug("CPU%d updated upon init\n", cpu); | ||
400 | apply_microcode_on_target(cpu); | ||
401 | } | ||
402 | |||
403 | return ustate; | ||
404 | } | ||
405 | |||
406 | static enum ucode_state microcode_update_cpu(int cpu) | ||
407 | { | ||
408 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | ||
409 | |||
410 | if (uci->valid) | ||
411 | return microcode_resume_cpu(cpu); | ||
412 | |||
413 | return microcode_init_cpu(cpu, false); | ||
414 | } | ||
415 | |||
416 | static int mc_device_add(struct device *dev, struct subsys_interface *sif) | ||
417 | { | ||
418 | int err, cpu = dev->id; | ||
419 | |||
420 | if (!cpu_online(cpu)) | ||
421 | return 0; | ||
422 | |||
423 | pr_debug("CPU%d added\n", cpu); | ||
424 | |||
425 | err = sysfs_create_group(&dev->kobj, &mc_attr_group); | ||
426 | if (err) | ||
427 | return err; | ||
428 | |||
429 | if (microcode_init_cpu(cpu, true) == UCODE_ERROR) | ||
430 | return -EINVAL; | ||
431 | |||
432 | return err; | ||
433 | } | ||
434 | |||
435 | static int mc_device_remove(struct device *dev, struct subsys_interface *sif) | ||
436 | { | ||
437 | int cpu = dev->id; | ||
438 | |||
439 | if (!cpu_online(cpu)) | ||
440 | return 0; | ||
441 | |||
442 | pr_debug("CPU%d removed\n", cpu); | ||
443 | microcode_fini_cpu(cpu); | ||
444 | sysfs_remove_group(&dev->kobj, &mc_attr_group); | ||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | static struct subsys_interface mc_cpu_interface = { | ||
449 | .name = "microcode", | ||
450 | .subsys = &cpu_subsys, | ||
451 | .add_dev = mc_device_add, | ||
452 | .remove_dev = mc_device_remove, | ||
453 | }; | ||
454 | |||
455 | /** | ||
456 | * mc_bp_resume - Update boot CPU microcode during resume. | ||
457 | */ | ||
458 | static void mc_bp_resume(void) | ||
459 | { | ||
460 | int cpu = smp_processor_id(); | ||
461 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | ||
462 | |||
463 | if (uci->valid && uci->mc) | ||
464 | microcode_ops->apply_microcode(cpu); | ||
465 | } | ||
466 | |||
467 | static struct syscore_ops mc_syscore_ops = { | ||
468 | .resume = mc_bp_resume, | ||
469 | }; | ||
470 | |||
471 | static int | ||
472 | mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) | ||
473 | { | ||
474 | unsigned int cpu = (unsigned long)hcpu; | ||
475 | struct device *dev; | ||
476 | |||
477 | dev = get_cpu_device(cpu); | ||
478 | |||
479 | switch (action & ~CPU_TASKS_FROZEN) { | ||
480 | case CPU_ONLINE: | ||
481 | microcode_update_cpu(cpu); | ||
482 | pr_debug("CPU%d added\n", cpu); | ||
483 | /* | ||
484 | * "break" is missing on purpose here because we want to fall | ||
485 | * through in order to create the sysfs group. | ||
486 | */ | ||
487 | |||
488 | case CPU_DOWN_FAILED: | ||
489 | if (sysfs_create_group(&dev->kobj, &mc_attr_group)) | ||
490 | pr_err("Failed to create group for CPU%d\n", cpu); | ||
491 | break; | ||
492 | |||
493 | case CPU_DOWN_PREPARE: | ||
494 | /* Suspend is in progress, only remove the interface */ | ||
495 | sysfs_remove_group(&dev->kobj, &mc_attr_group); | ||
496 | pr_debug("CPU%d removed\n", cpu); | ||
497 | break; | ||
498 | |||
499 | /* | ||
500 | * case CPU_DEAD: | ||
501 | * | ||
502 | * When a CPU goes offline, don't free up or invalidate the copy of | ||
503 | * the microcode in kernel memory, so that we can reuse it when the | ||
504 | * CPU comes back online without unnecessarily requesting the userspace | ||
505 | * for it again. | ||
506 | */ | ||
507 | } | ||
508 | |||
509 | /* The CPU refused to come up during a system resume */ | ||
510 | if (action == CPU_UP_CANCELED_FROZEN) | ||
511 | microcode_fini_cpu(cpu); | ||
512 | |||
513 | return NOTIFY_OK; | ||
514 | } | ||
515 | |||
516 | static struct notifier_block __refdata mc_cpu_notifier = { | ||
517 | .notifier_call = mc_cpu_callback, | ||
518 | }; | ||
519 | |||
520 | #ifdef MODULE | ||
521 | /* Autoload on Intel and AMD systems */ | ||
522 | static const struct x86_cpu_id __initconst microcode_id[] = { | ||
523 | #ifdef CONFIG_MICROCODE_INTEL | ||
524 | { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, }, | ||
525 | #endif | ||
526 | #ifdef CONFIG_MICROCODE_AMD | ||
527 | { X86_VENDOR_AMD, X86_FAMILY_ANY, X86_MODEL_ANY, }, | ||
528 | #endif | ||
529 | {} | ||
530 | }; | ||
531 | MODULE_DEVICE_TABLE(x86cpu, microcode_id); | ||
532 | #endif | ||
533 | |||
534 | static struct attribute *cpu_root_microcode_attrs[] = { | ||
535 | &dev_attr_reload.attr, | ||
536 | NULL | ||
537 | }; | ||
538 | |||
539 | static struct attribute_group cpu_root_microcode_group = { | ||
540 | .name = "microcode", | ||
541 | .attrs = cpu_root_microcode_attrs, | ||
542 | }; | ||
543 | |||
544 | static int __init microcode_init(void) | ||
545 | { | ||
546 | struct cpuinfo_x86 *c = &cpu_data(0); | ||
547 | int error; | ||
548 | |||
549 | if (c->x86_vendor == X86_VENDOR_INTEL) | ||
550 | microcode_ops = init_intel_microcode(); | ||
551 | else if (c->x86_vendor == X86_VENDOR_AMD) | ||
552 | microcode_ops = init_amd_microcode(); | ||
553 | else | ||
554 | pr_err("no support for this CPU vendor\n"); | ||
555 | |||
556 | if (!microcode_ops) | ||
557 | return -ENODEV; | ||
558 | |||
559 | microcode_pdev = platform_device_register_simple("microcode", -1, | ||
560 | NULL, 0); | ||
561 | if (IS_ERR(microcode_pdev)) | ||
562 | return PTR_ERR(microcode_pdev); | ||
563 | |||
564 | get_online_cpus(); | ||
565 | mutex_lock(µcode_mutex); | ||
566 | |||
567 | error = subsys_interface_register(&mc_cpu_interface); | ||
568 | if (!error) | ||
569 | perf_check_microcode(); | ||
570 | mutex_unlock(µcode_mutex); | ||
571 | put_online_cpus(); | ||
572 | |||
573 | if (error) | ||
574 | goto out_pdev; | ||
575 | |||
576 | error = sysfs_create_group(&cpu_subsys.dev_root->kobj, | ||
577 | &cpu_root_microcode_group); | ||
578 | |||
579 | if (error) { | ||
580 | pr_err("Error creating microcode group!\n"); | ||
581 | goto out_driver; | ||
582 | } | ||
583 | |||
584 | error = microcode_dev_init(); | ||
585 | if (error) | ||
586 | goto out_ucode_group; | ||
587 | |||
588 | register_syscore_ops(&mc_syscore_ops); | ||
589 | register_hotcpu_notifier(&mc_cpu_notifier); | ||
590 | |||
591 | pr_info("Microcode Update Driver: v" MICROCODE_VERSION | ||
592 | " <tigran@aivazian.fsnet.co.uk>, Peter Oruba\n"); | ||
593 | |||
594 | return 0; | ||
595 | |||
596 | out_ucode_group: | ||
597 | sysfs_remove_group(&cpu_subsys.dev_root->kobj, | ||
598 | &cpu_root_microcode_group); | ||
599 | |||
600 | out_driver: | ||
601 | get_online_cpus(); | ||
602 | mutex_lock(µcode_mutex); | ||
603 | |||
604 | subsys_interface_unregister(&mc_cpu_interface); | ||
605 | |||
606 | mutex_unlock(µcode_mutex); | ||
607 | put_online_cpus(); | ||
608 | |||
609 | out_pdev: | ||
610 | platform_device_unregister(microcode_pdev); | ||
611 | return error; | ||
612 | |||
613 | } | ||
614 | module_init(microcode_init); | ||
615 | |||
616 | static void __exit microcode_exit(void) | ||
617 | { | ||
618 | struct cpuinfo_x86 *c = &cpu_data(0); | ||
619 | |||
620 | microcode_dev_exit(); | ||
621 | |||
622 | unregister_hotcpu_notifier(&mc_cpu_notifier); | ||
623 | unregister_syscore_ops(&mc_syscore_ops); | ||
624 | |||
625 | sysfs_remove_group(&cpu_subsys.dev_root->kobj, | ||
626 | &cpu_root_microcode_group); | ||
627 | |||
628 | get_online_cpus(); | ||
629 | mutex_lock(µcode_mutex); | ||
630 | |||
631 | subsys_interface_unregister(&mc_cpu_interface); | ||
632 | |||
633 | mutex_unlock(µcode_mutex); | ||
634 | put_online_cpus(); | ||
635 | |||
636 | platform_device_unregister(microcode_pdev); | ||
637 | |||
638 | microcode_ops = NULL; | ||
639 | |||
640 | if (c->x86_vendor == X86_VENDOR_AMD) | ||
641 | exit_amd_microcode(); | ||
642 | |||
643 | pr_info("Microcode Update Driver: v" MICROCODE_VERSION " removed.\n"); | ||
644 | } | ||
645 | module_exit(microcode_exit); | ||
diff --git a/arch/x86/kernel/cpu/microcode/core_early.c b/arch/x86/kernel/cpu/microcode/core_early.c new file mode 100644 index 000000000000..be7f8514f577 --- /dev/null +++ b/arch/x86/kernel/cpu/microcode/core_early.c | |||
@@ -0,0 +1,141 @@ | |||
1 | /* | ||
2 | * X86 CPU microcode early update for Linux | ||
3 | * | ||
4 | * Copyright (C) 2012 Fenghua Yu <fenghua.yu@intel.com> | ||
5 | * H Peter Anvin" <hpa@zytor.com> | ||
6 | * | ||
7 | * This driver allows to early upgrade microcode on Intel processors | ||
8 | * belonging to IA-32 family - PentiumPro, Pentium II, | ||
9 | * Pentium III, Xeon, Pentium 4, etc. | ||
10 | * | ||
11 | * Reference: Section 9.11 of Volume 3, IA-32 Intel Architecture | ||
12 | * Software Developer's Manual. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License | ||
16 | * as published by the Free Software Foundation; either version | ||
17 | * 2 of the License, or (at your option) any later version. | ||
18 | */ | ||
19 | #include <linux/module.h> | ||
20 | #include <asm/microcode_intel.h> | ||
21 | #include <asm/microcode_amd.h> | ||
22 | #include <asm/processor.h> | ||
23 | |||
24 | #define QCHAR(a, b, c, d) ((a) + ((b) << 8) + ((c) << 16) + ((d) << 24)) | ||
25 | #define CPUID_INTEL1 QCHAR('G', 'e', 'n', 'u') | ||
26 | #define CPUID_INTEL2 QCHAR('i', 'n', 'e', 'I') | ||
27 | #define CPUID_INTEL3 QCHAR('n', 't', 'e', 'l') | ||
28 | #define CPUID_AMD1 QCHAR('A', 'u', 't', 'h') | ||
29 | #define CPUID_AMD2 QCHAR('e', 'n', 't', 'i') | ||
30 | #define CPUID_AMD3 QCHAR('c', 'A', 'M', 'D') | ||
31 | |||
32 | #define CPUID_IS(a, b, c, ebx, ecx, edx) \ | ||
33 | (!((ebx ^ (a))|(edx ^ (b))|(ecx ^ (c)))) | ||
34 | |||
35 | /* | ||
36 | * In early loading microcode phase on BSP, boot_cpu_data is not set up yet. | ||
37 | * x86_vendor() gets vendor id for BSP. | ||
38 | * | ||
39 | * In 32 bit AP case, accessing boot_cpu_data needs linear address. To simplify | ||
40 | * coding, we still use x86_vendor() to get vendor id for AP. | ||
41 | * | ||
42 | * x86_vendor() gets vendor information directly through cpuid. | ||
43 | */ | ||
44 | static int x86_vendor(void) | ||
45 | { | ||
46 | u32 eax = 0x00000000; | ||
47 | u32 ebx, ecx = 0, edx; | ||
48 | |||
49 | native_cpuid(&eax, &ebx, &ecx, &edx); | ||
50 | |||
51 | if (CPUID_IS(CPUID_INTEL1, CPUID_INTEL2, CPUID_INTEL3, ebx, ecx, edx)) | ||
52 | return X86_VENDOR_INTEL; | ||
53 | |||
54 | if (CPUID_IS(CPUID_AMD1, CPUID_AMD2, CPUID_AMD3, ebx, ecx, edx)) | ||
55 | return X86_VENDOR_AMD; | ||
56 | |||
57 | return X86_VENDOR_UNKNOWN; | ||
58 | } | ||
59 | |||
60 | static int x86_family(void) | ||
61 | { | ||
62 | u32 eax = 0x00000001; | ||
63 | u32 ebx, ecx = 0, edx; | ||
64 | int x86; | ||
65 | |||
66 | native_cpuid(&eax, &ebx, &ecx, &edx); | ||
67 | |||
68 | x86 = (eax >> 8) & 0xf; | ||
69 | if (x86 == 15) | ||
70 | x86 += (eax >> 20) & 0xff; | ||
71 | |||
72 | return x86; | ||
73 | } | ||
74 | |||
75 | void __init load_ucode_bsp(void) | ||
76 | { | ||
77 | int vendor, x86; | ||
78 | |||
79 | if (!have_cpuid_p()) | ||
80 | return; | ||
81 | |||
82 | vendor = x86_vendor(); | ||
83 | x86 = x86_family(); | ||
84 | |||
85 | switch (vendor) { | ||
86 | case X86_VENDOR_INTEL: | ||
87 | if (x86 >= 6) | ||
88 | load_ucode_intel_bsp(); | ||
89 | break; | ||
90 | case X86_VENDOR_AMD: | ||
91 | if (x86 >= 0x10) | ||
92 | load_ucode_amd_bsp(); | ||
93 | break; | ||
94 | default: | ||
95 | break; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | void load_ucode_ap(void) | ||
100 | { | ||
101 | int vendor, x86; | ||
102 | |||
103 | if (!have_cpuid_p()) | ||
104 | return; | ||
105 | |||
106 | vendor = x86_vendor(); | ||
107 | x86 = x86_family(); | ||
108 | |||
109 | switch (vendor) { | ||
110 | case X86_VENDOR_INTEL: | ||
111 | if (x86 >= 6) | ||
112 | load_ucode_intel_ap(); | ||
113 | break; | ||
114 | case X86_VENDOR_AMD: | ||
115 | if (x86 >= 0x10) | ||
116 | load_ucode_amd_ap(); | ||
117 | break; | ||
118 | default: | ||
119 | break; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | int __init save_microcode_in_initrd(void) | ||
124 | { | ||
125 | struct cpuinfo_x86 *c = &boot_cpu_data; | ||
126 | |||
127 | switch (c->x86_vendor) { | ||
128 | case X86_VENDOR_INTEL: | ||
129 | if (c->x86 >= 6) | ||
130 | save_microcode_in_initrd_intel(); | ||
131 | break; | ||
132 | case X86_VENDOR_AMD: | ||
133 | if (c->x86 >= 0x10) | ||
134 | save_microcode_in_initrd_amd(); | ||
135 | break; | ||
136 | default: | ||
137 | break; | ||
138 | } | ||
139 | |||
140 | return 0; | ||
141 | } | ||
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c new file mode 100644 index 000000000000..5fb2cebf556b --- /dev/null +++ b/arch/x86/kernel/cpu/microcode/intel.c | |||
@@ -0,0 +1,333 @@ | |||
1 | /* | ||
2 | * Intel CPU Microcode Update Driver for Linux | ||
3 | * | ||
4 | * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk> | ||
5 | * 2006 Shaohua Li <shaohua.li@intel.com> | ||
6 | * | ||
7 | * This driver allows to upgrade microcode on Intel processors | ||
8 | * belonging to IA-32 family - PentiumPro, Pentium II, | ||
9 | * Pentium III, Xeon, Pentium 4, etc. | ||
10 | * | ||
11 | * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture | ||
12 | * Software Developer's Manual | ||
13 | * Order Number 253668 or free download from: | ||
14 | * | ||
15 | * http://developer.intel.com/Assets/PDF/manual/253668.pdf | ||
16 | * | ||
17 | * For more information, go to http://www.urbanmyth.org/microcode | ||
18 | * | ||
19 | * This program is free software; you can redistribute it and/or | ||
20 | * modify it under the terms of the GNU General Public License | ||
21 | * as published by the Free Software Foundation; either version | ||
22 | * 2 of the License, or (at your option) any later version. | ||
23 | * | ||
24 | * 1.0 16 Feb 2000, Tigran Aivazian <tigran@sco.com> | ||
25 | * Initial release. | ||
26 | * 1.01 18 Feb 2000, Tigran Aivazian <tigran@sco.com> | ||
27 | * Added read() support + cleanups. | ||
28 | * 1.02 21 Feb 2000, Tigran Aivazian <tigran@sco.com> | ||
29 | * Added 'device trimming' support. open(O_WRONLY) zeroes | ||
30 | * and frees the saved copy of applied microcode. | ||
31 | * 1.03 29 Feb 2000, Tigran Aivazian <tigran@sco.com> | ||
32 | * Made to use devfs (/dev/cpu/microcode) + cleanups. | ||
33 | * 1.04 06 Jun 2000, Simon Trimmer <simon@veritas.com> | ||
34 | * Added misc device support (now uses both devfs and misc). | ||
35 | * Added MICROCODE_IOCFREE ioctl to clear memory. | ||
36 | * 1.05 09 Jun 2000, Simon Trimmer <simon@veritas.com> | ||
37 | * Messages for error cases (non Intel & no suitable microcode). | ||
38 | * 1.06 03 Aug 2000, Tigran Aivazian <tigran@veritas.com> | ||
39 | * Removed ->release(). Removed exclusive open and status bitmap. | ||
40 | * Added microcode_rwsem to serialize read()/write()/ioctl(). | ||
41 | * Removed global kernel lock usage. | ||
42 | * 1.07 07 Sep 2000, Tigran Aivazian <tigran@veritas.com> | ||
43 | * Write 0 to 0x8B msr and then cpuid before reading revision, | ||
44 | * so that it works even if there were no update done by the | ||
45 | * BIOS. Otherwise, reading from 0x8B gives junk (which happened | ||
46 | * to be 0 on my machine which is why it worked even when I | ||
47 | * disabled update by the BIOS) | ||
48 | * Thanks to Eric W. Biederman <ebiederman@lnxi.com> for the fix. | ||
49 | * 1.08 11 Dec 2000, Richard Schaal <richard.schaal@intel.com> and | ||
50 | * Tigran Aivazian <tigran@veritas.com> | ||
51 | * Intel Pentium 4 processor support and bugfixes. | ||
52 | * 1.09 30 Oct 2001, Tigran Aivazian <tigran@veritas.com> | ||
53 | * Bugfix for HT (Hyper-Threading) enabled processors | ||
54 | * whereby processor resources are shared by all logical processors | ||
55 | * in a single CPU package. | ||
56 | * 1.10 28 Feb 2002 Asit K Mallick <asit.k.mallick@intel.com> and | ||
57 | * Tigran Aivazian <tigran@veritas.com>, | ||
58 | * Serialize updates as required on HT processors due to | ||
59 | * speculative nature of implementation. | ||
60 | * 1.11 22 Mar 2002 Tigran Aivazian <tigran@veritas.com> | ||
61 | * Fix the panic when writing zero-length microcode chunk. | ||
62 | * 1.12 29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>, | ||
63 | * Jun Nakajima <jun.nakajima@intel.com> | ||
64 | * Support for the microcode updates in the new format. | ||
65 | * 1.13 10 Oct 2003 Tigran Aivazian <tigran@veritas.com> | ||
66 | * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl | ||
67 | * because we no longer hold a copy of applied microcode | ||
68 | * in kernel memory. | ||
69 | * 1.14 25 Jun 2004 Tigran Aivazian <tigran@veritas.com> | ||
70 | * Fix sigmatch() macro to handle old CPUs with pf == 0. | ||
71 | * Thanks to Stuart Swales for pointing out this bug. | ||
72 | */ | ||
73 | |||
74 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
75 | |||
76 | #include <linux/firmware.h> | ||
77 | #include <linux/uaccess.h> | ||
78 | #include <linux/kernel.h> | ||
79 | #include <linux/module.h> | ||
80 | #include <linux/vmalloc.h> | ||
81 | |||
82 | #include <asm/microcode_intel.h> | ||
83 | #include <asm/processor.h> | ||
84 | #include <asm/msr.h> | ||
85 | |||
86 | MODULE_DESCRIPTION("Microcode Update Driver"); | ||
87 | MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); | ||
88 | MODULE_LICENSE("GPL"); | ||
89 | |||
90 | static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) | ||
91 | { | ||
92 | struct cpuinfo_x86 *c = &cpu_data(cpu_num); | ||
93 | unsigned int val[2]; | ||
94 | |||
95 | memset(csig, 0, sizeof(*csig)); | ||
96 | |||
97 | csig->sig = cpuid_eax(0x00000001); | ||
98 | |||
99 | if ((c->x86_model >= 5) || (c->x86 > 6)) { | ||
100 | /* get processor flags from MSR 0x17 */ | ||
101 | rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); | ||
102 | csig->pf = 1 << ((val[1] >> 18) & 7); | ||
103 | } | ||
104 | |||
105 | csig->rev = c->microcode; | ||
106 | pr_info("CPU%d sig=0x%x, pf=0x%x, revision=0x%x\n", | ||
107 | cpu_num, csig->sig, csig->pf, csig->rev); | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | /* | ||
113 | * return 0 - no update found | ||
114 | * return 1 - found update | ||
115 | */ | ||
116 | static int get_matching_mc(struct microcode_intel *mc_intel, int cpu) | ||
117 | { | ||
118 | struct cpu_signature cpu_sig; | ||
119 | unsigned int csig, cpf, crev; | ||
120 | |||
121 | collect_cpu_info(cpu, &cpu_sig); | ||
122 | |||
123 | csig = cpu_sig.sig; | ||
124 | cpf = cpu_sig.pf; | ||
125 | crev = cpu_sig.rev; | ||
126 | |||
127 | return get_matching_microcode(csig, cpf, mc_intel, crev); | ||
128 | } | ||
129 | |||
130 | int apply_microcode(int cpu) | ||
131 | { | ||
132 | struct microcode_intel *mc_intel; | ||
133 | struct ucode_cpu_info *uci; | ||
134 | unsigned int val[2]; | ||
135 | int cpu_num = raw_smp_processor_id(); | ||
136 | struct cpuinfo_x86 *c = &cpu_data(cpu_num); | ||
137 | |||
138 | uci = ucode_cpu_info + cpu; | ||
139 | mc_intel = uci->mc; | ||
140 | |||
141 | /* We should bind the task to the CPU */ | ||
142 | BUG_ON(cpu_num != cpu); | ||
143 | |||
144 | if (mc_intel == NULL) | ||
145 | return 0; | ||
146 | |||
147 | /* | ||
148 | * Microcode on this CPU could be updated earlier. Only apply the | ||
149 | * microcode patch in mc_intel when it is newer than the one on this | ||
150 | * CPU. | ||
151 | */ | ||
152 | if (get_matching_mc(mc_intel, cpu) == 0) | ||
153 | return 0; | ||
154 | |||
155 | /* write microcode via MSR 0x79 */ | ||
156 | wrmsr(MSR_IA32_UCODE_WRITE, | ||
157 | (unsigned long) mc_intel->bits, | ||
158 | (unsigned long) mc_intel->bits >> 16 >> 16); | ||
159 | wrmsr(MSR_IA32_UCODE_REV, 0, 0); | ||
160 | |||
161 | /* As documented in the SDM: Do a CPUID 1 here */ | ||
162 | sync_core(); | ||
163 | |||
164 | /* get the current revision from MSR 0x8B */ | ||
165 | rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); | ||
166 | |||
167 | if (val[1] != mc_intel->hdr.rev) { | ||
168 | pr_err("CPU%d update to revision 0x%x failed\n", | ||
169 | cpu_num, mc_intel->hdr.rev); | ||
170 | return -1; | ||
171 | } | ||
172 | pr_info("CPU%d updated to revision 0x%x, date = %04x-%02x-%02x\n", | ||
173 | cpu_num, val[1], | ||
174 | mc_intel->hdr.date & 0xffff, | ||
175 | mc_intel->hdr.date >> 24, | ||
176 | (mc_intel->hdr.date >> 16) & 0xff); | ||
177 | |||
178 | uci->cpu_sig.rev = val[1]; | ||
179 | c->microcode = val[1]; | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, | ||
185 | int (*get_ucode_data)(void *, const void *, size_t)) | ||
186 | { | ||
187 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | ||
188 | u8 *ucode_ptr = data, *new_mc = NULL, *mc = NULL; | ||
189 | int new_rev = uci->cpu_sig.rev; | ||
190 | unsigned int leftover = size; | ||
191 | enum ucode_state state = UCODE_OK; | ||
192 | unsigned int curr_mc_size = 0; | ||
193 | unsigned int csig, cpf; | ||
194 | |||
195 | while (leftover) { | ||
196 | struct microcode_header_intel mc_header; | ||
197 | unsigned int mc_size; | ||
198 | |||
199 | if (get_ucode_data(&mc_header, ucode_ptr, sizeof(mc_header))) | ||
200 | break; | ||
201 | |||
202 | mc_size = get_totalsize(&mc_header); | ||
203 | if (!mc_size || mc_size > leftover) { | ||
204 | pr_err("error! Bad data in microcode data file\n"); | ||
205 | break; | ||
206 | } | ||
207 | |||
208 | /* For performance reasons, reuse mc area when possible */ | ||
209 | if (!mc || mc_size > curr_mc_size) { | ||
210 | vfree(mc); | ||
211 | mc = vmalloc(mc_size); | ||
212 | if (!mc) | ||
213 | break; | ||
214 | curr_mc_size = mc_size; | ||
215 | } | ||
216 | |||
217 | if (get_ucode_data(mc, ucode_ptr, mc_size) || | ||
218 | microcode_sanity_check(mc, 1) < 0) { | ||
219 | break; | ||
220 | } | ||
221 | |||
222 | csig = uci->cpu_sig.sig; | ||
223 | cpf = uci->cpu_sig.pf; | ||
224 | if (get_matching_microcode(csig, cpf, mc, new_rev)) { | ||
225 | vfree(new_mc); | ||
226 | new_rev = mc_header.rev; | ||
227 | new_mc = mc; | ||
228 | mc = NULL; /* trigger new vmalloc */ | ||
229 | } | ||
230 | |||
231 | ucode_ptr += mc_size; | ||
232 | leftover -= mc_size; | ||
233 | } | ||
234 | |||
235 | vfree(mc); | ||
236 | |||
237 | if (leftover) { | ||
238 | vfree(new_mc); | ||
239 | state = UCODE_ERROR; | ||
240 | goto out; | ||
241 | } | ||
242 | |||
243 | if (!new_mc) { | ||
244 | state = UCODE_NFOUND; | ||
245 | goto out; | ||
246 | } | ||
247 | |||
248 | vfree(uci->mc); | ||
249 | uci->mc = (struct microcode_intel *)new_mc; | ||
250 | |||
251 | /* | ||
252 | * If early loading microcode is supported, save this mc into | ||
253 | * permanent memory. So it will be loaded early when a CPU is hot added | ||
254 | * or resumes. | ||
255 | */ | ||
256 | save_mc_for_early(new_mc); | ||
257 | |||
258 | pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", | ||
259 | cpu, new_rev, uci->cpu_sig.rev); | ||
260 | out: | ||
261 | return state; | ||
262 | } | ||
263 | |||
264 | static int get_ucode_fw(void *to, const void *from, size_t n) | ||
265 | { | ||
266 | memcpy(to, from, n); | ||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static enum ucode_state request_microcode_fw(int cpu, struct device *device, | ||
271 | bool refresh_fw) | ||
272 | { | ||
273 | char name[30]; | ||
274 | struct cpuinfo_x86 *c = &cpu_data(cpu); | ||
275 | const struct firmware *firmware; | ||
276 | enum ucode_state ret; | ||
277 | |||
278 | sprintf(name, "intel-ucode/%02x-%02x-%02x", | ||
279 | c->x86, c->x86_model, c->x86_mask); | ||
280 | |||
281 | if (request_firmware(&firmware, name, device)) { | ||
282 | pr_debug("data file %s load failed\n", name); | ||
283 | return UCODE_NFOUND; | ||
284 | } | ||
285 | |||
286 | ret = generic_load_microcode(cpu, (void *)firmware->data, | ||
287 | firmware->size, &get_ucode_fw); | ||
288 | |||
289 | release_firmware(firmware); | ||
290 | |||
291 | return ret; | ||
292 | } | ||
293 | |||
294 | static int get_ucode_user(void *to, const void *from, size_t n) | ||
295 | { | ||
296 | return copy_from_user(to, from, n); | ||
297 | } | ||
298 | |||
299 | static enum ucode_state | ||
300 | request_microcode_user(int cpu, const void __user *buf, size_t size) | ||
301 | { | ||
302 | return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user); | ||
303 | } | ||
304 | |||
305 | static void microcode_fini_cpu(int cpu) | ||
306 | { | ||
307 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | ||
308 | |||
309 | vfree(uci->mc); | ||
310 | uci->mc = NULL; | ||
311 | } | ||
312 | |||
313 | static struct microcode_ops microcode_intel_ops = { | ||
314 | .request_microcode_user = request_microcode_user, | ||
315 | .request_microcode_fw = request_microcode_fw, | ||
316 | .collect_cpu_info = collect_cpu_info, | ||
317 | .apply_microcode = apply_microcode, | ||
318 | .microcode_fini_cpu = microcode_fini_cpu, | ||
319 | }; | ||
320 | |||
321 | struct microcode_ops * __init init_intel_microcode(void) | ||
322 | { | ||
323 | struct cpuinfo_x86 *c = &cpu_data(0); | ||
324 | |||
325 | if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || | ||
326 | cpu_has(c, X86_FEATURE_IA64)) { | ||
327 | pr_err("Intel CPU family 0x%x not supported\n", c->x86); | ||
328 | return NULL; | ||
329 | } | ||
330 | |||
331 | return µcode_intel_ops; | ||
332 | } | ||
333 | |||
diff --git a/arch/x86/kernel/cpu/microcode/intel_early.c b/arch/x86/kernel/cpu/microcode/intel_early.c new file mode 100644 index 000000000000..18f739129e72 --- /dev/null +++ b/arch/x86/kernel/cpu/microcode/intel_early.c | |||
@@ -0,0 +1,787 @@ | |||
1 | /* | ||
2 | * Intel CPU microcode early update for Linux | ||
3 | * | ||
4 | * Copyright (C) 2012 Fenghua Yu <fenghua.yu@intel.com> | ||
5 | * H Peter Anvin" <hpa@zytor.com> | ||
6 | * | ||
7 | * This allows to early upgrade microcode on Intel processors | ||
8 | * belonging to IA-32 family - PentiumPro, Pentium II, | ||
9 | * Pentium III, Xeon, Pentium 4, etc. | ||
10 | * | ||
11 | * Reference: Section 9.11 of Volume 3, IA-32 Intel Architecture | ||
12 | * Software Developer's Manual. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License | ||
16 | * as published by the Free Software Foundation; either version | ||
17 | * 2 of the License, or (at your option) any later version. | ||
18 | */ | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/mm.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/earlycpio.h> | ||
23 | #include <linux/initrd.h> | ||
24 | #include <linux/cpu.h> | ||
25 | #include <asm/msr.h> | ||
26 | #include <asm/microcode_intel.h> | ||
27 | #include <asm/processor.h> | ||
28 | #include <asm/tlbflush.h> | ||
29 | #include <asm/setup.h> | ||
30 | |||
31 | unsigned long mc_saved_in_initrd[MAX_UCODE_COUNT]; | ||
32 | struct mc_saved_data { | ||
33 | unsigned int mc_saved_count; | ||
34 | struct microcode_intel **mc_saved; | ||
35 | } mc_saved_data; | ||
36 | |||
37 | static enum ucode_state | ||
38 | generic_load_microcode_early(struct microcode_intel **mc_saved_p, | ||
39 | unsigned int mc_saved_count, | ||
40 | struct ucode_cpu_info *uci) | ||
41 | { | ||
42 | struct microcode_intel *ucode_ptr, *new_mc = NULL; | ||
43 | int new_rev = uci->cpu_sig.rev; | ||
44 | enum ucode_state state = UCODE_OK; | ||
45 | unsigned int mc_size; | ||
46 | struct microcode_header_intel *mc_header; | ||
47 | unsigned int csig = uci->cpu_sig.sig; | ||
48 | unsigned int cpf = uci->cpu_sig.pf; | ||
49 | int i; | ||
50 | |||
51 | for (i = 0; i < mc_saved_count; i++) { | ||
52 | ucode_ptr = mc_saved_p[i]; | ||
53 | |||
54 | mc_header = (struct microcode_header_intel *)ucode_ptr; | ||
55 | mc_size = get_totalsize(mc_header); | ||
56 | if (get_matching_microcode(csig, cpf, ucode_ptr, new_rev)) { | ||
57 | new_rev = mc_header->rev; | ||
58 | new_mc = ucode_ptr; | ||
59 | } | ||
60 | } | ||
61 | |||
62 | if (!new_mc) { | ||
63 | state = UCODE_NFOUND; | ||
64 | goto out; | ||
65 | } | ||
66 | |||
67 | uci->mc = (struct microcode_intel *)new_mc; | ||
68 | out: | ||
69 | return state; | ||
70 | } | ||
71 | |||
72 | static void | ||
73 | microcode_pointer(struct microcode_intel **mc_saved, | ||
74 | unsigned long *mc_saved_in_initrd, | ||
75 | unsigned long initrd_start, int mc_saved_count) | ||
76 | { | ||
77 | int i; | ||
78 | |||
79 | for (i = 0; i < mc_saved_count; i++) | ||
80 | mc_saved[i] = (struct microcode_intel *) | ||
81 | (mc_saved_in_initrd[i] + initrd_start); | ||
82 | } | ||
83 | |||
84 | #ifdef CONFIG_X86_32 | ||
85 | static void | ||
86 | microcode_phys(struct microcode_intel **mc_saved_tmp, | ||
87 | struct mc_saved_data *mc_saved_data) | ||
88 | { | ||
89 | int i; | ||
90 | struct microcode_intel ***mc_saved; | ||
91 | |||
92 | mc_saved = (struct microcode_intel ***) | ||
93 | __pa_nodebug(&mc_saved_data->mc_saved); | ||
94 | for (i = 0; i < mc_saved_data->mc_saved_count; i++) { | ||
95 | struct microcode_intel *p; | ||
96 | |||
97 | p = *(struct microcode_intel **) | ||
98 | __pa_nodebug(mc_saved_data->mc_saved + i); | ||
99 | mc_saved_tmp[i] = (struct microcode_intel *)__pa_nodebug(p); | ||
100 | } | ||
101 | } | ||
102 | #endif | ||
103 | |||
104 | static enum ucode_state | ||
105 | load_microcode(struct mc_saved_data *mc_saved_data, | ||
106 | unsigned long *mc_saved_in_initrd, | ||
107 | unsigned long initrd_start, | ||
108 | struct ucode_cpu_info *uci) | ||
109 | { | ||
110 | struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT]; | ||
111 | unsigned int count = mc_saved_data->mc_saved_count; | ||
112 | |||
113 | if (!mc_saved_data->mc_saved) { | ||
114 | microcode_pointer(mc_saved_tmp, mc_saved_in_initrd, | ||
115 | initrd_start, count); | ||
116 | |||
117 | return generic_load_microcode_early(mc_saved_tmp, count, uci); | ||
118 | } else { | ||
119 | #ifdef CONFIG_X86_32 | ||
120 | microcode_phys(mc_saved_tmp, mc_saved_data); | ||
121 | return generic_load_microcode_early(mc_saved_tmp, count, uci); | ||
122 | #else | ||
123 | return generic_load_microcode_early(mc_saved_data->mc_saved, | ||
124 | count, uci); | ||
125 | #endif | ||
126 | } | ||
127 | } | ||
128 | |||
129 | static u8 get_x86_family(unsigned long sig) | ||
130 | { | ||
131 | u8 x86; | ||
132 | |||
133 | x86 = (sig >> 8) & 0xf; | ||
134 | |||
135 | if (x86 == 0xf) | ||
136 | x86 += (sig >> 20) & 0xff; | ||
137 | |||
138 | return x86; | ||
139 | } | ||
140 | |||
141 | static u8 get_x86_model(unsigned long sig) | ||
142 | { | ||
143 | u8 x86, x86_model; | ||
144 | |||
145 | x86 = get_x86_family(sig); | ||
146 | x86_model = (sig >> 4) & 0xf; | ||
147 | |||
148 | if (x86 == 0x6 || x86 == 0xf) | ||
149 | x86_model += ((sig >> 16) & 0xf) << 4; | ||
150 | |||
151 | return x86_model; | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * Given CPU signature and a microcode patch, this function finds if the | ||
156 | * microcode patch has matching family and model with the CPU. | ||
157 | */ | ||
158 | static enum ucode_state | ||
159 | matching_model_microcode(struct microcode_header_intel *mc_header, | ||
160 | unsigned long sig) | ||
161 | { | ||
162 | u8 x86, x86_model; | ||
163 | u8 x86_ucode, x86_model_ucode; | ||
164 | struct extended_sigtable *ext_header; | ||
165 | unsigned long total_size = get_totalsize(mc_header); | ||
166 | unsigned long data_size = get_datasize(mc_header); | ||
167 | int ext_sigcount, i; | ||
168 | struct extended_signature *ext_sig; | ||
169 | |||
170 | x86 = get_x86_family(sig); | ||
171 | x86_model = get_x86_model(sig); | ||
172 | |||
173 | x86_ucode = get_x86_family(mc_header->sig); | ||
174 | x86_model_ucode = get_x86_model(mc_header->sig); | ||
175 | |||
176 | if (x86 == x86_ucode && x86_model == x86_model_ucode) | ||
177 | return UCODE_OK; | ||
178 | |||
179 | /* Look for ext. headers: */ | ||
180 | if (total_size <= data_size + MC_HEADER_SIZE) | ||
181 | return UCODE_NFOUND; | ||
182 | |||
183 | ext_header = (struct extended_sigtable *) | ||
184 | mc_header + data_size + MC_HEADER_SIZE; | ||
185 | ext_sigcount = ext_header->count; | ||
186 | ext_sig = (void *)ext_header + EXT_HEADER_SIZE; | ||
187 | |||
188 | for (i = 0; i < ext_sigcount; i++) { | ||
189 | x86_ucode = get_x86_family(ext_sig->sig); | ||
190 | x86_model_ucode = get_x86_model(ext_sig->sig); | ||
191 | |||
192 | if (x86 == x86_ucode && x86_model == x86_model_ucode) | ||
193 | return UCODE_OK; | ||
194 | |||
195 | ext_sig++; | ||
196 | } | ||
197 | |||
198 | return UCODE_NFOUND; | ||
199 | } | ||
200 | |||
201 | static int | ||
202 | save_microcode(struct mc_saved_data *mc_saved_data, | ||
203 | struct microcode_intel **mc_saved_src, | ||
204 | unsigned int mc_saved_count) | ||
205 | { | ||
206 | int i, j; | ||
207 | struct microcode_intel **mc_saved_p; | ||
208 | int ret; | ||
209 | |||
210 | if (!mc_saved_count) | ||
211 | return -EINVAL; | ||
212 | |||
213 | /* | ||
214 | * Copy new microcode data. | ||
215 | */ | ||
216 | mc_saved_p = kmalloc(mc_saved_count*sizeof(struct microcode_intel *), | ||
217 | GFP_KERNEL); | ||
218 | if (!mc_saved_p) | ||
219 | return -ENOMEM; | ||
220 | |||
221 | for (i = 0; i < mc_saved_count; i++) { | ||
222 | struct microcode_intel *mc = mc_saved_src[i]; | ||
223 | struct microcode_header_intel *mc_header = &mc->hdr; | ||
224 | unsigned long mc_size = get_totalsize(mc_header); | ||
225 | mc_saved_p[i] = kmalloc(mc_size, GFP_KERNEL); | ||
226 | if (!mc_saved_p[i]) { | ||
227 | ret = -ENOMEM; | ||
228 | goto err; | ||
229 | } | ||
230 | if (!mc_saved_src[i]) { | ||
231 | ret = -EINVAL; | ||
232 | goto err; | ||
233 | } | ||
234 | memcpy(mc_saved_p[i], mc, mc_size); | ||
235 | } | ||
236 | |||
237 | /* | ||
238 | * Point to newly saved microcode. | ||
239 | */ | ||
240 | mc_saved_data->mc_saved = mc_saved_p; | ||
241 | mc_saved_data->mc_saved_count = mc_saved_count; | ||
242 | |||
243 | return 0; | ||
244 | |||
245 | err: | ||
246 | for (j = 0; j <= i; j++) | ||
247 | kfree(mc_saved_p[j]); | ||
248 | kfree(mc_saved_p); | ||
249 | |||
250 | return ret; | ||
251 | } | ||
252 | |||
253 | /* | ||
254 | * A microcode patch in ucode_ptr is saved into mc_saved | ||
255 | * - if it has matching signature and newer revision compared to an existing | ||
256 | * patch mc_saved. | ||
257 | * - or if it is a newly discovered microcode patch. | ||
258 | * | ||
259 | * The microcode patch should have matching model with CPU. | ||
260 | */ | ||
261 | static void _save_mc(struct microcode_intel **mc_saved, u8 *ucode_ptr, | ||
262 | unsigned int *mc_saved_count_p) | ||
263 | { | ||
264 | int i; | ||
265 | int found = 0; | ||
266 | unsigned int mc_saved_count = *mc_saved_count_p; | ||
267 | struct microcode_header_intel *mc_header; | ||
268 | |||
269 | mc_header = (struct microcode_header_intel *)ucode_ptr; | ||
270 | for (i = 0; i < mc_saved_count; i++) { | ||
271 | unsigned int sig, pf; | ||
272 | unsigned int new_rev; | ||
273 | struct microcode_header_intel *mc_saved_header = | ||
274 | (struct microcode_header_intel *)mc_saved[i]; | ||
275 | sig = mc_saved_header->sig; | ||
276 | pf = mc_saved_header->pf; | ||
277 | new_rev = mc_header->rev; | ||
278 | |||
279 | if (get_matching_sig(sig, pf, ucode_ptr, new_rev)) { | ||
280 | found = 1; | ||
281 | if (update_match_revision(mc_header, new_rev)) { | ||
282 | /* | ||
283 | * Found an older ucode saved before. | ||
284 | * Replace the older one with this newer | ||
285 | * one. | ||
286 | */ | ||
287 | mc_saved[i] = | ||
288 | (struct microcode_intel *)ucode_ptr; | ||
289 | break; | ||
290 | } | ||
291 | } | ||
292 | } | ||
293 | if (i >= mc_saved_count && !found) | ||
294 | /* | ||
295 | * This ucode is first time discovered in ucode file. | ||
296 | * Save it to memory. | ||
297 | */ | ||
298 | mc_saved[mc_saved_count++] = | ||
299 | (struct microcode_intel *)ucode_ptr; | ||
300 | |||
301 | *mc_saved_count_p = mc_saved_count; | ||
302 | } | ||
303 | |||
304 | /* | ||
305 | * Get microcode matching with BSP's model. Only CPUs with the same model as | ||
306 | * BSP can stay in the platform. | ||
307 | */ | ||
308 | static enum ucode_state __init | ||
309 | get_matching_model_microcode(int cpu, unsigned long start, | ||
310 | void *data, size_t size, | ||
311 | struct mc_saved_data *mc_saved_data, | ||
312 | unsigned long *mc_saved_in_initrd, | ||
313 | struct ucode_cpu_info *uci) | ||
314 | { | ||
315 | u8 *ucode_ptr = data; | ||
316 | unsigned int leftover = size; | ||
317 | enum ucode_state state = UCODE_OK; | ||
318 | unsigned int mc_size; | ||
319 | struct microcode_header_intel *mc_header; | ||
320 | struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT]; | ||
321 | unsigned int mc_saved_count = mc_saved_data->mc_saved_count; | ||
322 | int i; | ||
323 | |||
324 | while (leftover) { | ||
325 | mc_header = (struct microcode_header_intel *)ucode_ptr; | ||
326 | |||
327 | mc_size = get_totalsize(mc_header); | ||
328 | if (!mc_size || mc_size > leftover || | ||
329 | microcode_sanity_check(ucode_ptr, 0) < 0) | ||
330 | break; | ||
331 | |||
332 | leftover -= mc_size; | ||
333 | |||
334 | /* | ||
335 | * Since APs with same family and model as the BSP may boot in | ||
336 | * the platform, we need to find and save microcode patches | ||
337 | * with the same family and model as the BSP. | ||
338 | */ | ||
339 | if (matching_model_microcode(mc_header, uci->cpu_sig.sig) != | ||
340 | UCODE_OK) { | ||
341 | ucode_ptr += mc_size; | ||
342 | continue; | ||
343 | } | ||
344 | |||
345 | _save_mc(mc_saved_tmp, ucode_ptr, &mc_saved_count); | ||
346 | |||
347 | ucode_ptr += mc_size; | ||
348 | } | ||
349 | |||
350 | if (leftover) { | ||
351 | state = UCODE_ERROR; | ||
352 | goto out; | ||
353 | } | ||
354 | |||
355 | if (mc_saved_count == 0) { | ||
356 | state = UCODE_NFOUND; | ||
357 | goto out; | ||
358 | } | ||
359 | |||
360 | for (i = 0; i < mc_saved_count; i++) | ||
361 | mc_saved_in_initrd[i] = (unsigned long)mc_saved_tmp[i] - start; | ||
362 | |||
363 | mc_saved_data->mc_saved_count = mc_saved_count; | ||
364 | out: | ||
365 | return state; | ||
366 | } | ||
367 | |||
368 | static int collect_cpu_info_early(struct ucode_cpu_info *uci) | ||
369 | { | ||
370 | unsigned int val[2]; | ||
371 | u8 x86, x86_model; | ||
372 | struct cpu_signature csig; | ||
373 | unsigned int eax, ebx, ecx, edx; | ||
374 | |||
375 | csig.sig = 0; | ||
376 | csig.pf = 0; | ||
377 | csig.rev = 0; | ||
378 | |||
379 | memset(uci, 0, sizeof(*uci)); | ||
380 | |||
381 | eax = 0x00000001; | ||
382 | ecx = 0; | ||
383 | native_cpuid(&eax, &ebx, &ecx, &edx); | ||
384 | csig.sig = eax; | ||
385 | |||
386 | x86 = get_x86_family(csig.sig); | ||
387 | x86_model = get_x86_model(csig.sig); | ||
388 | |||
389 | if ((x86_model >= 5) || (x86 > 6)) { | ||
390 | /* get processor flags from MSR 0x17 */ | ||
391 | native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); | ||
392 | csig.pf = 1 << ((val[1] >> 18) & 7); | ||
393 | } | ||
394 | native_wrmsr(MSR_IA32_UCODE_REV, 0, 0); | ||
395 | |||
396 | /* As documented in the SDM: Do a CPUID 1 here */ | ||
397 | sync_core(); | ||
398 | |||
399 | /* get the current revision from MSR 0x8B */ | ||
400 | native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); | ||
401 | |||
402 | csig.rev = val[1]; | ||
403 | |||
404 | uci->cpu_sig = csig; | ||
405 | uci->valid = 1; | ||
406 | |||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | #ifdef DEBUG | ||
411 | static void __ref show_saved_mc(void) | ||
412 | { | ||
413 | int i, j; | ||
414 | unsigned int sig, pf, rev, total_size, data_size, date; | ||
415 | struct ucode_cpu_info uci; | ||
416 | |||
417 | if (mc_saved_data.mc_saved_count == 0) { | ||
418 | pr_debug("no micorcode data saved.\n"); | ||
419 | return; | ||
420 | } | ||
421 | pr_debug("Total microcode saved: %d\n", mc_saved_data.mc_saved_count); | ||
422 | |||
423 | collect_cpu_info_early(&uci); | ||
424 | |||
425 | sig = uci.cpu_sig.sig; | ||
426 | pf = uci.cpu_sig.pf; | ||
427 | rev = uci.cpu_sig.rev; | ||
428 | pr_debug("CPU%d: sig=0x%x, pf=0x%x, rev=0x%x\n", | ||
429 | smp_processor_id(), sig, pf, rev); | ||
430 | |||
431 | for (i = 0; i < mc_saved_data.mc_saved_count; i++) { | ||
432 | struct microcode_header_intel *mc_saved_header; | ||
433 | struct extended_sigtable *ext_header; | ||
434 | int ext_sigcount; | ||
435 | struct extended_signature *ext_sig; | ||
436 | |||
437 | mc_saved_header = (struct microcode_header_intel *) | ||
438 | mc_saved_data.mc_saved[i]; | ||
439 | sig = mc_saved_header->sig; | ||
440 | pf = mc_saved_header->pf; | ||
441 | rev = mc_saved_header->rev; | ||
442 | total_size = get_totalsize(mc_saved_header); | ||
443 | data_size = get_datasize(mc_saved_header); | ||
444 | date = mc_saved_header->date; | ||
445 | |||
446 | pr_debug("mc_saved[%d]: sig=0x%x, pf=0x%x, rev=0x%x, toal size=0x%x, date = %04x-%02x-%02x\n", | ||
447 | i, sig, pf, rev, total_size, | ||
448 | date & 0xffff, | ||
449 | date >> 24, | ||
450 | (date >> 16) & 0xff); | ||
451 | |||
452 | /* Look for ext. headers: */ | ||
453 | if (total_size <= data_size + MC_HEADER_SIZE) | ||
454 | continue; | ||
455 | |||
456 | ext_header = (struct extended_sigtable *) | ||
457 | mc_saved_header + data_size + MC_HEADER_SIZE; | ||
458 | ext_sigcount = ext_header->count; | ||
459 | ext_sig = (void *)ext_header + EXT_HEADER_SIZE; | ||
460 | |||
461 | for (j = 0; j < ext_sigcount; j++) { | ||
462 | sig = ext_sig->sig; | ||
463 | pf = ext_sig->pf; | ||
464 | |||
465 | pr_debug("\tExtended[%d]: sig=0x%x, pf=0x%x\n", | ||
466 | j, sig, pf); | ||
467 | |||
468 | ext_sig++; | ||
469 | } | ||
470 | |||
471 | } | ||
472 | } | ||
473 | #else | ||
474 | static inline void show_saved_mc(void) | ||
475 | { | ||
476 | } | ||
477 | #endif | ||
478 | |||
479 | #if defined(CONFIG_MICROCODE_INTEL_EARLY) && defined(CONFIG_HOTPLUG_CPU) | ||
480 | static DEFINE_MUTEX(x86_cpu_microcode_mutex); | ||
481 | /* | ||
482 | * Save this mc into mc_saved_data. So it will be loaded early when a CPU is | ||
483 | * hot added or resumes. | ||
484 | * | ||
485 | * Please make sure this mc should be a valid microcode patch before calling | ||
486 | * this function. | ||
487 | */ | ||
488 | int save_mc_for_early(u8 *mc) | ||
489 | { | ||
490 | struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT]; | ||
491 | unsigned int mc_saved_count_init; | ||
492 | unsigned int mc_saved_count; | ||
493 | struct microcode_intel **mc_saved; | ||
494 | int ret = 0; | ||
495 | int i; | ||
496 | |||
497 | /* | ||
498 | * Hold hotplug lock so mc_saved_data is not accessed by a CPU in | ||
499 | * hotplug. | ||
500 | */ | ||
501 | mutex_lock(&x86_cpu_microcode_mutex); | ||
502 | |||
503 | mc_saved_count_init = mc_saved_data.mc_saved_count; | ||
504 | mc_saved_count = mc_saved_data.mc_saved_count; | ||
505 | mc_saved = mc_saved_data.mc_saved; | ||
506 | |||
507 | if (mc_saved && mc_saved_count) | ||
508 | memcpy(mc_saved_tmp, mc_saved, | ||
509 | mc_saved_count * sizeof(struct mirocode_intel *)); | ||
510 | /* | ||
511 | * Save the microcode patch mc in mc_save_tmp structure if it's a newer | ||
512 | * version. | ||
513 | */ | ||
514 | |||
515 | _save_mc(mc_saved_tmp, mc, &mc_saved_count); | ||
516 | |||
517 | /* | ||
518 | * Save the mc_save_tmp in global mc_saved_data. | ||
519 | */ | ||
520 | ret = save_microcode(&mc_saved_data, mc_saved_tmp, mc_saved_count); | ||
521 | if (ret) { | ||
522 | pr_err("Cannot save microcode patch.\n"); | ||
523 | goto out; | ||
524 | } | ||
525 | |||
526 | show_saved_mc(); | ||
527 | |||
528 | /* | ||
529 | * Free old saved microcod data. | ||
530 | */ | ||
531 | if (mc_saved) { | ||
532 | for (i = 0; i < mc_saved_count_init; i++) | ||
533 | kfree(mc_saved[i]); | ||
534 | kfree(mc_saved); | ||
535 | } | ||
536 | |||
537 | out: | ||
538 | mutex_unlock(&x86_cpu_microcode_mutex); | ||
539 | |||
540 | return ret; | ||
541 | } | ||
542 | EXPORT_SYMBOL_GPL(save_mc_for_early); | ||
543 | #endif | ||
544 | |||
545 | static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin"; | ||
546 | static __init enum ucode_state | ||
547 | scan_microcode(unsigned long start, unsigned long end, | ||
548 | struct mc_saved_data *mc_saved_data, | ||
549 | unsigned long *mc_saved_in_initrd, | ||
550 | struct ucode_cpu_info *uci) | ||
551 | { | ||
552 | unsigned int size = end - start + 1; | ||
553 | struct cpio_data cd; | ||
554 | long offset = 0; | ||
555 | #ifdef CONFIG_X86_32 | ||
556 | char *p = (char *)__pa_nodebug(ucode_name); | ||
557 | #else | ||
558 | char *p = ucode_name; | ||
559 | #endif | ||
560 | |||
561 | cd.data = NULL; | ||
562 | cd.size = 0; | ||
563 | |||
564 | cd = find_cpio_data(p, (void *)start, size, &offset); | ||
565 | if (!cd.data) | ||
566 | return UCODE_ERROR; | ||
567 | |||
568 | |||
569 | return get_matching_model_microcode(0, start, cd.data, cd.size, | ||
570 | mc_saved_data, mc_saved_in_initrd, | ||
571 | uci); | ||
572 | } | ||
573 | |||
574 | /* | ||
575 | * Print ucode update info. | ||
576 | */ | ||
577 | static void | ||
578 | print_ucode_info(struct ucode_cpu_info *uci, unsigned int date) | ||
579 | { | ||
580 | int cpu = smp_processor_id(); | ||
581 | |||
582 | pr_info("CPU%d microcode updated early to revision 0x%x, date = %04x-%02x-%02x\n", | ||
583 | cpu, | ||
584 | uci->cpu_sig.rev, | ||
585 | date & 0xffff, | ||
586 | date >> 24, | ||
587 | (date >> 16) & 0xff); | ||
588 | } | ||
589 | |||
590 | #ifdef CONFIG_X86_32 | ||
591 | |||
592 | static int delay_ucode_info; | ||
593 | static int current_mc_date; | ||
594 | |||
595 | /* | ||
596 | * Print early updated ucode info after printk works. This is delayed info dump. | ||
597 | */ | ||
598 | void show_ucode_info_early(void) | ||
599 | { | ||
600 | struct ucode_cpu_info uci; | ||
601 | |||
602 | if (delay_ucode_info) { | ||
603 | collect_cpu_info_early(&uci); | ||
604 | print_ucode_info(&uci, current_mc_date); | ||
605 | delay_ucode_info = 0; | ||
606 | } | ||
607 | } | ||
608 | |||
609 | /* | ||
610 | * At this point, we can not call printk() yet. Keep microcode patch number in | ||
611 | * mc_saved_data.mc_saved and delay printing microcode info in | ||
612 | * show_ucode_info_early() until printk() works. | ||
613 | */ | ||
614 | static void print_ucode(struct ucode_cpu_info *uci) | ||
615 | { | ||
616 | struct microcode_intel *mc_intel; | ||
617 | int *delay_ucode_info_p; | ||
618 | int *current_mc_date_p; | ||
619 | |||
620 | mc_intel = uci->mc; | ||
621 | if (mc_intel == NULL) | ||
622 | return; | ||
623 | |||
624 | delay_ucode_info_p = (int *)__pa_nodebug(&delay_ucode_info); | ||
625 | current_mc_date_p = (int *)__pa_nodebug(¤t_mc_date); | ||
626 | |||
627 | *delay_ucode_info_p = 1; | ||
628 | *current_mc_date_p = mc_intel->hdr.date; | ||
629 | } | ||
630 | #else | ||
631 | |||
632 | /* | ||
633 | * Flush global tlb. We only do this in x86_64 where paging has been enabled | ||
634 | * already and PGE should be enabled as well. | ||
635 | */ | ||
636 | static inline void flush_tlb_early(void) | ||
637 | { | ||
638 | __native_flush_tlb_global_irq_disabled(); | ||
639 | } | ||
640 | |||
641 | static inline void print_ucode(struct ucode_cpu_info *uci) | ||
642 | { | ||
643 | struct microcode_intel *mc_intel; | ||
644 | |||
645 | mc_intel = uci->mc; | ||
646 | if (mc_intel == NULL) | ||
647 | return; | ||
648 | |||
649 | print_ucode_info(uci, mc_intel->hdr.date); | ||
650 | } | ||
651 | #endif | ||
652 | |||
653 | static int apply_microcode_early(struct mc_saved_data *mc_saved_data, | ||
654 | struct ucode_cpu_info *uci) | ||
655 | { | ||
656 | struct microcode_intel *mc_intel; | ||
657 | unsigned int val[2]; | ||
658 | |||
659 | mc_intel = uci->mc; | ||
660 | if (mc_intel == NULL) | ||
661 | return 0; | ||
662 | |||
663 | /* write microcode via MSR 0x79 */ | ||
664 | native_wrmsr(MSR_IA32_UCODE_WRITE, | ||
665 | (unsigned long) mc_intel->bits, | ||
666 | (unsigned long) mc_intel->bits >> 16 >> 16); | ||
667 | native_wrmsr(MSR_IA32_UCODE_REV, 0, 0); | ||
668 | |||
669 | /* As documented in the SDM: Do a CPUID 1 here */ | ||
670 | sync_core(); | ||
671 | |||
672 | /* get the current revision from MSR 0x8B */ | ||
673 | native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); | ||
674 | if (val[1] != mc_intel->hdr.rev) | ||
675 | return -1; | ||
676 | |||
677 | #ifdef CONFIG_X86_64 | ||
678 | /* Flush global tlb. This is precaution. */ | ||
679 | flush_tlb_early(); | ||
680 | #endif | ||
681 | uci->cpu_sig.rev = val[1]; | ||
682 | |||
683 | print_ucode(uci); | ||
684 | |||
685 | return 0; | ||
686 | } | ||
687 | |||
688 | /* | ||
689 | * This function converts microcode patch offsets previously stored in | ||
690 | * mc_saved_in_initrd to pointers and stores the pointers in mc_saved_data. | ||
691 | */ | ||
692 | int __init save_microcode_in_initrd_intel(void) | ||
693 | { | ||
694 | unsigned int count = mc_saved_data.mc_saved_count; | ||
695 | struct microcode_intel *mc_saved[MAX_UCODE_COUNT]; | ||
696 | int ret = 0; | ||
697 | |||
698 | if (count == 0) | ||
699 | return ret; | ||
700 | |||
701 | microcode_pointer(mc_saved, mc_saved_in_initrd, initrd_start, count); | ||
702 | ret = save_microcode(&mc_saved_data, mc_saved, count); | ||
703 | if (ret) | ||
704 | pr_err("Cannot save microcode patches from initrd.\n"); | ||
705 | |||
706 | show_saved_mc(); | ||
707 | |||
708 | return ret; | ||
709 | } | ||
710 | |||
711 | static void __init | ||
712 | _load_ucode_intel_bsp(struct mc_saved_data *mc_saved_data, | ||
713 | unsigned long *mc_saved_in_initrd, | ||
714 | unsigned long initrd_start_early, | ||
715 | unsigned long initrd_end_early, | ||
716 | struct ucode_cpu_info *uci) | ||
717 | { | ||
718 | collect_cpu_info_early(uci); | ||
719 | scan_microcode(initrd_start_early, initrd_end_early, mc_saved_data, | ||
720 | mc_saved_in_initrd, uci); | ||
721 | load_microcode(mc_saved_data, mc_saved_in_initrd, | ||
722 | initrd_start_early, uci); | ||
723 | apply_microcode_early(mc_saved_data, uci); | ||
724 | } | ||
725 | |||
726 | void __init | ||
727 | load_ucode_intel_bsp(void) | ||
728 | { | ||
729 | u64 ramdisk_image, ramdisk_size; | ||
730 | unsigned long initrd_start_early, initrd_end_early; | ||
731 | struct ucode_cpu_info uci; | ||
732 | #ifdef CONFIG_X86_32 | ||
733 | struct boot_params *boot_params_p; | ||
734 | |||
735 | boot_params_p = (struct boot_params *)__pa_nodebug(&boot_params); | ||
736 | ramdisk_image = boot_params_p->hdr.ramdisk_image; | ||
737 | ramdisk_size = boot_params_p->hdr.ramdisk_size; | ||
738 | initrd_start_early = ramdisk_image; | ||
739 | initrd_end_early = initrd_start_early + ramdisk_size; | ||
740 | |||
741 | _load_ucode_intel_bsp( | ||
742 | (struct mc_saved_data *)__pa_nodebug(&mc_saved_data), | ||
743 | (unsigned long *)__pa_nodebug(&mc_saved_in_initrd), | ||
744 | initrd_start_early, initrd_end_early, &uci); | ||
745 | #else | ||
746 | ramdisk_image = boot_params.hdr.ramdisk_image; | ||
747 | ramdisk_size = boot_params.hdr.ramdisk_size; | ||
748 | initrd_start_early = ramdisk_image + PAGE_OFFSET; | ||
749 | initrd_end_early = initrd_start_early + ramdisk_size; | ||
750 | |||
751 | _load_ucode_intel_bsp(&mc_saved_data, mc_saved_in_initrd, | ||
752 | initrd_start_early, initrd_end_early, &uci); | ||
753 | #endif | ||
754 | } | ||
755 | |||
756 | void load_ucode_intel_ap(void) | ||
757 | { | ||
758 | struct mc_saved_data *mc_saved_data_p; | ||
759 | struct ucode_cpu_info uci; | ||
760 | unsigned long *mc_saved_in_initrd_p; | ||
761 | unsigned long initrd_start_addr; | ||
762 | #ifdef CONFIG_X86_32 | ||
763 | unsigned long *initrd_start_p; | ||
764 | |||
765 | mc_saved_in_initrd_p = | ||
766 | (unsigned long *)__pa_nodebug(mc_saved_in_initrd); | ||
767 | mc_saved_data_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data); | ||
768 | initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start); | ||
769 | initrd_start_addr = (unsigned long)__pa_nodebug(*initrd_start_p); | ||
770 | #else | ||
771 | mc_saved_data_p = &mc_saved_data; | ||
772 | mc_saved_in_initrd_p = mc_saved_in_initrd; | ||
773 | initrd_start_addr = initrd_start; | ||
774 | #endif | ||
775 | |||
776 | /* | ||
777 | * If there is no valid ucode previously saved in memory, no need to | ||
778 | * update ucode on this AP. | ||
779 | */ | ||
780 | if (mc_saved_data_p->mc_saved_count == 0) | ||
781 | return; | ||
782 | |||
783 | collect_cpu_info_early(&uci); | ||
784 | load_microcode(mc_saved_data_p, mc_saved_in_initrd_p, | ||
785 | initrd_start_addr, &uci); | ||
786 | apply_microcode_early(mc_saved_data_p, &uci); | ||
787 | } | ||
diff --git a/arch/x86/kernel/cpu/microcode/intel_lib.c b/arch/x86/kernel/cpu/microcode/intel_lib.c new file mode 100644 index 000000000000..ce69320d0179 --- /dev/null +++ b/arch/x86/kernel/cpu/microcode/intel_lib.c | |||
@@ -0,0 +1,174 @@ | |||
1 | /* | ||
2 | * Intel CPU Microcode Update Driver for Linux | ||
3 | * | ||
4 | * Copyright (C) 2012 Fenghua Yu <fenghua.yu@intel.com> | ||
5 | * H Peter Anvin" <hpa@zytor.com> | ||
6 | * | ||
7 | * This driver allows to upgrade microcode on Intel processors | ||
8 | * belonging to IA-32 family - PentiumPro, Pentium II, | ||
9 | * Pentium III, Xeon, Pentium 4, etc. | ||
10 | * | ||
11 | * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture | ||
12 | * Software Developer's Manual | ||
13 | * Order Number 253668 or free download from: | ||
14 | * | ||
15 | * http://developer.intel.com/Assets/PDF/manual/253668.pdf | ||
16 | * | ||
17 | * For more information, go to http://www.urbanmyth.org/microcode | ||
18 | * | ||
19 | * This program is free software; you can redistribute it and/or | ||
20 | * modify it under the terms of the GNU General Public License | ||
21 | * as published by the Free Software Foundation; either version | ||
22 | * 2 of the License, or (at your option) any later version. | ||
23 | * | ||
24 | */ | ||
25 | #include <linux/firmware.h> | ||
26 | #include <linux/uaccess.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | |||
30 | #include <asm/microcode_intel.h> | ||
31 | #include <asm/processor.h> | ||
32 | #include <asm/msr.h> | ||
33 | |||
34 | static inline int | ||
35 | update_match_cpu(unsigned int csig, unsigned int cpf, | ||
36 | unsigned int sig, unsigned int pf) | ||
37 | { | ||
38 | return (!sigmatch(sig, csig, pf, cpf)) ? 0 : 1; | ||
39 | } | ||
40 | |||
41 | int | ||
42 | update_match_revision(struct microcode_header_intel *mc_header, int rev) | ||
43 | { | ||
44 | return (mc_header->rev <= rev) ? 0 : 1; | ||
45 | } | ||
46 | |||
47 | int microcode_sanity_check(void *mc, int print_err) | ||
48 | { | ||
49 | unsigned long total_size, data_size, ext_table_size; | ||
50 | struct microcode_header_intel *mc_header = mc; | ||
51 | struct extended_sigtable *ext_header = NULL; | ||
52 | int sum, orig_sum, ext_sigcount = 0, i; | ||
53 | struct extended_signature *ext_sig; | ||
54 | |||
55 | total_size = get_totalsize(mc_header); | ||
56 | data_size = get_datasize(mc_header); | ||
57 | |||
58 | if (data_size + MC_HEADER_SIZE > total_size) { | ||
59 | if (print_err) | ||
60 | pr_err("error! Bad data size in microcode data file\n"); | ||
61 | return -EINVAL; | ||
62 | } | ||
63 | |||
64 | if (mc_header->ldrver != 1 || mc_header->hdrver != 1) { | ||
65 | if (print_err) | ||
66 | pr_err("error! Unknown microcode update format\n"); | ||
67 | return -EINVAL; | ||
68 | } | ||
69 | ext_table_size = total_size - (MC_HEADER_SIZE + data_size); | ||
70 | if (ext_table_size) { | ||
71 | if ((ext_table_size < EXT_HEADER_SIZE) | ||
72 | || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { | ||
73 | if (print_err) | ||
74 | pr_err("error! Small exttable size in microcode data file\n"); | ||
75 | return -EINVAL; | ||
76 | } | ||
77 | ext_header = mc + MC_HEADER_SIZE + data_size; | ||
78 | if (ext_table_size != exttable_size(ext_header)) { | ||
79 | if (print_err) | ||
80 | pr_err("error! Bad exttable size in microcode data file\n"); | ||
81 | return -EFAULT; | ||
82 | } | ||
83 | ext_sigcount = ext_header->count; | ||
84 | } | ||
85 | |||
86 | /* check extended table checksum */ | ||
87 | if (ext_table_size) { | ||
88 | int ext_table_sum = 0; | ||
89 | int *ext_tablep = (int *)ext_header; | ||
90 | |||
91 | i = ext_table_size / DWSIZE; | ||
92 | while (i--) | ||
93 | ext_table_sum += ext_tablep[i]; | ||
94 | if (ext_table_sum) { | ||
95 | if (print_err) | ||
96 | pr_warn("aborting, bad extended signature table checksum\n"); | ||
97 | return -EINVAL; | ||
98 | } | ||
99 | } | ||
100 | |||
101 | /* calculate the checksum */ | ||
102 | orig_sum = 0; | ||
103 | i = (MC_HEADER_SIZE + data_size) / DWSIZE; | ||
104 | while (i--) | ||
105 | orig_sum += ((int *)mc)[i]; | ||
106 | if (orig_sum) { | ||
107 | if (print_err) | ||
108 | pr_err("aborting, bad checksum\n"); | ||
109 | return -EINVAL; | ||
110 | } | ||
111 | if (!ext_table_size) | ||
112 | return 0; | ||
113 | /* check extended signature checksum */ | ||
114 | for (i = 0; i < ext_sigcount; i++) { | ||
115 | ext_sig = (void *)ext_header + EXT_HEADER_SIZE + | ||
116 | EXT_SIGNATURE_SIZE * i; | ||
117 | sum = orig_sum | ||
118 | - (mc_header->sig + mc_header->pf + mc_header->cksum) | ||
119 | + (ext_sig->sig + ext_sig->pf + ext_sig->cksum); | ||
120 | if (sum) { | ||
121 | if (print_err) | ||
122 | pr_err("aborting, bad checksum\n"); | ||
123 | return -EINVAL; | ||
124 | } | ||
125 | } | ||
126 | return 0; | ||
127 | } | ||
128 | EXPORT_SYMBOL_GPL(microcode_sanity_check); | ||
129 | |||
130 | /* | ||
131 | * return 0 - no update found | ||
132 | * return 1 - found update | ||
133 | */ | ||
134 | int get_matching_sig(unsigned int csig, int cpf, void *mc, int rev) | ||
135 | { | ||
136 | struct microcode_header_intel *mc_header = mc; | ||
137 | struct extended_sigtable *ext_header; | ||
138 | unsigned long total_size = get_totalsize(mc_header); | ||
139 | int ext_sigcount, i; | ||
140 | struct extended_signature *ext_sig; | ||
141 | |||
142 | if (update_match_cpu(csig, cpf, mc_header->sig, mc_header->pf)) | ||
143 | return 1; | ||
144 | |||
145 | /* Look for ext. headers: */ | ||
146 | if (total_size <= get_datasize(mc_header) + MC_HEADER_SIZE) | ||
147 | return 0; | ||
148 | |||
149 | ext_header = mc + get_datasize(mc_header) + MC_HEADER_SIZE; | ||
150 | ext_sigcount = ext_header->count; | ||
151 | ext_sig = (void *)ext_header + EXT_HEADER_SIZE; | ||
152 | |||
153 | for (i = 0; i < ext_sigcount; i++) { | ||
154 | if (update_match_cpu(csig, cpf, ext_sig->sig, ext_sig->pf)) | ||
155 | return 1; | ||
156 | ext_sig++; | ||
157 | } | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * return 0 - no update found | ||
163 | * return 1 - found update | ||
164 | */ | ||
165 | int get_matching_microcode(unsigned int csig, int cpf, void *mc, int rev) | ||
166 | { | ||
167 | struct microcode_header_intel *mc_header = mc; | ||
168 | |||
169 | if (!update_match_revision(mc_header, rev)) | ||
170 | return 0; | ||
171 | |||
172 | return get_matching_sig(csig, cpf, mc, rev); | ||
173 | } | ||
174 | EXPORT_SYMBOL_GPL(get_matching_microcode); | ||
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 8e132931614d..b88645191fe5 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -1883,21 +1883,27 @@ static struct pmu pmu = { | |||
1883 | 1883 | ||
1884 | void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now) | 1884 | void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now) |
1885 | { | 1885 | { |
1886 | struct cyc2ns_data *data; | ||
1887 | |||
1886 | userpg->cap_user_time = 0; | 1888 | userpg->cap_user_time = 0; |
1887 | userpg->cap_user_time_zero = 0; | 1889 | userpg->cap_user_time_zero = 0; |
1888 | userpg->cap_user_rdpmc = x86_pmu.attr_rdpmc; | 1890 | userpg->cap_user_rdpmc = x86_pmu.attr_rdpmc; |
1889 | userpg->pmc_width = x86_pmu.cntval_bits; | 1891 | userpg->pmc_width = x86_pmu.cntval_bits; |
1890 | 1892 | ||
1891 | if (!sched_clock_stable) | 1893 | if (!sched_clock_stable()) |
1892 | return; | 1894 | return; |
1893 | 1895 | ||
1896 | data = cyc2ns_read_begin(); | ||
1897 | |||
1894 | userpg->cap_user_time = 1; | 1898 | userpg->cap_user_time = 1; |
1895 | userpg->time_mult = this_cpu_read(cyc2ns); | 1899 | userpg->time_mult = data->cyc2ns_mul; |
1896 | userpg->time_shift = CYC2NS_SCALE_FACTOR; | 1900 | userpg->time_shift = data->cyc2ns_shift; |
1897 | userpg->time_offset = this_cpu_read(cyc2ns_offset) - now; | 1901 | userpg->time_offset = data->cyc2ns_offset - now; |
1898 | 1902 | ||
1899 | userpg->cap_user_time_zero = 1; | 1903 | userpg->cap_user_time_zero = 1; |
1900 | userpg->time_zero = this_cpu_read(cyc2ns_offset); | 1904 | userpg->time_zero = data->cyc2ns_offset; |
1905 | |||
1906 | cyc2ns_read_end(data); | ||
1901 | } | 1907 | } |
1902 | 1908 | ||
1903 | /* | 1909 | /* |
diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c index e09f0bfb7b8f..4b8e4d3cd6ea 100644 --- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c +++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/pci.h> | 11 | #include <linux/pci.h> |
12 | #include <linux/ptrace.h> | 12 | #include <linux/ptrace.h> |
13 | #include <linux/syscore_ops.h> | ||
13 | 14 | ||
14 | #include <asm/apic.h> | 15 | #include <asm/apic.h> |
15 | 16 | ||
@@ -816,6 +817,18 @@ out: | |||
816 | return ret; | 817 | return ret; |
817 | } | 818 | } |
818 | 819 | ||
820 | static void ibs_eilvt_setup(void) | ||
821 | { | ||
822 | /* | ||
823 | * Force LVT offset assignment for family 10h: The offsets are | ||
824 | * not assigned by the BIOS for this family, so the OS is | ||
825 | * responsible for doing it. If the OS assignment fails, fall | ||
826 | * back to BIOS settings and try to setup this. | ||
827 | */ | ||
828 | if (boot_cpu_data.x86 == 0x10) | ||
829 | force_ibs_eilvt_setup(); | ||
830 | } | ||
831 | |||
819 | static inline int get_ibs_lvt_offset(void) | 832 | static inline int get_ibs_lvt_offset(void) |
820 | { | 833 | { |
821 | u64 val; | 834 | u64 val; |
@@ -851,6 +864,36 @@ static void clear_APIC_ibs(void *dummy) | |||
851 | setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1); | 864 | setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1); |
852 | } | 865 | } |
853 | 866 | ||
867 | #ifdef CONFIG_PM | ||
868 | |||
869 | static int perf_ibs_suspend(void) | ||
870 | { | ||
871 | clear_APIC_ibs(NULL); | ||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | static void perf_ibs_resume(void) | ||
876 | { | ||
877 | ibs_eilvt_setup(); | ||
878 | setup_APIC_ibs(NULL); | ||
879 | } | ||
880 | |||
881 | static struct syscore_ops perf_ibs_syscore_ops = { | ||
882 | .resume = perf_ibs_resume, | ||
883 | .suspend = perf_ibs_suspend, | ||
884 | }; | ||
885 | |||
886 | static void perf_ibs_pm_init(void) | ||
887 | { | ||
888 | register_syscore_ops(&perf_ibs_syscore_ops); | ||
889 | } | ||
890 | |||
891 | #else | ||
892 | |||
893 | static inline void perf_ibs_pm_init(void) { } | ||
894 | |||
895 | #endif | ||
896 | |||
854 | static int | 897 | static int |
855 | perf_ibs_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) | 898 | perf_ibs_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) |
856 | { | 899 | { |
@@ -877,18 +920,12 @@ static __init int amd_ibs_init(void) | |||
877 | if (!caps) | 920 | if (!caps) |
878 | return -ENODEV; /* ibs not supported by the cpu */ | 921 | return -ENODEV; /* ibs not supported by the cpu */ |
879 | 922 | ||
880 | /* | 923 | ibs_eilvt_setup(); |
881 | * Force LVT offset assignment for family 10h: The offsets are | ||
882 | * not assigned by the BIOS for this family, so the OS is | ||
883 | * responsible for doing it. If the OS assignment fails, fall | ||
884 | * back to BIOS settings and try to setup this. | ||
885 | */ | ||
886 | if (boot_cpu_data.x86 == 0x10) | ||
887 | force_ibs_eilvt_setup(); | ||
888 | 924 | ||
889 | if (!ibs_eilvt_valid()) | 925 | if (!ibs_eilvt_valid()) |
890 | goto out; | 926 | goto out; |
891 | 927 | ||
928 | perf_ibs_pm_init(); | ||
892 | get_online_cpus(); | 929 | get_online_cpus(); |
893 | ibs_caps = caps; | 930 | ibs_caps = caps; |
894 | /* make ibs_caps visible to other cpus: */ | 931 | /* make ibs_caps visible to other cpus: */ |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c new file mode 100644 index 000000000000..5ad35ad94d0f --- /dev/null +++ b/arch/x86/kernel/cpu/perf_event_intel_rapl.c | |||
@@ -0,0 +1,679 @@ | |||
1 | /* | ||
2 | * perf_event_intel_rapl.c: support Intel RAPL energy consumption counters | ||
3 | * Copyright (C) 2013 Google, Inc., Stephane Eranian | ||
4 | * | ||
5 | * Intel RAPL interface is specified in the IA-32 Manual Vol3b | ||
6 | * section 14.7.1 (September 2013) | ||
7 | * | ||
8 | * RAPL provides more controls than just reporting energy consumption | ||
9 | * however here we only expose the 3 energy consumption free running | ||
10 | * counters (pp0, pkg, dram). | ||
11 | * | ||
12 | * Each of those counters increments in a power unit defined by the | ||
13 | * RAPL_POWER_UNIT MSR. On SandyBridge, this unit is 1/(2^16) Joules | ||
14 | * but it can vary. | ||
15 | * | ||
16 | * Counter to rapl events mappings: | ||
17 | * | ||
18 | * pp0 counter: consumption of all physical cores (power plane 0) | ||
19 | * event: rapl_energy_cores | ||
20 | * perf code: 0x1 | ||
21 | * | ||
22 | * pkg counter: consumption of the whole processor package | ||
23 | * event: rapl_energy_pkg | ||
24 | * perf code: 0x2 | ||
25 | * | ||
26 | * dram counter: consumption of the dram domain (servers only) | ||
27 | * event: rapl_energy_dram | ||
28 | * perf code: 0x3 | ||
29 | * | ||
30 | * dram counter: consumption of the builtin-gpu domain (client only) | ||
31 | * event: rapl_energy_gpu | ||
32 | * perf code: 0x4 | ||
33 | * | ||
34 | * We manage those counters as free running (read-only). They may be | ||
35 | * use simultaneously by other tools, such as turbostat. | ||
36 | * | ||
37 | * The events only support system-wide mode counting. There is no | ||
38 | * sampling support because it does not make sense and is not | ||
39 | * supported by the RAPL hardware. | ||
40 | * | ||
41 | * Because we want to avoid floating-point operations in the kernel, | ||
42 | * the events are all reported in fixed point arithmetic (32.32). | ||
43 | * Tools must adjust the counts to convert them to Watts using | ||
44 | * the duration of the measurement. Tools may use a function such as | ||
45 | * ldexp(raw_count, -32); | ||
46 | */ | ||
47 | #include <linux/module.h> | ||
48 | #include <linux/slab.h> | ||
49 | #include <linux/perf_event.h> | ||
50 | #include <asm/cpu_device_id.h> | ||
51 | #include "perf_event.h" | ||
52 | |||
53 | /* | ||
54 | * RAPL energy status counters | ||
55 | */ | ||
56 | #define RAPL_IDX_PP0_NRG_STAT 0 /* all cores */ | ||
57 | #define INTEL_RAPL_PP0 0x1 /* pseudo-encoding */ | ||
58 | #define RAPL_IDX_PKG_NRG_STAT 1 /* entire package */ | ||
59 | #define INTEL_RAPL_PKG 0x2 /* pseudo-encoding */ | ||
60 | #define RAPL_IDX_RAM_NRG_STAT 2 /* DRAM */ | ||
61 | #define INTEL_RAPL_RAM 0x3 /* pseudo-encoding */ | ||
62 | #define RAPL_IDX_PP1_NRG_STAT 3 /* DRAM */ | ||
63 | #define INTEL_RAPL_PP1 0x4 /* pseudo-encoding */ | ||
64 | |||
65 | /* Clients have PP0, PKG */ | ||
66 | #define RAPL_IDX_CLN (1<<RAPL_IDX_PP0_NRG_STAT|\ | ||
67 | 1<<RAPL_IDX_PKG_NRG_STAT|\ | ||
68 | 1<<RAPL_IDX_PP1_NRG_STAT) | ||
69 | |||
70 | /* Servers have PP0, PKG, RAM */ | ||
71 | #define RAPL_IDX_SRV (1<<RAPL_IDX_PP0_NRG_STAT|\ | ||
72 | 1<<RAPL_IDX_PKG_NRG_STAT|\ | ||
73 | 1<<RAPL_IDX_RAM_NRG_STAT) | ||
74 | |||
75 | /* | ||
76 | * event code: LSB 8 bits, passed in attr->config | ||
77 | * any other bit is reserved | ||
78 | */ | ||
79 | #define RAPL_EVENT_MASK 0xFFULL | ||
80 | |||
81 | #define DEFINE_RAPL_FORMAT_ATTR(_var, _name, _format) \ | ||
82 | static ssize_t __rapl_##_var##_show(struct kobject *kobj, \ | ||
83 | struct kobj_attribute *attr, \ | ||
84 | char *page) \ | ||
85 | { \ | ||
86 | BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ | ||
87 | return sprintf(page, _format "\n"); \ | ||
88 | } \ | ||
89 | static struct kobj_attribute format_attr_##_var = \ | ||
90 | __ATTR(_name, 0444, __rapl_##_var##_show, NULL) | ||
91 | |||
92 | #define RAPL_EVENT_DESC(_name, _config) \ | ||
93 | { \ | ||
94 | .attr = __ATTR(_name, 0444, rapl_event_show, NULL), \ | ||
95 | .config = _config, \ | ||
96 | } | ||
97 | |||
98 | #define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */ | ||
99 | |||
100 | struct rapl_pmu { | ||
101 | spinlock_t lock; | ||
102 | int hw_unit; /* 1/2^hw_unit Joule */ | ||
103 | int n_active; /* number of active events */ | ||
104 | struct list_head active_list; | ||
105 | struct pmu *pmu; /* pointer to rapl_pmu_class */ | ||
106 | ktime_t timer_interval; /* in ktime_t unit */ | ||
107 | struct hrtimer hrtimer; | ||
108 | }; | ||
109 | |||
110 | static struct pmu rapl_pmu_class; | ||
111 | static cpumask_t rapl_cpu_mask; | ||
112 | static int rapl_cntr_mask; | ||
113 | |||
114 | static DEFINE_PER_CPU(struct rapl_pmu *, rapl_pmu); | ||
115 | static DEFINE_PER_CPU(struct rapl_pmu *, rapl_pmu_to_free); | ||
116 | |||
117 | static inline u64 rapl_read_counter(struct perf_event *event) | ||
118 | { | ||
119 | u64 raw; | ||
120 | rdmsrl(event->hw.event_base, raw); | ||
121 | return raw; | ||
122 | } | ||
123 | |||
124 | static inline u64 rapl_scale(u64 v) | ||
125 | { | ||
126 | /* | ||
127 | * scale delta to smallest unit (1/2^32) | ||
128 | * users must then scale back: count * 1/(1e9*2^32) to get Joules | ||
129 | * or use ldexp(count, -32). | ||
130 | * Watts = Joules/Time delta | ||
131 | */ | ||
132 | return v << (32 - __get_cpu_var(rapl_pmu)->hw_unit); | ||
133 | } | ||
134 | |||
135 | static u64 rapl_event_update(struct perf_event *event) | ||
136 | { | ||
137 | struct hw_perf_event *hwc = &event->hw; | ||
138 | u64 prev_raw_count, new_raw_count; | ||
139 | s64 delta, sdelta; | ||
140 | int shift = RAPL_CNTR_WIDTH; | ||
141 | |||
142 | again: | ||
143 | prev_raw_count = local64_read(&hwc->prev_count); | ||
144 | rdmsrl(event->hw.event_base, new_raw_count); | ||
145 | |||
146 | if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, | ||
147 | new_raw_count) != prev_raw_count) { | ||
148 | cpu_relax(); | ||
149 | goto again; | ||
150 | } | ||
151 | |||
152 | /* | ||
153 | * Now we have the new raw value and have updated the prev | ||
154 | * timestamp already. We can now calculate the elapsed delta | ||
155 | * (event-)time and add that to the generic event. | ||
156 | * | ||
157 | * Careful, not all hw sign-extends above the physical width | ||
158 | * of the count. | ||
159 | */ | ||
160 | delta = (new_raw_count << shift) - (prev_raw_count << shift); | ||
161 | delta >>= shift; | ||
162 | |||
163 | sdelta = rapl_scale(delta); | ||
164 | |||
165 | local64_add(sdelta, &event->count); | ||
166 | |||
167 | return new_raw_count; | ||
168 | } | ||
169 | |||
170 | static void rapl_start_hrtimer(struct rapl_pmu *pmu) | ||
171 | { | ||
172 | __hrtimer_start_range_ns(&pmu->hrtimer, | ||
173 | pmu->timer_interval, 0, | ||
174 | HRTIMER_MODE_REL_PINNED, 0); | ||
175 | } | ||
176 | |||
177 | static void rapl_stop_hrtimer(struct rapl_pmu *pmu) | ||
178 | { | ||
179 | hrtimer_cancel(&pmu->hrtimer); | ||
180 | } | ||
181 | |||
182 | static enum hrtimer_restart rapl_hrtimer_handle(struct hrtimer *hrtimer) | ||
183 | { | ||
184 | struct rapl_pmu *pmu = __get_cpu_var(rapl_pmu); | ||
185 | struct perf_event *event; | ||
186 | unsigned long flags; | ||
187 | |||
188 | if (!pmu->n_active) | ||
189 | return HRTIMER_NORESTART; | ||
190 | |||
191 | spin_lock_irqsave(&pmu->lock, flags); | ||
192 | |||
193 | list_for_each_entry(event, &pmu->active_list, active_entry) { | ||
194 | rapl_event_update(event); | ||
195 | } | ||
196 | |||
197 | spin_unlock_irqrestore(&pmu->lock, flags); | ||
198 | |||
199 | hrtimer_forward_now(hrtimer, pmu->timer_interval); | ||
200 | |||
201 | return HRTIMER_RESTART; | ||
202 | } | ||
203 | |||
204 | static void rapl_hrtimer_init(struct rapl_pmu *pmu) | ||
205 | { | ||
206 | struct hrtimer *hr = &pmu->hrtimer; | ||
207 | |||
208 | hrtimer_init(hr, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
209 | hr->function = rapl_hrtimer_handle; | ||
210 | } | ||
211 | |||
212 | static void __rapl_pmu_event_start(struct rapl_pmu *pmu, | ||
213 | struct perf_event *event) | ||
214 | { | ||
215 | if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) | ||
216 | return; | ||
217 | |||
218 | event->hw.state = 0; | ||
219 | |||
220 | list_add_tail(&event->active_entry, &pmu->active_list); | ||
221 | |||
222 | local64_set(&event->hw.prev_count, rapl_read_counter(event)); | ||
223 | |||
224 | pmu->n_active++; | ||
225 | if (pmu->n_active == 1) | ||
226 | rapl_start_hrtimer(pmu); | ||
227 | } | ||
228 | |||
229 | static void rapl_pmu_event_start(struct perf_event *event, int mode) | ||
230 | { | ||
231 | struct rapl_pmu *pmu = __get_cpu_var(rapl_pmu); | ||
232 | unsigned long flags; | ||
233 | |||
234 | spin_lock_irqsave(&pmu->lock, flags); | ||
235 | __rapl_pmu_event_start(pmu, event); | ||
236 | spin_unlock_irqrestore(&pmu->lock, flags); | ||
237 | } | ||
238 | |||
239 | static void rapl_pmu_event_stop(struct perf_event *event, int mode) | ||
240 | { | ||
241 | struct rapl_pmu *pmu = __get_cpu_var(rapl_pmu); | ||
242 | struct hw_perf_event *hwc = &event->hw; | ||
243 | unsigned long flags; | ||
244 | |||
245 | spin_lock_irqsave(&pmu->lock, flags); | ||
246 | |||
247 | /* mark event as deactivated and stopped */ | ||
248 | if (!(hwc->state & PERF_HES_STOPPED)) { | ||
249 | WARN_ON_ONCE(pmu->n_active <= 0); | ||
250 | pmu->n_active--; | ||
251 | if (pmu->n_active == 0) | ||
252 | rapl_stop_hrtimer(pmu); | ||
253 | |||
254 | list_del(&event->active_entry); | ||
255 | |||
256 | WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); | ||
257 | hwc->state |= PERF_HES_STOPPED; | ||
258 | } | ||
259 | |||
260 | /* check if update of sw counter is necessary */ | ||
261 | if ((mode & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { | ||
262 | /* | ||
263 | * Drain the remaining delta count out of a event | ||
264 | * that we are disabling: | ||
265 | */ | ||
266 | rapl_event_update(event); | ||
267 | hwc->state |= PERF_HES_UPTODATE; | ||
268 | } | ||
269 | |||
270 | spin_unlock_irqrestore(&pmu->lock, flags); | ||
271 | } | ||
272 | |||
273 | static int rapl_pmu_event_add(struct perf_event *event, int mode) | ||
274 | { | ||
275 | struct rapl_pmu *pmu = __get_cpu_var(rapl_pmu); | ||
276 | struct hw_perf_event *hwc = &event->hw; | ||
277 | unsigned long flags; | ||
278 | |||
279 | spin_lock_irqsave(&pmu->lock, flags); | ||
280 | |||
281 | hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; | ||
282 | |||
283 | if (mode & PERF_EF_START) | ||
284 | __rapl_pmu_event_start(pmu, event); | ||
285 | |||
286 | spin_unlock_irqrestore(&pmu->lock, flags); | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static void rapl_pmu_event_del(struct perf_event *event, int flags) | ||
292 | { | ||
293 | rapl_pmu_event_stop(event, PERF_EF_UPDATE); | ||
294 | } | ||
295 | |||
296 | static int rapl_pmu_event_init(struct perf_event *event) | ||
297 | { | ||
298 | u64 cfg = event->attr.config & RAPL_EVENT_MASK; | ||
299 | int bit, msr, ret = 0; | ||
300 | |||
301 | /* only look at RAPL events */ | ||
302 | if (event->attr.type != rapl_pmu_class.type) | ||
303 | return -ENOENT; | ||
304 | |||
305 | /* check only supported bits are set */ | ||
306 | if (event->attr.config & ~RAPL_EVENT_MASK) | ||
307 | return -EINVAL; | ||
308 | |||
309 | /* | ||
310 | * check event is known (determines counter) | ||
311 | */ | ||
312 | switch (cfg) { | ||
313 | case INTEL_RAPL_PP0: | ||
314 | bit = RAPL_IDX_PP0_NRG_STAT; | ||
315 | msr = MSR_PP0_ENERGY_STATUS; | ||
316 | break; | ||
317 | case INTEL_RAPL_PKG: | ||
318 | bit = RAPL_IDX_PKG_NRG_STAT; | ||
319 | msr = MSR_PKG_ENERGY_STATUS; | ||
320 | break; | ||
321 | case INTEL_RAPL_RAM: | ||
322 | bit = RAPL_IDX_RAM_NRG_STAT; | ||
323 | msr = MSR_DRAM_ENERGY_STATUS; | ||
324 | break; | ||
325 | case INTEL_RAPL_PP1: | ||
326 | bit = RAPL_IDX_PP1_NRG_STAT; | ||
327 | msr = MSR_PP1_ENERGY_STATUS; | ||
328 | break; | ||
329 | default: | ||
330 | return -EINVAL; | ||
331 | } | ||
332 | /* check event supported */ | ||
333 | if (!(rapl_cntr_mask & (1 << bit))) | ||
334 | return -EINVAL; | ||
335 | |||
336 | /* unsupported modes and filters */ | ||
337 | if (event->attr.exclude_user || | ||
338 | event->attr.exclude_kernel || | ||
339 | event->attr.exclude_hv || | ||
340 | event->attr.exclude_idle || | ||
341 | event->attr.exclude_host || | ||
342 | event->attr.exclude_guest || | ||
343 | event->attr.sample_period) /* no sampling */ | ||
344 | return -EINVAL; | ||
345 | |||
346 | /* must be done before validate_group */ | ||
347 | event->hw.event_base = msr; | ||
348 | event->hw.config = cfg; | ||
349 | event->hw.idx = bit; | ||
350 | |||
351 | return ret; | ||
352 | } | ||
353 | |||
354 | static void rapl_pmu_event_read(struct perf_event *event) | ||
355 | { | ||
356 | rapl_event_update(event); | ||
357 | } | ||
358 | |||
359 | static ssize_t rapl_get_attr_cpumask(struct device *dev, | ||
360 | struct device_attribute *attr, char *buf) | ||
361 | { | ||
362 | int n = cpulist_scnprintf(buf, PAGE_SIZE - 2, &rapl_cpu_mask); | ||
363 | |||
364 | buf[n++] = '\n'; | ||
365 | buf[n] = '\0'; | ||
366 | return n; | ||
367 | } | ||
368 | |||
369 | static DEVICE_ATTR(cpumask, S_IRUGO, rapl_get_attr_cpumask, NULL); | ||
370 | |||
371 | static struct attribute *rapl_pmu_attrs[] = { | ||
372 | &dev_attr_cpumask.attr, | ||
373 | NULL, | ||
374 | }; | ||
375 | |||
376 | static struct attribute_group rapl_pmu_attr_group = { | ||
377 | .attrs = rapl_pmu_attrs, | ||
378 | }; | ||
379 | |||
380 | EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01"); | ||
381 | EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02"); | ||
382 | EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03"); | ||
383 | EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04"); | ||
384 | |||
385 | EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules"); | ||
386 | EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules"); | ||
387 | EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules"); | ||
388 | EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules"); | ||
389 | |||
390 | /* | ||
391 | * we compute in 0.23 nJ increments regardless of MSR | ||
392 | */ | ||
393 | EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10"); | ||
394 | EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10"); | ||
395 | EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10"); | ||
396 | EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10"); | ||
397 | |||
398 | static struct attribute *rapl_events_srv_attr[] = { | ||
399 | EVENT_PTR(rapl_cores), | ||
400 | EVENT_PTR(rapl_pkg), | ||
401 | EVENT_PTR(rapl_ram), | ||
402 | |||
403 | EVENT_PTR(rapl_cores_unit), | ||
404 | EVENT_PTR(rapl_pkg_unit), | ||
405 | EVENT_PTR(rapl_ram_unit), | ||
406 | |||
407 | EVENT_PTR(rapl_cores_scale), | ||
408 | EVENT_PTR(rapl_pkg_scale), | ||
409 | EVENT_PTR(rapl_ram_scale), | ||
410 | NULL, | ||
411 | }; | ||
412 | |||
413 | static struct attribute *rapl_events_cln_attr[] = { | ||
414 | EVENT_PTR(rapl_cores), | ||
415 | EVENT_PTR(rapl_pkg), | ||
416 | EVENT_PTR(rapl_gpu), | ||
417 | |||
418 | EVENT_PTR(rapl_cores_unit), | ||
419 | EVENT_PTR(rapl_pkg_unit), | ||
420 | EVENT_PTR(rapl_gpu_unit), | ||
421 | |||
422 | EVENT_PTR(rapl_cores_scale), | ||
423 | EVENT_PTR(rapl_pkg_scale), | ||
424 | EVENT_PTR(rapl_gpu_scale), | ||
425 | NULL, | ||
426 | }; | ||
427 | |||
428 | static struct attribute_group rapl_pmu_events_group = { | ||
429 | .name = "events", | ||
430 | .attrs = NULL, /* patched at runtime */ | ||
431 | }; | ||
432 | |||
433 | DEFINE_RAPL_FORMAT_ATTR(event, event, "config:0-7"); | ||
434 | static struct attribute *rapl_formats_attr[] = { | ||
435 | &format_attr_event.attr, | ||
436 | NULL, | ||
437 | }; | ||
438 | |||
439 | static struct attribute_group rapl_pmu_format_group = { | ||
440 | .name = "format", | ||
441 | .attrs = rapl_formats_attr, | ||
442 | }; | ||
443 | |||
444 | const struct attribute_group *rapl_attr_groups[] = { | ||
445 | &rapl_pmu_attr_group, | ||
446 | &rapl_pmu_format_group, | ||
447 | &rapl_pmu_events_group, | ||
448 | NULL, | ||
449 | }; | ||
450 | |||
451 | static struct pmu rapl_pmu_class = { | ||
452 | .attr_groups = rapl_attr_groups, | ||
453 | .task_ctx_nr = perf_invalid_context, /* system-wide only */ | ||
454 | .event_init = rapl_pmu_event_init, | ||
455 | .add = rapl_pmu_event_add, /* must have */ | ||
456 | .del = rapl_pmu_event_del, /* must have */ | ||
457 | .start = rapl_pmu_event_start, | ||
458 | .stop = rapl_pmu_event_stop, | ||
459 | .read = rapl_pmu_event_read, | ||
460 | }; | ||
461 | |||
462 | static void rapl_cpu_exit(int cpu) | ||
463 | { | ||
464 | struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu); | ||
465 | int i, phys_id = topology_physical_package_id(cpu); | ||
466 | int target = -1; | ||
467 | |||
468 | /* find a new cpu on same package */ | ||
469 | for_each_online_cpu(i) { | ||
470 | if (i == cpu) | ||
471 | continue; | ||
472 | if (phys_id == topology_physical_package_id(i)) { | ||
473 | target = i; | ||
474 | break; | ||
475 | } | ||
476 | } | ||
477 | /* | ||
478 | * clear cpu from cpumask | ||
479 | * if was set in cpumask and still some cpu on package, | ||
480 | * then move to new cpu | ||
481 | */ | ||
482 | if (cpumask_test_and_clear_cpu(cpu, &rapl_cpu_mask) && target >= 0) | ||
483 | cpumask_set_cpu(target, &rapl_cpu_mask); | ||
484 | |||
485 | WARN_ON(cpumask_empty(&rapl_cpu_mask)); | ||
486 | /* | ||
487 | * migrate events and context to new cpu | ||
488 | */ | ||
489 | if (target >= 0) | ||
490 | perf_pmu_migrate_context(pmu->pmu, cpu, target); | ||
491 | |||
492 | /* cancel overflow polling timer for CPU */ | ||
493 | rapl_stop_hrtimer(pmu); | ||
494 | } | ||
495 | |||
496 | static void rapl_cpu_init(int cpu) | ||
497 | { | ||
498 | int i, phys_id = topology_physical_package_id(cpu); | ||
499 | |||
500 | /* check if phys_is is already covered */ | ||
501 | for_each_cpu(i, &rapl_cpu_mask) { | ||
502 | if (phys_id == topology_physical_package_id(i)) | ||
503 | return; | ||
504 | } | ||
505 | /* was not found, so add it */ | ||
506 | cpumask_set_cpu(cpu, &rapl_cpu_mask); | ||
507 | } | ||
508 | |||
509 | static int rapl_cpu_prepare(int cpu) | ||
510 | { | ||
511 | struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu); | ||
512 | int phys_id = topology_physical_package_id(cpu); | ||
513 | u64 ms; | ||
514 | |||
515 | if (pmu) | ||
516 | return 0; | ||
517 | |||
518 | if (phys_id < 0) | ||
519 | return -1; | ||
520 | |||
521 | pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu)); | ||
522 | if (!pmu) | ||
523 | return -1; | ||
524 | |||
525 | spin_lock_init(&pmu->lock); | ||
526 | |||
527 | INIT_LIST_HEAD(&pmu->active_list); | ||
528 | |||
529 | /* | ||
530 | * grab power unit as: 1/2^unit Joules | ||
531 | * | ||
532 | * we cache in local PMU instance | ||
533 | */ | ||
534 | rdmsrl(MSR_RAPL_POWER_UNIT, pmu->hw_unit); | ||
535 | pmu->hw_unit = (pmu->hw_unit >> 8) & 0x1FULL; | ||
536 | pmu->pmu = &rapl_pmu_class; | ||
537 | |||
538 | /* | ||
539 | * use reference of 200W for scaling the timeout | ||
540 | * to avoid missing counter overflows. | ||
541 | * 200W = 200 Joules/sec | ||
542 | * divide interval by 2 to avoid lockstep (2 * 100) | ||
543 | * if hw unit is 32, then we use 2 ms 1/200/2 | ||
544 | */ | ||
545 | if (pmu->hw_unit < 32) | ||
546 | ms = (1000 / (2 * 100)) * (1ULL << (32 - pmu->hw_unit - 1)); | ||
547 | else | ||
548 | ms = 2; | ||
549 | |||
550 | pmu->timer_interval = ms_to_ktime(ms); | ||
551 | |||
552 | rapl_hrtimer_init(pmu); | ||
553 | |||
554 | /* set RAPL pmu for this cpu for now */ | ||
555 | per_cpu(rapl_pmu, cpu) = pmu; | ||
556 | per_cpu(rapl_pmu_to_free, cpu) = NULL; | ||
557 | |||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | static void rapl_cpu_kfree(int cpu) | ||
562 | { | ||
563 | struct rapl_pmu *pmu = per_cpu(rapl_pmu_to_free, cpu); | ||
564 | |||
565 | kfree(pmu); | ||
566 | |||
567 | per_cpu(rapl_pmu_to_free, cpu) = NULL; | ||
568 | } | ||
569 | |||
570 | static int rapl_cpu_dying(int cpu) | ||
571 | { | ||
572 | struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu); | ||
573 | |||
574 | if (!pmu) | ||
575 | return 0; | ||
576 | |||
577 | per_cpu(rapl_pmu, cpu) = NULL; | ||
578 | |||
579 | per_cpu(rapl_pmu_to_free, cpu) = pmu; | ||
580 | |||
581 | return 0; | ||
582 | } | ||
583 | |||
584 | static int rapl_cpu_notifier(struct notifier_block *self, | ||
585 | unsigned long action, void *hcpu) | ||
586 | { | ||
587 | unsigned int cpu = (long)hcpu; | ||
588 | |||
589 | switch (action & ~CPU_TASKS_FROZEN) { | ||
590 | case CPU_UP_PREPARE: | ||
591 | rapl_cpu_prepare(cpu); | ||
592 | break; | ||
593 | case CPU_STARTING: | ||
594 | rapl_cpu_init(cpu); | ||
595 | break; | ||
596 | case CPU_UP_CANCELED: | ||
597 | case CPU_DYING: | ||
598 | rapl_cpu_dying(cpu); | ||
599 | break; | ||
600 | case CPU_ONLINE: | ||
601 | case CPU_DEAD: | ||
602 | rapl_cpu_kfree(cpu); | ||
603 | break; | ||
604 | case CPU_DOWN_PREPARE: | ||
605 | rapl_cpu_exit(cpu); | ||
606 | break; | ||
607 | default: | ||
608 | break; | ||
609 | } | ||
610 | |||
611 | return NOTIFY_OK; | ||
612 | } | ||
613 | |||
614 | static const struct x86_cpu_id rapl_cpu_match[] = { | ||
615 | [0] = { .vendor = X86_VENDOR_INTEL, .family = 6 }, | ||
616 | [1] = {}, | ||
617 | }; | ||
618 | |||
619 | static int __init rapl_pmu_init(void) | ||
620 | { | ||
621 | struct rapl_pmu *pmu; | ||
622 | int cpu, ret; | ||
623 | |||
624 | /* | ||
625 | * check for Intel processor family 6 | ||
626 | */ | ||
627 | if (!x86_match_cpu(rapl_cpu_match)) | ||
628 | return 0; | ||
629 | |||
630 | /* check supported CPU */ | ||
631 | switch (boot_cpu_data.x86_model) { | ||
632 | case 42: /* Sandy Bridge */ | ||
633 | case 58: /* Ivy Bridge */ | ||
634 | case 60: /* Haswell */ | ||
635 | case 69: /* Haswell-Celeron */ | ||
636 | rapl_cntr_mask = RAPL_IDX_CLN; | ||
637 | rapl_pmu_events_group.attrs = rapl_events_cln_attr; | ||
638 | break; | ||
639 | case 45: /* Sandy Bridge-EP */ | ||
640 | case 62: /* IvyTown */ | ||
641 | rapl_cntr_mask = RAPL_IDX_SRV; | ||
642 | rapl_pmu_events_group.attrs = rapl_events_srv_attr; | ||
643 | break; | ||
644 | |||
645 | default: | ||
646 | /* unsupported */ | ||
647 | return 0; | ||
648 | } | ||
649 | get_online_cpus(); | ||
650 | |||
651 | for_each_online_cpu(cpu) { | ||
652 | rapl_cpu_prepare(cpu); | ||
653 | rapl_cpu_init(cpu); | ||
654 | } | ||
655 | |||
656 | perf_cpu_notifier(rapl_cpu_notifier); | ||
657 | |||
658 | ret = perf_pmu_register(&rapl_pmu_class, "power", -1); | ||
659 | if (WARN_ON(ret)) { | ||
660 | pr_info("RAPL PMU detected, registration failed (%d), RAPL PMU disabled\n", ret); | ||
661 | put_online_cpus(); | ||
662 | return -1; | ||
663 | } | ||
664 | |||
665 | pmu = __get_cpu_var(rapl_pmu); | ||
666 | |||
667 | pr_info("RAPL PMU detected, hw unit 2^-%d Joules," | ||
668 | " API unit is 2^-32 Joules," | ||
669 | " %d fixed counters" | ||
670 | " %llu ms ovfl timer\n", | ||
671 | pmu->hw_unit, | ||
672 | hweight32(rapl_cntr_mask), | ||
673 | ktime_to_ms(pmu->timer_interval)); | ||
674 | |||
675 | put_online_cpus(); | ||
676 | |||
677 | return 0; | ||
678 | } | ||
679 | device_initcall(rapl_pmu_init); | ||
diff --git a/arch/x86/kernel/cpu/rdrand.c b/arch/x86/kernel/cpu/rdrand.c index 88db010845cb..384df5105fbc 100644 --- a/arch/x86/kernel/cpu/rdrand.c +++ b/arch/x86/kernel/cpu/rdrand.c | |||
@@ -31,20 +31,6 @@ static int __init x86_rdrand_setup(char *s) | |||
31 | } | 31 | } |
32 | __setup("nordrand", x86_rdrand_setup); | 32 | __setup("nordrand", x86_rdrand_setup); |
33 | 33 | ||
34 | /* We can't use arch_get_random_long() here since alternatives haven't run */ | ||
35 | static inline int rdrand_long(unsigned long *v) | ||
36 | { | ||
37 | int ok; | ||
38 | asm volatile("1: " RDRAND_LONG "\n\t" | ||
39 | "jc 2f\n\t" | ||
40 | "decl %0\n\t" | ||
41 | "jnz 1b\n\t" | ||
42 | "2:" | ||
43 | : "=r" (ok), "=a" (*v) | ||
44 | : "0" (RDRAND_RETRY_LOOPS)); | ||
45 | return ok; | ||
46 | } | ||
47 | |||
48 | /* | 34 | /* |
49 | * Force a reseed cycle; we are architecturally guaranteed a reseed | 35 | * Force a reseed cycle; we are architecturally guaranteed a reseed |
50 | * after no more than 512 128-bit chunks of random data. This also | 36 | * after no more than 512 128-bit chunks of random data. This also |
diff --git a/arch/x86/kernel/cpu/transmeta.c b/arch/x86/kernel/cpu/transmeta.c index aa0430d69b90..3fa0e5ad86b4 100644 --- a/arch/x86/kernel/cpu/transmeta.c +++ b/arch/x86/kernel/cpu/transmeta.c | |||
@@ -1,6 +1,5 @@ | |||
1 | #include <linux/kernel.h> | 1 | #include <linux/kernel.h> |
2 | #include <linux/mm.h> | 2 | #include <linux/mm.h> |
3 | #include <linux/init.h> | ||
4 | #include <asm/processor.h> | 3 | #include <asm/processor.h> |
5 | #include <asm/msr.h> | 4 | #include <asm/msr.h> |
6 | #include "cpu.h" | 5 | #include "cpu.h" |
diff --git a/arch/x86/kernel/cpu/umc.c b/arch/x86/kernel/cpu/umc.c index 75c5ad5d35cc..ef9c2a0078bd 100644 --- a/arch/x86/kernel/cpu/umc.c +++ b/arch/x86/kernel/cpu/umc.c | |||
@@ -1,5 +1,4 @@ | |||
1 | #include <linux/kernel.h> | 1 | #include <linux/kernel.h> |
2 | #include <linux/init.h> | ||
3 | #include <asm/processor.h> | 2 | #include <asm/processor.h> |
4 | #include "cpu.h" | 3 | #include "cpu.h" |
5 | 4 | ||