diff options
| author | Steve French <sfrench@us.ibm.com> | 2011-12-16 01:39:20 -0500 |
|---|---|---|
| committer | Steve French <sfrench@us.ibm.com> | 2011-12-16 01:39:20 -0500 |
| commit | aaf015890754d58dcb71a4aa44ed246bb082bcf6 (patch) | |
| tree | 17b51ff707fd1b3efec3a3ab872f0d7a7416aca5 /arch/x86/kernel/cpu | |
| parent | 9c32c63bb70b2fafc3b18bee29959c3bf245ceba (diff) | |
| parent | 8def5f51b012efb00e77ba2d04696cc0aadd0609 (diff) | |
Merge branch 'master' of git+ssh://git.samba.org/data/git/sfrench/cifs-2.6
Diffstat (limited to 'arch/x86/kernel/cpu')
| -rw-r--r-- | arch/x86/kernel/cpu/amd.c | 8 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce-inject.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 25 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mtrr/generic.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 16 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_amd_ibs.c | 29 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel.c | 8 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_ds.c | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_p4.c | 2 |
9 files changed, 67 insertions, 31 deletions
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index c7e46cb35327..0bab2b18bb20 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
| @@ -442,8 +442,6 @@ static void __cpuinit bsp_init_amd(struct cpuinfo_x86 *c) | |||
| 442 | 442 | ||
| 443 | static void __cpuinit early_init_amd(struct cpuinfo_x86 *c) | 443 | static void __cpuinit early_init_amd(struct cpuinfo_x86 *c) |
| 444 | { | 444 | { |
| 445 | u32 dummy; | ||
| 446 | |||
| 447 | early_init_amd_mc(c); | 445 | early_init_amd_mc(c); |
| 448 | 446 | ||
| 449 | /* | 447 | /* |
| @@ -473,12 +471,12 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c) | |||
| 473 | set_cpu_cap(c, X86_FEATURE_EXTD_APICID); | 471 | set_cpu_cap(c, X86_FEATURE_EXTD_APICID); |
| 474 | } | 472 | } |
| 475 | #endif | 473 | #endif |
| 476 | |||
| 477 | rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy); | ||
| 478 | } | 474 | } |
| 479 | 475 | ||
| 480 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) | 476 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) |
| 481 | { | 477 | { |
| 478 | u32 dummy; | ||
| 479 | |||
| 482 | #ifdef CONFIG_SMP | 480 | #ifdef CONFIG_SMP |
| 483 | unsigned long long value; | 481 | unsigned long long value; |
| 484 | 482 | ||
| @@ -657,6 +655,8 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
| 657 | checking_wrmsrl(MSR_AMD64_MCx_MASK(4), mask); | 655 | checking_wrmsrl(MSR_AMD64_MCx_MASK(4), mask); |
| 658 | } | 656 | } |
| 659 | } | 657 | } |
| 658 | |||
| 659 | rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy); | ||
| 660 | } | 660 | } |
| 661 | 661 | ||
| 662 | #ifdef CONFIG_X86_32 | 662 | #ifdef CONFIG_X86_32 |
diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c b/arch/x86/kernel/cpu/mcheck/mce-inject.c index 6199232161cf..319882ef848d 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-inject.c +++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c | |||
| @@ -208,7 +208,7 @@ static int inject_init(void) | |||
| 208 | if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL)) | 208 | if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL)) |
| 209 | return -ENOMEM; | 209 | return -ENOMEM; |
| 210 | printk(KERN_INFO "Machine check injector initialized\n"); | 210 | printk(KERN_INFO "Machine check injector initialized\n"); |
| 211 | mce_chrdev_ops.write = mce_write; | 211 | register_mce_write_callback(mce_write); |
| 212 | register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0, | 212 | register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0, |
| 213 | "mce_notify"); | 213 | "mce_notify"); |
| 214 | return 0; | 214 | return 0; |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 362056aefeb4..2af127d4c3d1 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
| @@ -1634,16 +1634,35 @@ static long mce_chrdev_ioctl(struct file *f, unsigned int cmd, | |||
| 1634 | } | 1634 | } |
| 1635 | } | 1635 | } |
| 1636 | 1636 | ||
| 1637 | /* Modified in mce-inject.c, so not static or const */ | 1637 | static ssize_t (*mce_write)(struct file *filp, const char __user *ubuf, |
| 1638 | struct file_operations mce_chrdev_ops = { | 1638 | size_t usize, loff_t *off); |
| 1639 | |||
| 1640 | void register_mce_write_callback(ssize_t (*fn)(struct file *filp, | ||
| 1641 | const char __user *ubuf, | ||
| 1642 | size_t usize, loff_t *off)) | ||
| 1643 | { | ||
| 1644 | mce_write = fn; | ||
| 1645 | } | ||
| 1646 | EXPORT_SYMBOL_GPL(register_mce_write_callback); | ||
| 1647 | |||
| 1648 | ssize_t mce_chrdev_write(struct file *filp, const char __user *ubuf, | ||
| 1649 | size_t usize, loff_t *off) | ||
| 1650 | { | ||
| 1651 | if (mce_write) | ||
| 1652 | return mce_write(filp, ubuf, usize, off); | ||
| 1653 | else | ||
| 1654 | return -EINVAL; | ||
| 1655 | } | ||
| 1656 | |||
| 1657 | static const struct file_operations mce_chrdev_ops = { | ||
| 1639 | .open = mce_chrdev_open, | 1658 | .open = mce_chrdev_open, |
| 1640 | .release = mce_chrdev_release, | 1659 | .release = mce_chrdev_release, |
| 1641 | .read = mce_chrdev_read, | 1660 | .read = mce_chrdev_read, |
| 1661 | .write = mce_chrdev_write, | ||
| 1642 | .poll = mce_chrdev_poll, | 1662 | .poll = mce_chrdev_poll, |
| 1643 | .unlocked_ioctl = mce_chrdev_ioctl, | 1663 | .unlocked_ioctl = mce_chrdev_ioctl, |
| 1644 | .llseek = no_llseek, | 1664 | .llseek = no_llseek, |
| 1645 | }; | 1665 | }; |
| 1646 | EXPORT_SYMBOL_GPL(mce_chrdev_ops); | ||
| 1647 | 1666 | ||
| 1648 | static struct miscdevice mce_chrdev_device = { | 1667 | static struct miscdevice mce_chrdev_device = { |
| 1649 | MISC_MCELOG_MINOR, | 1668 | MISC_MCELOG_MINOR, |
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index a71efcdbb092..97b26356e9ee 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c | |||
| @@ -547,6 +547,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, | |||
| 547 | 547 | ||
| 548 | if (tmp != mask_lo) { | 548 | if (tmp != mask_lo) { |
| 549 | printk(KERN_WARNING "mtrr: your BIOS has configured an incorrect mask, fixing it.\n"); | 549 | printk(KERN_WARNING "mtrr: your BIOS has configured an incorrect mask, fixing it.\n"); |
| 550 | add_taint(TAINT_FIRMWARE_WORKAROUND); | ||
| 550 | mask_lo = tmp; | 551 | mask_lo = tmp; |
| 551 | } | 552 | } |
| 552 | } | 553 | } |
| @@ -693,6 +694,7 @@ static void prepare_set(void) __acquires(set_atomicity_lock) | |||
| 693 | 694 | ||
| 694 | /* Disable MTRRs, and set the default type to uncached */ | 695 | /* Disable MTRRs, and set the default type to uncached */ |
| 695 | mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi); | 696 | mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi); |
| 697 | wbinvd(); | ||
| 696 | } | 698 | } |
| 697 | 699 | ||
| 698 | static void post_set(void) __releases(set_atomicity_lock) | 700 | static void post_set(void) __releases(set_atomicity_lock) |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 640891014b2a..2bda212a0010 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
| @@ -312,12 +312,8 @@ int x86_setup_perfctr(struct perf_event *event) | |||
| 312 | return -EOPNOTSUPP; | 312 | return -EOPNOTSUPP; |
| 313 | } | 313 | } |
| 314 | 314 | ||
| 315 | /* | ||
| 316 | * Do not allow config1 (extended registers) to propagate, | ||
| 317 | * there's no sane user-space generalization yet: | ||
| 318 | */ | ||
| 319 | if (attr->type == PERF_TYPE_RAW) | 315 | if (attr->type == PERF_TYPE_RAW) |
| 320 | return 0; | 316 | return x86_pmu_extra_regs(event->attr.config, event); |
| 321 | 317 | ||
| 322 | if (attr->type == PERF_TYPE_HW_CACHE) | 318 | if (attr->type == PERF_TYPE_HW_CACHE) |
| 323 | return set_ext_hw_attr(hwc, event); | 319 | return set_ext_hw_attr(hwc, event); |
| @@ -588,7 +584,7 @@ done: | |||
| 588 | x86_pmu.put_event_constraints(cpuc, cpuc->event_list[i]); | 584 | x86_pmu.put_event_constraints(cpuc, cpuc->event_list[i]); |
| 589 | } | 585 | } |
| 590 | } | 586 | } |
| 591 | return num ? -ENOSPC : 0; | 587 | return num ? -EINVAL : 0; |
| 592 | } | 588 | } |
| 593 | 589 | ||
| 594 | /* | 590 | /* |
| @@ -607,7 +603,7 @@ static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader, | |||
| 607 | 603 | ||
| 608 | if (is_x86_event(leader)) { | 604 | if (is_x86_event(leader)) { |
| 609 | if (n >= max_count) | 605 | if (n >= max_count) |
| 610 | return -ENOSPC; | 606 | return -EINVAL; |
| 611 | cpuc->event_list[n] = leader; | 607 | cpuc->event_list[n] = leader; |
| 612 | n++; | 608 | n++; |
| 613 | } | 609 | } |
| @@ -620,7 +616,7 @@ static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader, | |||
| 620 | continue; | 616 | continue; |
| 621 | 617 | ||
| 622 | if (n >= max_count) | 618 | if (n >= max_count) |
| 623 | return -ENOSPC; | 619 | return -EINVAL; |
| 624 | 620 | ||
| 625 | cpuc->event_list[n] = event; | 621 | cpuc->event_list[n] = event; |
| 626 | n++; | 622 | n++; |
| @@ -1316,7 +1312,7 @@ static int validate_event(struct perf_event *event) | |||
| 1316 | c = x86_pmu.get_event_constraints(fake_cpuc, event); | 1312 | c = x86_pmu.get_event_constraints(fake_cpuc, event); |
| 1317 | 1313 | ||
| 1318 | if (!c || !c->weight) | 1314 | if (!c || !c->weight) |
| 1319 | ret = -ENOSPC; | 1315 | ret = -EINVAL; |
| 1320 | 1316 | ||
| 1321 | if (x86_pmu.put_event_constraints) | 1317 | if (x86_pmu.put_event_constraints) |
| 1322 | x86_pmu.put_event_constraints(fake_cpuc, event); | 1318 | x86_pmu.put_event_constraints(fake_cpuc, event); |
| @@ -1341,7 +1337,7 @@ static int validate_group(struct perf_event *event) | |||
| 1341 | { | 1337 | { |
| 1342 | struct perf_event *leader = event->group_leader; | 1338 | struct perf_event *leader = event->group_leader; |
| 1343 | struct cpu_hw_events *fake_cpuc; | 1339 | struct cpu_hw_events *fake_cpuc; |
| 1344 | int ret = -ENOSPC, n; | 1340 | int ret = -EINVAL, n; |
| 1345 | 1341 | ||
| 1346 | fake_cpuc = allocate_fake_cpuc(); | 1342 | fake_cpuc = allocate_fake_cpuc(); |
| 1347 | if (IS_ERR(fake_cpuc)) | 1343 | if (IS_ERR(fake_cpuc)) |
diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c index ab6343d21825..3b8a2d30d14e 100644 --- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c +++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c | |||
| @@ -199,8 +199,7 @@ static int force_ibs_eilvt_setup(void) | |||
| 199 | goto out; | 199 | goto out; |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | pr_err(FW_BUG "using offset %d for IBS interrupts\n", offset); | 202 | pr_info("IBS: LVT offset %d assigned\n", offset); |
| 203 | pr_err(FW_BUG "workaround enabled for IBS LVT offset\n"); | ||
| 204 | 203 | ||
| 205 | return 0; | 204 | return 0; |
| 206 | out: | 205 | out: |
| @@ -265,19 +264,23 @@ perf_ibs_cpu_notifier(struct notifier_block *self, unsigned long action, void *h | |||
| 265 | static __init int amd_ibs_init(void) | 264 | static __init int amd_ibs_init(void) |
| 266 | { | 265 | { |
| 267 | u32 caps; | 266 | u32 caps; |
| 268 | int ret; | 267 | int ret = -EINVAL; |
| 269 | 268 | ||
| 270 | caps = __get_ibs_caps(); | 269 | caps = __get_ibs_caps(); |
| 271 | if (!caps) | 270 | if (!caps) |
| 272 | return -ENODEV; /* ibs not supported by the cpu */ | 271 | return -ENODEV; /* ibs not supported by the cpu */ |
| 273 | 272 | ||
| 274 | if (!ibs_eilvt_valid()) { | 273 | /* |
| 275 | ret = force_ibs_eilvt_setup(); | 274 | * Force LVT offset assignment for family 10h: The offsets are |
| 276 | if (ret) { | 275 | * not assigned by the BIOS for this family, so the OS is |
| 277 | pr_err("Failed to setup IBS, %d\n", ret); | 276 | * responsible for doing it. If the OS assignment fails, fall |
| 278 | return ret; | 277 | * back to BIOS settings and try to setup this. |
| 279 | } | 278 | */ |
| 280 | } | 279 | if (boot_cpu_data.x86 == 0x10) |
| 280 | force_ibs_eilvt_setup(); | ||
| 281 | |||
| 282 | if (!ibs_eilvt_valid()) | ||
| 283 | goto out; | ||
| 281 | 284 | ||
| 282 | get_online_cpus(); | 285 | get_online_cpus(); |
| 283 | ibs_caps = caps; | 286 | ibs_caps = caps; |
| @@ -287,7 +290,11 @@ static __init int amd_ibs_init(void) | |||
| 287 | smp_call_function(setup_APIC_ibs, NULL, 1); | 290 | smp_call_function(setup_APIC_ibs, NULL, 1); |
| 288 | put_online_cpus(); | 291 | put_online_cpus(); |
| 289 | 292 | ||
| 290 | return perf_event_ibs_init(); | 293 | ret = perf_event_ibs_init(); |
| 294 | out: | ||
| 295 | if (ret) | ||
| 296 | pr_err("Failed to setup IBS, %d\n", ret); | ||
| 297 | return ret; | ||
| 291 | } | 298 | } |
| 292 | 299 | ||
| 293 | /* Since we need the pci subsystem to init ibs we can't do this earlier: */ | 300 | /* Since we need the pci subsystem to init ibs we can't do this earlier: */ |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 2be5ebe99872..8d601b18bf9f 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
| @@ -1545,6 +1545,13 @@ static void intel_clovertown_quirks(void) | |||
| 1545 | x86_pmu.pebs_constraints = NULL; | 1545 | x86_pmu.pebs_constraints = NULL; |
| 1546 | } | 1546 | } |
| 1547 | 1547 | ||
| 1548 | static void intel_sandybridge_quirks(void) | ||
| 1549 | { | ||
| 1550 | printk(KERN_WARNING "PEBS disabled due to CPU errata.\n"); | ||
| 1551 | x86_pmu.pebs = 0; | ||
| 1552 | x86_pmu.pebs_constraints = NULL; | ||
| 1553 | } | ||
| 1554 | |||
| 1548 | __init int intel_pmu_init(void) | 1555 | __init int intel_pmu_init(void) |
| 1549 | { | 1556 | { |
| 1550 | union cpuid10_edx edx; | 1557 | union cpuid10_edx edx; |
| @@ -1694,6 +1701,7 @@ __init int intel_pmu_init(void) | |||
| 1694 | break; | 1701 | break; |
| 1695 | 1702 | ||
| 1696 | case 42: /* SandyBridge */ | 1703 | case 42: /* SandyBridge */ |
| 1704 | x86_pmu.quirks = intel_sandybridge_quirks; | ||
| 1697 | case 45: /* SandyBridge, "Romely-EP" */ | 1705 | case 45: /* SandyBridge, "Romely-EP" */ |
| 1698 | memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, | 1706 | memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, |
| 1699 | sizeof(hw_cache_event_ids)); | 1707 | sizeof(hw_cache_event_ids)); |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index c0d238f49db8..73da6b64f5b7 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c | |||
| @@ -493,6 +493,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) | |||
| 493 | unsigned long from = cpuc->lbr_entries[0].from; | 493 | unsigned long from = cpuc->lbr_entries[0].from; |
| 494 | unsigned long old_to, to = cpuc->lbr_entries[0].to; | 494 | unsigned long old_to, to = cpuc->lbr_entries[0].to; |
| 495 | unsigned long ip = regs->ip; | 495 | unsigned long ip = regs->ip; |
| 496 | int is_64bit = 0; | ||
| 496 | 497 | ||
| 497 | /* | 498 | /* |
| 498 | * We don't need to fixup if the PEBS assist is fault like | 499 | * We don't need to fixup if the PEBS assist is fault like |
| @@ -544,7 +545,10 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) | |||
| 544 | } else | 545 | } else |
| 545 | kaddr = (void *)to; | 546 | kaddr = (void *)to; |
| 546 | 547 | ||
| 547 | kernel_insn_init(&insn, kaddr); | 548 | #ifdef CONFIG_X86_64 |
| 549 | is_64bit = kernel_ip(to) || !test_thread_flag(TIF_IA32); | ||
| 550 | #endif | ||
| 551 | insn_init(&insn, kaddr, is_64bit); | ||
| 548 | insn_get_length(&insn); | 552 | insn_get_length(&insn); |
| 549 | to += insn.length; | 553 | to += insn.length; |
| 550 | } while (to < ip); | 554 | } while (to < ip); |
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index 492bf1358a7c..ef484d9d0a25 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c | |||
| @@ -1268,7 +1268,7 @@ reserve: | |||
| 1268 | } | 1268 | } |
| 1269 | 1269 | ||
| 1270 | done: | 1270 | done: |
| 1271 | return num ? -ENOSPC : 0; | 1271 | return num ? -EINVAL : 0; |
| 1272 | } | 1272 | } |
| 1273 | 1273 | ||
| 1274 | static __initconst const struct x86_pmu p4_pmu = { | 1274 | static __initconst const struct x86_pmu p4_pmu = { |
