diff options
Diffstat (limited to 'arch/x86/events')
| -rw-r--r-- | arch/x86/events/core.c | 24 | ||||
| -rw-r--r-- | arch/x86/events/intel/core.c | 31 | ||||
| -rw-r--r-- | arch/x86/events/intel/ds.c | 108 | ||||
| -rw-r--r-- | arch/x86/events/intel/lbr.c | 70 | ||||
| -rw-r--r-- | arch/x86/events/intel/pt.c | 24 | ||||
| -rw-r--r-- | arch/x86/events/intel/pt.h | 5 | ||||
| -rw-r--r-- | arch/x86/events/intel/rapl.c | 4 | ||||
| -rw-r--r-- | arch/x86/events/intel/uncore.c | 11 | ||||
| -rw-r--r-- | arch/x86/events/intel/uncore.h | 7 | ||||
| -rw-r--r-- | arch/x86/events/intel/uncore_snb.c | 2 | ||||
| -rw-r--r-- | arch/x86/events/intel/uncore_snbep.c | 626 | ||||
| -rw-r--r-- | arch/x86/events/perf_event.h | 13 |
12 files changed, 820 insertions, 105 deletions
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 0a8bd7fcdbed..d31735f37ed7 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c | |||
| @@ -1202,6 +1202,9 @@ static int x86_pmu_add(struct perf_event *event, int flags) | |||
| 1202 | * If group events scheduling transaction was started, | 1202 | * If group events scheduling transaction was started, |
| 1203 | * skip the schedulability test here, it will be performed | 1203 | * skip the schedulability test here, it will be performed |
| 1204 | * at commit time (->commit_txn) as a whole. | 1204 | * at commit time (->commit_txn) as a whole. |
| 1205 | * | ||
| 1206 | * If commit fails, we'll call ->del() on all events | ||
| 1207 | * for which ->add() was called. | ||
| 1205 | */ | 1208 | */ |
| 1206 | if (cpuc->txn_flags & PERF_PMU_TXN_ADD) | 1209 | if (cpuc->txn_flags & PERF_PMU_TXN_ADD) |
| 1207 | goto done_collect; | 1210 | goto done_collect; |
| @@ -1224,6 +1227,14 @@ done_collect: | |||
| 1224 | cpuc->n_added += n - n0; | 1227 | cpuc->n_added += n - n0; |
| 1225 | cpuc->n_txn += n - n0; | 1228 | cpuc->n_txn += n - n0; |
| 1226 | 1229 | ||
| 1230 | if (x86_pmu.add) { | ||
| 1231 | /* | ||
| 1232 | * This is before x86_pmu_enable() will call x86_pmu_start(), | ||
| 1233 | * so we enable LBRs before an event needs them etc.. | ||
| 1234 | */ | ||
| 1235 | x86_pmu.add(event); | ||
| 1236 | } | ||
| 1237 | |||
| 1227 | ret = 0; | 1238 | ret = 0; |
| 1228 | out: | 1239 | out: |
| 1229 | return ret; | 1240 | return ret; |
| @@ -1347,7 +1358,7 @@ static void x86_pmu_del(struct perf_event *event, int flags) | |||
| 1347 | event->hw.flags &= ~PERF_X86_EVENT_COMMITTED; | 1358 | event->hw.flags &= ~PERF_X86_EVENT_COMMITTED; |
| 1348 | 1359 | ||
| 1349 | /* | 1360 | /* |
| 1350 | * If we're called during a txn, we don't need to do anything. | 1361 | * If we're called during a txn, we only need to undo x86_pmu.add. |
| 1351 | * The events never got scheduled and ->cancel_txn will truncate | 1362 | * The events never got scheduled and ->cancel_txn will truncate |
| 1352 | * the event_list. | 1363 | * the event_list. |
| 1353 | * | 1364 | * |
| @@ -1355,7 +1366,7 @@ static void x86_pmu_del(struct perf_event *event, int flags) | |||
| 1355 | * an event added during that same TXN. | 1366 | * an event added during that same TXN. |
| 1356 | */ | 1367 | */ |
| 1357 | if (cpuc->txn_flags & PERF_PMU_TXN_ADD) | 1368 | if (cpuc->txn_flags & PERF_PMU_TXN_ADD) |
| 1358 | return; | 1369 | goto do_del; |
| 1359 | 1370 | ||
| 1360 | /* | 1371 | /* |
| 1361 | * Not a TXN, therefore cleanup properly. | 1372 | * Not a TXN, therefore cleanup properly. |
| @@ -1385,6 +1396,15 @@ static void x86_pmu_del(struct perf_event *event, int flags) | |||
| 1385 | --cpuc->n_events; | 1396 | --cpuc->n_events; |
| 1386 | 1397 | ||
| 1387 | perf_event_update_userpage(event); | 1398 | perf_event_update_userpage(event); |
| 1399 | |||
| 1400 | do_del: | ||
| 1401 | if (x86_pmu.del) { | ||
| 1402 | /* | ||
| 1403 | * This is after x86_pmu_stop(); so we disable LBRs after any | ||
| 1404 | * event can need them etc.. | ||
| 1405 | */ | ||
| 1406 | x86_pmu.del(event); | ||
| 1407 | } | ||
| 1388 | } | 1408 | } |
| 1389 | 1409 | ||
| 1390 | int x86_pmu_handle_irq(struct pt_regs *regs) | 1410 | int x86_pmu_handle_irq(struct pt_regs *regs) |
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 4c9a79b9cd69..a3a9eb84b5cf 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c | |||
| @@ -1906,13 +1906,6 @@ static void intel_pmu_disable_event(struct perf_event *event) | |||
| 1906 | cpuc->intel_ctrl_host_mask &= ~(1ull << hwc->idx); | 1906 | cpuc->intel_ctrl_host_mask &= ~(1ull << hwc->idx); |
| 1907 | cpuc->intel_cp_status &= ~(1ull << hwc->idx); | 1907 | cpuc->intel_cp_status &= ~(1ull << hwc->idx); |
| 1908 | 1908 | ||
| 1909 | /* | ||
| 1910 | * must disable before any actual event | ||
| 1911 | * because any event may be combined with LBR | ||
| 1912 | */ | ||
| 1913 | if (needs_branch_stack(event)) | ||
| 1914 | intel_pmu_lbr_disable(event); | ||
| 1915 | |||
| 1916 | if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { | 1909 | if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { |
| 1917 | intel_pmu_disable_fixed(hwc); | 1910 | intel_pmu_disable_fixed(hwc); |
| 1918 | return; | 1911 | return; |
| @@ -1924,6 +1917,14 @@ static void intel_pmu_disable_event(struct perf_event *event) | |||
| 1924 | intel_pmu_pebs_disable(event); | 1917 | intel_pmu_pebs_disable(event); |
| 1925 | } | 1918 | } |
| 1926 | 1919 | ||
| 1920 | static void intel_pmu_del_event(struct perf_event *event) | ||
| 1921 | { | ||
| 1922 | if (needs_branch_stack(event)) | ||
| 1923 | intel_pmu_lbr_del(event); | ||
| 1924 | if (event->attr.precise_ip) | ||
| 1925 | intel_pmu_pebs_del(event); | ||
| 1926 | } | ||
| 1927 | |||
| 1927 | static void intel_pmu_enable_fixed(struct hw_perf_event *hwc) | 1928 | static void intel_pmu_enable_fixed(struct hw_perf_event *hwc) |
| 1928 | { | 1929 | { |
| 1929 | int idx = hwc->idx - INTEL_PMC_IDX_FIXED; | 1930 | int idx = hwc->idx - INTEL_PMC_IDX_FIXED; |
| @@ -1967,12 +1968,6 @@ static void intel_pmu_enable_event(struct perf_event *event) | |||
| 1967 | intel_pmu_enable_bts(hwc->config); | 1968 | intel_pmu_enable_bts(hwc->config); |
| 1968 | return; | 1969 | return; |
| 1969 | } | 1970 | } |
| 1970 | /* | ||
| 1971 | * must enabled before any actual event | ||
| 1972 | * because any event may be combined with LBR | ||
| 1973 | */ | ||
| 1974 | if (needs_branch_stack(event)) | ||
| 1975 | intel_pmu_lbr_enable(event); | ||
| 1976 | 1971 | ||
| 1977 | if (event->attr.exclude_host) | 1972 | if (event->attr.exclude_host) |
| 1978 | cpuc->intel_ctrl_guest_mask |= (1ull << hwc->idx); | 1973 | cpuc->intel_ctrl_guest_mask |= (1ull << hwc->idx); |
| @@ -1993,6 +1988,14 @@ static void intel_pmu_enable_event(struct perf_event *event) | |||
| 1993 | __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE); | 1988 | __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE); |
| 1994 | } | 1989 | } |
| 1995 | 1990 | ||
| 1991 | static void intel_pmu_add_event(struct perf_event *event) | ||
| 1992 | { | ||
| 1993 | if (event->attr.precise_ip) | ||
| 1994 | intel_pmu_pebs_add(event); | ||
| 1995 | if (needs_branch_stack(event)) | ||
| 1996 | intel_pmu_lbr_add(event); | ||
| 1997 | } | ||
| 1998 | |||
| 1996 | /* | 1999 | /* |
| 1997 | * Save and restart an expired event. Called by NMI contexts, | 2000 | * Save and restart an expired event. Called by NMI contexts, |
| 1998 | * so it has to be careful about preempting normal event ops: | 2001 | * so it has to be careful about preempting normal event ops: |
| @@ -3291,6 +3294,8 @@ static __initconst const struct x86_pmu intel_pmu = { | |||
| 3291 | .enable_all = intel_pmu_enable_all, | 3294 | .enable_all = intel_pmu_enable_all, |
| 3292 | .enable = intel_pmu_enable_event, | 3295 | .enable = intel_pmu_enable_event, |
| 3293 | .disable = intel_pmu_disable_event, | 3296 | .disable = intel_pmu_disable_event, |
| 3297 | .add = intel_pmu_add_event, | ||
| 3298 | .del = intel_pmu_del_event, | ||
| 3294 | .hw_config = intel_pmu_hw_config, | 3299 | .hw_config = intel_pmu_hw_config, |
| 3295 | .schedule_events = x86_schedule_events, | 3300 | .schedule_events = x86_schedule_events, |
| 3296 | .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, | 3301 | .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, |
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c index 9b983a474253..0319311dbdbb 100644 --- a/arch/x86/events/intel/ds.c +++ b/arch/x86/events/intel/ds.c | |||
| @@ -806,9 +806,65 @@ struct event_constraint *intel_pebs_constraints(struct perf_event *event) | |||
| 806 | return &emptyconstraint; | 806 | return &emptyconstraint; |
| 807 | } | 807 | } |
| 808 | 808 | ||
| 809 | static inline bool pebs_is_enabled(struct cpu_hw_events *cpuc) | 809 | /* |
| 810 | * We need the sched_task callback even for per-cpu events when we use | ||
| 811 | * the large interrupt threshold, such that we can provide PID and TID | ||
| 812 | * to PEBS samples. | ||
| 813 | */ | ||
| 814 | static inline bool pebs_needs_sched_cb(struct cpu_hw_events *cpuc) | ||
| 815 | { | ||
| 816 | return cpuc->n_pebs && (cpuc->n_pebs == cpuc->n_large_pebs); | ||
| 817 | } | ||
| 818 | |||
| 819 | static inline void pebs_update_threshold(struct cpu_hw_events *cpuc) | ||
| 820 | { | ||
| 821 | struct debug_store *ds = cpuc->ds; | ||
| 822 | u64 threshold; | ||
| 823 | |||
| 824 | if (cpuc->n_pebs == cpuc->n_large_pebs) { | ||
| 825 | threshold = ds->pebs_absolute_maximum - | ||
| 826 | x86_pmu.max_pebs_events * x86_pmu.pebs_record_size; | ||
| 827 | } else { | ||
| 828 | threshold = ds->pebs_buffer_base + x86_pmu.pebs_record_size; | ||
| 829 | } | ||
| 830 | |||
| 831 | ds->pebs_interrupt_threshold = threshold; | ||
| 832 | } | ||
| 833 | |||
| 834 | static void | ||
| 835 | pebs_update_state(bool needed_cb, struct cpu_hw_events *cpuc, struct pmu *pmu) | ||
| 836 | { | ||
| 837 | /* | ||
| 838 | * Make sure we get updated with the first PEBS | ||
| 839 | * event. It will trigger also during removal, but | ||
| 840 | * that does not hurt: | ||
| 841 | */ | ||
| 842 | bool update = cpuc->n_pebs == 1; | ||
| 843 | |||
| 844 | if (needed_cb != pebs_needs_sched_cb(cpuc)) { | ||
| 845 | if (!needed_cb) | ||
| 846 | perf_sched_cb_inc(pmu); | ||
| 847 | else | ||
| 848 | perf_sched_cb_dec(pmu); | ||
| 849 | |||
| 850 | update = true; | ||
| 851 | } | ||
| 852 | |||
| 853 | if (update) | ||
| 854 | pebs_update_threshold(cpuc); | ||
| 855 | } | ||
| 856 | |||
| 857 | void intel_pmu_pebs_add(struct perf_event *event) | ||
| 810 | { | 858 | { |
| 811 | return (cpuc->pebs_enabled & ((1ULL << MAX_PEBS_EVENTS) - 1)); | 859 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
| 860 | struct hw_perf_event *hwc = &event->hw; | ||
| 861 | bool needed_cb = pebs_needs_sched_cb(cpuc); | ||
| 862 | |||
| 863 | cpuc->n_pebs++; | ||
| 864 | if (hwc->flags & PERF_X86_EVENT_FREERUNNING) | ||
| 865 | cpuc->n_large_pebs++; | ||
| 866 | |||
| 867 | pebs_update_state(needed_cb, cpuc, event->ctx->pmu); | ||
| 812 | } | 868 | } |
| 813 | 869 | ||
| 814 | void intel_pmu_pebs_enable(struct perf_event *event) | 870 | void intel_pmu_pebs_enable(struct perf_event *event) |
| @@ -816,12 +872,9 @@ void intel_pmu_pebs_enable(struct perf_event *event) | |||
| 816 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); | 872 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
| 817 | struct hw_perf_event *hwc = &event->hw; | 873 | struct hw_perf_event *hwc = &event->hw; |
| 818 | struct debug_store *ds = cpuc->ds; | 874 | struct debug_store *ds = cpuc->ds; |
| 819 | bool first_pebs; | ||
| 820 | u64 threshold; | ||
| 821 | 875 | ||
| 822 | hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT; | 876 | hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT; |
| 823 | 877 | ||
| 824 | first_pebs = !pebs_is_enabled(cpuc); | ||
| 825 | cpuc->pebs_enabled |= 1ULL << hwc->idx; | 878 | cpuc->pebs_enabled |= 1ULL << hwc->idx; |
| 826 | 879 | ||
| 827 | if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT) | 880 | if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT) |
| @@ -830,46 +883,34 @@ void intel_pmu_pebs_enable(struct perf_event *event) | |||
| 830 | cpuc->pebs_enabled |= 1ULL << 63; | 883 | cpuc->pebs_enabled |= 1ULL << 63; |
| 831 | 884 | ||
| 832 | /* | 885 | /* |
| 833 | * When the event is constrained enough we can use a larger | 886 | * Use auto-reload if possible to save a MSR write in the PMI. |
| 834 | * threshold and run the event with less frequent PMI. | 887 | * This must be done in pmu::start(), because PERF_EVENT_IOC_PERIOD. |
| 835 | */ | 888 | */ |
| 836 | if (hwc->flags & PERF_X86_EVENT_FREERUNNING) { | ||
| 837 | threshold = ds->pebs_absolute_maximum - | ||
| 838 | x86_pmu.max_pebs_events * x86_pmu.pebs_record_size; | ||
| 839 | |||
| 840 | if (first_pebs) | ||
| 841 | perf_sched_cb_inc(event->ctx->pmu); | ||
| 842 | } else { | ||
| 843 | threshold = ds->pebs_buffer_base + x86_pmu.pebs_record_size; | ||
| 844 | |||
| 845 | /* | ||
| 846 | * If not all events can use larger buffer, | ||
| 847 | * roll back to threshold = 1 | ||
| 848 | */ | ||
| 849 | if (!first_pebs && | ||
| 850 | (ds->pebs_interrupt_threshold > threshold)) | ||
| 851 | perf_sched_cb_dec(event->ctx->pmu); | ||
| 852 | } | ||
| 853 | |||
| 854 | /* Use auto-reload if possible to save a MSR write in the PMI */ | ||
| 855 | if (hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) { | 889 | if (hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) { |
| 856 | ds->pebs_event_reset[hwc->idx] = | 890 | ds->pebs_event_reset[hwc->idx] = |
| 857 | (u64)(-hwc->sample_period) & x86_pmu.cntval_mask; | 891 | (u64)(-hwc->sample_period) & x86_pmu.cntval_mask; |
| 858 | } | 892 | } |
| 893 | } | ||
| 894 | |||
| 895 | void intel_pmu_pebs_del(struct perf_event *event) | ||
| 896 | { | ||
| 897 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); | ||
| 898 | struct hw_perf_event *hwc = &event->hw; | ||
| 899 | bool needed_cb = pebs_needs_sched_cb(cpuc); | ||
| 859 | 900 | ||
| 860 | if (first_pebs || ds->pebs_interrupt_threshold > threshold) | 901 | cpuc->n_pebs--; |
| 861 | ds->pebs_interrupt_threshold = threshold; | 902 | if (hwc->flags & PERF_X86_EVENT_FREERUNNING) |
| 903 | cpuc->n_large_pebs--; | ||
| 904 | |||
| 905 | pebs_update_state(needed_cb, cpuc, event->ctx->pmu); | ||
| 862 | } | 906 | } |
| 863 | 907 | ||
| 864 | void intel_pmu_pebs_disable(struct perf_event *event) | 908 | void intel_pmu_pebs_disable(struct perf_event *event) |
| 865 | { | 909 | { |
| 866 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); | 910 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
| 867 | struct hw_perf_event *hwc = &event->hw; | 911 | struct hw_perf_event *hwc = &event->hw; |
| 868 | struct debug_store *ds = cpuc->ds; | ||
| 869 | bool large_pebs = ds->pebs_interrupt_threshold > | ||
| 870 | ds->pebs_buffer_base + x86_pmu.pebs_record_size; | ||
| 871 | 912 | ||
| 872 | if (large_pebs) | 913 | if (cpuc->n_pebs == cpuc->n_large_pebs) |
| 873 | intel_pmu_drain_pebs_buffer(); | 914 | intel_pmu_drain_pebs_buffer(); |
| 874 | 915 | ||
| 875 | cpuc->pebs_enabled &= ~(1ULL << hwc->idx); | 916 | cpuc->pebs_enabled &= ~(1ULL << hwc->idx); |
| @@ -879,9 +920,6 @@ void intel_pmu_pebs_disable(struct perf_event *event) | |||
| 879 | else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST) | 920 | else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST) |
| 880 | cpuc->pebs_enabled &= ~(1ULL << 63); | 921 | cpuc->pebs_enabled &= ~(1ULL << 63); |
| 881 | 922 | ||
| 882 | if (large_pebs && !pebs_is_enabled(cpuc)) | ||
| 883 | perf_sched_cb_dec(event->ctx->pmu); | ||
| 884 | |||
| 885 | if (cpuc->enabled) | 923 | if (cpuc->enabled) |
| 886 | wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled); | 924 | wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled); |
| 887 | 925 | ||
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c index 707d358e0dff..fc6cf21c535e 100644 --- a/arch/x86/events/intel/lbr.c +++ b/arch/x86/events/intel/lbr.c | |||
| @@ -380,7 +380,6 @@ static void __intel_pmu_lbr_save(struct x86_perf_task_context *task_ctx) | |||
| 380 | 380 | ||
| 381 | void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in) | 381 | void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in) |
| 382 | { | 382 | { |
| 383 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); | ||
| 384 | struct x86_perf_task_context *task_ctx; | 383 | struct x86_perf_task_context *task_ctx; |
| 385 | 384 | ||
| 386 | /* | 385 | /* |
| @@ -390,31 +389,21 @@ void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in) | |||
| 390 | */ | 389 | */ |
| 391 | task_ctx = ctx ? ctx->task_ctx_data : NULL; | 390 | task_ctx = ctx ? ctx->task_ctx_data : NULL; |
| 392 | if (task_ctx) { | 391 | if (task_ctx) { |
| 393 | if (sched_in) { | 392 | if (sched_in) |
| 394 | __intel_pmu_lbr_restore(task_ctx); | 393 | __intel_pmu_lbr_restore(task_ctx); |
| 395 | cpuc->lbr_context = ctx; | 394 | else |
| 396 | } else { | ||
| 397 | __intel_pmu_lbr_save(task_ctx); | 395 | __intel_pmu_lbr_save(task_ctx); |
| 398 | } | ||
| 399 | return; | 396 | return; |
| 400 | } | 397 | } |
| 401 | 398 | ||
| 402 | /* | 399 | /* |
| 403 | * When sampling the branck stack in system-wide, it may be | 400 | * Since a context switch can flip the address space and LBR entries |
| 404 | * necessary to flush the stack on context switch. This happens | 401 | * are not tagged with an identifier, we need to wipe the LBR, even for |
| 405 | * when the branch stack does not tag its entries with the pid | 402 | * per-cpu events. You simply cannot resolve the branches from the old |
| 406 | * of the current task. Otherwise it becomes impossible to | 403 | * address space. |
| 407 | * associate a branch entry with a task. This ambiguity is more | 404 | */ |
| 408 | * likely to appear when the branch stack supports priv level | 405 | if (sched_in) |
| 409 | * filtering and the user sets it to monitor only at the user | ||
| 410 | * level (which could be a useful measurement in system-wide | ||
| 411 | * mode). In that case, the risk is high of having a branch | ||
| 412 | * stack with branch from multiple tasks. | ||
| 413 | */ | ||
| 414 | if (sched_in) { | ||
| 415 | intel_pmu_lbr_reset(); | 406 | intel_pmu_lbr_reset(); |
| 416 | cpuc->lbr_context = ctx; | ||
| 417 | } | ||
| 418 | } | 407 | } |
| 419 | 408 | ||
| 420 | static inline bool branch_user_callstack(unsigned br_sel) | 409 | static inline bool branch_user_callstack(unsigned br_sel) |
| @@ -422,7 +411,7 @@ static inline bool branch_user_callstack(unsigned br_sel) | |||
| 422 | return (br_sel & X86_BR_USER) && (br_sel & X86_BR_CALL_STACK); | 411 | return (br_sel & X86_BR_USER) && (br_sel & X86_BR_CALL_STACK); |
| 423 | } | 412 | } |
| 424 | 413 | ||
| 425 | void intel_pmu_lbr_enable(struct perf_event *event) | 414 | void intel_pmu_lbr_add(struct perf_event *event) |
| 426 | { | 415 | { |
| 427 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); | 416 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
| 428 | struct x86_perf_task_context *task_ctx; | 417 | struct x86_perf_task_context *task_ctx; |
| @@ -430,27 +419,38 @@ void intel_pmu_lbr_enable(struct perf_event *event) | |||
| 430 | if (!x86_pmu.lbr_nr) | 419 | if (!x86_pmu.lbr_nr) |
| 431 | return; | 420 | return; |
| 432 | 421 | ||
| 433 | /* | ||
| 434 | * Reset the LBR stack if we changed task context to | ||
| 435 | * avoid data leaks. | ||
| 436 | */ | ||
| 437 | if (event->ctx->task && cpuc->lbr_context != event->ctx) { | ||
| 438 | intel_pmu_lbr_reset(); | ||
| 439 | cpuc->lbr_context = event->ctx; | ||
| 440 | } | ||
| 441 | cpuc->br_sel = event->hw.branch_reg.reg; | 422 | cpuc->br_sel = event->hw.branch_reg.reg; |
| 442 | 423 | ||
| 443 | if (branch_user_callstack(cpuc->br_sel) && event->ctx && | 424 | if (branch_user_callstack(cpuc->br_sel) && event->ctx->task_ctx_data) { |
| 444 | event->ctx->task_ctx_data) { | ||
| 445 | task_ctx = event->ctx->task_ctx_data; | 425 | task_ctx = event->ctx->task_ctx_data; |
| 446 | task_ctx->lbr_callstack_users++; | 426 | task_ctx->lbr_callstack_users++; |
| 447 | } | 427 | } |
| 448 | 428 | ||
| 449 | cpuc->lbr_users++; | 429 | /* |
| 430 | * Request pmu::sched_task() callback, which will fire inside the | ||
| 431 | * regular perf event scheduling, so that call will: | ||
| 432 | * | ||
| 433 | * - restore or wipe; when LBR-callstack, | ||
| 434 | * - wipe; otherwise, | ||
| 435 | * | ||
| 436 | * when this is from __perf_event_task_sched_in(). | ||
| 437 | * | ||
| 438 | * However, if this is from perf_install_in_context(), no such callback | ||
| 439 | * will follow and we'll need to reset the LBR here if this is the | ||
| 440 | * first LBR event. | ||
| 441 | * | ||
| 442 | * The problem is, we cannot tell these cases apart... but we can | ||
| 443 | * exclude the biggest chunk of cases by looking at | ||
| 444 | * event->total_time_running. An event that has accrued runtime cannot | ||
| 445 | * be 'new'. Conversely, a new event can get installed through the | ||
| 446 | * context switch path for the first time. | ||
| 447 | */ | ||
| 450 | perf_sched_cb_inc(event->ctx->pmu); | 448 | perf_sched_cb_inc(event->ctx->pmu); |
| 449 | if (!cpuc->lbr_users++ && !event->total_time_running) | ||
| 450 | intel_pmu_lbr_reset(); | ||
| 451 | } | 451 | } |
| 452 | 452 | ||
| 453 | void intel_pmu_lbr_disable(struct perf_event *event) | 453 | void intel_pmu_lbr_del(struct perf_event *event) |
| 454 | { | 454 | { |
| 455 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); | 455 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
| 456 | struct x86_perf_task_context *task_ctx; | 456 | struct x86_perf_task_context *task_ctx; |
| @@ -467,12 +467,6 @@ void intel_pmu_lbr_disable(struct perf_event *event) | |||
| 467 | cpuc->lbr_users--; | 467 | cpuc->lbr_users--; |
| 468 | WARN_ON_ONCE(cpuc->lbr_users < 0); | 468 | WARN_ON_ONCE(cpuc->lbr_users < 0); |
| 469 | perf_sched_cb_dec(event->ctx->pmu); | 469 | perf_sched_cb_dec(event->ctx->pmu); |
| 470 | |||
| 471 | if (cpuc->enabled && !cpuc->lbr_users) { | ||
| 472 | __intel_pmu_lbr_disable(); | ||
| 473 | /* avoid stale pointer */ | ||
| 474 | cpuc->lbr_context = NULL; | ||
| 475 | } | ||
| 476 | } | 470 | } |
| 477 | 471 | ||
| 478 | void intel_pmu_lbr_enable_all(bool pmi) | 472 | void intel_pmu_lbr_enable_all(bool pmi) |
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 861a7d9cb60f..c5047b8f777b 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c | |||
| @@ -69,6 +69,8 @@ static struct pt_cap_desc { | |||
| 69 | PT_CAP(psb_cyc, 0, CR_EBX, BIT(1)), | 69 | PT_CAP(psb_cyc, 0, CR_EBX, BIT(1)), |
| 70 | PT_CAP(ip_filtering, 0, CR_EBX, BIT(2)), | 70 | PT_CAP(ip_filtering, 0, CR_EBX, BIT(2)), |
| 71 | PT_CAP(mtc, 0, CR_EBX, BIT(3)), | 71 | PT_CAP(mtc, 0, CR_EBX, BIT(3)), |
| 72 | PT_CAP(ptwrite, 0, CR_EBX, BIT(4)), | ||
| 73 | PT_CAP(power_event_trace, 0, CR_EBX, BIT(5)), | ||
| 72 | PT_CAP(topa_output, 0, CR_ECX, BIT(0)), | 74 | PT_CAP(topa_output, 0, CR_ECX, BIT(0)), |
| 73 | PT_CAP(topa_multiple_entries, 0, CR_ECX, BIT(1)), | 75 | PT_CAP(topa_multiple_entries, 0, CR_ECX, BIT(1)), |
| 74 | PT_CAP(single_range_output, 0, CR_ECX, BIT(2)), | 76 | PT_CAP(single_range_output, 0, CR_ECX, BIT(2)), |
| @@ -259,10 +261,16 @@ fail: | |||
| 259 | #define RTIT_CTL_MTC (RTIT_CTL_MTC_EN | \ | 261 | #define RTIT_CTL_MTC (RTIT_CTL_MTC_EN | \ |
| 260 | RTIT_CTL_MTC_RANGE) | 262 | RTIT_CTL_MTC_RANGE) |
| 261 | 263 | ||
| 264 | #define RTIT_CTL_PTW (RTIT_CTL_PTW_EN | \ | ||
| 265 | RTIT_CTL_FUP_ON_PTW) | ||
| 266 | |||
| 262 | #define PT_CONFIG_MASK (RTIT_CTL_TSC_EN | \ | 267 | #define PT_CONFIG_MASK (RTIT_CTL_TSC_EN | \ |
| 263 | RTIT_CTL_DISRETC | \ | 268 | RTIT_CTL_DISRETC | \ |
| 264 | RTIT_CTL_CYC_PSB | \ | 269 | RTIT_CTL_CYC_PSB | \ |
| 265 | RTIT_CTL_MTC) | 270 | RTIT_CTL_MTC | \ |
| 271 | RTIT_CTL_PWR_EVT_EN | \ | ||
| 272 | RTIT_CTL_FUP_ON_PTW | \ | ||
| 273 | RTIT_CTL_PTW_EN) | ||
| 266 | 274 | ||
| 267 | static bool pt_event_valid(struct perf_event *event) | 275 | static bool pt_event_valid(struct perf_event *event) |
| 268 | { | 276 | { |
| @@ -311,6 +319,20 @@ static bool pt_event_valid(struct perf_event *event) | |||
| 311 | return false; | 319 | return false; |
| 312 | } | 320 | } |
| 313 | 321 | ||
| 322 | if (config & RTIT_CTL_PWR_EVT_EN && | ||
| 323 | !pt_cap_get(PT_CAP_power_event_trace)) | ||
| 324 | return false; | ||
| 325 | |||
| 326 | if (config & RTIT_CTL_PTW) { | ||
| 327 | if (!pt_cap_get(PT_CAP_ptwrite)) | ||
| 328 | return false; | ||
| 329 | |||
| 330 | /* FUPonPTW without PTW doesn't make sense */ | ||
| 331 | if ((config & RTIT_CTL_FUP_ON_PTW) && | ||
| 332 | !(config & RTIT_CTL_PTW_EN)) | ||
| 333 | return false; | ||
| 334 | } | ||
| 335 | |||
| 314 | return true; | 336 | return true; |
| 315 | } | 337 | } |
| 316 | 338 | ||
diff --git a/arch/x86/events/intel/pt.h b/arch/x86/events/intel/pt.h index efffa4a09f68..53473c21b554 100644 --- a/arch/x86/events/intel/pt.h +++ b/arch/x86/events/intel/pt.h | |||
| @@ -26,11 +26,14 @@ | |||
| 26 | #define RTIT_CTL_CYCLEACC BIT(1) | 26 | #define RTIT_CTL_CYCLEACC BIT(1) |
| 27 | #define RTIT_CTL_OS BIT(2) | 27 | #define RTIT_CTL_OS BIT(2) |
| 28 | #define RTIT_CTL_USR BIT(3) | 28 | #define RTIT_CTL_USR BIT(3) |
| 29 | #define RTIT_CTL_PWR_EVT_EN BIT(4) | ||
| 30 | #define RTIT_CTL_FUP_ON_PTW BIT(5) | ||
| 29 | #define RTIT_CTL_CR3EN BIT(7) | 31 | #define RTIT_CTL_CR3EN BIT(7) |
| 30 | #define RTIT_CTL_TOPA BIT(8) | 32 | #define RTIT_CTL_TOPA BIT(8) |
| 31 | #define RTIT_CTL_MTC_EN BIT(9) | 33 | #define RTIT_CTL_MTC_EN BIT(9) |
| 32 | #define RTIT_CTL_TSC_EN BIT(10) | 34 | #define RTIT_CTL_TSC_EN BIT(10) |
| 33 | #define RTIT_CTL_DISRETC BIT(11) | 35 | #define RTIT_CTL_DISRETC BIT(11) |
| 36 | #define RTIT_CTL_PTW_EN BIT(12) | ||
| 34 | #define RTIT_CTL_BRANCH_EN BIT(13) | 37 | #define RTIT_CTL_BRANCH_EN BIT(13) |
| 35 | #define RTIT_CTL_MTC_RANGE_OFFSET 14 | 38 | #define RTIT_CTL_MTC_RANGE_OFFSET 14 |
| 36 | #define RTIT_CTL_MTC_RANGE (0x0full << RTIT_CTL_MTC_RANGE_OFFSET) | 39 | #define RTIT_CTL_MTC_RANGE (0x0full << RTIT_CTL_MTC_RANGE_OFFSET) |
| @@ -91,6 +94,8 @@ enum pt_capabilities { | |||
| 91 | PT_CAP_psb_cyc, | 94 | PT_CAP_psb_cyc, |
| 92 | PT_CAP_ip_filtering, | 95 | PT_CAP_ip_filtering, |
| 93 | PT_CAP_mtc, | 96 | PT_CAP_mtc, |
| 97 | PT_CAP_ptwrite, | ||
| 98 | PT_CAP_power_event_trace, | ||
| 94 | PT_CAP_topa_output, | 99 | PT_CAP_topa_output, |
| 95 | PT_CAP_topa_multiple_entries, | 100 | PT_CAP_topa_multiple_entries, |
| 96 | PT_CAP_single_range_output, | 101 | PT_CAP_single_range_output, |
diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c index 28865938aadf..b0f0e835a770 100644 --- a/arch/x86/events/intel/rapl.c +++ b/arch/x86/events/intel/rapl.c | |||
| @@ -357,6 +357,8 @@ static int rapl_pmu_event_init(struct perf_event *event) | |||
| 357 | if (event->cpu < 0) | 357 | if (event->cpu < 0) |
| 358 | return -EINVAL; | 358 | return -EINVAL; |
| 359 | 359 | ||
| 360 | event->event_caps |= PERF_EV_CAP_READ_ACTIVE_PKG; | ||
| 361 | |||
| 360 | /* | 362 | /* |
| 361 | * check event is known (determines counter) | 363 | * check event is known (determines counter) |
| 362 | */ | 364 | */ |
| @@ -765,6 +767,8 @@ static const struct x86_cpu_id rapl_cpu_match[] __initconst = { | |||
| 765 | X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_MOBILE, skl_rapl_init), | 767 | X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_MOBILE, skl_rapl_init), |
| 766 | X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_DESKTOP, skl_rapl_init), | 768 | X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_DESKTOP, skl_rapl_init), |
| 767 | X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_X, hsx_rapl_init), | 769 | X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_X, hsx_rapl_init), |
| 770 | |||
| 771 | X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT, hsw_rapl_init), | ||
| 768 | {}, | 772 | {}, |
| 769 | }; | 773 | }; |
| 770 | 774 | ||
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index 463dc7a5a6c3..d9844cc74486 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c | |||
| @@ -664,6 +664,8 @@ static int uncore_pmu_event_init(struct perf_event *event) | |||
| 664 | event->cpu = box->cpu; | 664 | event->cpu = box->cpu; |
| 665 | event->pmu_private = box; | 665 | event->pmu_private = box; |
| 666 | 666 | ||
| 667 | event->event_caps |= PERF_EV_CAP_READ_ACTIVE_PKG; | ||
| 668 | |||
| 667 | event->hw.idx = -1; | 669 | event->hw.idx = -1; |
| 668 | event->hw.last_tag = ~0ULL; | 670 | event->hw.last_tag = ~0ULL; |
| 669 | event->hw.extra_reg.idx = EXTRA_REG_NONE; | 671 | event->hw.extra_reg.idx = EXTRA_REG_NONE; |
| @@ -683,7 +685,8 @@ static int uncore_pmu_event_init(struct perf_event *event) | |||
| 683 | /* fixed counters have event field hardcoded to zero */ | 685 | /* fixed counters have event field hardcoded to zero */ |
| 684 | hwc->config = 0ULL; | 686 | hwc->config = 0ULL; |
| 685 | } else { | 687 | } else { |
| 686 | hwc->config = event->attr.config & pmu->type->event_mask; | 688 | hwc->config = event->attr.config & |
| 689 | (pmu->type->event_mask | ((u64)pmu->type->event_mask_ext << 32)); | ||
| 687 | if (pmu->type->ops->hw_config) { | 690 | if (pmu->type->ops->hw_config) { |
| 688 | ret = pmu->type->ops->hw_config(box, event); | 691 | ret = pmu->type->ops->hw_config(box, event); |
| 689 | if (ret) | 692 | if (ret) |
| @@ -1321,6 +1324,11 @@ static const struct intel_uncore_init_fun skl_uncore_init __initconst = { | |||
| 1321 | .pci_init = skl_uncore_pci_init, | 1324 | .pci_init = skl_uncore_pci_init, |
| 1322 | }; | 1325 | }; |
| 1323 | 1326 | ||
| 1327 | static const struct intel_uncore_init_fun skx_uncore_init __initconst = { | ||
| 1328 | .cpu_init = skx_uncore_cpu_init, | ||
| 1329 | .pci_init = skx_uncore_pci_init, | ||
| 1330 | }; | ||
| 1331 | |||
| 1324 | static const struct x86_cpu_id intel_uncore_match[] __initconst = { | 1332 | static const struct x86_cpu_id intel_uncore_match[] __initconst = { |
| 1325 | X86_UNCORE_MODEL_MATCH(INTEL_FAM6_NEHALEM_EP, nhm_uncore_init), | 1333 | X86_UNCORE_MODEL_MATCH(INTEL_FAM6_NEHALEM_EP, nhm_uncore_init), |
| 1326 | X86_UNCORE_MODEL_MATCH(INTEL_FAM6_NEHALEM, nhm_uncore_init), | 1334 | X86_UNCORE_MODEL_MATCH(INTEL_FAM6_NEHALEM, nhm_uncore_init), |
| @@ -1343,6 +1351,7 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = { | |||
| 1343 | X86_UNCORE_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL, knl_uncore_init), | 1351 | X86_UNCORE_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL, knl_uncore_init), |
| 1344 | X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE_DESKTOP,skl_uncore_init), | 1352 | X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE_DESKTOP,skl_uncore_init), |
| 1345 | X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE_MOBILE, skl_uncore_init), | 1353 | X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE_MOBILE, skl_uncore_init), |
| 1354 | X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE_X, skx_uncore_init), | ||
| 1346 | {}, | 1355 | {}, |
| 1347 | }; | 1356 | }; |
| 1348 | 1357 | ||
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h index 78b9c23e2d8d..ad986c1e29bc 100644 --- a/arch/x86/events/intel/uncore.h +++ b/arch/x86/events/intel/uncore.h | |||
| @@ -44,6 +44,7 @@ struct intel_uncore_type { | |||
| 44 | unsigned perf_ctr; | 44 | unsigned perf_ctr; |
| 45 | unsigned event_ctl; | 45 | unsigned event_ctl; |
| 46 | unsigned event_mask; | 46 | unsigned event_mask; |
| 47 | unsigned event_mask_ext; | ||
| 47 | unsigned fixed_ctr; | 48 | unsigned fixed_ctr; |
| 48 | unsigned fixed_ctl; | 49 | unsigned fixed_ctl; |
| 49 | unsigned box_ctl; | 50 | unsigned box_ctl; |
| @@ -120,6 +121,7 @@ struct intel_uncore_box { | |||
| 120 | }; | 121 | }; |
| 121 | 122 | ||
| 122 | #define UNCORE_BOX_FLAG_INITIATED 0 | 123 | #define UNCORE_BOX_FLAG_INITIATED 0 |
| 124 | #define UNCORE_BOX_FLAG_CTL_OFFS8 1 /* event config registers are 8-byte apart */ | ||
| 123 | 125 | ||
| 124 | struct uncore_event_desc { | 126 | struct uncore_event_desc { |
| 125 | struct kobj_attribute attr; | 127 | struct kobj_attribute attr; |
| @@ -172,6 +174,9 @@ static inline unsigned uncore_pci_fixed_ctr(struct intel_uncore_box *box) | |||
| 172 | static inline | 174 | static inline |
| 173 | unsigned uncore_pci_event_ctl(struct intel_uncore_box *box, int idx) | 175 | unsigned uncore_pci_event_ctl(struct intel_uncore_box *box, int idx) |
| 174 | { | 176 | { |
| 177 | if (test_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags)) | ||
| 178 | return idx * 8 + box->pmu->type->event_ctl; | ||
| 179 | |||
| 175 | return idx * 4 + box->pmu->type->event_ctl; | 180 | return idx * 4 + box->pmu->type->event_ctl; |
| 176 | } | 181 | } |
| 177 | 182 | ||
| @@ -377,6 +382,8 @@ int bdx_uncore_pci_init(void); | |||
| 377 | void bdx_uncore_cpu_init(void); | 382 | void bdx_uncore_cpu_init(void); |
| 378 | int knl_uncore_pci_init(void); | 383 | int knl_uncore_pci_init(void); |
| 379 | void knl_uncore_cpu_init(void); | 384 | void knl_uncore_cpu_init(void); |
| 385 | int skx_uncore_pci_init(void); | ||
| 386 | void skx_uncore_cpu_init(void); | ||
| 380 | 387 | ||
| 381 | /* perf_event_intel_uncore_nhmex.c */ | 388 | /* perf_event_intel_uncore_nhmex.c */ |
| 382 | void nhmex_uncore_cpu_init(void); | 389 | void nhmex_uncore_cpu_init(void); |
diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c index 9d35ec0cb8fc..5f845eef9a4d 100644 --- a/arch/x86/events/intel/uncore_snb.c +++ b/arch/x86/events/intel/uncore_snb.c | |||
| @@ -388,6 +388,8 @@ static int snb_uncore_imc_event_init(struct perf_event *event) | |||
| 388 | event->cpu = box->cpu; | 388 | event->cpu = box->cpu; |
| 389 | event->pmu_private = box; | 389 | event->pmu_private = box; |
| 390 | 390 | ||
| 391 | event->event_caps |= PERF_EV_CAP_READ_ACTIVE_PKG; | ||
| 392 | |||
| 391 | event->hw.idx = -1; | 393 | event->hw.idx = -1; |
| 392 | event->hw.last_tag = ~0ULL; | 394 | event->hw.last_tag = ~0ULL; |
| 393 | event->hw.extra_reg.idx = EXTRA_REG_NONE; | 395 | event->hw.extra_reg.idx = EXTRA_REG_NONE; |
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index 8aee83bcf71f..272427700d48 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c | |||
| @@ -1,6 +1,10 @@ | |||
| 1 | /* SandyBridge-EP/IvyTown uncore support */ | 1 | /* SandyBridge-EP/IvyTown uncore support */ |
| 2 | #include "uncore.h" | 2 | #include "uncore.h" |
| 3 | 3 | ||
| 4 | /* SNB-EP pci bus to socket mapping */ | ||
| 5 | #define SNBEP_CPUNODEID 0x40 | ||
| 6 | #define SNBEP_GIDNIDMAP 0x54 | ||
| 7 | |||
| 4 | /* SNB-EP Box level control */ | 8 | /* SNB-EP Box level control */ |
| 5 | #define SNBEP_PMON_BOX_CTL_RST_CTRL (1 << 0) | 9 | #define SNBEP_PMON_BOX_CTL_RST_CTRL (1 << 0) |
| 6 | #define SNBEP_PMON_BOX_CTL_RST_CTRS (1 << 1) | 10 | #define SNBEP_PMON_BOX_CTL_RST_CTRS (1 << 1) |
| @@ -264,15 +268,72 @@ | |||
| 264 | SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ | 268 | SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ |
| 265 | SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET) | 269 | SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET) |
| 266 | 270 | ||
| 271 | /* SKX pci bus to socket mapping */ | ||
| 272 | #define SKX_CPUNODEID 0xc0 | ||
| 273 | #define SKX_GIDNIDMAP 0xd4 | ||
| 274 | |||
| 275 | /* SKX CHA */ | ||
| 276 | #define SKX_CHA_MSR_PMON_BOX_FILTER_TID (0x1ffULL << 0) | ||
| 277 | #define SKX_CHA_MSR_PMON_BOX_FILTER_LINK (0xfULL << 9) | ||
| 278 | #define SKX_CHA_MSR_PMON_BOX_FILTER_STATE (0x3ffULL << 17) | ||
| 279 | #define SKX_CHA_MSR_PMON_BOX_FILTER_REM (0x1ULL << 32) | ||
| 280 | #define SKX_CHA_MSR_PMON_BOX_FILTER_LOC (0x1ULL << 33) | ||
| 281 | #define SKX_CHA_MSR_PMON_BOX_FILTER_ALL_OPC (0x1ULL << 35) | ||
| 282 | #define SKX_CHA_MSR_PMON_BOX_FILTER_NM (0x1ULL << 36) | ||
| 283 | #define SKX_CHA_MSR_PMON_BOX_FILTER_NOT_NM (0x1ULL << 37) | ||
| 284 | #define SKX_CHA_MSR_PMON_BOX_FILTER_OPC0 (0x3ffULL << 41) | ||
| 285 | #define SKX_CHA_MSR_PMON_BOX_FILTER_OPC1 (0x3ffULL << 51) | ||
| 286 | #define SKX_CHA_MSR_PMON_BOX_FILTER_C6 (0x1ULL << 61) | ||
| 287 | #define SKX_CHA_MSR_PMON_BOX_FILTER_NC (0x1ULL << 62) | ||
| 288 | #define SKX_CHA_MSR_PMON_BOX_FILTER_ISOC (0x1ULL << 63) | ||
| 289 | |||
| 290 | /* SKX IIO */ | ||
| 291 | #define SKX_IIO0_MSR_PMON_CTL0 0xa48 | ||
| 292 | #define SKX_IIO0_MSR_PMON_CTR0 0xa41 | ||
| 293 | #define SKX_IIO0_MSR_PMON_BOX_CTL 0xa40 | ||
| 294 | #define SKX_IIO_MSR_OFFSET 0x20 | ||
| 295 | |||
| 296 | #define SKX_PMON_CTL_TRESH_MASK (0xff << 24) | ||
| 297 | #define SKX_PMON_CTL_TRESH_MASK_EXT (0xf) | ||
| 298 | #define SKX_PMON_CTL_CH_MASK (0xff << 4) | ||
| 299 | #define SKX_PMON_CTL_FC_MASK (0x7 << 12) | ||
| 300 | #define SKX_IIO_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \ | ||
| 301 | SNBEP_PMON_CTL_UMASK_MASK | \ | ||
| 302 | SNBEP_PMON_CTL_EDGE_DET | \ | ||
| 303 | SNBEP_PMON_CTL_INVERT | \ | ||
| 304 | SKX_PMON_CTL_TRESH_MASK) | ||
| 305 | #define SKX_IIO_PMON_RAW_EVENT_MASK_EXT (SKX_PMON_CTL_TRESH_MASK_EXT | \ | ||
| 306 | SKX_PMON_CTL_CH_MASK | \ | ||
| 307 | SKX_PMON_CTL_FC_MASK) | ||
| 308 | |||
| 309 | /* SKX IRP */ | ||
| 310 | #define SKX_IRP0_MSR_PMON_CTL0 0xa5b | ||
| 311 | #define SKX_IRP0_MSR_PMON_CTR0 0xa59 | ||
| 312 | #define SKX_IRP0_MSR_PMON_BOX_CTL 0xa58 | ||
| 313 | #define SKX_IRP_MSR_OFFSET 0x20 | ||
| 314 | |||
| 315 | /* SKX UPI */ | ||
| 316 | #define SKX_UPI_PCI_PMON_CTL0 0x350 | ||
| 317 | #define SKX_UPI_PCI_PMON_CTR0 0x318 | ||
| 318 | #define SKX_UPI_PCI_PMON_BOX_CTL 0x378 | ||
| 319 | #define SKX_PMON_CTL_UMASK_EXT 0xff | ||
| 320 | |||
| 321 | /* SKX M2M */ | ||
| 322 | #define SKX_M2M_PCI_PMON_CTL0 0x228 | ||
| 323 | #define SKX_M2M_PCI_PMON_CTR0 0x200 | ||
| 324 | #define SKX_M2M_PCI_PMON_BOX_CTL 0x258 | ||
| 325 | |||
| 267 | DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); | 326 | DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); |
| 268 | DEFINE_UNCORE_FORMAT_ATTR(event2, event, "config:0-6"); | 327 | DEFINE_UNCORE_FORMAT_ATTR(event2, event, "config:0-6"); |
| 269 | DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21"); | 328 | DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21"); |
| 270 | DEFINE_UNCORE_FORMAT_ATTR(use_occ_ctr, use_occ_ctr, "config:7"); | 329 | DEFINE_UNCORE_FORMAT_ATTR(use_occ_ctr, use_occ_ctr, "config:7"); |
| 271 | DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); | 330 | DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); |
| 331 | DEFINE_UNCORE_FORMAT_ATTR(umask_ext, umask, "config:8-15,32-39"); | ||
| 272 | DEFINE_UNCORE_FORMAT_ATTR(qor, qor, "config:16"); | 332 | DEFINE_UNCORE_FORMAT_ATTR(qor, qor, "config:16"); |
| 273 | DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); | 333 | DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); |
| 274 | DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19"); | 334 | DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19"); |
| 275 | DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23"); | 335 | DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23"); |
| 336 | DEFINE_UNCORE_FORMAT_ATTR(thresh9, thresh, "config:24-35"); | ||
| 276 | DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31"); | 337 | DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31"); |
| 277 | DEFINE_UNCORE_FORMAT_ATTR(thresh6, thresh, "config:24-29"); | 338 | DEFINE_UNCORE_FORMAT_ATTR(thresh6, thresh, "config:24-29"); |
| 278 | DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28"); | 339 | DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28"); |
| @@ -280,6 +341,8 @@ DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15"); | |||
| 280 | DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30"); | 341 | DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30"); |
| 281 | DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51"); | 342 | DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51"); |
| 282 | DEFINE_UNCORE_FORMAT_ATTR(occ_edge_det, occ_edge_det, "config:31"); | 343 | DEFINE_UNCORE_FORMAT_ATTR(occ_edge_det, occ_edge_det, "config:31"); |
| 344 | DEFINE_UNCORE_FORMAT_ATTR(ch_mask, ch_mask, "config:36-43"); | ||
| 345 | DEFINE_UNCORE_FORMAT_ATTR(fc_mask, fc_mask, "config:44-46"); | ||
| 283 | DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4"); | 346 | DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4"); |
| 284 | DEFINE_UNCORE_FORMAT_ATTR(filter_tid2, filter_tid, "config1:0"); | 347 | DEFINE_UNCORE_FORMAT_ATTR(filter_tid2, filter_tid, "config1:0"); |
| 285 | DEFINE_UNCORE_FORMAT_ATTR(filter_tid3, filter_tid, "config1:0-5"); | 348 | DEFINE_UNCORE_FORMAT_ATTR(filter_tid3, filter_tid, "config1:0-5"); |
| @@ -288,18 +351,26 @@ DEFINE_UNCORE_FORMAT_ATTR(filter_cid, filter_cid, "config1:5"); | |||
| 288 | DEFINE_UNCORE_FORMAT_ATTR(filter_link, filter_link, "config1:5-8"); | 351 | DEFINE_UNCORE_FORMAT_ATTR(filter_link, filter_link, "config1:5-8"); |
| 289 | DEFINE_UNCORE_FORMAT_ATTR(filter_link2, filter_link, "config1:6-8"); | 352 | DEFINE_UNCORE_FORMAT_ATTR(filter_link2, filter_link, "config1:6-8"); |
| 290 | DEFINE_UNCORE_FORMAT_ATTR(filter_link3, filter_link, "config1:12"); | 353 | DEFINE_UNCORE_FORMAT_ATTR(filter_link3, filter_link, "config1:12"); |
| 354 | DEFINE_UNCORE_FORMAT_ATTR(filter_link4, filter_link, "config1:9-12"); | ||
| 291 | DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17"); | 355 | DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17"); |
| 292 | DEFINE_UNCORE_FORMAT_ATTR(filter_nid2, filter_nid, "config1:32-47"); | 356 | DEFINE_UNCORE_FORMAT_ATTR(filter_nid2, filter_nid, "config1:32-47"); |
| 293 | DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22"); | 357 | DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22"); |
| 294 | DEFINE_UNCORE_FORMAT_ATTR(filter_state2, filter_state, "config1:17-22"); | 358 | DEFINE_UNCORE_FORMAT_ATTR(filter_state2, filter_state, "config1:17-22"); |
| 295 | DEFINE_UNCORE_FORMAT_ATTR(filter_state3, filter_state, "config1:17-23"); | 359 | DEFINE_UNCORE_FORMAT_ATTR(filter_state3, filter_state, "config1:17-23"); |
| 296 | DEFINE_UNCORE_FORMAT_ATTR(filter_state4, filter_state, "config1:18-20"); | 360 | DEFINE_UNCORE_FORMAT_ATTR(filter_state4, filter_state, "config1:18-20"); |
| 361 | DEFINE_UNCORE_FORMAT_ATTR(filter_state5, filter_state, "config1:17-26"); | ||
| 362 | DEFINE_UNCORE_FORMAT_ATTR(filter_rem, filter_rem, "config1:32"); | ||
| 363 | DEFINE_UNCORE_FORMAT_ATTR(filter_loc, filter_loc, "config1:33"); | ||
| 364 | DEFINE_UNCORE_FORMAT_ATTR(filter_nm, filter_nm, "config1:36"); | ||
| 365 | DEFINE_UNCORE_FORMAT_ATTR(filter_not_nm, filter_not_nm, "config1:37"); | ||
| 297 | DEFINE_UNCORE_FORMAT_ATTR(filter_local, filter_local, "config1:33"); | 366 | DEFINE_UNCORE_FORMAT_ATTR(filter_local, filter_local, "config1:33"); |
| 298 | DEFINE_UNCORE_FORMAT_ATTR(filter_all_op, filter_all_op, "config1:35"); | 367 | DEFINE_UNCORE_FORMAT_ATTR(filter_all_op, filter_all_op, "config1:35"); |
| 299 | DEFINE_UNCORE_FORMAT_ATTR(filter_nnm, filter_nnm, "config1:37"); | 368 | DEFINE_UNCORE_FORMAT_ATTR(filter_nnm, filter_nnm, "config1:37"); |
| 300 | DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31"); | 369 | DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31"); |
| 301 | DEFINE_UNCORE_FORMAT_ATTR(filter_opc2, filter_opc, "config1:52-60"); | 370 | DEFINE_UNCORE_FORMAT_ATTR(filter_opc2, filter_opc, "config1:52-60"); |
| 302 | DEFINE_UNCORE_FORMAT_ATTR(filter_opc3, filter_opc, "config1:41-60"); | 371 | DEFINE_UNCORE_FORMAT_ATTR(filter_opc3, filter_opc, "config1:41-60"); |
| 372 | DEFINE_UNCORE_FORMAT_ATTR(filter_opc_0, filter_opc0, "config1:41-50"); | ||
| 373 | DEFINE_UNCORE_FORMAT_ATTR(filter_opc_1, filter_opc1, "config1:51-60"); | ||
| 303 | DEFINE_UNCORE_FORMAT_ATTR(filter_nc, filter_nc, "config1:62"); | 374 | DEFINE_UNCORE_FORMAT_ATTR(filter_nc, filter_nc, "config1:62"); |
| 304 | DEFINE_UNCORE_FORMAT_ATTR(filter_c6, filter_c6, "config1:61"); | 375 | DEFINE_UNCORE_FORMAT_ATTR(filter_c6, filter_c6, "config1:61"); |
| 305 | DEFINE_UNCORE_FORMAT_ATTR(filter_isoc, filter_isoc, "config1:63"); | 376 | DEFINE_UNCORE_FORMAT_ATTR(filter_isoc, filter_isoc, "config1:63"); |
| @@ -1153,7 +1224,7 @@ static struct pci_driver snbep_uncore_pci_driver = { | |||
| 1153 | /* | 1224 | /* |
| 1154 | * build pci bus to socket mapping | 1225 | * build pci bus to socket mapping |
| 1155 | */ | 1226 | */ |
| 1156 | static int snbep_pci2phy_map_init(int devid) | 1227 | static int snbep_pci2phy_map_init(int devid, int nodeid_loc, int idmap_loc, bool reverse) |
| 1157 | { | 1228 | { |
| 1158 | struct pci_dev *ubox_dev = NULL; | 1229 | struct pci_dev *ubox_dev = NULL; |
| 1159 | int i, bus, nodeid, segment; | 1230 | int i, bus, nodeid, segment; |
| @@ -1168,12 +1239,12 @@ static int snbep_pci2phy_map_init(int devid) | |||
| 1168 | break; | 1239 | break; |
| 1169 | bus = ubox_dev->bus->number; | 1240 | bus = ubox_dev->bus->number; |
| 1170 | /* get the Node ID of the local register */ | 1241 | /* get the Node ID of the local register */ |
| 1171 | err = pci_read_config_dword(ubox_dev, 0x40, &config); | 1242 | err = pci_read_config_dword(ubox_dev, nodeid_loc, &config); |
| 1172 | if (err) | 1243 | if (err) |
| 1173 | break; | 1244 | break; |
| 1174 | nodeid = config; | 1245 | nodeid = config; |
| 1175 | /* get the Node ID mapping */ | 1246 | /* get the Node ID mapping */ |
| 1176 | err = pci_read_config_dword(ubox_dev, 0x54, &config); | 1247 | err = pci_read_config_dword(ubox_dev, idmap_loc, &config); |
| 1177 | if (err) | 1248 | if (err) |
| 1178 | break; | 1249 | break; |
| 1179 | 1250 | ||
| @@ -1207,11 +1278,20 @@ static int snbep_pci2phy_map_init(int devid) | |||
| 1207 | raw_spin_lock(&pci2phy_map_lock); | 1278 | raw_spin_lock(&pci2phy_map_lock); |
| 1208 | list_for_each_entry(map, &pci2phy_map_head, list) { | 1279 | list_for_each_entry(map, &pci2phy_map_head, list) { |
| 1209 | i = -1; | 1280 | i = -1; |
| 1210 | for (bus = 255; bus >= 0; bus--) { | 1281 | if (reverse) { |
| 1211 | if (map->pbus_to_physid[bus] >= 0) | 1282 | for (bus = 255; bus >= 0; bus--) { |
| 1212 | i = map->pbus_to_physid[bus]; | 1283 | if (map->pbus_to_physid[bus] >= 0) |
| 1213 | else | 1284 | i = map->pbus_to_physid[bus]; |
| 1214 | map->pbus_to_physid[bus] = i; | 1285 | else |
| 1286 | map->pbus_to_physid[bus] = i; | ||
| 1287 | } | ||
| 1288 | } else { | ||
| 1289 | for (bus = 0; bus <= 255; bus++) { | ||
| 1290 | if (map->pbus_to_physid[bus] >= 0) | ||
| 1291 | i = map->pbus_to_physid[bus]; | ||
| 1292 | else | ||
| 1293 | map->pbus_to_physid[bus] = i; | ||
| 1294 | } | ||
| 1215 | } | 1295 | } |
| 1216 | } | 1296 | } |
| 1217 | raw_spin_unlock(&pci2phy_map_lock); | 1297 | raw_spin_unlock(&pci2phy_map_lock); |
| @@ -1224,7 +1304,7 @@ static int snbep_pci2phy_map_init(int devid) | |||
| 1224 | 1304 | ||
| 1225 | int snbep_uncore_pci_init(void) | 1305 | int snbep_uncore_pci_init(void) |
| 1226 | { | 1306 | { |
| 1227 | int ret = snbep_pci2phy_map_init(0x3ce0); | 1307 | int ret = snbep_pci2phy_map_init(0x3ce0, SNBEP_CPUNODEID, SNBEP_GIDNIDMAP, true); |
| 1228 | if (ret) | 1308 | if (ret) |
| 1229 | return ret; | 1309 | return ret; |
| 1230 | uncore_pci_uncores = snbep_pci_uncores; | 1310 | uncore_pci_uncores = snbep_pci_uncores; |
| @@ -1788,7 +1868,7 @@ static struct pci_driver ivbep_uncore_pci_driver = { | |||
| 1788 | 1868 | ||
| 1789 | int ivbep_uncore_pci_init(void) | 1869 | int ivbep_uncore_pci_init(void) |
| 1790 | { | 1870 | { |
| 1791 | int ret = snbep_pci2phy_map_init(0x0e1e); | 1871 | int ret = snbep_pci2phy_map_init(0x0e1e, SNBEP_CPUNODEID, SNBEP_GIDNIDMAP, true); |
| 1792 | if (ret) | 1872 | if (ret) |
| 1793 | return ret; | 1873 | return ret; |
| 1794 | uncore_pci_uncores = ivbep_pci_uncores; | 1874 | uncore_pci_uncores = ivbep_pci_uncores; |
| @@ -2897,7 +2977,7 @@ static struct pci_driver hswep_uncore_pci_driver = { | |||
| 2897 | 2977 | ||
| 2898 | int hswep_uncore_pci_init(void) | 2978 | int hswep_uncore_pci_init(void) |
| 2899 | { | 2979 | { |
| 2900 | int ret = snbep_pci2phy_map_init(0x2f1e); | 2980 | int ret = snbep_pci2phy_map_init(0x2f1e, SNBEP_CPUNODEID, SNBEP_GIDNIDMAP, true); |
| 2901 | if (ret) | 2981 | if (ret) |
| 2902 | return ret; | 2982 | return ret; |
| 2903 | uncore_pci_uncores = hswep_pci_uncores; | 2983 | uncore_pci_uncores = hswep_pci_uncores; |
| @@ -3186,7 +3266,7 @@ static struct pci_driver bdx_uncore_pci_driver = { | |||
| 3186 | 3266 | ||
| 3187 | int bdx_uncore_pci_init(void) | 3267 | int bdx_uncore_pci_init(void) |
| 3188 | { | 3268 | { |
| 3189 | int ret = snbep_pci2phy_map_init(0x6f1e); | 3269 | int ret = snbep_pci2phy_map_init(0x6f1e, SNBEP_CPUNODEID, SNBEP_GIDNIDMAP, true); |
| 3190 | 3270 | ||
| 3191 | if (ret) | 3271 | if (ret) |
| 3192 | return ret; | 3272 | return ret; |
| @@ -3196,3 +3276,525 @@ int bdx_uncore_pci_init(void) | |||
| 3196 | } | 3276 | } |
| 3197 | 3277 | ||
| 3198 | /* end of BDX uncore support */ | 3278 | /* end of BDX uncore support */ |
| 3279 | |||
| 3280 | /* SKX uncore support */ | ||
| 3281 | |||
| 3282 | static struct intel_uncore_type skx_uncore_ubox = { | ||
| 3283 | .name = "ubox", | ||
| 3284 | .num_counters = 2, | ||
| 3285 | .num_boxes = 1, | ||
| 3286 | .perf_ctr_bits = 48, | ||
| 3287 | .fixed_ctr_bits = 48, | ||
| 3288 | .perf_ctr = HSWEP_U_MSR_PMON_CTR0, | ||
| 3289 | .event_ctl = HSWEP_U_MSR_PMON_CTL0, | ||
| 3290 | .event_mask = SNBEP_U_MSR_PMON_RAW_EVENT_MASK, | ||
| 3291 | .fixed_ctr = HSWEP_U_MSR_PMON_UCLK_FIXED_CTR, | ||
| 3292 | .fixed_ctl = HSWEP_U_MSR_PMON_UCLK_FIXED_CTL, | ||
| 3293 | .ops = &ivbep_uncore_msr_ops, | ||
| 3294 | .format_group = &ivbep_uncore_ubox_format_group, | ||
| 3295 | }; | ||
| 3296 | |||
| 3297 | static struct attribute *skx_uncore_cha_formats_attr[] = { | ||
| 3298 | &format_attr_event.attr, | ||
| 3299 | &format_attr_umask.attr, | ||
| 3300 | &format_attr_edge.attr, | ||
| 3301 | &format_attr_tid_en.attr, | ||
| 3302 | &format_attr_inv.attr, | ||
| 3303 | &format_attr_thresh8.attr, | ||
| 3304 | &format_attr_filter_tid4.attr, | ||
| 3305 | &format_attr_filter_link4.attr, | ||
| 3306 | &format_attr_filter_state5.attr, | ||
| 3307 | &format_attr_filter_rem.attr, | ||
| 3308 | &format_attr_filter_loc.attr, | ||
| 3309 | &format_attr_filter_nm.attr, | ||
| 3310 | &format_attr_filter_all_op.attr, | ||
| 3311 | &format_attr_filter_not_nm.attr, | ||
| 3312 | &format_attr_filter_opc_0.attr, | ||
| 3313 | &format_attr_filter_opc_1.attr, | ||
| 3314 | &format_attr_filter_nc.attr, | ||
| 3315 | &format_attr_filter_c6.attr, | ||
| 3316 | &format_attr_filter_isoc.attr, | ||
| 3317 | NULL, | ||
| 3318 | }; | ||
| 3319 | |||
| 3320 | static struct attribute_group skx_uncore_chabox_format_group = { | ||
| 3321 | .name = "format", | ||
| 3322 | .attrs = skx_uncore_cha_formats_attr, | ||
| 3323 | }; | ||
| 3324 | |||
| 3325 | static struct event_constraint skx_uncore_chabox_constraints[] = { | ||
| 3326 | UNCORE_EVENT_CONSTRAINT(0x11, 0x1), | ||
| 3327 | UNCORE_EVENT_CONSTRAINT(0x36, 0x1), | ||
| 3328 | EVENT_CONSTRAINT_END | ||
| 3329 | }; | ||
| 3330 | |||
| 3331 | static struct extra_reg skx_uncore_cha_extra_regs[] = { | ||
| 3332 | SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), | ||
| 3333 | SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), | ||
| 3334 | SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), | ||
| 3335 | SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4), | ||
| 3336 | SNBEP_CBO_EVENT_EXTRA_REG(0x2134, 0xffff, 0x4), | ||
| 3337 | SNBEP_CBO_EVENT_EXTRA_REG(0x8134, 0xffff, 0x4), | ||
| 3338 | }; | ||
| 3339 | |||
| 3340 | static u64 skx_cha_filter_mask(int fields) | ||
| 3341 | { | ||
| 3342 | u64 mask = 0; | ||
| 3343 | |||
| 3344 | if (fields & 0x1) | ||
| 3345 | mask |= SKX_CHA_MSR_PMON_BOX_FILTER_TID; | ||
| 3346 | if (fields & 0x2) | ||
| 3347 | mask |= SKX_CHA_MSR_PMON_BOX_FILTER_LINK; | ||
| 3348 | if (fields & 0x4) | ||
| 3349 | mask |= SKX_CHA_MSR_PMON_BOX_FILTER_STATE; | ||
| 3350 | return mask; | ||
| 3351 | } | ||
| 3352 | |||
| 3353 | static struct event_constraint * | ||
| 3354 | skx_cha_get_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
| 3355 | { | ||
| 3356 | return __snbep_cbox_get_constraint(box, event, skx_cha_filter_mask); | ||
| 3357 | } | ||
| 3358 | |||
| 3359 | static int skx_cha_hw_config(struct intel_uncore_box *box, struct perf_event *event) | ||
| 3360 | { | ||
| 3361 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
| 3362 | struct extra_reg *er; | ||
| 3363 | int idx = 0; | ||
| 3364 | |||
| 3365 | for (er = skx_uncore_cha_extra_regs; er->msr; er++) { | ||
| 3366 | if (er->event != (event->hw.config & er->config_mask)) | ||
| 3367 | continue; | ||
| 3368 | idx |= er->idx; | ||
| 3369 | } | ||
| 3370 | |||
| 3371 | if (idx) { | ||
| 3372 | reg1->reg = HSWEP_C0_MSR_PMON_BOX_FILTER0 + | ||
| 3373 | HSWEP_CBO_MSR_OFFSET * box->pmu->pmu_idx; | ||
| 3374 | reg1->config = event->attr.config1 & skx_cha_filter_mask(idx); | ||
| 3375 | reg1->idx = idx; | ||
| 3376 | } | ||
| 3377 | return 0; | ||
| 3378 | } | ||
| 3379 | |||
| 3380 | static struct intel_uncore_ops skx_uncore_chabox_ops = { | ||
| 3381 | /* There is no frz_en for chabox ctl */ | ||
| 3382 | .init_box = ivbep_uncore_msr_init_box, | ||
| 3383 | .disable_box = snbep_uncore_msr_disable_box, | ||
| 3384 | .enable_box = snbep_uncore_msr_enable_box, | ||
| 3385 | .disable_event = snbep_uncore_msr_disable_event, | ||
| 3386 | .enable_event = hswep_cbox_enable_event, | ||
| 3387 | .read_counter = uncore_msr_read_counter, | ||
| 3388 | .hw_config = skx_cha_hw_config, | ||
| 3389 | .get_constraint = skx_cha_get_constraint, | ||
| 3390 | .put_constraint = snbep_cbox_put_constraint, | ||
| 3391 | }; | ||
| 3392 | |||
| 3393 | static struct intel_uncore_type skx_uncore_chabox = { | ||
| 3394 | .name = "cha", | ||
| 3395 | .num_counters = 4, | ||
| 3396 | .perf_ctr_bits = 48, | ||
| 3397 | .event_ctl = HSWEP_C0_MSR_PMON_CTL0, | ||
| 3398 | .perf_ctr = HSWEP_C0_MSR_PMON_CTR0, | ||
| 3399 | .event_mask = HSWEP_S_MSR_PMON_RAW_EVENT_MASK, | ||
| 3400 | .box_ctl = HSWEP_C0_MSR_PMON_BOX_CTL, | ||
| 3401 | .msr_offset = HSWEP_CBO_MSR_OFFSET, | ||
| 3402 | .num_shared_regs = 1, | ||
| 3403 | .constraints = skx_uncore_chabox_constraints, | ||
| 3404 | .ops = &skx_uncore_chabox_ops, | ||
| 3405 | .format_group = &skx_uncore_chabox_format_group, | ||
| 3406 | }; | ||
| 3407 | |||
| 3408 | static struct attribute *skx_uncore_iio_formats_attr[] = { | ||
| 3409 | &format_attr_event.attr, | ||
| 3410 | &format_attr_umask.attr, | ||
| 3411 | &format_attr_edge.attr, | ||
| 3412 | &format_attr_inv.attr, | ||
| 3413 | &format_attr_thresh9.attr, | ||
| 3414 | &format_attr_ch_mask.attr, | ||
| 3415 | &format_attr_fc_mask.attr, | ||
| 3416 | NULL, | ||
| 3417 | }; | ||
| 3418 | |||
| 3419 | static struct attribute_group skx_uncore_iio_format_group = { | ||
| 3420 | .name = "format", | ||
| 3421 | .attrs = skx_uncore_iio_formats_attr, | ||
| 3422 | }; | ||
| 3423 | |||
| 3424 | static struct event_constraint skx_uncore_iio_constraints[] = { | ||
| 3425 | UNCORE_EVENT_CONSTRAINT(0x83, 0x3), | ||
| 3426 | UNCORE_EVENT_CONSTRAINT(0x88, 0xc), | ||
| 3427 | UNCORE_EVENT_CONSTRAINT(0x95, 0xc), | ||
| 3428 | UNCORE_EVENT_CONSTRAINT(0xc0, 0xc), | ||
| 3429 | UNCORE_EVENT_CONSTRAINT(0xc5, 0xc), | ||
| 3430 | UNCORE_EVENT_CONSTRAINT(0xd4, 0xc), | ||
| 3431 | EVENT_CONSTRAINT_END | ||
| 3432 | }; | ||
| 3433 | |||
| 3434 | static void skx_iio_enable_event(struct intel_uncore_box *box, | ||
| 3435 | struct perf_event *event) | ||
| 3436 | { | ||
| 3437 | struct hw_perf_event *hwc = &event->hw; | ||
| 3438 | |||
| 3439 | wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); | ||
| 3440 | } | ||
| 3441 | |||
| 3442 | static struct intel_uncore_ops skx_uncore_iio_ops = { | ||
| 3443 | .init_box = ivbep_uncore_msr_init_box, | ||
| 3444 | .disable_box = snbep_uncore_msr_disable_box, | ||
| 3445 | .enable_box = snbep_uncore_msr_enable_box, | ||
| 3446 | .disable_event = snbep_uncore_msr_disable_event, | ||
| 3447 | .enable_event = skx_iio_enable_event, | ||
| 3448 | .read_counter = uncore_msr_read_counter, | ||
| 3449 | }; | ||
| 3450 | |||
| 3451 | static struct intel_uncore_type skx_uncore_iio = { | ||
| 3452 | .name = "iio", | ||
| 3453 | .num_counters = 4, | ||
| 3454 | .num_boxes = 5, | ||
| 3455 | .perf_ctr_bits = 48, | ||
| 3456 | .event_ctl = SKX_IIO0_MSR_PMON_CTL0, | ||
| 3457 | .perf_ctr = SKX_IIO0_MSR_PMON_CTR0, | ||
| 3458 | .event_mask = SKX_IIO_PMON_RAW_EVENT_MASK, | ||
| 3459 | .event_mask_ext = SKX_IIO_PMON_RAW_EVENT_MASK_EXT, | ||
| 3460 | .box_ctl = SKX_IIO0_MSR_PMON_BOX_CTL, | ||
| 3461 | .msr_offset = SKX_IIO_MSR_OFFSET, | ||
| 3462 | .constraints = skx_uncore_iio_constraints, | ||
| 3463 | .ops = &skx_uncore_iio_ops, | ||
| 3464 | .format_group = &skx_uncore_iio_format_group, | ||
| 3465 | }; | ||
| 3466 | |||
| 3467 | static struct attribute *skx_uncore_formats_attr[] = { | ||
| 3468 | &format_attr_event.attr, | ||
| 3469 | &format_attr_umask.attr, | ||
| 3470 | &format_attr_edge.attr, | ||
| 3471 | &format_attr_inv.attr, | ||
| 3472 | &format_attr_thresh8.attr, | ||
| 3473 | NULL, | ||
| 3474 | }; | ||
| 3475 | |||
| 3476 | static struct attribute_group skx_uncore_format_group = { | ||
| 3477 | .name = "format", | ||
| 3478 | .attrs = skx_uncore_formats_attr, | ||
| 3479 | }; | ||
| 3480 | |||
| 3481 | static struct intel_uncore_type skx_uncore_irp = { | ||
| 3482 | .name = "irp", | ||
| 3483 | .num_counters = 2, | ||
| 3484 | .num_boxes = 5, | ||
| 3485 | .perf_ctr_bits = 48, | ||
| 3486 | .event_ctl = SKX_IRP0_MSR_PMON_CTL0, | ||
| 3487 | .perf_ctr = SKX_IRP0_MSR_PMON_CTR0, | ||
| 3488 | .event_mask = SNBEP_PMON_RAW_EVENT_MASK, | ||
| 3489 | .box_ctl = SKX_IRP0_MSR_PMON_BOX_CTL, | ||
| 3490 | .msr_offset = SKX_IRP_MSR_OFFSET, | ||
| 3491 | .ops = &skx_uncore_iio_ops, | ||
| 3492 | .format_group = &skx_uncore_format_group, | ||
| 3493 | }; | ||
| 3494 | |||
| 3495 | static struct intel_uncore_ops skx_uncore_pcu_ops = { | ||
| 3496 | IVBEP_UNCORE_MSR_OPS_COMMON_INIT(), | ||
| 3497 | .hw_config = hswep_pcu_hw_config, | ||
| 3498 | .get_constraint = snbep_pcu_get_constraint, | ||
| 3499 | .put_constraint = snbep_pcu_put_constraint, | ||
| 3500 | }; | ||
| 3501 | |||
| 3502 | static struct intel_uncore_type skx_uncore_pcu = { | ||
| 3503 | .name = "pcu", | ||
| 3504 | .num_counters = 4, | ||
| 3505 | .num_boxes = 1, | ||
| 3506 | .perf_ctr_bits = 48, | ||
| 3507 | .perf_ctr = HSWEP_PCU_MSR_PMON_CTR0, | ||
| 3508 | .event_ctl = HSWEP_PCU_MSR_PMON_CTL0, | ||
| 3509 | .event_mask = SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK, | ||
| 3510 | .box_ctl = HSWEP_PCU_MSR_PMON_BOX_CTL, | ||
| 3511 | .num_shared_regs = 1, | ||
| 3512 | .ops = &skx_uncore_pcu_ops, | ||
| 3513 | .format_group = &snbep_uncore_pcu_format_group, | ||
| 3514 | }; | ||
| 3515 | |||
| 3516 | static struct intel_uncore_type *skx_msr_uncores[] = { | ||
| 3517 | &skx_uncore_ubox, | ||
| 3518 | &skx_uncore_chabox, | ||
| 3519 | &skx_uncore_iio, | ||
| 3520 | &skx_uncore_irp, | ||
| 3521 | &skx_uncore_pcu, | ||
| 3522 | NULL, | ||
| 3523 | }; | ||
| 3524 | |||
| 3525 | static int skx_count_chabox(void) | ||
| 3526 | { | ||
| 3527 | struct pci_dev *chabox_dev = NULL; | ||
| 3528 | int bus, count = 0; | ||
| 3529 | |||
| 3530 | while (1) { | ||
| 3531 | chabox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x208d, chabox_dev); | ||
| 3532 | if (!chabox_dev) | ||
| 3533 | break; | ||
| 3534 | if (count == 0) | ||
| 3535 | bus = chabox_dev->bus->number; | ||
| 3536 | if (bus != chabox_dev->bus->number) | ||
| 3537 | break; | ||
| 3538 | count++; | ||
| 3539 | } | ||
| 3540 | |||
| 3541 | pci_dev_put(chabox_dev); | ||
| 3542 | return count; | ||
| 3543 | } | ||
| 3544 | |||
| 3545 | void skx_uncore_cpu_init(void) | ||
| 3546 | { | ||
| 3547 | skx_uncore_chabox.num_boxes = skx_count_chabox(); | ||
| 3548 | uncore_msr_uncores = skx_msr_uncores; | ||
| 3549 | } | ||
| 3550 | |||
| 3551 | static struct intel_uncore_type skx_uncore_imc = { | ||
| 3552 | .name = "imc", | ||
| 3553 | .num_counters = 4, | ||
| 3554 | .num_boxes = 6, | ||
| 3555 | .perf_ctr_bits = 48, | ||
| 3556 | .fixed_ctr_bits = 48, | ||
| 3557 | .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR, | ||
| 3558 | .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL, | ||
| 3559 | .event_descs = hswep_uncore_imc_events, | ||
| 3560 | .perf_ctr = SNBEP_PCI_PMON_CTR0, | ||
| 3561 | .event_ctl = SNBEP_PCI_PMON_CTL0, | ||
| 3562 | .event_mask = SNBEP_PMON_RAW_EVENT_MASK, | ||
| 3563 | .box_ctl = SNBEP_PCI_PMON_BOX_CTL, | ||
| 3564 | .ops = &ivbep_uncore_pci_ops, | ||
| 3565 | .format_group = &skx_uncore_format_group, | ||
| 3566 | }; | ||
| 3567 | |||
| 3568 | static struct attribute *skx_upi_uncore_formats_attr[] = { | ||
| 3569 | &format_attr_event_ext.attr, | ||
| 3570 | &format_attr_umask_ext.attr, | ||
| 3571 | &format_attr_edge.attr, | ||
| 3572 | &format_attr_inv.attr, | ||
| 3573 | &format_attr_thresh8.attr, | ||
| 3574 | NULL, | ||
| 3575 | }; | ||
| 3576 | |||
| 3577 | static struct attribute_group skx_upi_uncore_format_group = { | ||
| 3578 | .name = "format", | ||
| 3579 | .attrs = skx_upi_uncore_formats_attr, | ||
| 3580 | }; | ||
| 3581 | |||
| 3582 | static void skx_upi_uncore_pci_init_box(struct intel_uncore_box *box) | ||
| 3583 | { | ||
| 3584 | struct pci_dev *pdev = box->pci_dev; | ||
| 3585 | |||
| 3586 | __set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags); | ||
| 3587 | pci_write_config_dword(pdev, SKX_UPI_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT); | ||
| 3588 | } | ||
| 3589 | |||
| 3590 | static struct intel_uncore_ops skx_upi_uncore_pci_ops = { | ||
| 3591 | .init_box = skx_upi_uncore_pci_init_box, | ||
| 3592 | .disable_box = snbep_uncore_pci_disable_box, | ||
| 3593 | .enable_box = snbep_uncore_pci_enable_box, | ||
| 3594 | .disable_event = snbep_uncore_pci_disable_event, | ||
| 3595 | .enable_event = snbep_uncore_pci_enable_event, | ||
| 3596 | .read_counter = snbep_uncore_pci_read_counter, | ||
| 3597 | }; | ||
| 3598 | |||
| 3599 | static struct intel_uncore_type skx_uncore_upi = { | ||
| 3600 | .name = "upi", | ||
| 3601 | .num_counters = 4, | ||
| 3602 | .num_boxes = 3, | ||
| 3603 | .perf_ctr_bits = 48, | ||
| 3604 | .perf_ctr = SKX_UPI_PCI_PMON_CTR0, | ||
| 3605 | .event_ctl = SKX_UPI_PCI_PMON_CTL0, | ||
| 3606 | .event_mask = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK, | ||
| 3607 | .event_mask_ext = SKX_PMON_CTL_UMASK_EXT, | ||
| 3608 | .box_ctl = SKX_UPI_PCI_PMON_BOX_CTL, | ||
| 3609 | .ops = &skx_upi_uncore_pci_ops, | ||
| 3610 | .format_group = &skx_upi_uncore_format_group, | ||
| 3611 | }; | ||
| 3612 | |||
| 3613 | static void skx_m2m_uncore_pci_init_box(struct intel_uncore_box *box) | ||
| 3614 | { | ||
| 3615 | struct pci_dev *pdev = box->pci_dev; | ||
| 3616 | |||
| 3617 | __set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags); | ||
| 3618 | pci_write_config_dword(pdev, SKX_M2M_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT); | ||
| 3619 | } | ||
| 3620 | |||
| 3621 | static struct intel_uncore_ops skx_m2m_uncore_pci_ops = { | ||
| 3622 | .init_box = skx_m2m_uncore_pci_init_box, | ||
| 3623 | .disable_box = snbep_uncore_pci_disable_box, | ||
| 3624 | .enable_box = snbep_uncore_pci_enable_box, | ||
| 3625 | .disable_event = snbep_uncore_pci_disable_event, | ||
| 3626 | .enable_event = snbep_uncore_pci_enable_event, | ||
| 3627 | .read_counter = snbep_uncore_pci_read_counter, | ||
| 3628 | }; | ||
| 3629 | |||
| 3630 | static struct intel_uncore_type skx_uncore_m2m = { | ||
| 3631 | .name = "m2m", | ||
| 3632 | .num_counters = 4, | ||
| 3633 | .num_boxes = 2, | ||
| 3634 | .perf_ctr_bits = 48, | ||
| 3635 | .perf_ctr = SKX_M2M_PCI_PMON_CTR0, | ||
| 3636 | .event_ctl = SKX_M2M_PCI_PMON_CTL0, | ||
| 3637 | .event_mask = SNBEP_PMON_RAW_EVENT_MASK, | ||
| 3638 | .box_ctl = SKX_M2M_PCI_PMON_BOX_CTL, | ||
| 3639 | .ops = &skx_m2m_uncore_pci_ops, | ||
| 3640 | .format_group = &skx_uncore_format_group, | ||
| 3641 | }; | ||
| 3642 | |||
| 3643 | static struct event_constraint skx_uncore_m2pcie_constraints[] = { | ||
| 3644 | UNCORE_EVENT_CONSTRAINT(0x23, 0x3), | ||
| 3645 | EVENT_CONSTRAINT_END | ||
| 3646 | }; | ||
| 3647 | |||
| 3648 | static struct intel_uncore_type skx_uncore_m2pcie = { | ||
| 3649 | .name = "m2pcie", | ||
| 3650 | .num_counters = 4, | ||
| 3651 | .num_boxes = 4, | ||
| 3652 | .perf_ctr_bits = 48, | ||
| 3653 | .constraints = skx_uncore_m2pcie_constraints, | ||
| 3654 | .perf_ctr = SNBEP_PCI_PMON_CTR0, | ||
| 3655 | .event_ctl = SNBEP_PCI_PMON_CTL0, | ||
| 3656 | .event_mask = SNBEP_PMON_RAW_EVENT_MASK, | ||
| 3657 | .box_ctl = SNBEP_PCI_PMON_BOX_CTL, | ||
| 3658 | .ops = &ivbep_uncore_pci_ops, | ||
| 3659 | .format_group = &skx_uncore_format_group, | ||
| 3660 | }; | ||
| 3661 | |||
| 3662 | static struct event_constraint skx_uncore_m3upi_constraints[] = { | ||
| 3663 | UNCORE_EVENT_CONSTRAINT(0x1d, 0x1), | ||
| 3664 | UNCORE_EVENT_CONSTRAINT(0x1e, 0x1), | ||
| 3665 | UNCORE_EVENT_CONSTRAINT(0x40, 0x7), | ||
| 3666 | UNCORE_EVENT_CONSTRAINT(0x4e, 0x7), | ||
| 3667 | UNCORE_EVENT_CONSTRAINT(0x4f, 0x7), | ||
| 3668 | UNCORE_EVENT_CONSTRAINT(0x50, 0x7), | ||
| 3669 | UNCORE_EVENT_CONSTRAINT(0x51, 0x7), | ||
| 3670 | UNCORE_EVENT_CONSTRAINT(0x52, 0x7), | ||
| 3671 | EVENT_CONSTRAINT_END | ||
| 3672 | }; | ||
| 3673 | |||
| 3674 | static struct intel_uncore_type skx_uncore_m3upi = { | ||
| 3675 | .name = "m3upi", | ||
| 3676 | .num_counters = 3, | ||
| 3677 | .num_boxes = 3, | ||
| 3678 | .perf_ctr_bits = 48, | ||
| 3679 | .constraints = skx_uncore_m3upi_constraints, | ||
| 3680 | .perf_ctr = SNBEP_PCI_PMON_CTR0, | ||
| 3681 | .event_ctl = SNBEP_PCI_PMON_CTL0, | ||
| 3682 | .event_mask = SNBEP_PMON_RAW_EVENT_MASK, | ||
| 3683 | .box_ctl = SNBEP_PCI_PMON_BOX_CTL, | ||
| 3684 | .ops = &ivbep_uncore_pci_ops, | ||
| 3685 | .format_group = &skx_uncore_format_group, | ||
| 3686 | }; | ||
| 3687 | |||
| 3688 | enum { | ||
| 3689 | SKX_PCI_UNCORE_IMC, | ||
| 3690 | SKX_PCI_UNCORE_M2M, | ||
| 3691 | SKX_PCI_UNCORE_UPI, | ||
| 3692 | SKX_PCI_UNCORE_M2PCIE, | ||
| 3693 | SKX_PCI_UNCORE_M3UPI, | ||
| 3694 | }; | ||
| 3695 | |||
| 3696 | static struct intel_uncore_type *skx_pci_uncores[] = { | ||
| 3697 | [SKX_PCI_UNCORE_IMC] = &skx_uncore_imc, | ||
| 3698 | [SKX_PCI_UNCORE_M2M] = &skx_uncore_m2m, | ||
| 3699 | [SKX_PCI_UNCORE_UPI] = &skx_uncore_upi, | ||
| 3700 | [SKX_PCI_UNCORE_M2PCIE] = &skx_uncore_m2pcie, | ||
| 3701 | [SKX_PCI_UNCORE_M3UPI] = &skx_uncore_m3upi, | ||
| 3702 | NULL, | ||
| 3703 | }; | ||
| 3704 | |||
| 3705 | static const struct pci_device_id skx_uncore_pci_ids[] = { | ||
| 3706 | { /* MC0 Channel 0 */ | ||
| 3707 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2042), | ||
| 3708 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(10, 2, SKX_PCI_UNCORE_IMC, 0), | ||
| 3709 | }, | ||
| 3710 | { /* MC0 Channel 1 */ | ||
| 3711 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2046), | ||
| 3712 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(10, 6, SKX_PCI_UNCORE_IMC, 1), | ||
| 3713 | }, | ||
| 3714 | { /* MC0 Channel 2 */ | ||
| 3715 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204a), | ||
| 3716 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(11, 2, SKX_PCI_UNCORE_IMC, 2), | ||
| 3717 | }, | ||
| 3718 | { /* MC1 Channel 0 */ | ||
| 3719 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2042), | ||
| 3720 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 2, SKX_PCI_UNCORE_IMC, 3), | ||
| 3721 | }, | ||
| 3722 | { /* MC1 Channel 1 */ | ||
| 3723 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2046), | ||
| 3724 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 6, SKX_PCI_UNCORE_IMC, 4), | ||
| 3725 | }, | ||
| 3726 | { /* MC1 Channel 2 */ | ||
| 3727 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204a), | ||
| 3728 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(13, 2, SKX_PCI_UNCORE_IMC, 5), | ||
| 3729 | }, | ||
| 3730 | { /* M2M0 */ | ||
| 3731 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2066), | ||
| 3732 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(8, 0, SKX_PCI_UNCORE_M2M, 0), | ||
| 3733 | }, | ||
| 3734 | { /* M2M1 */ | ||
| 3735 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2066), | ||
| 3736 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(9, 0, SKX_PCI_UNCORE_M2M, 1), | ||
| 3737 | }, | ||
| 3738 | { /* UPI0 Link 0 */ | ||
| 3739 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2058), | ||
| 3740 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(14, 0, SKX_PCI_UNCORE_UPI, 0), | ||
| 3741 | }, | ||
| 3742 | { /* UPI0 Link 1 */ | ||
| 3743 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2058), | ||
| 3744 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(15, 0, SKX_PCI_UNCORE_UPI, 1), | ||
| 3745 | }, | ||
| 3746 | { /* UPI1 Link 2 */ | ||
| 3747 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2058), | ||
| 3748 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(16, 0, SKX_PCI_UNCORE_UPI, 2), | ||
| 3749 | }, | ||
| 3750 | { /* M2PCIe 0 */ | ||
| 3751 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2088), | ||
| 3752 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(21, 1, SKX_PCI_UNCORE_M2PCIE, 0), | ||
| 3753 | }, | ||
| 3754 | { /* M2PCIe 1 */ | ||
| 3755 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2088), | ||
| 3756 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(22, 1, SKX_PCI_UNCORE_M2PCIE, 1), | ||
| 3757 | }, | ||
| 3758 | { /* M2PCIe 2 */ | ||
| 3759 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2088), | ||
| 3760 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(23, 1, SKX_PCI_UNCORE_M2PCIE, 2), | ||
| 3761 | }, | ||
| 3762 | { /* M2PCIe 3 */ | ||
| 3763 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2088), | ||
| 3764 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(21, 5, SKX_PCI_UNCORE_M2PCIE, 3), | ||
| 3765 | }, | ||
| 3766 | { /* M3UPI0 Link 0 */ | ||
| 3767 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204C), | ||
| 3768 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 0, SKX_PCI_UNCORE_M3UPI, 0), | ||
| 3769 | }, | ||
| 3770 | { /* M3UPI0 Link 1 */ | ||
| 3771 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204D), | ||
| 3772 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 1, SKX_PCI_UNCORE_M3UPI, 1), | ||
| 3773 | }, | ||
| 3774 | { /* M3UPI1 Link 2 */ | ||
| 3775 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204C), | ||
| 3776 | .driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 4, SKX_PCI_UNCORE_M3UPI, 2), | ||
| 3777 | }, | ||
| 3778 | { /* end: all zeroes */ } | ||
| 3779 | }; | ||
| 3780 | |||
| 3781 | |||
| 3782 | static struct pci_driver skx_uncore_pci_driver = { | ||
| 3783 | .name = "skx_uncore", | ||
| 3784 | .id_table = skx_uncore_pci_ids, | ||
| 3785 | }; | ||
| 3786 | |||
| 3787 | int skx_uncore_pci_init(void) | ||
| 3788 | { | ||
| 3789 | /* need to double check pci address */ | ||
| 3790 | int ret = snbep_pci2phy_map_init(0x2014, SKX_CPUNODEID, SKX_GIDNIDMAP, false); | ||
| 3791 | |||
| 3792 | if (ret) | ||
| 3793 | return ret; | ||
| 3794 | |||
| 3795 | uncore_pci_uncores = skx_pci_uncores; | ||
| 3796 | uncore_pci_driver = &skx_uncore_pci_driver; | ||
| 3797 | return 0; | ||
| 3798 | } | ||
| 3799 | |||
| 3800 | /* end of SKX uncore support */ | ||
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 8c4a47706296..5874d8de1f8d 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h | |||
| @@ -194,12 +194,13 @@ struct cpu_hw_events { | |||
| 194 | */ | 194 | */ |
| 195 | struct debug_store *ds; | 195 | struct debug_store *ds; |
| 196 | u64 pebs_enabled; | 196 | u64 pebs_enabled; |
| 197 | int n_pebs; | ||
| 198 | int n_large_pebs; | ||
| 197 | 199 | ||
| 198 | /* | 200 | /* |
| 199 | * Intel LBR bits | 201 | * Intel LBR bits |
| 200 | */ | 202 | */ |
| 201 | int lbr_users; | 203 | int lbr_users; |
| 202 | void *lbr_context; | ||
| 203 | struct perf_branch_stack lbr_stack; | 204 | struct perf_branch_stack lbr_stack; |
| 204 | struct perf_branch_entry lbr_entries[MAX_LBR_ENTRIES]; | 205 | struct perf_branch_entry lbr_entries[MAX_LBR_ENTRIES]; |
| 205 | struct er_account *lbr_sel; | 206 | struct er_account *lbr_sel; |
| @@ -508,6 +509,8 @@ struct x86_pmu { | |||
| 508 | void (*enable_all)(int added); | 509 | void (*enable_all)(int added); |
| 509 | void (*enable)(struct perf_event *); | 510 | void (*enable)(struct perf_event *); |
| 510 | void (*disable)(struct perf_event *); | 511 | void (*disable)(struct perf_event *); |
| 512 | void (*add)(struct perf_event *); | ||
| 513 | void (*del)(struct perf_event *); | ||
| 511 | int (*hw_config)(struct perf_event *event); | 514 | int (*hw_config)(struct perf_event *event); |
| 512 | int (*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign); | 515 | int (*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign); |
| 513 | unsigned eventsel; | 516 | unsigned eventsel; |
| @@ -888,6 +891,10 @@ extern struct event_constraint intel_skl_pebs_event_constraints[]; | |||
| 888 | 891 | ||
| 889 | struct event_constraint *intel_pebs_constraints(struct perf_event *event); | 892 | struct event_constraint *intel_pebs_constraints(struct perf_event *event); |
| 890 | 893 | ||
| 894 | void intel_pmu_pebs_add(struct perf_event *event); | ||
| 895 | |||
| 896 | void intel_pmu_pebs_del(struct perf_event *event); | ||
| 897 | |||
| 891 | void intel_pmu_pebs_enable(struct perf_event *event); | 898 | void intel_pmu_pebs_enable(struct perf_event *event); |
| 892 | 899 | ||
| 893 | void intel_pmu_pebs_disable(struct perf_event *event); | 900 | void intel_pmu_pebs_disable(struct perf_event *event); |
| @@ -906,9 +913,9 @@ u64 lbr_from_signext_quirk_wr(u64 val); | |||
| 906 | 913 | ||
| 907 | void intel_pmu_lbr_reset(void); | 914 | void intel_pmu_lbr_reset(void); |
| 908 | 915 | ||
| 909 | void intel_pmu_lbr_enable(struct perf_event *event); | 916 | void intel_pmu_lbr_add(struct perf_event *event); |
| 910 | 917 | ||
| 911 | void intel_pmu_lbr_disable(struct perf_event *event); | 918 | void intel_pmu_lbr_del(struct perf_event *event); |
| 912 | 919 | ||
| 913 | void intel_pmu_lbr_enable_all(bool pmi); | 920 | void intel_pmu_lbr_enable_all(bool pmi); |
| 914 | 921 | ||
