| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Per core/cpu state |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 17 | 18 | #include <asm/cpufeature.h> |
|---|
| 18 | 19 | #include <asm/hardirq.h> |
|---|
| 19 | 20 | #include <asm/intel-family.h> |
|---|
| 21 | +#include <asm/intel_pt.h> |
|---|
| 20 | 22 | #include <asm/apic.h> |
|---|
| 23 | +#include <asm/cpu_device_id.h> |
|---|
| 21 | 24 | |
|---|
| 22 | 25 | #include "../perf_event.h" |
|---|
| 23 | 26 | |
|---|
| .. | .. |
|---|
| 238 | 241 | EVENT_EXTRA_END |
|---|
| 239 | 242 | }; |
|---|
| 240 | 243 | |
|---|
| 244 | +static struct event_constraint intel_icl_event_constraints[] = { |
|---|
| 245 | + FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ |
|---|
| 246 | + FIXED_EVENT_CONSTRAINT(0x01c0, 0), /* INST_RETIRED.PREC_DIST */ |
|---|
| 247 | + FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ |
|---|
| 248 | + FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */ |
|---|
| 249 | + FIXED_EVENT_CONSTRAINT(0x0400, 3), /* SLOTS */ |
|---|
| 250 | + METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_RETIRING, 0), |
|---|
| 251 | + METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_BAD_SPEC, 1), |
|---|
| 252 | + METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_FE_BOUND, 2), |
|---|
| 253 | + METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_BE_BOUND, 3), |
|---|
| 254 | + INTEL_EVENT_CONSTRAINT_RANGE(0x03, 0x0a, 0xf), |
|---|
| 255 | + INTEL_EVENT_CONSTRAINT_RANGE(0x1f, 0x28, 0xf), |
|---|
| 256 | + INTEL_EVENT_CONSTRAINT(0x32, 0xf), /* SW_PREFETCH_ACCESS.* */ |
|---|
| 257 | + INTEL_EVENT_CONSTRAINT_RANGE(0x48, 0x56, 0xf), |
|---|
| 258 | + INTEL_EVENT_CONSTRAINT_RANGE(0x60, 0x8b, 0xf), |
|---|
| 259 | + INTEL_UEVENT_CONSTRAINT(0x04a3, 0xff), /* CYCLE_ACTIVITY.STALLS_TOTAL */ |
|---|
| 260 | + INTEL_UEVENT_CONSTRAINT(0x10a3, 0xff), /* CYCLE_ACTIVITY.CYCLES_MEM_ANY */ |
|---|
| 261 | + INTEL_UEVENT_CONSTRAINT(0x14a3, 0xff), /* CYCLE_ACTIVITY.STALLS_MEM_ANY */ |
|---|
| 262 | + INTEL_EVENT_CONSTRAINT(0xa3, 0xf), /* CYCLE_ACTIVITY.* */ |
|---|
| 263 | + INTEL_EVENT_CONSTRAINT_RANGE(0xa8, 0xb0, 0xf), |
|---|
| 264 | + INTEL_EVENT_CONSTRAINT_RANGE(0xb7, 0xbd, 0xf), |
|---|
| 265 | + INTEL_EVENT_CONSTRAINT_RANGE(0xd0, 0xe6, 0xf), |
|---|
| 266 | + INTEL_EVENT_CONSTRAINT(0xef, 0xf), |
|---|
| 267 | + INTEL_EVENT_CONSTRAINT_RANGE(0xf0, 0xf4, 0xf), |
|---|
| 268 | + EVENT_CONSTRAINT_END |
|---|
| 269 | +}; |
|---|
| 270 | + |
|---|
| 271 | +static struct extra_reg intel_icl_extra_regs[] __read_mostly = { |
|---|
| 272 | + INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3fffffbfffull, RSP_0), |
|---|
| 273 | + INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3fffffbfffull, RSP_1), |
|---|
| 274 | + INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd), |
|---|
| 275 | + INTEL_UEVENT_EXTRA_REG(0x01c6, MSR_PEBS_FRONTEND, 0x7fff17, FE), |
|---|
| 276 | + EVENT_EXTRA_END |
|---|
| 277 | +}; |
|---|
| 278 | + |
|---|
| 241 | 279 | EVENT_ATTR_STR(mem-loads, mem_ld_nhm, "event=0x0b,umask=0x10,ldlat=3"); |
|---|
| 242 | 280 | EVENT_ATTR_STR(mem-loads, mem_ld_snb, "event=0xcd,umask=0x1,ldlat=3"); |
|---|
| 243 | 281 | EVENT_ATTR_STR(mem-stores, mem_st_snb, "event=0xcd,umask=0x2"); |
|---|
| 244 | 282 | |
|---|
| 245 | | -static struct attribute *nhm_events_attrs[] = { |
|---|
| 283 | +static struct attribute *nhm_mem_events_attrs[] = { |
|---|
| 246 | 284 | EVENT_PTR(mem_ld_nhm), |
|---|
| 247 | 285 | NULL, |
|---|
| 248 | 286 | }; |
|---|
| .. | .. |
|---|
| 277 | 315 | EVENT_ATTR_STR_HT(topdown-recovery-bubbles.scale, td_recovery_bubbles_scale, |
|---|
| 278 | 316 | "4", "2"); |
|---|
| 279 | 317 | |
|---|
| 318 | +EVENT_ATTR_STR(slots, slots, "event=0x00,umask=0x4"); |
|---|
| 319 | +EVENT_ATTR_STR(topdown-retiring, td_retiring, "event=0x00,umask=0x80"); |
|---|
| 320 | +EVENT_ATTR_STR(topdown-bad-spec, td_bad_spec, "event=0x00,umask=0x81"); |
|---|
| 321 | +EVENT_ATTR_STR(topdown-fe-bound, td_fe_bound, "event=0x00,umask=0x82"); |
|---|
| 322 | +EVENT_ATTR_STR(topdown-be-bound, td_be_bound, "event=0x00,umask=0x83"); |
|---|
| 323 | + |
|---|
| 280 | 324 | static struct attribute *snb_events_attrs[] = { |
|---|
| 281 | | - EVENT_PTR(mem_ld_snb), |
|---|
| 282 | | - EVENT_PTR(mem_st_snb), |
|---|
| 283 | 325 | EVENT_PTR(td_slots_issued), |
|---|
| 284 | 326 | EVENT_PTR(td_slots_retired), |
|---|
| 285 | 327 | EVENT_PTR(td_fetch_bubbles), |
|---|
| .. | .. |
|---|
| 287 | 329 | EVENT_PTR(td_total_slots_scale), |
|---|
| 288 | 330 | EVENT_PTR(td_recovery_bubbles), |
|---|
| 289 | 331 | EVENT_PTR(td_recovery_bubbles_scale), |
|---|
| 332 | + NULL, |
|---|
| 333 | +}; |
|---|
| 334 | + |
|---|
| 335 | +static struct attribute *snb_mem_events_attrs[] = { |
|---|
| 336 | + EVENT_PTR(mem_ld_snb), |
|---|
| 337 | + EVENT_PTR(mem_st_snb), |
|---|
| 290 | 338 | NULL, |
|---|
| 291 | 339 | }; |
|---|
| 292 | 340 | |
|---|
| .. | .. |
|---|
| 1822 | 1870 | }, |
|---|
| 1823 | 1871 | }; |
|---|
| 1824 | 1872 | |
|---|
| 1873 | +#define TNT_LOCAL_DRAM BIT_ULL(26) |
|---|
| 1874 | +#define TNT_DEMAND_READ GLM_DEMAND_DATA_RD |
|---|
| 1875 | +#define TNT_DEMAND_WRITE GLM_DEMAND_RFO |
|---|
| 1876 | +#define TNT_LLC_ACCESS GLM_ANY_RESPONSE |
|---|
| 1877 | +#define TNT_SNP_ANY (SNB_SNP_NOT_NEEDED|SNB_SNP_MISS| \ |
|---|
| 1878 | + SNB_NO_FWD|SNB_SNP_FWD|SNB_HITM) |
|---|
| 1879 | +#define TNT_LLC_MISS (TNT_SNP_ANY|SNB_NON_DRAM|TNT_LOCAL_DRAM) |
|---|
| 1880 | + |
|---|
| 1881 | +static __initconst const u64 tnt_hw_cache_extra_regs |
|---|
| 1882 | + [PERF_COUNT_HW_CACHE_MAX] |
|---|
| 1883 | + [PERF_COUNT_HW_CACHE_OP_MAX] |
|---|
| 1884 | + [PERF_COUNT_HW_CACHE_RESULT_MAX] = { |
|---|
| 1885 | + [C(LL)] = { |
|---|
| 1886 | + [C(OP_READ)] = { |
|---|
| 1887 | + [C(RESULT_ACCESS)] = TNT_DEMAND_READ| |
|---|
| 1888 | + TNT_LLC_ACCESS, |
|---|
| 1889 | + [C(RESULT_MISS)] = TNT_DEMAND_READ| |
|---|
| 1890 | + TNT_LLC_MISS, |
|---|
| 1891 | + }, |
|---|
| 1892 | + [C(OP_WRITE)] = { |
|---|
| 1893 | + [C(RESULT_ACCESS)] = TNT_DEMAND_WRITE| |
|---|
| 1894 | + TNT_LLC_ACCESS, |
|---|
| 1895 | + [C(RESULT_MISS)] = TNT_DEMAND_WRITE| |
|---|
| 1896 | + TNT_LLC_MISS, |
|---|
| 1897 | + }, |
|---|
| 1898 | + [C(OP_PREFETCH)] = { |
|---|
| 1899 | + [C(RESULT_ACCESS)] = 0x0, |
|---|
| 1900 | + [C(RESULT_MISS)] = 0x0, |
|---|
| 1901 | + }, |
|---|
| 1902 | + }, |
|---|
| 1903 | +}; |
|---|
| 1904 | + |
|---|
| 1905 | +static struct extra_reg intel_tnt_extra_regs[] __read_mostly = { |
|---|
| 1906 | + /* must define OFFCORE_RSP_X first, see intel_fixup_er() */ |
|---|
| 1907 | + INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x800ff0ffffff9fffull, RSP_0), |
|---|
| 1908 | + INTEL_UEVENT_EXTRA_REG(0x02b7, MSR_OFFCORE_RSP_1, 0xff0ffffff9fffull, RSP_1), |
|---|
| 1909 | + EVENT_EXTRA_END |
|---|
| 1910 | +}; |
|---|
| 1911 | + |
|---|
| 1825 | 1912 | #define KNL_OT_L2_HITE BIT_ULL(19) /* Other Tile L2 Hit */ |
|---|
| 1826 | 1913 | #define KNL_OT_L2_HITF BIT_ULL(20) /* Other Tile L2 Hit */ |
|---|
| 1827 | 1914 | #define KNL_MCDRAM_LOCAL BIT_ULL(21) |
|---|
| .. | .. |
|---|
| 1870 | 1957 | * intel_bts events don't coexist with intel PMU's BTS events because of |
|---|
| 1871 | 1958 | * x86_add_exclusive(x86_lbr_exclusive_lbr); there's no need to keep them |
|---|
| 1872 | 1959 | * disabled around intel PMU's event batching etc, only inside the PMI handler. |
|---|
| 1960 | + * |
|---|
| 1961 | + * Avoid PEBS_ENABLE MSR access in PMIs. |
|---|
| 1962 | + * The GLOBAL_CTRL has been disabled. All the counters do not count anymore. |
|---|
| 1963 | + * It doesn't matter if the PEBS is enabled or not. |
|---|
| 1964 | + * Usually, the PEBS status are not changed in PMIs. It's unnecessary to |
|---|
| 1965 | + * access PEBS_ENABLE MSR in disable_all()/enable_all(). |
|---|
| 1966 | + * However, there are some cases which may change PEBS status, e.g. PMI |
|---|
| 1967 | + * throttle. The PEBS_ENABLE should be updated where the status changes. |
|---|
| 1873 | 1968 | */ |
|---|
| 1874 | 1969 | static void __intel_pmu_disable_all(void) |
|---|
| 1875 | 1970 | { |
|---|
| .. | .. |
|---|
| 1879 | 1974 | |
|---|
| 1880 | 1975 | if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) |
|---|
| 1881 | 1976 | intel_pmu_disable_bts(); |
|---|
| 1882 | | - |
|---|
| 1883 | | - intel_pmu_pebs_disable_all(); |
|---|
| 1884 | 1977 | } |
|---|
| 1885 | 1978 | |
|---|
| 1886 | 1979 | static void intel_pmu_disable_all(void) |
|---|
| 1887 | 1980 | { |
|---|
| 1888 | 1981 | __intel_pmu_disable_all(); |
|---|
| 1982 | + intel_pmu_pebs_disable_all(); |
|---|
| 1889 | 1983 | intel_pmu_lbr_disable_all(); |
|---|
| 1890 | 1984 | } |
|---|
| 1891 | 1985 | |
|---|
| .. | .. |
|---|
| 1893 | 1987 | { |
|---|
| 1894 | 1988 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
|---|
| 1895 | 1989 | |
|---|
| 1896 | | - intel_pmu_pebs_enable_all(); |
|---|
| 1897 | 1990 | intel_pmu_lbr_enable_all(pmi); |
|---|
| 1898 | 1991 | wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, |
|---|
| 1899 | 1992 | x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask); |
|---|
| .. | .. |
|---|
| 1911 | 2004 | |
|---|
| 1912 | 2005 | static void intel_pmu_enable_all(int added) |
|---|
| 1913 | 2006 | { |
|---|
| 2007 | + intel_pmu_pebs_enable_all(); |
|---|
| 1914 | 2008 | __intel_pmu_enable_all(added, false); |
|---|
| 1915 | 2009 | } |
|---|
| 1916 | 2010 | |
|---|
| .. | .. |
|---|
| 1926 | 2020 | * in sequence on the same PMC or on different PMCs. |
|---|
| 1927 | 2021 | * |
|---|
| 1928 | 2022 | * In practise it appears some of these events do in fact count, and |
|---|
| 1929 | | - * we need to programm all 4 events. |
|---|
| 2023 | + * we need to program all 4 events. |
|---|
| 1930 | 2024 | */ |
|---|
| 1931 | 2025 | static void intel_pmu_nhm_workaround(void) |
|---|
| 1932 | 2026 | { |
|---|
| .. | .. |
|---|
| 2010 | 2104 | /* |
|---|
| 2011 | 2105 | * We're going to use PMC3, make sure TFA is set before we touch it. |
|---|
| 2012 | 2106 | */ |
|---|
| 2013 | | - if (cntr == 3 && !cpuc->is_fake) |
|---|
| 2107 | + if (cntr == 3) |
|---|
| 2014 | 2108 | intel_set_tfa(cpuc, true); |
|---|
| 2015 | 2109 | } |
|---|
| 2016 | 2110 | |
|---|
| .. | .. |
|---|
| 2028 | 2122 | intel_pmu_enable_all(added); |
|---|
| 2029 | 2123 | } |
|---|
| 2030 | 2124 | |
|---|
| 2125 | +static void enable_counter_freeze(void) |
|---|
| 2126 | +{ |
|---|
| 2127 | + update_debugctlmsr(get_debugctlmsr() | |
|---|
| 2128 | + DEBUGCTLMSR_FREEZE_PERFMON_ON_PMI); |
|---|
| 2129 | +} |
|---|
| 2130 | + |
|---|
| 2131 | +static void disable_counter_freeze(void) |
|---|
| 2132 | +{ |
|---|
| 2133 | + update_debugctlmsr(get_debugctlmsr() & |
|---|
| 2134 | + ~DEBUGCTLMSR_FREEZE_PERFMON_ON_PMI); |
|---|
| 2135 | +} |
|---|
| 2136 | + |
|---|
| 2031 | 2137 | static inline u64 intel_pmu_get_status(void) |
|---|
| 2032 | 2138 | { |
|---|
| 2033 | 2139 | u64 status; |
|---|
| .. | .. |
|---|
| 2042 | 2148 | wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack); |
|---|
| 2043 | 2149 | } |
|---|
| 2044 | 2150 | |
|---|
| 2045 | | -static void intel_pmu_disable_fixed(struct hw_perf_event *hwc) |
|---|
| 2151 | +static inline bool event_is_checkpointed(struct perf_event *event) |
|---|
| 2046 | 2152 | { |
|---|
| 2047 | | - int idx = hwc->idx - INTEL_PMC_IDX_FIXED; |
|---|
| 2153 | + return unlikely(event->hw.config & HSW_IN_TX_CHECKPOINTED) != 0; |
|---|
| 2154 | +} |
|---|
| 2155 | + |
|---|
| 2156 | +static inline void intel_set_masks(struct perf_event *event, int idx) |
|---|
| 2157 | +{ |
|---|
| 2158 | + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
|---|
| 2159 | + |
|---|
| 2160 | + if (event->attr.exclude_host) |
|---|
| 2161 | + __set_bit(idx, (unsigned long *)&cpuc->intel_ctrl_guest_mask); |
|---|
| 2162 | + if (event->attr.exclude_guest) |
|---|
| 2163 | + __set_bit(idx, (unsigned long *)&cpuc->intel_ctrl_host_mask); |
|---|
| 2164 | + if (event_is_checkpointed(event)) |
|---|
| 2165 | + __set_bit(idx, (unsigned long *)&cpuc->intel_cp_status); |
|---|
| 2166 | +} |
|---|
| 2167 | + |
|---|
| 2168 | +static inline void intel_clear_masks(struct perf_event *event, int idx) |
|---|
| 2169 | +{ |
|---|
| 2170 | + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
|---|
| 2171 | + |
|---|
| 2172 | + __clear_bit(idx, (unsigned long *)&cpuc->intel_ctrl_guest_mask); |
|---|
| 2173 | + __clear_bit(idx, (unsigned long *)&cpuc->intel_ctrl_host_mask); |
|---|
| 2174 | + __clear_bit(idx, (unsigned long *)&cpuc->intel_cp_status); |
|---|
| 2175 | +} |
|---|
| 2176 | + |
|---|
| 2177 | +static void intel_pmu_disable_fixed(struct perf_event *event) |
|---|
| 2178 | +{ |
|---|
| 2179 | + struct hw_perf_event *hwc = &event->hw; |
|---|
| 2048 | 2180 | u64 ctrl_val, mask; |
|---|
| 2181 | + int idx = hwc->idx; |
|---|
| 2049 | 2182 | |
|---|
| 2050 | | - mask = 0xfULL << (idx * 4); |
|---|
| 2183 | + if (is_topdown_idx(idx)) { |
|---|
| 2184 | + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
|---|
| 2051 | 2185 | |
|---|
| 2186 | + /* |
|---|
| 2187 | + * When there are other active TopDown events, |
|---|
| 2188 | + * don't disable the fixed counter 3. |
|---|
| 2189 | + */ |
|---|
| 2190 | + if (*(u64 *)cpuc->active_mask & INTEL_PMC_OTHER_TOPDOWN_BITS(idx)) |
|---|
| 2191 | + return; |
|---|
| 2192 | + idx = INTEL_PMC_IDX_FIXED_SLOTS; |
|---|
| 2193 | + } |
|---|
| 2194 | + |
|---|
| 2195 | + intel_clear_masks(event, idx); |
|---|
| 2196 | + |
|---|
| 2197 | + mask = 0xfULL << ((idx - INTEL_PMC_IDX_FIXED) * 4); |
|---|
| 2052 | 2198 | rdmsrl(hwc->config_base, ctrl_val); |
|---|
| 2053 | 2199 | ctrl_val &= ~mask; |
|---|
| 2054 | 2200 | wrmsrl(hwc->config_base, ctrl_val); |
|---|
| 2055 | 2201 | } |
|---|
| 2056 | 2202 | |
|---|
| 2057 | | -static inline bool event_is_checkpointed(struct perf_event *event) |
|---|
| 2058 | | -{ |
|---|
| 2059 | | - return (event->hw.config & HSW_IN_TX_CHECKPOINTED) != 0; |
|---|
| 2060 | | -} |
|---|
| 2061 | | - |
|---|
| 2062 | 2203 | static void intel_pmu_disable_event(struct perf_event *event) |
|---|
| 2063 | 2204 | { |
|---|
| 2064 | 2205 | struct hw_perf_event *hwc = &event->hw; |
|---|
| 2065 | | - struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
|---|
| 2206 | + int idx = hwc->idx; |
|---|
| 2066 | 2207 | |
|---|
| 2067 | | - if (unlikely(hwc->idx == INTEL_PMC_IDX_FIXED_BTS)) { |
|---|
| 2208 | + switch (idx) { |
|---|
| 2209 | + case 0 ... INTEL_PMC_IDX_FIXED - 1: |
|---|
| 2210 | + intel_clear_masks(event, idx); |
|---|
| 2211 | + x86_pmu_disable_event(event); |
|---|
| 2212 | + break; |
|---|
| 2213 | + case INTEL_PMC_IDX_FIXED ... INTEL_PMC_IDX_FIXED_BTS - 1: |
|---|
| 2214 | + case INTEL_PMC_IDX_METRIC_BASE ... INTEL_PMC_IDX_METRIC_END: |
|---|
| 2215 | + intel_pmu_disable_fixed(event); |
|---|
| 2216 | + break; |
|---|
| 2217 | + case INTEL_PMC_IDX_FIXED_BTS: |
|---|
| 2068 | 2218 | intel_pmu_disable_bts(); |
|---|
| 2069 | 2219 | intel_pmu_drain_bts_buffer(); |
|---|
| 2070 | 2220 | return; |
|---|
| 2221 | + case INTEL_PMC_IDX_FIXED_VLBR: |
|---|
| 2222 | + intel_clear_masks(event, idx); |
|---|
| 2223 | + break; |
|---|
| 2224 | + default: |
|---|
| 2225 | + intel_clear_masks(event, idx); |
|---|
| 2226 | + pr_warn("Failed to disable the event with invalid index %d\n", |
|---|
| 2227 | + idx); |
|---|
| 2228 | + return; |
|---|
| 2071 | 2229 | } |
|---|
| 2072 | | - |
|---|
| 2073 | | - cpuc->intel_ctrl_guest_mask &= ~(1ull << hwc->idx); |
|---|
| 2074 | | - cpuc->intel_ctrl_host_mask &= ~(1ull << hwc->idx); |
|---|
| 2075 | | - cpuc->intel_cp_status &= ~(1ull << hwc->idx); |
|---|
| 2076 | | - |
|---|
| 2077 | | - if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) |
|---|
| 2078 | | - intel_pmu_disable_fixed(hwc); |
|---|
| 2079 | | - else |
|---|
| 2080 | | - x86_pmu_disable_event(event); |
|---|
| 2081 | 2230 | |
|---|
| 2082 | 2231 | /* |
|---|
| 2083 | 2232 | * Needs to be called after x86_pmu_disable_event, |
|---|
| .. | .. |
|---|
| 2095 | 2244 | intel_pmu_pebs_del(event); |
|---|
| 2096 | 2245 | } |
|---|
| 2097 | 2246 | |
|---|
| 2247 | +static int icl_set_topdown_event_period(struct perf_event *event) |
|---|
| 2248 | +{ |
|---|
| 2249 | + struct hw_perf_event *hwc = &event->hw; |
|---|
| 2250 | + s64 left = local64_read(&hwc->period_left); |
|---|
| 2251 | + |
|---|
| 2252 | + /* |
|---|
| 2253 | + * The values in PERF_METRICS MSR are derived from fixed counter 3. |
|---|
| 2254 | + * Software should start both registers, PERF_METRICS and fixed |
|---|
| 2255 | + * counter 3, from zero. |
|---|
| 2256 | + * Clear PERF_METRICS and Fixed counter 3 in initialization. |
|---|
| 2257 | + * After that, both MSRs will be cleared for each read. |
|---|
| 2258 | + * Don't need to clear them again. |
|---|
| 2259 | + */ |
|---|
| 2260 | + if (left == x86_pmu.max_period) { |
|---|
| 2261 | + wrmsrl(MSR_CORE_PERF_FIXED_CTR3, 0); |
|---|
| 2262 | + wrmsrl(MSR_PERF_METRICS, 0); |
|---|
| 2263 | + hwc->saved_slots = 0; |
|---|
| 2264 | + hwc->saved_metric = 0; |
|---|
| 2265 | + } |
|---|
| 2266 | + |
|---|
| 2267 | + if ((hwc->saved_slots) && is_slots_event(event)) { |
|---|
| 2268 | + wrmsrl(MSR_CORE_PERF_FIXED_CTR3, hwc->saved_slots); |
|---|
| 2269 | + wrmsrl(MSR_PERF_METRICS, hwc->saved_metric); |
|---|
| 2270 | + } |
|---|
| 2271 | + |
|---|
| 2272 | + perf_event_update_userpage(event); |
|---|
| 2273 | + |
|---|
| 2274 | + return 0; |
|---|
| 2275 | +} |
|---|
| 2276 | + |
|---|
| 2277 | +static inline u64 icl_get_metrics_event_value(u64 metric, u64 slots, int idx) |
|---|
| 2278 | +{ |
|---|
| 2279 | + u32 val; |
|---|
| 2280 | + |
|---|
| 2281 | + /* |
|---|
| 2282 | + * The metric is reported as an 8bit integer fraction |
|---|
| 2283 | + * suming up to 0xff. |
|---|
| 2284 | + * slots-in-metric = (Metric / 0xff) * slots |
|---|
| 2285 | + */ |
|---|
| 2286 | + val = (metric >> ((idx - INTEL_PMC_IDX_METRIC_BASE) * 8)) & 0xff; |
|---|
| 2287 | + return mul_u64_u32_div(slots, val, 0xff); |
|---|
| 2288 | +} |
|---|
| 2289 | + |
|---|
| 2290 | +static u64 icl_get_topdown_value(struct perf_event *event, |
|---|
| 2291 | + u64 slots, u64 metrics) |
|---|
| 2292 | +{ |
|---|
| 2293 | + int idx = event->hw.idx; |
|---|
| 2294 | + u64 delta; |
|---|
| 2295 | + |
|---|
| 2296 | + if (is_metric_idx(idx)) |
|---|
| 2297 | + delta = icl_get_metrics_event_value(metrics, slots, idx); |
|---|
| 2298 | + else |
|---|
| 2299 | + delta = slots; |
|---|
| 2300 | + |
|---|
| 2301 | + return delta; |
|---|
| 2302 | +} |
|---|
| 2303 | + |
|---|
| 2304 | +static void __icl_update_topdown_event(struct perf_event *event, |
|---|
| 2305 | + u64 slots, u64 metrics, |
|---|
| 2306 | + u64 last_slots, u64 last_metrics) |
|---|
| 2307 | +{ |
|---|
| 2308 | + u64 delta, last = 0; |
|---|
| 2309 | + |
|---|
| 2310 | + delta = icl_get_topdown_value(event, slots, metrics); |
|---|
| 2311 | + if (last_slots) |
|---|
| 2312 | + last = icl_get_topdown_value(event, last_slots, last_metrics); |
|---|
| 2313 | + |
|---|
| 2314 | + /* |
|---|
| 2315 | + * The 8bit integer fraction of metric may be not accurate, |
|---|
| 2316 | + * especially when the changes is very small. |
|---|
| 2317 | + * For example, if only a few bad_spec happens, the fraction |
|---|
| 2318 | + * may be reduced from 1 to 0. If so, the bad_spec event value |
|---|
| 2319 | + * will be 0 which is definitely less than the last value. |
|---|
| 2320 | + * Avoid update event->count for this case. |
|---|
| 2321 | + */ |
|---|
| 2322 | + if (delta > last) { |
|---|
| 2323 | + delta -= last; |
|---|
| 2324 | + local64_add(delta, &event->count); |
|---|
| 2325 | + } |
|---|
| 2326 | +} |
|---|
| 2327 | + |
|---|
| 2328 | +static void update_saved_topdown_regs(struct perf_event *event, |
|---|
| 2329 | + u64 slots, u64 metrics) |
|---|
| 2330 | +{ |
|---|
| 2331 | + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
|---|
| 2332 | + struct perf_event *other; |
|---|
| 2333 | + int idx; |
|---|
| 2334 | + |
|---|
| 2335 | + event->hw.saved_slots = slots; |
|---|
| 2336 | + event->hw.saved_metric = metrics; |
|---|
| 2337 | + |
|---|
| 2338 | + for_each_set_bit(idx, cpuc->active_mask, INTEL_PMC_IDX_TD_BE_BOUND + 1) { |
|---|
| 2339 | + if (!is_topdown_idx(idx)) |
|---|
| 2340 | + continue; |
|---|
| 2341 | + other = cpuc->events[idx]; |
|---|
| 2342 | + other->hw.saved_slots = slots; |
|---|
| 2343 | + other->hw.saved_metric = metrics; |
|---|
| 2344 | + } |
|---|
| 2345 | +} |
|---|
| 2346 | + |
|---|
| 2347 | +/* |
|---|
| 2348 | + * Update all active Topdown events. |
|---|
| 2349 | + * |
|---|
| 2350 | + * The PERF_METRICS and Fixed counter 3 are read separately. The values may be |
|---|
| 2351 | + * modify by a NMI. PMU has to be disabled before calling this function. |
|---|
| 2352 | + */ |
|---|
| 2353 | +static u64 icl_update_topdown_event(struct perf_event *event) |
|---|
| 2354 | +{ |
|---|
| 2355 | + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
|---|
| 2356 | + struct perf_event *other; |
|---|
| 2357 | + u64 slots, metrics; |
|---|
| 2358 | + bool reset = true; |
|---|
| 2359 | + int idx; |
|---|
| 2360 | + |
|---|
| 2361 | + /* read Fixed counter 3 */ |
|---|
| 2362 | + rdpmcl((3 | INTEL_PMC_FIXED_RDPMC_BASE), slots); |
|---|
| 2363 | + if (!slots) |
|---|
| 2364 | + return 0; |
|---|
| 2365 | + |
|---|
| 2366 | + /* read PERF_METRICS */ |
|---|
| 2367 | + rdpmcl(INTEL_PMC_FIXED_RDPMC_METRICS, metrics); |
|---|
| 2368 | + |
|---|
| 2369 | + for_each_set_bit(idx, cpuc->active_mask, INTEL_PMC_IDX_TD_BE_BOUND + 1) { |
|---|
| 2370 | + if (!is_topdown_idx(idx)) |
|---|
| 2371 | + continue; |
|---|
| 2372 | + other = cpuc->events[idx]; |
|---|
| 2373 | + __icl_update_topdown_event(other, slots, metrics, |
|---|
| 2374 | + event ? event->hw.saved_slots : 0, |
|---|
| 2375 | + event ? event->hw.saved_metric : 0); |
|---|
| 2376 | + } |
|---|
| 2377 | + |
|---|
| 2378 | + /* |
|---|
| 2379 | + * Check and update this event, which may have been cleared |
|---|
| 2380 | + * in active_mask e.g. x86_pmu_stop() |
|---|
| 2381 | + */ |
|---|
| 2382 | + if (event && !test_bit(event->hw.idx, cpuc->active_mask)) { |
|---|
| 2383 | + __icl_update_topdown_event(event, slots, metrics, |
|---|
| 2384 | + event->hw.saved_slots, |
|---|
| 2385 | + event->hw.saved_metric); |
|---|
| 2386 | + |
|---|
| 2387 | + /* |
|---|
| 2388 | + * In x86_pmu_stop(), the event is cleared in active_mask first, |
|---|
| 2389 | + * then drain the delta, which indicates context switch for |
|---|
| 2390 | + * counting. |
|---|
| 2391 | + * Save metric and slots for context switch. |
|---|
| 2392 | + * Don't need to reset the PERF_METRICS and Fixed counter 3. |
|---|
| 2393 | + * Because the values will be restored in next schedule in. |
|---|
| 2394 | + */ |
|---|
| 2395 | + update_saved_topdown_regs(event, slots, metrics); |
|---|
| 2396 | + reset = false; |
|---|
| 2397 | + } |
|---|
| 2398 | + |
|---|
| 2399 | + if (reset) { |
|---|
| 2400 | + /* The fixed counter 3 has to be written before the PERF_METRICS. */ |
|---|
| 2401 | + wrmsrl(MSR_CORE_PERF_FIXED_CTR3, 0); |
|---|
| 2402 | + wrmsrl(MSR_PERF_METRICS, 0); |
|---|
| 2403 | + if (event) |
|---|
| 2404 | + update_saved_topdown_regs(event, 0, 0); |
|---|
| 2405 | + } |
|---|
| 2406 | + |
|---|
| 2407 | + return slots; |
|---|
| 2408 | +} |
|---|
| 2409 | + |
|---|
| 2410 | +static void intel_pmu_read_topdown_event(struct perf_event *event) |
|---|
| 2411 | +{ |
|---|
| 2412 | + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
|---|
| 2413 | + |
|---|
| 2414 | + /* Only need to call update_topdown_event() once for group read. */ |
|---|
| 2415 | + if ((cpuc->txn_flags & PERF_PMU_TXN_READ) && |
|---|
| 2416 | + !is_slots_event(event)) |
|---|
| 2417 | + return; |
|---|
| 2418 | + |
|---|
| 2419 | + perf_pmu_disable(event->pmu); |
|---|
| 2420 | + x86_pmu.update_topdown_event(event); |
|---|
| 2421 | + perf_pmu_enable(event->pmu); |
|---|
| 2422 | +} |
|---|
| 2423 | + |
|---|
| 2098 | 2424 | static void intel_pmu_read_event(struct perf_event *event) |
|---|
| 2099 | 2425 | { |
|---|
| 2100 | 2426 | if (event->hw.flags & PERF_X86_EVENT_AUTO_RELOAD) |
|---|
| 2101 | 2427 | intel_pmu_auto_reload_read(event); |
|---|
| 2428 | + else if (is_topdown_count(event) && x86_pmu.update_topdown_event) |
|---|
| 2429 | + intel_pmu_read_topdown_event(event); |
|---|
| 2102 | 2430 | else |
|---|
| 2103 | 2431 | x86_perf_event_update(event); |
|---|
| 2104 | 2432 | } |
|---|
| .. | .. |
|---|
| 2106 | 2434 | static void intel_pmu_enable_fixed(struct perf_event *event) |
|---|
| 2107 | 2435 | { |
|---|
| 2108 | 2436 | struct hw_perf_event *hwc = &event->hw; |
|---|
| 2109 | | - int idx = hwc->idx - INTEL_PMC_IDX_FIXED; |
|---|
| 2110 | 2437 | u64 ctrl_val, mask, bits = 0; |
|---|
| 2438 | + int idx = hwc->idx; |
|---|
| 2439 | + |
|---|
| 2440 | + if (is_topdown_idx(idx)) { |
|---|
| 2441 | + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
|---|
| 2442 | + /* |
|---|
| 2443 | + * When there are other active TopDown events, |
|---|
| 2444 | + * don't enable the fixed counter 3 again. |
|---|
| 2445 | + */ |
|---|
| 2446 | + if (*(u64 *)cpuc->active_mask & INTEL_PMC_OTHER_TOPDOWN_BITS(idx)) |
|---|
| 2447 | + return; |
|---|
| 2448 | + |
|---|
| 2449 | + idx = INTEL_PMC_IDX_FIXED_SLOTS; |
|---|
| 2450 | + } |
|---|
| 2451 | + |
|---|
| 2452 | + intel_set_masks(event, idx); |
|---|
| 2111 | 2453 | |
|---|
| 2112 | 2454 | /* |
|---|
| 2113 | 2455 | * Enable IRQ generation (0x8), if not PEBS, |
|---|
| .. | .. |
|---|
| 2127 | 2469 | if (x86_pmu.version > 2 && hwc->config & ARCH_PERFMON_EVENTSEL_ANY) |
|---|
| 2128 | 2470 | bits |= 0x4; |
|---|
| 2129 | 2471 | |
|---|
| 2472 | + idx -= INTEL_PMC_IDX_FIXED; |
|---|
| 2130 | 2473 | bits <<= (idx * 4); |
|---|
| 2131 | 2474 | mask = 0xfULL << (idx * 4); |
|---|
| 2475 | + |
|---|
| 2476 | + if (x86_pmu.intel_cap.pebs_baseline && event->attr.precise_ip) { |
|---|
| 2477 | + bits |= ICL_FIXED_0_ADAPTIVE << (idx * 4); |
|---|
| 2478 | + mask |= ICL_FIXED_0_ADAPTIVE << (idx * 4); |
|---|
| 2479 | + } |
|---|
| 2132 | 2480 | |
|---|
| 2133 | 2481 | rdmsrl(hwc->config_base, ctrl_val); |
|---|
| 2134 | 2482 | ctrl_val &= ~mask; |
|---|
| .. | .. |
|---|
| 2139 | 2487 | static void intel_pmu_enable_event(struct perf_event *event) |
|---|
| 2140 | 2488 | { |
|---|
| 2141 | 2489 | struct hw_perf_event *hwc = &event->hw; |
|---|
| 2142 | | - struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
|---|
| 2143 | | - |
|---|
| 2144 | | - if (unlikely(hwc->idx == INTEL_PMC_IDX_FIXED_BTS)) { |
|---|
| 2145 | | - if (!__this_cpu_read(cpu_hw_events.enabled)) |
|---|
| 2146 | | - return; |
|---|
| 2147 | | - |
|---|
| 2148 | | - intel_pmu_enable_bts(hwc->config); |
|---|
| 2149 | | - return; |
|---|
| 2150 | | - } |
|---|
| 2151 | | - |
|---|
| 2152 | | - if (event->attr.exclude_host) |
|---|
| 2153 | | - cpuc->intel_ctrl_guest_mask |= (1ull << hwc->idx); |
|---|
| 2154 | | - if (event->attr.exclude_guest) |
|---|
| 2155 | | - cpuc->intel_ctrl_host_mask |= (1ull << hwc->idx); |
|---|
| 2156 | | - |
|---|
| 2157 | | - if (unlikely(event_is_checkpointed(event))) |
|---|
| 2158 | | - cpuc->intel_cp_status |= (1ull << hwc->idx); |
|---|
| 2490 | + int idx = hwc->idx; |
|---|
| 2159 | 2491 | |
|---|
| 2160 | 2492 | if (unlikely(event->attr.precise_ip)) |
|---|
| 2161 | 2493 | intel_pmu_pebs_enable(event); |
|---|
| 2162 | 2494 | |
|---|
| 2163 | | - if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { |
|---|
| 2495 | + switch (idx) { |
|---|
| 2496 | + case 0 ... INTEL_PMC_IDX_FIXED - 1: |
|---|
| 2497 | + intel_set_masks(event, idx); |
|---|
| 2498 | + __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE); |
|---|
| 2499 | + break; |
|---|
| 2500 | + case INTEL_PMC_IDX_FIXED ... INTEL_PMC_IDX_FIXED_BTS - 1: |
|---|
| 2501 | + case INTEL_PMC_IDX_METRIC_BASE ... INTEL_PMC_IDX_METRIC_END: |
|---|
| 2164 | 2502 | intel_pmu_enable_fixed(event); |
|---|
| 2165 | | - return; |
|---|
| 2503 | + break; |
|---|
| 2504 | + case INTEL_PMC_IDX_FIXED_BTS: |
|---|
| 2505 | + if (!__this_cpu_read(cpu_hw_events.enabled)) |
|---|
| 2506 | + return; |
|---|
| 2507 | + intel_pmu_enable_bts(hwc->config); |
|---|
| 2508 | + break; |
|---|
| 2509 | + case INTEL_PMC_IDX_FIXED_VLBR: |
|---|
| 2510 | + intel_set_masks(event, idx); |
|---|
| 2511 | + break; |
|---|
| 2512 | + default: |
|---|
| 2513 | + pr_warn("Failed to enable the event with invalid index %d\n", |
|---|
| 2514 | + idx); |
|---|
| 2166 | 2515 | } |
|---|
| 2167 | | - |
|---|
| 2168 | | - __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE); |
|---|
| 2169 | 2516 | } |
|---|
| 2170 | 2517 | |
|---|
| 2171 | 2518 | static void intel_pmu_add_event(struct perf_event *event) |
|---|
| .. | .. |
|---|
| 2235 | 2582 | local_irq_restore(flags); |
|---|
| 2236 | 2583 | } |
|---|
| 2237 | 2584 | |
|---|
| 2585 | +static int handle_pmi_common(struct pt_regs *regs, u64 status) |
|---|
| 2586 | +{ |
|---|
| 2587 | + struct perf_sample_data data; |
|---|
| 2588 | + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
|---|
| 2589 | + struct perf_guest_info_callbacks *guest_cbs; |
|---|
| 2590 | + int bit; |
|---|
| 2591 | + int handled = 0; |
|---|
| 2592 | + |
|---|
| 2593 | + inc_irq_stat(apic_perf_irqs); |
|---|
| 2594 | + |
|---|
| 2595 | + /* |
|---|
| 2596 | + * Ignore a range of extra bits in status that do not indicate |
|---|
| 2597 | + * overflow by themselves. |
|---|
| 2598 | + */ |
|---|
| 2599 | + status &= ~(GLOBAL_STATUS_COND_CHG | |
|---|
| 2600 | + GLOBAL_STATUS_ASIF | |
|---|
| 2601 | + GLOBAL_STATUS_LBRS_FROZEN); |
|---|
| 2602 | + if (!status) |
|---|
| 2603 | + return 0; |
|---|
| 2604 | + /* |
|---|
| 2605 | + * In case multiple PEBS events are sampled at the same time, |
|---|
| 2606 | + * it is possible to have GLOBAL_STATUS bit 62 set indicating |
|---|
| 2607 | + * PEBS buffer overflow and also seeing at most 3 PEBS counters |
|---|
| 2608 | + * having their bits set in the status register. This is a sign |
|---|
| 2609 | + * that there was at least one PEBS record pending at the time |
|---|
| 2610 | + * of the PMU interrupt. PEBS counters must only be processed |
|---|
| 2611 | + * via the drain_pebs() calls and not via the regular sample |
|---|
| 2612 | + * processing loop coming after that the function, otherwise |
|---|
| 2613 | + * phony regular samples may be generated in the sampling buffer |
|---|
| 2614 | + * not marked with the EXACT tag. Another possibility is to have |
|---|
| 2615 | + * one PEBS event and at least one non-PEBS event whic hoverflows |
|---|
| 2616 | + * while PEBS has armed. In this case, bit 62 of GLOBAL_STATUS will |
|---|
| 2617 | + * not be set, yet the overflow status bit for the PEBS counter will |
|---|
| 2618 | + * be on Skylake. |
|---|
| 2619 | + * |
|---|
| 2620 | + * To avoid this problem, we systematically ignore the PEBS-enabled |
|---|
| 2621 | + * counters from the GLOBAL_STATUS mask and we always process PEBS |
|---|
| 2622 | + * events via drain_pebs(). |
|---|
| 2623 | + */ |
|---|
| 2624 | + if (x86_pmu.flags & PMU_FL_PEBS_ALL) |
|---|
| 2625 | + status &= ~cpuc->pebs_enabled; |
|---|
| 2626 | + else |
|---|
| 2627 | + status &= ~(cpuc->pebs_enabled & PEBS_COUNTER_MASK); |
|---|
| 2628 | + |
|---|
| 2629 | + /* |
|---|
| 2630 | + * PEBS overflow sets bit 62 in the global status register |
|---|
| 2631 | + */ |
|---|
| 2632 | + if (__test_and_clear_bit(GLOBAL_STATUS_BUFFER_OVF_BIT, (unsigned long *)&status)) { |
|---|
| 2633 | + u64 pebs_enabled = cpuc->pebs_enabled; |
|---|
| 2634 | + |
|---|
| 2635 | + handled++; |
|---|
| 2636 | + x86_pmu.drain_pebs(regs, &data); |
|---|
| 2637 | + status &= x86_pmu.intel_ctrl | GLOBAL_STATUS_TRACE_TOPAPMI; |
|---|
| 2638 | + |
|---|
| 2639 | + /* |
|---|
| 2640 | + * PMI throttle may be triggered, which stops the PEBS event. |
|---|
| 2641 | + * Although cpuc->pebs_enabled is updated accordingly, the |
|---|
| 2642 | + * MSR_IA32_PEBS_ENABLE is not updated. Because the |
|---|
| 2643 | + * cpuc->enabled has been forced to 0 in PMI. |
|---|
| 2644 | + * Update the MSR if pebs_enabled is changed. |
|---|
| 2645 | + */ |
|---|
| 2646 | + if (pebs_enabled != cpuc->pebs_enabled) |
|---|
| 2647 | + wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled); |
|---|
| 2648 | + } |
|---|
| 2649 | + |
|---|
| 2650 | + /* |
|---|
| 2651 | + * Intel PT |
|---|
| 2652 | + */ |
|---|
| 2653 | + if (__test_and_clear_bit(GLOBAL_STATUS_TRACE_TOPAPMI_BIT, (unsigned long *)&status)) { |
|---|
| 2654 | + handled++; |
|---|
| 2655 | + |
|---|
| 2656 | + guest_cbs = perf_get_guest_cbs(); |
|---|
| 2657 | + if (unlikely(guest_cbs && guest_cbs->is_in_guest() && |
|---|
| 2658 | + guest_cbs->handle_intel_pt_intr)) |
|---|
| 2659 | + guest_cbs->handle_intel_pt_intr(); |
|---|
| 2660 | + else |
|---|
| 2661 | + intel_pt_interrupt(); |
|---|
| 2662 | + } |
|---|
| 2663 | + |
|---|
| 2664 | + /* |
|---|
| 2665 | + * Intel Perf mertrics |
|---|
| 2666 | + */ |
|---|
| 2667 | + if (__test_and_clear_bit(GLOBAL_STATUS_PERF_METRICS_OVF_BIT, (unsigned long *)&status)) { |
|---|
| 2668 | + handled++; |
|---|
| 2669 | + if (x86_pmu.update_topdown_event) |
|---|
| 2670 | + x86_pmu.update_topdown_event(NULL); |
|---|
| 2671 | + } |
|---|
| 2672 | + |
|---|
| 2673 | + /* |
|---|
| 2674 | + * Checkpointed counters can lead to 'spurious' PMIs because the |
|---|
| 2675 | + * rollback caused by the PMI will have cleared the overflow status |
|---|
| 2676 | + * bit. Therefore always force probe these counters. |
|---|
| 2677 | + */ |
|---|
| 2678 | + status |= cpuc->intel_cp_status; |
|---|
| 2679 | + |
|---|
| 2680 | + for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { |
|---|
| 2681 | + struct perf_event *event = cpuc->events[bit]; |
|---|
| 2682 | + |
|---|
| 2683 | + handled++; |
|---|
| 2684 | + |
|---|
| 2685 | + if (!test_bit(bit, cpuc->active_mask)) |
|---|
| 2686 | + continue; |
|---|
| 2687 | + |
|---|
| 2688 | + if (!intel_pmu_save_and_restart(event)) |
|---|
| 2689 | + continue; |
|---|
| 2690 | + |
|---|
| 2691 | + perf_sample_data_init(&data, 0, event->hw.last_period); |
|---|
| 2692 | + |
|---|
| 2693 | + if (has_branch_stack(event)) |
|---|
| 2694 | + data.br_stack = &cpuc->lbr_stack; |
|---|
| 2695 | + |
|---|
| 2696 | + if (perf_event_overflow(event, &data, regs)) |
|---|
| 2697 | + x86_pmu_stop(event, 0); |
|---|
| 2698 | + } |
|---|
| 2699 | + |
|---|
| 2700 | + return handled; |
|---|
| 2701 | +} |
|---|
| 2702 | + |
|---|
| 2703 | +static bool disable_counter_freezing = true; |
|---|
| 2704 | +static int __init intel_perf_counter_freezing_setup(char *s) |
|---|
| 2705 | +{ |
|---|
| 2706 | + bool res; |
|---|
| 2707 | + |
|---|
| 2708 | + if (kstrtobool(s, &res)) |
|---|
| 2709 | + return -EINVAL; |
|---|
| 2710 | + |
|---|
| 2711 | + disable_counter_freezing = !res; |
|---|
| 2712 | + return 1; |
|---|
| 2713 | +} |
|---|
| 2714 | +__setup("perf_v4_pmi=", intel_perf_counter_freezing_setup); |
|---|
| 2715 | + |
|---|
| 2716 | +/* |
|---|
| 2717 | + * Simplified handler for Arch Perfmon v4: |
|---|
| 2718 | + * - We rely on counter freezing/unfreezing to enable/disable the PMU. |
|---|
| 2719 | + * This is done automatically on PMU ack. |
|---|
| 2720 | + * - Ack the PMU only after the APIC. |
|---|
| 2721 | + */ |
|---|
| 2722 | + |
|---|
| 2723 | +static int intel_pmu_handle_irq_v4(struct pt_regs *regs) |
|---|
| 2724 | +{ |
|---|
| 2725 | + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
|---|
| 2726 | + int handled = 0; |
|---|
| 2727 | + bool bts = false; |
|---|
| 2728 | + u64 status; |
|---|
| 2729 | + int pmu_enabled = cpuc->enabled; |
|---|
| 2730 | + int loops = 0; |
|---|
| 2731 | + |
|---|
| 2732 | + /* PMU has been disabled because of counter freezing */ |
|---|
| 2733 | + cpuc->enabled = 0; |
|---|
| 2734 | + if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) { |
|---|
| 2735 | + bts = true; |
|---|
| 2736 | + intel_bts_disable_local(); |
|---|
| 2737 | + handled = intel_pmu_drain_bts_buffer(); |
|---|
| 2738 | + handled += intel_bts_interrupt(); |
|---|
| 2739 | + } |
|---|
| 2740 | + status = intel_pmu_get_status(); |
|---|
| 2741 | + if (!status) |
|---|
| 2742 | + goto done; |
|---|
| 2743 | +again: |
|---|
| 2744 | + intel_pmu_lbr_read(); |
|---|
| 2745 | + if (++loops > 100) { |
|---|
| 2746 | + static bool warned; |
|---|
| 2747 | + |
|---|
| 2748 | + if (!warned) { |
|---|
| 2749 | + WARN(1, "perfevents: irq loop stuck!\n"); |
|---|
| 2750 | + perf_event_print_debug(); |
|---|
| 2751 | + warned = true; |
|---|
| 2752 | + } |
|---|
| 2753 | + intel_pmu_reset(); |
|---|
| 2754 | + goto done; |
|---|
| 2755 | + } |
|---|
| 2756 | + |
|---|
| 2757 | + |
|---|
| 2758 | + handled += handle_pmi_common(regs, status); |
|---|
| 2759 | +done: |
|---|
| 2760 | + /* Ack the PMI in the APIC */ |
|---|
| 2761 | + apic_write(APIC_LVTPC, APIC_DM_NMI); |
|---|
| 2762 | + |
|---|
| 2763 | + /* |
|---|
| 2764 | + * The counters start counting immediately while ack the status. |
|---|
| 2765 | + * Make it as close as possible to IRET. This avoids bogus |
|---|
| 2766 | + * freezing on Skylake CPUs. |
|---|
| 2767 | + */ |
|---|
| 2768 | + if (status) { |
|---|
| 2769 | + intel_pmu_ack_status(status); |
|---|
| 2770 | + } else { |
|---|
| 2771 | + /* |
|---|
| 2772 | + * CPU may issues two PMIs very close to each other. |
|---|
| 2773 | + * When the PMI handler services the first one, the |
|---|
| 2774 | + * GLOBAL_STATUS is already updated to reflect both. |
|---|
| 2775 | + * When it IRETs, the second PMI is immediately |
|---|
| 2776 | + * handled and it sees clear status. At the meantime, |
|---|
| 2777 | + * there may be a third PMI, because the freezing bit |
|---|
| 2778 | + * isn't set since the ack in first PMI handlers. |
|---|
| 2779 | + * Double check if there is more work to be done. |
|---|
| 2780 | + */ |
|---|
| 2781 | + status = intel_pmu_get_status(); |
|---|
| 2782 | + if (status) |
|---|
| 2783 | + goto again; |
|---|
| 2784 | + } |
|---|
| 2785 | + |
|---|
| 2786 | + if (bts) |
|---|
| 2787 | + intel_bts_enable_local(); |
|---|
| 2788 | + cpuc->enabled = pmu_enabled; |
|---|
| 2789 | + return handled; |
|---|
| 2790 | +} |
|---|
| 2791 | + |
|---|
| 2238 | 2792 | /* |
|---|
| 2239 | 2793 | * This handler is triggered by the local APIC, so the APIC IRQ handling |
|---|
| 2240 | 2794 | * rules apply: |
|---|
| 2241 | 2795 | */ |
|---|
| 2242 | 2796 | static int intel_pmu_handle_irq(struct pt_regs *regs) |
|---|
| 2243 | 2797 | { |
|---|
| 2244 | | - struct perf_sample_data data; |
|---|
| 2245 | 2798 | struct cpu_hw_events *cpuc; |
|---|
| 2246 | | - int bit, loops; |
|---|
| 2799 | + int loops; |
|---|
| 2247 | 2800 | u64 status; |
|---|
| 2248 | 2801 | int handled; |
|---|
| 2249 | 2802 | int pmu_enabled; |
|---|
| .. | .. |
|---|
| 2275 | 2828 | intel_pmu_lbr_read(); |
|---|
| 2276 | 2829 | intel_pmu_ack_status(status); |
|---|
| 2277 | 2830 | if (++loops > 100) { |
|---|
| 2278 | | - static bool warned = false; |
|---|
| 2831 | + static bool warned; |
|---|
| 2832 | + |
|---|
| 2279 | 2833 | if (!warned) { |
|---|
| 2280 | 2834 | WARN(1, "perfevents: irq loop stuck!\n"); |
|---|
| 2281 | 2835 | perf_event_print_debug(); |
|---|
| .. | .. |
|---|
| 2285 | 2839 | goto done; |
|---|
| 2286 | 2840 | } |
|---|
| 2287 | 2841 | |
|---|
| 2288 | | - inc_irq_stat(apic_perf_irqs); |
|---|
| 2289 | | - |
|---|
| 2290 | | - |
|---|
| 2291 | | - /* |
|---|
| 2292 | | - * Ignore a range of extra bits in status that do not indicate |
|---|
| 2293 | | - * overflow by themselves. |
|---|
| 2294 | | - */ |
|---|
| 2295 | | - status &= ~(GLOBAL_STATUS_COND_CHG | |
|---|
| 2296 | | - GLOBAL_STATUS_ASIF | |
|---|
| 2297 | | - GLOBAL_STATUS_LBRS_FROZEN); |
|---|
| 2298 | | - if (!status) |
|---|
| 2299 | | - goto done; |
|---|
| 2300 | | - /* |
|---|
| 2301 | | - * In case multiple PEBS events are sampled at the same time, |
|---|
| 2302 | | - * it is possible to have GLOBAL_STATUS bit 62 set indicating |
|---|
| 2303 | | - * PEBS buffer overflow and also seeing at most 3 PEBS counters |
|---|
| 2304 | | - * having their bits set in the status register. This is a sign |
|---|
| 2305 | | - * that there was at least one PEBS record pending at the time |
|---|
| 2306 | | - * of the PMU interrupt. PEBS counters must only be processed |
|---|
| 2307 | | - * via the drain_pebs() calls and not via the regular sample |
|---|
| 2308 | | - * processing loop coming after that the function, otherwise |
|---|
| 2309 | | - * phony regular samples may be generated in the sampling buffer |
|---|
| 2310 | | - * not marked with the EXACT tag. Another possibility is to have |
|---|
| 2311 | | - * one PEBS event and at least one non-PEBS event whic hoverflows |
|---|
| 2312 | | - * while PEBS has armed. In this case, bit 62 of GLOBAL_STATUS will |
|---|
| 2313 | | - * not be set, yet the overflow status bit for the PEBS counter will |
|---|
| 2314 | | - * be on Skylake. |
|---|
| 2315 | | - * |
|---|
| 2316 | | - * To avoid this problem, we systematically ignore the PEBS-enabled |
|---|
| 2317 | | - * counters from the GLOBAL_STATUS mask and we always process PEBS |
|---|
| 2318 | | - * events via drain_pebs(). |
|---|
| 2319 | | - */ |
|---|
| 2320 | | - if (x86_pmu.flags & PMU_FL_PEBS_ALL) |
|---|
| 2321 | | - status &= ~cpuc->pebs_enabled; |
|---|
| 2322 | | - else |
|---|
| 2323 | | - status &= ~(cpuc->pebs_enabled & PEBS_COUNTER_MASK); |
|---|
| 2324 | | - |
|---|
| 2325 | | - /* |
|---|
| 2326 | | - * PEBS overflow sets bit 62 in the global status register |
|---|
| 2327 | | - */ |
|---|
| 2328 | | - if (__test_and_clear_bit(62, (unsigned long *)&status)) { |
|---|
| 2329 | | - handled++; |
|---|
| 2330 | | - x86_pmu.drain_pebs(regs); |
|---|
| 2331 | | - status &= x86_pmu.intel_ctrl | GLOBAL_STATUS_TRACE_TOPAPMI; |
|---|
| 2332 | | - } |
|---|
| 2333 | | - |
|---|
| 2334 | | - /* |
|---|
| 2335 | | - * Intel PT |
|---|
| 2336 | | - */ |
|---|
| 2337 | | - if (__test_and_clear_bit(55, (unsigned long *)&status)) { |
|---|
| 2338 | | - handled++; |
|---|
| 2339 | | - intel_pt_interrupt(); |
|---|
| 2340 | | - } |
|---|
| 2341 | | - |
|---|
| 2342 | | - /* |
|---|
| 2343 | | - * Checkpointed counters can lead to 'spurious' PMIs because the |
|---|
| 2344 | | - * rollback caused by the PMI will have cleared the overflow status |
|---|
| 2345 | | - * bit. Therefore always force probe these counters. |
|---|
| 2346 | | - */ |
|---|
| 2347 | | - status |= cpuc->intel_cp_status; |
|---|
| 2348 | | - |
|---|
| 2349 | | - for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { |
|---|
| 2350 | | - struct perf_event *event = cpuc->events[bit]; |
|---|
| 2351 | | - |
|---|
| 2352 | | - handled++; |
|---|
| 2353 | | - |
|---|
| 2354 | | - if (!test_bit(bit, cpuc->active_mask)) |
|---|
| 2355 | | - continue; |
|---|
| 2356 | | - |
|---|
| 2357 | | - if (!intel_pmu_save_and_restart(event)) |
|---|
| 2358 | | - continue; |
|---|
| 2359 | | - |
|---|
| 2360 | | - perf_sample_data_init(&data, 0, event->hw.last_period); |
|---|
| 2361 | | - |
|---|
| 2362 | | - if (has_branch_stack(event)) |
|---|
| 2363 | | - data.br_stack = &cpuc->lbr_stack; |
|---|
| 2364 | | - |
|---|
| 2365 | | - if (perf_event_overflow(event, &data, regs)) |
|---|
| 2366 | | - x86_pmu_stop(event, 0); |
|---|
| 2367 | | - } |
|---|
| 2842 | + handled += handle_pmi_common(regs, status); |
|---|
| 2368 | 2843 | |
|---|
| 2369 | 2844 | /* |
|---|
| 2370 | 2845 | * Repeat if there is more work to be done: |
|---|
| .. | .. |
|---|
| 2395 | 2870 | { |
|---|
| 2396 | 2871 | if (unlikely(intel_pmu_has_bts(event))) |
|---|
| 2397 | 2872 | return &bts_constraint; |
|---|
| 2873 | + |
|---|
| 2874 | + return NULL; |
|---|
| 2875 | +} |
|---|
| 2876 | + |
|---|
| 2877 | +/* |
|---|
| 2878 | + * Note: matches a fake event, like Fixed2. |
|---|
| 2879 | + */ |
|---|
| 2880 | +static struct event_constraint * |
|---|
| 2881 | +intel_vlbr_constraints(struct perf_event *event) |
|---|
| 2882 | +{ |
|---|
| 2883 | + struct event_constraint *c = &vlbr_constraint; |
|---|
| 2884 | + |
|---|
| 2885 | + if (unlikely(constraint_match(c, event->hw.config))) { |
|---|
| 2886 | + event->hw.flags |= c->flags; |
|---|
| 2887 | + return c; |
|---|
| 2888 | + } |
|---|
| 2398 | 2889 | |
|---|
| 2399 | 2890 | return NULL; |
|---|
| 2400 | 2891 | } |
|---|
| .. | .. |
|---|
| 2573 | 3064 | |
|---|
| 2574 | 3065 | if (x86_pmu.event_constraints) { |
|---|
| 2575 | 3066 | for_each_event_constraint(c, x86_pmu.event_constraints) { |
|---|
| 2576 | | - if ((event->hw.config & c->cmask) == c->code) { |
|---|
| 3067 | + if (constraint_match(c, event->hw.config)) { |
|---|
| 2577 | 3068 | event->hw.flags |= c->flags; |
|---|
| 2578 | 3069 | return c; |
|---|
| 2579 | 3070 | } |
|---|
| .. | .. |
|---|
| 2588 | 3079 | struct perf_event *event) |
|---|
| 2589 | 3080 | { |
|---|
| 2590 | 3081 | struct event_constraint *c; |
|---|
| 3082 | + |
|---|
| 3083 | + c = intel_vlbr_constraints(event); |
|---|
| 3084 | + if (c) |
|---|
| 3085 | + return c; |
|---|
| 2591 | 3086 | |
|---|
| 2592 | 3087 | c = intel_bts_constraints(event); |
|---|
| 2593 | 3088 | if (c) |
|---|
| .. | .. |
|---|
| 2723 | 3218 | struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs; |
|---|
| 2724 | 3219 | struct intel_excl_states *xlo; |
|---|
| 2725 | 3220 | int tid = cpuc->excl_thread_id; |
|---|
| 2726 | | - int is_excl, i; |
|---|
| 3221 | + int is_excl, i, w; |
|---|
| 2727 | 3222 | |
|---|
| 2728 | 3223 | /* |
|---|
| 2729 | 3224 | * validating a group does not require |
|---|
| .. | .. |
|---|
| 2779 | 3274 | * SHARED : sibling counter measuring non-exclusive event |
|---|
| 2780 | 3275 | * UNUSED : sibling counter unused |
|---|
| 2781 | 3276 | */ |
|---|
| 3277 | + w = c->weight; |
|---|
| 2782 | 3278 | for_each_set_bit(i, c->idxmsk, X86_PMC_IDX_MAX) { |
|---|
| 2783 | 3279 | /* |
|---|
| 2784 | 3280 | * exclusive event in sibling counter |
|---|
| 2785 | 3281 | * our corresponding counter cannot be used |
|---|
| 2786 | 3282 | * regardless of our event |
|---|
| 2787 | 3283 | */ |
|---|
| 2788 | | - if (xlo->state[i] == INTEL_EXCL_EXCLUSIVE) |
|---|
| 3284 | + if (xlo->state[i] == INTEL_EXCL_EXCLUSIVE) { |
|---|
| 2789 | 3285 | __clear_bit(i, c->idxmsk); |
|---|
| 3286 | + w--; |
|---|
| 3287 | + continue; |
|---|
| 3288 | + } |
|---|
| 2790 | 3289 | /* |
|---|
| 2791 | 3290 | * if measuring an exclusive event, sibling |
|---|
| 2792 | 3291 | * measuring non-exclusive, then counter cannot |
|---|
| 2793 | 3292 | * be used |
|---|
| 2794 | 3293 | */ |
|---|
| 2795 | | - if (is_excl && xlo->state[i] == INTEL_EXCL_SHARED) |
|---|
| 3294 | + if (is_excl && xlo->state[i] == INTEL_EXCL_SHARED) { |
|---|
| 2796 | 3295 | __clear_bit(i, c->idxmsk); |
|---|
| 3296 | + w--; |
|---|
| 3297 | + continue; |
|---|
| 3298 | + } |
|---|
| 2797 | 3299 | } |
|---|
| 2798 | | - |
|---|
| 2799 | | - /* |
|---|
| 2800 | | - * recompute actual bit weight for scheduling algorithm |
|---|
| 2801 | | - */ |
|---|
| 2802 | | - c->weight = hweight64(c->idxmsk64); |
|---|
| 2803 | 3300 | |
|---|
| 2804 | 3301 | /* |
|---|
| 2805 | 3302 | * if we return an empty mask, then switch |
|---|
| 2806 | 3303 | * back to static empty constraint to avoid |
|---|
| 2807 | 3304 | * the cost of freeing later on |
|---|
| 2808 | 3305 | */ |
|---|
| 2809 | | - if (c->weight == 0) |
|---|
| 3306 | + if (!w) |
|---|
| 2810 | 3307 | c = &emptyconstraint; |
|---|
| 3308 | + |
|---|
| 3309 | + c->weight = w; |
|---|
| 2811 | 3310 | |
|---|
| 2812 | 3311 | return c; |
|---|
| 2813 | 3312 | } |
|---|
| .. | .. |
|---|
| 2816 | 3315 | intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx, |
|---|
| 2817 | 3316 | struct perf_event *event) |
|---|
| 2818 | 3317 | { |
|---|
| 2819 | | - struct event_constraint *c1 = NULL; |
|---|
| 2820 | | - struct event_constraint *c2; |
|---|
| 3318 | + struct event_constraint *c1, *c2; |
|---|
| 2821 | 3319 | |
|---|
| 2822 | | - if (idx >= 0) /* fake does < 0 */ |
|---|
| 2823 | | - c1 = cpuc->event_constraint[idx]; |
|---|
| 3320 | + c1 = cpuc->event_constraint[idx]; |
|---|
| 2824 | 3321 | |
|---|
| 2825 | 3322 | /* |
|---|
| 2826 | 3323 | * first time only |
|---|
| .. | .. |
|---|
| 2828 | 3325 | * - dynamic constraint: handled by intel_get_excl_constraints() |
|---|
| 2829 | 3326 | */ |
|---|
| 2830 | 3327 | c2 = __intel_get_event_constraints(cpuc, idx, event); |
|---|
| 2831 | | - if (c1 && (c1->flags & PERF_X86_EVENT_DYNAMIC)) { |
|---|
| 3328 | + if (c1) { |
|---|
| 3329 | + WARN_ON_ONCE(!(c1->flags & PERF_X86_EVENT_DYNAMIC)); |
|---|
| 2832 | 3330 | bitmap_copy(c1->idxmsk, c2->idxmsk, X86_PMC_IDX_MAX); |
|---|
| 2833 | 3331 | c1->weight = c2->weight; |
|---|
| 2834 | 3332 | c2 = c1; |
|---|
| .. | .. |
|---|
| 3070 | 3568 | return ret; |
|---|
| 3071 | 3569 | |
|---|
| 3072 | 3570 | if (event->attr.precise_ip) { |
|---|
| 3571 | + if ((event->attr.config & INTEL_ARCH_EVENT_MASK) == INTEL_FIXED_VLBR_EVENT) |
|---|
| 3572 | + return -EINVAL; |
|---|
| 3573 | + |
|---|
| 3073 | 3574 | if (!(event->attr.freq || (event->attr.wakeup_events && !event->attr.watermark))) { |
|---|
| 3074 | 3575 | event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD; |
|---|
| 3075 | 3576 | if (!(event->attr.sample_type & |
|---|
| 3076 | | - ~intel_pmu_large_pebs_flags(event))) |
|---|
| 3577 | + ~intel_pmu_large_pebs_flags(event))) { |
|---|
| 3077 | 3578 | event->hw.flags |= PERF_X86_EVENT_LARGE_PEBS; |
|---|
| 3579 | + event->attach_state |= PERF_ATTACH_SCHED_CB; |
|---|
| 3580 | + } |
|---|
| 3078 | 3581 | } |
|---|
| 3079 | 3582 | if (x86_pmu.pebs_aliases) |
|---|
| 3080 | 3583 | x86_pmu.pebs_aliases(event); |
|---|
| .. | .. |
|---|
| 3087 | 3590 | ret = intel_pmu_setup_lbr_filter(event); |
|---|
| 3088 | 3591 | if (ret) |
|---|
| 3089 | 3592 | return ret; |
|---|
| 3593 | + event->attach_state |= PERF_ATTACH_SCHED_CB; |
|---|
| 3090 | 3594 | |
|---|
| 3091 | 3595 | /* |
|---|
| 3092 | 3596 | * BTS is set up earlier in this path, so don't account twice |
|---|
| .. | .. |
|---|
| 3100 | 3604 | } |
|---|
| 3101 | 3605 | } |
|---|
| 3102 | 3606 | |
|---|
| 3607 | + if (event->attr.aux_output) { |
|---|
| 3608 | + if (!event->attr.precise_ip) |
|---|
| 3609 | + return -EINVAL; |
|---|
| 3610 | + |
|---|
| 3611 | + event->hw.flags |= PERF_X86_EVENT_PEBS_VIA_PT; |
|---|
| 3612 | + } |
|---|
| 3613 | + |
|---|
| 3103 | 3614 | if (event->attr.type != PERF_TYPE_RAW) |
|---|
| 3104 | 3615 | return 0; |
|---|
| 3616 | + |
|---|
| 3617 | + /* |
|---|
| 3618 | + * Config Topdown slots and metric events |
|---|
| 3619 | + * |
|---|
| 3620 | + * The slots event on Fixed Counter 3 can support sampling, |
|---|
| 3621 | + * which will be handled normally in x86_perf_event_update(). |
|---|
| 3622 | + * |
|---|
| 3623 | + * Metric events don't support sampling and require being paired |
|---|
| 3624 | + * with a slots event as group leader. When the slots event |
|---|
| 3625 | + * is used in a metrics group, it too cannot support sampling. |
|---|
| 3626 | + */ |
|---|
| 3627 | + if (x86_pmu.intel_cap.perf_metrics && is_topdown_event(event)) { |
|---|
| 3628 | + if (event->attr.config1 || event->attr.config2) |
|---|
| 3629 | + return -EINVAL; |
|---|
| 3630 | + |
|---|
| 3631 | + /* |
|---|
| 3632 | + * The TopDown metrics events and slots event don't |
|---|
| 3633 | + * support any filters. |
|---|
| 3634 | + */ |
|---|
| 3635 | + if (event->attr.config & X86_ALL_EVENT_FLAGS) |
|---|
| 3636 | + return -EINVAL; |
|---|
| 3637 | + |
|---|
| 3638 | + if (is_metric_event(event)) { |
|---|
| 3639 | + struct perf_event *leader = event->group_leader; |
|---|
| 3640 | + |
|---|
| 3641 | + /* The metric events don't support sampling. */ |
|---|
| 3642 | + if (is_sampling_event(event)) |
|---|
| 3643 | + return -EINVAL; |
|---|
| 3644 | + |
|---|
| 3645 | + /* The metric events require a slots group leader. */ |
|---|
| 3646 | + if (!is_slots_event(leader)) |
|---|
| 3647 | + return -EINVAL; |
|---|
| 3648 | + |
|---|
| 3649 | + /* |
|---|
| 3650 | + * The leader/SLOTS must not be a sampling event for |
|---|
| 3651 | + * metric use; hardware requires it starts at 0 when used |
|---|
| 3652 | + * in conjunction with MSR_PERF_METRICS. |
|---|
| 3653 | + */ |
|---|
| 3654 | + if (is_sampling_event(leader)) |
|---|
| 3655 | + return -EINVAL; |
|---|
| 3656 | + |
|---|
| 3657 | + event->event_caps |= PERF_EV_CAP_SIBLING; |
|---|
| 3658 | + /* |
|---|
| 3659 | + * Only once we have a METRICs sibling do we |
|---|
| 3660 | + * need TopDown magic. |
|---|
| 3661 | + */ |
|---|
| 3662 | + leader->hw.flags |= PERF_X86_EVENT_TOPDOWN; |
|---|
| 3663 | + event->hw.flags |= PERF_X86_EVENT_TOPDOWN; |
|---|
| 3664 | + } |
|---|
| 3665 | + } |
|---|
| 3105 | 3666 | |
|---|
| 3106 | 3667 | if (!(event->attr.config & ARCH_PERFMON_EVENTSEL_ANY)) |
|---|
| 3107 | 3668 | return 0; |
|---|
| .. | .. |
|---|
| 3118 | 3679 | return 0; |
|---|
| 3119 | 3680 | } |
|---|
| 3120 | 3681 | |
|---|
| 3682 | +#ifdef CONFIG_RETPOLINE |
|---|
| 3683 | +static struct perf_guest_switch_msr *core_guest_get_msrs(int *nr); |
|---|
| 3684 | +static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr); |
|---|
| 3685 | +#endif |
|---|
| 3686 | + |
|---|
| 3121 | 3687 | struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr) |
|---|
| 3122 | 3688 | { |
|---|
| 3689 | +#ifdef CONFIG_RETPOLINE |
|---|
| 3690 | + if (x86_pmu.guest_get_msrs == intel_guest_get_msrs) |
|---|
| 3691 | + return intel_guest_get_msrs(nr); |
|---|
| 3692 | + else if (x86_pmu.guest_get_msrs == core_guest_get_msrs) |
|---|
| 3693 | + return core_guest_get_msrs(nr); |
|---|
| 3694 | +#endif |
|---|
| 3123 | 3695 | if (x86_pmu.guest_get_msrs) |
|---|
| 3124 | 3696 | return x86_pmu.guest_get_msrs(nr); |
|---|
| 3125 | 3697 | *nr = 0; |
|---|
| .. | .. |
|---|
| 3135 | 3707 | arr[0].msr = MSR_CORE_PERF_GLOBAL_CTRL; |
|---|
| 3136 | 3708 | arr[0].host = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask; |
|---|
| 3137 | 3709 | arr[0].guest = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_host_mask; |
|---|
| 3138 | | - /* |
|---|
| 3139 | | - * If PMU counter has PEBS enabled it is not enough to disable counter |
|---|
| 3140 | | - * on a guest entry since PEBS memory write can overshoot guest entry |
|---|
| 3141 | | - * and corrupt guest memory. Disabling PEBS solves the problem. |
|---|
| 3142 | | - */ |
|---|
| 3143 | | - arr[1].msr = MSR_IA32_PEBS_ENABLE; |
|---|
| 3144 | | - arr[1].host = cpuc->pebs_enabled; |
|---|
| 3145 | | - arr[1].guest = 0; |
|---|
| 3710 | + if (x86_pmu.flags & PMU_FL_PEBS_ALL) |
|---|
| 3711 | + arr[0].guest &= ~cpuc->pebs_enabled; |
|---|
| 3712 | + else |
|---|
| 3713 | + arr[0].guest &= ~(cpuc->pebs_enabled & PEBS_COUNTER_MASK); |
|---|
| 3714 | + *nr = 1; |
|---|
| 3146 | 3715 | |
|---|
| 3147 | | - *nr = 2; |
|---|
| 3716 | + if (x86_pmu.pebs && x86_pmu.pebs_no_isolation) { |
|---|
| 3717 | + /* |
|---|
| 3718 | + * If PMU counter has PEBS enabled it is not enough to |
|---|
| 3719 | + * disable counter on a guest entry since PEBS memory |
|---|
| 3720 | + * write can overshoot guest entry and corrupt guest |
|---|
| 3721 | + * memory. Disabling PEBS solves the problem. |
|---|
| 3722 | + * |
|---|
| 3723 | + * Don't do this if the CPU already enforces it. |
|---|
| 3724 | + */ |
|---|
| 3725 | + arr[1].msr = MSR_IA32_PEBS_ENABLE; |
|---|
| 3726 | + arr[1].host = cpuc->pebs_enabled; |
|---|
| 3727 | + arr[1].guest = 0; |
|---|
| 3728 | + *nr = 2; |
|---|
| 3729 | + } |
|---|
| 3730 | + |
|---|
| 3148 | 3731 | return arr; |
|---|
| 3149 | 3732 | } |
|---|
| 3150 | 3733 | |
|---|
| .. | .. |
|---|
| 3241 | 3824 | static struct event_constraint counter2_constraint = |
|---|
| 3242 | 3825 | EVENT_CONSTRAINT(0, 0x4, 0); |
|---|
| 3243 | 3826 | |
|---|
| 3827 | +static struct event_constraint fixed0_constraint = |
|---|
| 3828 | + FIXED_EVENT_CONSTRAINT(0x00c0, 0); |
|---|
| 3829 | + |
|---|
| 3830 | +static struct event_constraint fixed0_counter0_constraint = |
|---|
| 3831 | + INTEL_ALL_EVENT_CONSTRAINT(0, 0x100000001ULL); |
|---|
| 3832 | + |
|---|
| 3244 | 3833 | static struct event_constraint * |
|---|
| 3245 | 3834 | hsw_get_event_constraints(struct cpu_hw_events *cpuc, int idx, |
|---|
| 3246 | 3835 | struct perf_event *event) |
|---|
| .. | .. |
|---|
| 3260 | 3849 | } |
|---|
| 3261 | 3850 | |
|---|
| 3262 | 3851 | static struct event_constraint * |
|---|
| 3852 | +icl_get_event_constraints(struct cpu_hw_events *cpuc, int idx, |
|---|
| 3853 | + struct perf_event *event) |
|---|
| 3854 | +{ |
|---|
| 3855 | + /* |
|---|
| 3856 | + * Fixed counter 0 has less skid. |
|---|
| 3857 | + * Force instruction:ppp in Fixed counter 0 |
|---|
| 3858 | + */ |
|---|
| 3859 | + if ((event->attr.precise_ip == 3) && |
|---|
| 3860 | + constraint_match(&fixed0_constraint, event->hw.config)) |
|---|
| 3861 | + return &fixed0_constraint; |
|---|
| 3862 | + |
|---|
| 3863 | + return hsw_get_event_constraints(cpuc, idx, event); |
|---|
| 3864 | +} |
|---|
| 3865 | + |
|---|
| 3866 | +static struct event_constraint * |
|---|
| 3263 | 3867 | glp_get_event_constraints(struct cpu_hw_events *cpuc, int idx, |
|---|
| 3264 | 3868 | struct perf_event *event) |
|---|
| 3265 | 3869 | { |
|---|
| .. | .. |
|---|
| 3268 | 3872 | /* :ppp means to do reduced skid PEBS which is PMC0 only. */ |
|---|
| 3269 | 3873 | if (event->attr.precise_ip == 3) |
|---|
| 3270 | 3874 | return &counter0_constraint; |
|---|
| 3875 | + |
|---|
| 3876 | + c = intel_get_event_constraints(cpuc, idx, event); |
|---|
| 3877 | + |
|---|
| 3878 | + return c; |
|---|
| 3879 | +} |
|---|
| 3880 | + |
|---|
| 3881 | +static struct event_constraint * |
|---|
| 3882 | +tnt_get_event_constraints(struct cpu_hw_events *cpuc, int idx, |
|---|
| 3883 | + struct perf_event *event) |
|---|
| 3884 | +{ |
|---|
| 3885 | + struct event_constraint *c; |
|---|
| 3886 | + |
|---|
| 3887 | + /* |
|---|
| 3888 | + * :ppp means to do reduced skid PEBS, |
|---|
| 3889 | + * which is available on PMC0 and fixed counter 0. |
|---|
| 3890 | + */ |
|---|
| 3891 | + if (event->attr.precise_ip == 3) { |
|---|
| 3892 | + /* Force instruction:ppp on PMC0 and Fixed counter 0 */ |
|---|
| 3893 | + if (constraint_match(&fixed0_constraint, event->hw.config)) |
|---|
| 3894 | + return &fixed0_counter0_constraint; |
|---|
| 3895 | + |
|---|
| 3896 | + return &counter0_constraint; |
|---|
| 3897 | + } |
|---|
| 3271 | 3898 | |
|---|
| 3272 | 3899 | c = intel_get_event_constraints(cpuc, idx, event); |
|---|
| 3273 | 3900 | |
|---|
| .. | .. |
|---|
| 3285 | 3912 | /* |
|---|
| 3286 | 3913 | * Without TFA we must not use PMC3. |
|---|
| 3287 | 3914 | */ |
|---|
| 3288 | | - if (!allow_tsx_force_abort && test_bit(3, c->idxmsk) && idx >= 0) { |
|---|
| 3915 | + if (!allow_tsx_force_abort && test_bit(3, c->idxmsk)) { |
|---|
| 3289 | 3916 | c = dyn_constraint(cpuc, c, idx); |
|---|
| 3290 | 3917 | c->idxmsk64 &= ~(1ULL << 3); |
|---|
| 3291 | 3918 | c->weight--; |
|---|
| .. | .. |
|---|
| 3387 | 4014 | |
|---|
| 3388 | 4015 | int intel_cpuc_prepare(struct cpu_hw_events *cpuc, int cpu) |
|---|
| 3389 | 4016 | { |
|---|
| 4017 | + cpuc->pebs_record_size = x86_pmu.pebs_record_size; |
|---|
| 4018 | + |
|---|
| 3390 | 4019 | if (x86_pmu.extra_regs || x86_pmu.lbr_sel_map) { |
|---|
| 3391 | 4020 | cpuc->shared_regs = allocate_shared_regs(cpu); |
|---|
| 3392 | 4021 | if (!cpuc->shared_regs) |
|---|
| .. | .. |
|---|
| 3464 | 4093 | if (x86_pmu.version > 1) |
|---|
| 3465 | 4094 | flip_smm_bit(&x86_pmu.attr_freeze_on_smi); |
|---|
| 3466 | 4095 | |
|---|
| 4096 | + if (x86_pmu.counter_freezing) |
|---|
| 4097 | + enable_counter_freeze(); |
|---|
| 4098 | + |
|---|
| 4099 | + /* Disable perf metrics if any added CPU doesn't support it. */ |
|---|
| 4100 | + if (x86_pmu.intel_cap.perf_metrics) { |
|---|
| 4101 | + union perf_capabilities perf_cap; |
|---|
| 4102 | + |
|---|
| 4103 | + rdmsrl(MSR_IA32_PERF_CAPABILITIES, perf_cap.capabilities); |
|---|
| 4104 | + if (!perf_cap.perf_metrics) { |
|---|
| 4105 | + x86_pmu.intel_cap.perf_metrics = 0; |
|---|
| 4106 | + x86_pmu.intel_ctrl &= ~(1ULL << GLOBAL_CTRL_EN_PERF_METRICS); |
|---|
| 4107 | + } |
|---|
| 4108 | + } |
|---|
| 4109 | + |
|---|
| 3467 | 4110 | if (!cpuc->shared_regs) |
|---|
| 3468 | 4111 | return; |
|---|
| 3469 | 4112 | |
|---|
| .. | .. |
|---|
| 3523 | 4166 | static void intel_pmu_cpu_dying(int cpu) |
|---|
| 3524 | 4167 | { |
|---|
| 3525 | 4168 | fini_debug_store_on_cpu(cpu); |
|---|
| 4169 | + |
|---|
| 4170 | + if (x86_pmu.counter_freezing) |
|---|
| 4171 | + disable_counter_freeze(); |
|---|
| 3526 | 4172 | } |
|---|
| 3527 | 4173 | |
|---|
| 3528 | 4174 | void intel_cpuc_finish(struct cpu_hw_events *cpuc) |
|---|
| .. | .. |
|---|
| 3551 | 4197 | intel_pmu_lbr_sched_task(ctx, sched_in); |
|---|
| 3552 | 4198 | } |
|---|
| 3553 | 4199 | |
|---|
| 4200 | +static void intel_pmu_swap_task_ctx(struct perf_event_context *prev, |
|---|
| 4201 | + struct perf_event_context *next) |
|---|
| 4202 | +{ |
|---|
| 4203 | + intel_pmu_lbr_swap_task_ctx(prev, next); |
|---|
| 4204 | +} |
|---|
| 4205 | + |
|---|
| 3554 | 4206 | static int intel_pmu_check_period(struct perf_event *event, u64 value) |
|---|
| 3555 | 4207 | { |
|---|
| 3556 | 4208 | return intel_pmu_has_bts_period(event, value) ? -EINVAL : 0; |
|---|
| 4209 | +} |
|---|
| 4210 | + |
|---|
| 4211 | +static int intel_pmu_aux_output_match(struct perf_event *event) |
|---|
| 4212 | +{ |
|---|
| 4213 | + if (!x86_pmu.intel_cap.pebs_output_pt_available) |
|---|
| 4214 | + return 0; |
|---|
| 4215 | + |
|---|
| 4216 | + return is_intel_pt_event(event); |
|---|
| 3557 | 4217 | } |
|---|
| 3558 | 4218 | |
|---|
| 3559 | 4219 | PMU_FORMAT_ATTR(offcore_rsp, "config1:0-63"); |
|---|
| .. | .. |
|---|
| 3638 | 4298 | .cpu_dead = intel_pmu_cpu_dead, |
|---|
| 3639 | 4299 | |
|---|
| 3640 | 4300 | .check_period = intel_pmu_check_period, |
|---|
| 3641 | | -}; |
|---|
| 3642 | 4301 | |
|---|
| 3643 | | -static struct attribute *intel_pmu_attrs[]; |
|---|
| 4302 | + .lbr_reset = intel_pmu_lbr_reset_64, |
|---|
| 4303 | + .lbr_read = intel_pmu_lbr_read_64, |
|---|
| 4304 | + .lbr_save = intel_pmu_lbr_save, |
|---|
| 4305 | + .lbr_restore = intel_pmu_lbr_restore, |
|---|
| 4306 | +}; |
|---|
| 3644 | 4307 | |
|---|
| 3645 | 4308 | static __initconst const struct x86_pmu intel_pmu = { |
|---|
| 3646 | 4309 | .name = "Intel", |
|---|
| .. | .. |
|---|
| 3673 | 4336 | .format_attrs = intel_arch3_formats_attr, |
|---|
| 3674 | 4337 | .events_sysfs_show = intel_event_sysfs_show, |
|---|
| 3675 | 4338 | |
|---|
| 3676 | | - .attrs = intel_pmu_attrs, |
|---|
| 3677 | | - |
|---|
| 3678 | 4339 | .cpu_prepare = intel_pmu_cpu_prepare, |
|---|
| 3679 | 4340 | .cpu_starting = intel_pmu_cpu_starting, |
|---|
| 3680 | 4341 | .cpu_dying = intel_pmu_cpu_dying, |
|---|
| .. | .. |
|---|
| 3682 | 4343 | |
|---|
| 3683 | 4344 | .guest_get_msrs = intel_guest_get_msrs, |
|---|
| 3684 | 4345 | .sched_task = intel_pmu_sched_task, |
|---|
| 4346 | + .swap_task_ctx = intel_pmu_swap_task_ctx, |
|---|
| 3685 | 4347 | |
|---|
| 3686 | 4348 | .check_period = intel_pmu_check_period, |
|---|
| 4349 | + |
|---|
| 4350 | + .aux_output_match = intel_pmu_aux_output_match, |
|---|
| 4351 | + |
|---|
| 4352 | + .lbr_reset = intel_pmu_lbr_reset_64, |
|---|
| 4353 | + .lbr_read = intel_pmu_lbr_read_64, |
|---|
| 4354 | + .lbr_save = intel_pmu_lbr_save, |
|---|
| 4355 | + .lbr_restore = intel_pmu_lbr_restore, |
|---|
| 4356 | + |
|---|
| 4357 | + /* |
|---|
| 4358 | + * SMM has access to all 4 rings and while traditionally SMM code only |
|---|
| 4359 | + * ran in CPL0, 2021-era firmware is starting to make use of CPL3 in SMM. |
|---|
| 4360 | + * |
|---|
| 4361 | + * Since the EVENTSEL.{USR,OS} CPL filtering makes no distinction |
|---|
| 4362 | + * between SMM or not, this results in what should be pure userspace |
|---|
| 4363 | + * counters including SMM data. |
|---|
| 4364 | + * |
|---|
| 4365 | + * This is a clear privilege issue, therefore globally disable |
|---|
| 4366 | + * counting SMM by default. |
|---|
| 4367 | + */ |
|---|
| 4368 | + .attr_freeze_on_smi = 1, |
|---|
| 3687 | 4369 | }; |
|---|
| 3688 | 4370 | |
|---|
| 3689 | 4371 | static __init void intel_clovertown_quirk(void) |
|---|
| .. | .. |
|---|
| 3712 | 4394 | x86_pmu.pebs_constraints = NULL; |
|---|
| 3713 | 4395 | } |
|---|
| 3714 | 4396 | |
|---|
| 3715 | | -static int intel_snb_pebs_broken(int cpu) |
|---|
| 4397 | +static const struct x86_cpu_desc isolation_ucodes[] = { |
|---|
| 4398 | + INTEL_CPU_DESC(INTEL_FAM6_HASWELL, 3, 0x0000001f), |
|---|
| 4399 | + INTEL_CPU_DESC(INTEL_FAM6_HASWELL_L, 1, 0x0000001e), |
|---|
| 4400 | + INTEL_CPU_DESC(INTEL_FAM6_HASWELL_G, 1, 0x00000015), |
|---|
| 4401 | + INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 2, 0x00000037), |
|---|
| 4402 | + INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 4, 0x0000000a), |
|---|
| 4403 | + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL, 4, 0x00000023), |
|---|
| 4404 | + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_G, 1, 0x00000014), |
|---|
| 4405 | + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 2, 0x00000010), |
|---|
| 4406 | + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 3, 0x07000009), |
|---|
| 4407 | + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 4, 0x0f000009), |
|---|
| 4408 | + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 5, 0x0e000002), |
|---|
| 4409 | + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_X, 1, 0x0b000014), |
|---|
| 4410 | + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 3, 0x00000021), |
|---|
| 4411 | + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 4, 0x00000000), |
|---|
| 4412 | + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 5, 0x00000000), |
|---|
| 4413 | + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 6, 0x00000000), |
|---|
| 4414 | + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 7, 0x00000000), |
|---|
| 4415 | + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 11, 0x00000000), |
|---|
| 4416 | + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_L, 3, 0x0000007c), |
|---|
| 4417 | + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE, 3, 0x0000007c), |
|---|
| 4418 | + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 9, 0x0000004e), |
|---|
| 4419 | + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_L, 9, 0x0000004e), |
|---|
| 4420 | + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_L, 10, 0x0000004e), |
|---|
| 4421 | + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_L, 11, 0x0000004e), |
|---|
| 4422 | + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_L, 12, 0x0000004e), |
|---|
| 4423 | + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 10, 0x0000004e), |
|---|
| 4424 | + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 11, 0x0000004e), |
|---|
| 4425 | + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 12, 0x0000004e), |
|---|
| 4426 | + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 13, 0x0000004e), |
|---|
| 4427 | + {} |
|---|
| 4428 | +}; |
|---|
| 4429 | + |
|---|
| 4430 | +static void intel_check_pebs_isolation(void) |
|---|
| 3716 | 4431 | { |
|---|
| 3717 | | - u32 rev = UINT_MAX; /* default to broken for unknown models */ |
|---|
| 4432 | + x86_pmu.pebs_no_isolation = !x86_cpu_has_min_microcode_rev(isolation_ucodes); |
|---|
| 4433 | +} |
|---|
| 3718 | 4434 | |
|---|
| 3719 | | - switch (cpu_data(cpu).x86_model) { |
|---|
| 3720 | | - case INTEL_FAM6_SANDYBRIDGE: |
|---|
| 3721 | | - rev = 0x28; |
|---|
| 3722 | | - break; |
|---|
| 4435 | +static __init void intel_pebs_isolation_quirk(void) |
|---|
| 4436 | +{ |
|---|
| 4437 | + WARN_ON_ONCE(x86_pmu.check_microcode); |
|---|
| 4438 | + x86_pmu.check_microcode = intel_check_pebs_isolation; |
|---|
| 4439 | + intel_check_pebs_isolation(); |
|---|
| 4440 | +} |
|---|
| 3723 | 4441 | |
|---|
| 3724 | | - case INTEL_FAM6_SANDYBRIDGE_X: |
|---|
| 3725 | | - switch (cpu_data(cpu).x86_stepping) { |
|---|
| 3726 | | - case 6: rev = 0x618; break; |
|---|
| 3727 | | - case 7: rev = 0x70c; break; |
|---|
| 3728 | | - } |
|---|
| 3729 | | - } |
|---|
| 4442 | +static const struct x86_cpu_desc pebs_ucodes[] = { |
|---|
| 4443 | + INTEL_CPU_DESC(INTEL_FAM6_SANDYBRIDGE, 7, 0x00000028), |
|---|
| 4444 | + INTEL_CPU_DESC(INTEL_FAM6_SANDYBRIDGE_X, 6, 0x00000618), |
|---|
| 4445 | + INTEL_CPU_DESC(INTEL_FAM6_SANDYBRIDGE_X, 7, 0x0000070c), |
|---|
| 4446 | + {} |
|---|
| 4447 | +}; |
|---|
| 3730 | 4448 | |
|---|
| 3731 | | - return (cpu_data(cpu).microcode < rev); |
|---|
| 4449 | +static bool intel_snb_pebs_broken(void) |
|---|
| 4450 | +{ |
|---|
| 4451 | + return !x86_cpu_has_min_microcode_rev(pebs_ucodes); |
|---|
| 3732 | 4452 | } |
|---|
| 3733 | 4453 | |
|---|
| 3734 | 4454 | static void intel_snb_check_microcode(void) |
|---|
| 3735 | 4455 | { |
|---|
| 3736 | | - int pebs_broken = 0; |
|---|
| 3737 | | - int cpu; |
|---|
| 3738 | | - |
|---|
| 3739 | | - for_each_online_cpu(cpu) { |
|---|
| 3740 | | - if ((pebs_broken = intel_snb_pebs_broken(cpu))) |
|---|
| 3741 | | - break; |
|---|
| 3742 | | - } |
|---|
| 3743 | | - |
|---|
| 3744 | | - if (pebs_broken == x86_pmu.pebs_broken) |
|---|
| 4456 | + if (intel_snb_pebs_broken() == x86_pmu.pebs_broken) |
|---|
| 3745 | 4457 | return; |
|---|
| 3746 | 4458 | |
|---|
| 3747 | 4459 | /* |
|---|
| .. | .. |
|---|
| 3770 | 4482 | static bool check_msr(unsigned long msr, u64 mask) |
|---|
| 3771 | 4483 | { |
|---|
| 3772 | 4484 | u64 val_old, val_new, val_tmp; |
|---|
| 4485 | + |
|---|
| 4486 | + /* |
|---|
| 4487 | + * Disable the check for real HW, so we don't |
|---|
| 4488 | + * mess with potentionaly enabled registers: |
|---|
| 4489 | + */ |
|---|
| 4490 | + if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) |
|---|
| 4491 | + return true; |
|---|
| 3773 | 4492 | |
|---|
| 3774 | 4493 | /* |
|---|
| 3775 | 4494 | * Read the current value, change it and read it back to see if it |
|---|
| .. | .. |
|---|
| 3858 | 4577 | } |
|---|
| 3859 | 4578 | } |
|---|
| 3860 | 4579 | |
|---|
| 4580 | +static const struct x86_cpu_desc counter_freezing_ucodes[] = { |
|---|
| 4581 | + INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT, 2, 0x0000000e), |
|---|
| 4582 | + INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT, 9, 0x0000002e), |
|---|
| 4583 | + INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT, 10, 0x00000008), |
|---|
| 4584 | + INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT_D, 1, 0x00000028), |
|---|
| 4585 | + INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT_PLUS, 1, 0x00000028), |
|---|
| 4586 | + INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT_PLUS, 8, 0x00000006), |
|---|
| 4587 | + {} |
|---|
| 4588 | +}; |
|---|
| 4589 | + |
|---|
| 4590 | +static bool intel_counter_freezing_broken(void) |
|---|
| 4591 | +{ |
|---|
| 4592 | + return !x86_cpu_has_min_microcode_rev(counter_freezing_ucodes); |
|---|
| 4593 | +} |
|---|
| 4594 | + |
|---|
| 4595 | +static __init void intel_counter_freezing_quirk(void) |
|---|
| 4596 | +{ |
|---|
| 4597 | + /* Check if it's already disabled */ |
|---|
| 4598 | + if (disable_counter_freezing) |
|---|
| 4599 | + return; |
|---|
| 4600 | + |
|---|
| 4601 | + /* |
|---|
| 4602 | + * If the system starts with the wrong ucode, leave the |
|---|
| 4603 | + * counter-freezing feature permanently disabled. |
|---|
| 4604 | + */ |
|---|
| 4605 | + if (intel_counter_freezing_broken()) { |
|---|
| 4606 | + pr_info("PMU counter freezing disabled due to CPU errata," |
|---|
| 4607 | + "please upgrade microcode\n"); |
|---|
| 4608 | + x86_pmu.counter_freezing = false; |
|---|
| 4609 | + x86_pmu.handle_irq = intel_pmu_handle_irq; |
|---|
| 4610 | + } |
|---|
| 4611 | +} |
|---|
| 4612 | + |
|---|
| 3861 | 4613 | /* |
|---|
| 3862 | 4614 | * enable software workaround for errata: |
|---|
| 3863 | 4615 | * SNB: BJ122 |
|---|
| .. | .. |
|---|
| 3897 | 4649 | EVENT_ATTR_STR(cycles-ct, cycles_ct, "event=0x3c,in_tx=1,in_tx_cp=1"); |
|---|
| 3898 | 4650 | |
|---|
| 3899 | 4651 | static struct attribute *hsw_events_attrs[] = { |
|---|
| 3900 | | - EVENT_PTR(mem_ld_hsw), |
|---|
| 3901 | | - EVENT_PTR(mem_st_hsw), |
|---|
| 3902 | 4652 | EVENT_PTR(td_slots_issued), |
|---|
| 3903 | 4653 | EVENT_PTR(td_slots_retired), |
|---|
| 3904 | 4654 | EVENT_PTR(td_fetch_bubbles), |
|---|
| .. | .. |
|---|
| 3907 | 4657 | EVENT_PTR(td_recovery_bubbles), |
|---|
| 3908 | 4658 | EVENT_PTR(td_recovery_bubbles_scale), |
|---|
| 3909 | 4659 | NULL |
|---|
| 4660 | +}; |
|---|
| 4661 | + |
|---|
| 4662 | +static struct attribute *hsw_mem_events_attrs[] = { |
|---|
| 4663 | + EVENT_PTR(mem_ld_hsw), |
|---|
| 4664 | + EVENT_PTR(mem_st_hsw), |
|---|
| 4665 | + NULL, |
|---|
| 3910 | 4666 | }; |
|---|
| 3911 | 4667 | |
|---|
| 3912 | 4668 | static struct attribute *hsw_tsx_events_attrs[] = { |
|---|
| .. | .. |
|---|
| 3925 | 4681 | NULL |
|---|
| 3926 | 4682 | }; |
|---|
| 3927 | 4683 | |
|---|
| 3928 | | -static __init struct attribute **get_hsw_events_attrs(void) |
|---|
| 3929 | | -{ |
|---|
| 3930 | | - return boot_cpu_has(X86_FEATURE_RTM) ? |
|---|
| 3931 | | - merge_attr(hsw_events_attrs, hsw_tsx_events_attrs) : |
|---|
| 3932 | | - hsw_events_attrs; |
|---|
| 3933 | | -} |
|---|
| 4684 | +EVENT_ATTR_STR(tx-capacity-read, tx_capacity_read, "event=0x54,umask=0x80"); |
|---|
| 4685 | +EVENT_ATTR_STR(tx-capacity-write, tx_capacity_write, "event=0x54,umask=0x2"); |
|---|
| 4686 | +EVENT_ATTR_STR(el-capacity-read, el_capacity_read, "event=0x54,umask=0x80"); |
|---|
| 4687 | +EVENT_ATTR_STR(el-capacity-write, el_capacity_write, "event=0x54,umask=0x2"); |
|---|
| 4688 | + |
|---|
| 4689 | +static struct attribute *icl_events_attrs[] = { |
|---|
| 4690 | + EVENT_PTR(mem_ld_hsw), |
|---|
| 4691 | + EVENT_PTR(mem_st_hsw), |
|---|
| 4692 | + NULL, |
|---|
| 4693 | +}; |
|---|
| 4694 | + |
|---|
| 4695 | +static struct attribute *icl_td_events_attrs[] = { |
|---|
| 4696 | + EVENT_PTR(slots), |
|---|
| 4697 | + EVENT_PTR(td_retiring), |
|---|
| 4698 | + EVENT_PTR(td_bad_spec), |
|---|
| 4699 | + EVENT_PTR(td_fe_bound), |
|---|
| 4700 | + EVENT_PTR(td_be_bound), |
|---|
| 4701 | + NULL, |
|---|
| 4702 | +}; |
|---|
| 4703 | + |
|---|
| 4704 | +static struct attribute *icl_tsx_events_attrs[] = { |
|---|
| 4705 | + EVENT_PTR(tx_start), |
|---|
| 4706 | + EVENT_PTR(tx_abort), |
|---|
| 4707 | + EVENT_PTR(tx_commit), |
|---|
| 4708 | + EVENT_PTR(tx_capacity_read), |
|---|
| 4709 | + EVENT_PTR(tx_capacity_write), |
|---|
| 4710 | + EVENT_PTR(tx_conflict), |
|---|
| 4711 | + EVENT_PTR(el_start), |
|---|
| 4712 | + EVENT_PTR(el_abort), |
|---|
| 4713 | + EVENT_PTR(el_commit), |
|---|
| 4714 | + EVENT_PTR(el_capacity_read), |
|---|
| 4715 | + EVENT_PTR(el_capacity_write), |
|---|
| 4716 | + EVENT_PTR(el_conflict), |
|---|
| 4717 | + EVENT_PTR(cycles_t), |
|---|
| 4718 | + EVENT_PTR(cycles_ct), |
|---|
| 4719 | + NULL, |
|---|
| 4720 | +}; |
|---|
| 3934 | 4721 | |
|---|
| 3935 | 4722 | static ssize_t freeze_on_smi_show(struct device *cdev, |
|---|
| 3936 | 4723 | struct device_attribute *attr, |
|---|
| .. | .. |
|---|
| 3971 | 4758 | return count; |
|---|
| 3972 | 4759 | } |
|---|
| 3973 | 4760 | |
|---|
| 4761 | +static void update_tfa_sched(void *ignored) |
|---|
| 4762 | +{ |
|---|
| 4763 | + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
|---|
| 4764 | + |
|---|
| 4765 | + /* |
|---|
| 4766 | + * check if PMC3 is used |
|---|
| 4767 | + * and if so force schedule out for all event types all contexts |
|---|
| 4768 | + */ |
|---|
| 4769 | + if (test_bit(3, cpuc->active_mask)) |
|---|
| 4770 | + perf_pmu_resched(x86_get_pmu(smp_processor_id())); |
|---|
| 4771 | +} |
|---|
| 4772 | + |
|---|
| 4773 | +static ssize_t show_sysctl_tfa(struct device *cdev, |
|---|
| 4774 | + struct device_attribute *attr, |
|---|
| 4775 | + char *buf) |
|---|
| 4776 | +{ |
|---|
| 4777 | + return snprintf(buf, 40, "%d\n", allow_tsx_force_abort); |
|---|
| 4778 | +} |
|---|
| 4779 | + |
|---|
| 4780 | +static ssize_t set_sysctl_tfa(struct device *cdev, |
|---|
| 4781 | + struct device_attribute *attr, |
|---|
| 4782 | + const char *buf, size_t count) |
|---|
| 4783 | +{ |
|---|
| 4784 | + bool val; |
|---|
| 4785 | + ssize_t ret; |
|---|
| 4786 | + |
|---|
| 4787 | + ret = kstrtobool(buf, &val); |
|---|
| 4788 | + if (ret) |
|---|
| 4789 | + return ret; |
|---|
| 4790 | + |
|---|
| 4791 | + /* no change */ |
|---|
| 4792 | + if (val == allow_tsx_force_abort) |
|---|
| 4793 | + return count; |
|---|
| 4794 | + |
|---|
| 4795 | + allow_tsx_force_abort = val; |
|---|
| 4796 | + |
|---|
| 4797 | + get_online_cpus(); |
|---|
| 4798 | + on_each_cpu(update_tfa_sched, NULL, 1); |
|---|
| 4799 | + put_online_cpus(); |
|---|
| 4800 | + |
|---|
| 4801 | + return count; |
|---|
| 4802 | +} |
|---|
| 4803 | + |
|---|
| 4804 | + |
|---|
| 3974 | 4805 | static DEVICE_ATTR_RW(freeze_on_smi); |
|---|
| 3975 | 4806 | |
|---|
| 3976 | 4807 | static ssize_t branches_show(struct device *cdev, |
|---|
| .. | .. |
|---|
| 4003 | 4834 | NULL |
|---|
| 4004 | 4835 | }; |
|---|
| 4005 | 4836 | |
|---|
| 4006 | | -static DEVICE_BOOL_ATTR(allow_tsx_force_abort, 0644, allow_tsx_force_abort); |
|---|
| 4837 | +static DEVICE_ATTR(allow_tsx_force_abort, 0644, |
|---|
| 4838 | + show_sysctl_tfa, |
|---|
| 4839 | + set_sysctl_tfa); |
|---|
| 4007 | 4840 | |
|---|
| 4008 | 4841 | static struct attribute *intel_pmu_attrs[] = { |
|---|
| 4009 | 4842 | &dev_attr_freeze_on_smi.attr, |
|---|
| 4010 | | - NULL, /* &dev_attr_allow_tsx_force_abort.attr.attr */ |
|---|
| 4843 | + &dev_attr_allow_tsx_force_abort.attr, |
|---|
| 4011 | 4844 | NULL, |
|---|
| 4012 | 4845 | }; |
|---|
| 4013 | 4846 | |
|---|
| 4847 | +static umode_t |
|---|
| 4848 | +tsx_is_visible(struct kobject *kobj, struct attribute *attr, int i) |
|---|
| 4849 | +{ |
|---|
| 4850 | + return boot_cpu_has(X86_FEATURE_RTM) ? attr->mode : 0; |
|---|
| 4851 | +} |
|---|
| 4852 | + |
|---|
| 4853 | +static umode_t |
|---|
| 4854 | +pebs_is_visible(struct kobject *kobj, struct attribute *attr, int i) |
|---|
| 4855 | +{ |
|---|
| 4856 | + return x86_pmu.pebs ? attr->mode : 0; |
|---|
| 4857 | +} |
|---|
| 4858 | + |
|---|
| 4859 | +static umode_t |
|---|
| 4860 | +lbr_is_visible(struct kobject *kobj, struct attribute *attr, int i) |
|---|
| 4861 | +{ |
|---|
| 4862 | + return x86_pmu.lbr_nr ? attr->mode : 0; |
|---|
| 4863 | +} |
|---|
| 4864 | + |
|---|
| 4865 | +static umode_t |
|---|
| 4866 | +exra_is_visible(struct kobject *kobj, struct attribute *attr, int i) |
|---|
| 4867 | +{ |
|---|
| 4868 | + return x86_pmu.version >= 2 ? attr->mode : 0; |
|---|
| 4869 | +} |
|---|
| 4870 | + |
|---|
| 4871 | +static umode_t |
|---|
| 4872 | +default_is_visible(struct kobject *kobj, struct attribute *attr, int i) |
|---|
| 4873 | +{ |
|---|
| 4874 | + if (attr == &dev_attr_allow_tsx_force_abort.attr) |
|---|
| 4875 | + return x86_pmu.flags & PMU_FL_TFA ? attr->mode : 0; |
|---|
| 4876 | + |
|---|
| 4877 | + return attr->mode; |
|---|
| 4878 | +} |
|---|
| 4879 | + |
|---|
| 4880 | +static struct attribute_group group_events_td = { |
|---|
| 4881 | + .name = "events", |
|---|
| 4882 | +}; |
|---|
| 4883 | + |
|---|
| 4884 | +static struct attribute_group group_events_mem = { |
|---|
| 4885 | + .name = "events", |
|---|
| 4886 | + .is_visible = pebs_is_visible, |
|---|
| 4887 | +}; |
|---|
| 4888 | + |
|---|
| 4889 | +static struct attribute_group group_events_tsx = { |
|---|
| 4890 | + .name = "events", |
|---|
| 4891 | + .is_visible = tsx_is_visible, |
|---|
| 4892 | +}; |
|---|
| 4893 | + |
|---|
| 4894 | +static struct attribute_group group_caps_gen = { |
|---|
| 4895 | + .name = "caps", |
|---|
| 4896 | + .attrs = intel_pmu_caps_attrs, |
|---|
| 4897 | +}; |
|---|
| 4898 | + |
|---|
| 4899 | +static struct attribute_group group_caps_lbr = { |
|---|
| 4900 | + .name = "caps", |
|---|
| 4901 | + .attrs = lbr_attrs, |
|---|
| 4902 | + .is_visible = lbr_is_visible, |
|---|
| 4903 | +}; |
|---|
| 4904 | + |
|---|
| 4905 | +static struct attribute_group group_format_extra = { |
|---|
| 4906 | + .name = "format", |
|---|
| 4907 | + .is_visible = exra_is_visible, |
|---|
| 4908 | +}; |
|---|
| 4909 | + |
|---|
| 4910 | +static struct attribute_group group_format_extra_skl = { |
|---|
| 4911 | + .name = "format", |
|---|
| 4912 | + .is_visible = exra_is_visible, |
|---|
| 4913 | +}; |
|---|
| 4914 | + |
|---|
| 4915 | +static struct attribute_group group_default = { |
|---|
| 4916 | + .attrs = intel_pmu_attrs, |
|---|
| 4917 | + .is_visible = default_is_visible, |
|---|
| 4918 | +}; |
|---|
| 4919 | + |
|---|
| 4920 | +static const struct attribute_group *attr_update[] = { |
|---|
| 4921 | + &group_events_td, |
|---|
| 4922 | + &group_events_mem, |
|---|
| 4923 | + &group_events_tsx, |
|---|
| 4924 | + &group_caps_gen, |
|---|
| 4925 | + &group_caps_lbr, |
|---|
| 4926 | + &group_format_extra, |
|---|
| 4927 | + &group_format_extra_skl, |
|---|
| 4928 | + &group_default, |
|---|
| 4929 | + NULL, |
|---|
| 4930 | +}; |
|---|
| 4931 | + |
|---|
| 4932 | +static struct attribute *empty_attrs; |
|---|
| 4933 | + |
|---|
| 4014 | 4934 | __init int intel_pmu_init(void) |
|---|
| 4015 | 4935 | { |
|---|
| 4016 | | - struct attribute **extra_attr = NULL; |
|---|
| 4017 | | - struct attribute **to_free = NULL; |
|---|
| 4936 | + struct attribute **extra_skl_attr = &empty_attrs; |
|---|
| 4937 | + struct attribute **extra_attr = &empty_attrs; |
|---|
| 4938 | + struct attribute **td_attr = &empty_attrs; |
|---|
| 4939 | + struct attribute **mem_attr = &empty_attrs; |
|---|
| 4940 | + struct attribute **tsx_attr = &empty_attrs; |
|---|
| 4018 | 4941 | union cpuid10_edx edx; |
|---|
| 4019 | 4942 | union cpuid10_eax eax; |
|---|
| 4020 | 4943 | union cpuid10_ebx ebx; |
|---|
| 4021 | 4944 | struct event_constraint *c; |
|---|
| 4022 | 4945 | unsigned int unused; |
|---|
| 4023 | 4946 | struct extra_reg *er; |
|---|
| 4947 | + bool pmem = false; |
|---|
| 4024 | 4948 | int version, i; |
|---|
| 4025 | 4949 | char *name; |
|---|
| 4026 | 4950 | |
|---|
| .. | .. |
|---|
| 4071 | 4995 | max((int)edx.split.num_counters_fixed, assume); |
|---|
| 4072 | 4996 | } |
|---|
| 4073 | 4997 | |
|---|
| 4998 | + if (version >= 4) |
|---|
| 4999 | + x86_pmu.counter_freezing = !disable_counter_freezing; |
|---|
| 5000 | + |
|---|
| 4074 | 5001 | if (boot_cpu_has(X86_FEATURE_PDCM)) { |
|---|
| 4075 | 5002 | u64 capabilities; |
|---|
| 4076 | 5003 | |
|---|
| .. | .. |
|---|
| 4078 | 5005 | x86_pmu.intel_cap.capabilities = capabilities; |
|---|
| 4079 | 5006 | } |
|---|
| 4080 | 5007 | |
|---|
| 5008 | + if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32) { |
|---|
| 5009 | + x86_pmu.lbr_reset = intel_pmu_lbr_reset_32; |
|---|
| 5010 | + x86_pmu.lbr_read = intel_pmu_lbr_read_32; |
|---|
| 5011 | + } |
|---|
| 5012 | + |
|---|
| 5013 | + if (boot_cpu_has(X86_FEATURE_ARCH_LBR)) |
|---|
| 5014 | + intel_pmu_arch_lbr_init(); |
|---|
| 5015 | + |
|---|
| 4081 | 5016 | intel_ds_init(); |
|---|
| 4082 | 5017 | |
|---|
| 4083 | 5018 | x86_add_quirk(intel_arch_events_quirk); /* Install first, so it runs last */ |
|---|
| 5019 | + |
|---|
| 5020 | + if (version >= 5) { |
|---|
| 5021 | + x86_pmu.intel_cap.anythread_deprecated = edx.split.anythread_deprecated; |
|---|
| 5022 | + if (x86_pmu.intel_cap.anythread_deprecated) |
|---|
| 5023 | + pr_cont(" AnyThread deprecated, "); |
|---|
| 5024 | + } |
|---|
| 4084 | 5025 | |
|---|
| 4085 | 5026 | /* |
|---|
| 4086 | 5027 | * Install the hw-cache-events table: |
|---|
| .. | .. |
|---|
| 4093 | 5034 | |
|---|
| 4094 | 5035 | case INTEL_FAM6_CORE2_MEROM: |
|---|
| 4095 | 5036 | x86_add_quirk(intel_clovertown_quirk); |
|---|
| 5037 | + fallthrough; |
|---|
| 5038 | + |
|---|
| 4096 | 5039 | case INTEL_FAM6_CORE2_MEROM_L: |
|---|
| 4097 | 5040 | case INTEL_FAM6_CORE2_PENRYN: |
|---|
| 4098 | 5041 | case INTEL_FAM6_CORE2_DUNNINGTON: |
|---|
| .. | .. |
|---|
| 4123 | 5066 | x86_pmu.extra_regs = intel_nehalem_extra_regs; |
|---|
| 4124 | 5067 | x86_pmu.limit_period = nhm_limit_period; |
|---|
| 4125 | 5068 | |
|---|
| 4126 | | - x86_pmu.cpu_events = nhm_events_attrs; |
|---|
| 5069 | + mem_attr = nhm_mem_events_attrs; |
|---|
| 4127 | 5070 | |
|---|
| 4128 | 5071 | /* UOPS_ISSUED.STALLED_CYCLES */ |
|---|
| 4129 | 5072 | intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = |
|---|
| .. | .. |
|---|
| 4159 | 5102 | break; |
|---|
| 4160 | 5103 | |
|---|
| 4161 | 5104 | case INTEL_FAM6_ATOM_SILVERMONT: |
|---|
| 4162 | | - case INTEL_FAM6_ATOM_SILVERMONT_X: |
|---|
| 5105 | + case INTEL_FAM6_ATOM_SILVERMONT_D: |
|---|
| 4163 | 5106 | case INTEL_FAM6_ATOM_SILVERMONT_MID: |
|---|
| 4164 | 5107 | case INTEL_FAM6_ATOM_AIRMONT: |
|---|
| 4165 | 5108 | case INTEL_FAM6_ATOM_AIRMONT_MID: |
|---|
| .. | .. |
|---|
| 4174 | 5117 | x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints; |
|---|
| 4175 | 5118 | x86_pmu.extra_regs = intel_slm_extra_regs; |
|---|
| 4176 | 5119 | x86_pmu.flags |= PMU_FL_HAS_RSP_1; |
|---|
| 4177 | | - x86_pmu.cpu_events = slm_events_attrs; |
|---|
| 5120 | + td_attr = slm_events_attrs; |
|---|
| 4178 | 5121 | extra_attr = slm_format_attr; |
|---|
| 4179 | 5122 | pr_cont("Silvermont events, "); |
|---|
| 4180 | 5123 | name = "silvermont"; |
|---|
| 4181 | 5124 | break; |
|---|
| 4182 | 5125 | |
|---|
| 4183 | 5126 | case INTEL_FAM6_ATOM_GOLDMONT: |
|---|
| 4184 | | - case INTEL_FAM6_ATOM_GOLDMONT_X: |
|---|
| 5127 | + case INTEL_FAM6_ATOM_GOLDMONT_D: |
|---|
| 5128 | + x86_add_quirk(intel_counter_freezing_quirk); |
|---|
| 4185 | 5129 | memcpy(hw_cache_event_ids, glm_hw_cache_event_ids, |
|---|
| 4186 | 5130 | sizeof(hw_cache_event_ids)); |
|---|
| 4187 | 5131 | memcpy(hw_cache_extra_regs, glm_hw_cache_extra_regs, |
|---|
| .. | .. |
|---|
| 4201 | 5145 | x86_pmu.pebs_prec_dist = true; |
|---|
| 4202 | 5146 | x86_pmu.lbr_pt_coexist = true; |
|---|
| 4203 | 5147 | x86_pmu.flags |= PMU_FL_HAS_RSP_1; |
|---|
| 4204 | | - x86_pmu.cpu_events = glm_events_attrs; |
|---|
| 5148 | + td_attr = glm_events_attrs; |
|---|
| 4205 | 5149 | extra_attr = slm_format_attr; |
|---|
| 4206 | 5150 | pr_cont("Goldmont events, "); |
|---|
| 4207 | 5151 | name = "goldmont"; |
|---|
| 4208 | 5152 | break; |
|---|
| 4209 | 5153 | |
|---|
| 4210 | 5154 | case INTEL_FAM6_ATOM_GOLDMONT_PLUS: |
|---|
| 5155 | + x86_add_quirk(intel_counter_freezing_quirk); |
|---|
| 4211 | 5156 | memcpy(hw_cache_event_ids, glp_hw_cache_event_ids, |
|---|
| 4212 | 5157 | sizeof(hw_cache_event_ids)); |
|---|
| 4213 | 5158 | memcpy(hw_cache_extra_regs, glp_hw_cache_extra_regs, |
|---|
| .. | .. |
|---|
| 4227 | 5172 | x86_pmu.flags |= PMU_FL_HAS_RSP_1; |
|---|
| 4228 | 5173 | x86_pmu.flags |= PMU_FL_PEBS_ALL; |
|---|
| 4229 | 5174 | x86_pmu.get_event_constraints = glp_get_event_constraints; |
|---|
| 4230 | | - x86_pmu.cpu_events = glm_events_attrs; |
|---|
| 5175 | + td_attr = glm_events_attrs; |
|---|
| 4231 | 5176 | /* Goldmont Plus has 4-wide pipeline */ |
|---|
| 4232 | 5177 | event_attr_td_total_slots_scale_glm.event_str = "4"; |
|---|
| 4233 | 5178 | extra_attr = slm_format_attr; |
|---|
| 4234 | 5179 | pr_cont("Goldmont plus events, "); |
|---|
| 4235 | 5180 | name = "goldmont_plus"; |
|---|
| 5181 | + break; |
|---|
| 5182 | + |
|---|
| 5183 | + case INTEL_FAM6_ATOM_TREMONT_D: |
|---|
| 5184 | + case INTEL_FAM6_ATOM_TREMONT: |
|---|
| 5185 | + case INTEL_FAM6_ATOM_TREMONT_L: |
|---|
| 5186 | + x86_pmu.late_ack = true; |
|---|
| 5187 | + memcpy(hw_cache_event_ids, glp_hw_cache_event_ids, |
|---|
| 5188 | + sizeof(hw_cache_event_ids)); |
|---|
| 5189 | + memcpy(hw_cache_extra_regs, tnt_hw_cache_extra_regs, |
|---|
| 5190 | + sizeof(hw_cache_extra_regs)); |
|---|
| 5191 | + hw_cache_event_ids[C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = -1; |
|---|
| 5192 | + |
|---|
| 5193 | + intel_pmu_lbr_init_skl(); |
|---|
| 5194 | + |
|---|
| 5195 | + x86_pmu.event_constraints = intel_slm_event_constraints; |
|---|
| 5196 | + x86_pmu.extra_regs = intel_tnt_extra_regs; |
|---|
| 5197 | + /* |
|---|
| 5198 | + * It's recommended to use CPU_CLK_UNHALTED.CORE_P + NPEBS |
|---|
| 5199 | + * for precise cycles. |
|---|
| 5200 | + */ |
|---|
| 5201 | + x86_pmu.pebs_aliases = NULL; |
|---|
| 5202 | + x86_pmu.pebs_prec_dist = true; |
|---|
| 5203 | + x86_pmu.lbr_pt_coexist = true; |
|---|
| 5204 | + x86_pmu.flags |= PMU_FL_HAS_RSP_1; |
|---|
| 5205 | + x86_pmu.get_event_constraints = tnt_get_event_constraints; |
|---|
| 5206 | + extra_attr = slm_format_attr; |
|---|
| 5207 | + pr_cont("Tremont events, "); |
|---|
| 5208 | + name = "Tremont"; |
|---|
| 4236 | 5209 | break; |
|---|
| 4237 | 5210 | |
|---|
| 4238 | 5211 | case INTEL_FAM6_WESTMERE: |
|---|
| .. | .. |
|---|
| 4251 | 5224 | x86_pmu.extra_regs = intel_westmere_extra_regs; |
|---|
| 4252 | 5225 | x86_pmu.flags |= PMU_FL_HAS_RSP_1; |
|---|
| 4253 | 5226 | |
|---|
| 4254 | | - x86_pmu.cpu_events = nhm_events_attrs; |
|---|
| 5227 | + mem_attr = nhm_mem_events_attrs; |
|---|
| 4255 | 5228 | |
|---|
| 4256 | 5229 | /* UOPS_ISSUED.STALLED_CYCLES */ |
|---|
| 4257 | 5230 | intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = |
|---|
| .. | .. |
|---|
| 4290 | 5263 | x86_pmu.flags |= PMU_FL_HAS_RSP_1; |
|---|
| 4291 | 5264 | x86_pmu.flags |= PMU_FL_NO_HT_SHARING; |
|---|
| 4292 | 5265 | |
|---|
| 4293 | | - x86_pmu.cpu_events = snb_events_attrs; |
|---|
| 5266 | + td_attr = snb_events_attrs; |
|---|
| 5267 | + mem_attr = snb_mem_events_attrs; |
|---|
| 4294 | 5268 | |
|---|
| 4295 | 5269 | /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */ |
|---|
| 4296 | 5270 | intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = |
|---|
| .. | .. |
|---|
| 4330 | 5304 | x86_pmu.flags |= PMU_FL_HAS_RSP_1; |
|---|
| 4331 | 5305 | x86_pmu.flags |= PMU_FL_NO_HT_SHARING; |
|---|
| 4332 | 5306 | |
|---|
| 4333 | | - x86_pmu.cpu_events = snb_events_attrs; |
|---|
| 5307 | + td_attr = snb_events_attrs; |
|---|
| 5308 | + mem_attr = snb_mem_events_attrs; |
|---|
| 4334 | 5309 | |
|---|
| 4335 | 5310 | /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */ |
|---|
| 4336 | 5311 | intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = |
|---|
| .. | .. |
|---|
| 4343 | 5318 | break; |
|---|
| 4344 | 5319 | |
|---|
| 4345 | 5320 | |
|---|
| 4346 | | - case INTEL_FAM6_HASWELL_CORE: |
|---|
| 5321 | + case INTEL_FAM6_HASWELL: |
|---|
| 4347 | 5322 | case INTEL_FAM6_HASWELL_X: |
|---|
| 4348 | | - case INTEL_FAM6_HASWELL_ULT: |
|---|
| 4349 | | - case INTEL_FAM6_HASWELL_GT3E: |
|---|
| 5323 | + case INTEL_FAM6_HASWELL_L: |
|---|
| 5324 | + case INTEL_FAM6_HASWELL_G: |
|---|
| 4350 | 5325 | x86_add_quirk(intel_ht_bug); |
|---|
| 5326 | + x86_add_quirk(intel_pebs_isolation_quirk); |
|---|
| 4351 | 5327 | x86_pmu.late_ack = true; |
|---|
| 4352 | 5328 | memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids)); |
|---|
| 4353 | 5329 | memcpy(hw_cache_extra_regs, hsw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); |
|---|
| .. | .. |
|---|
| 4365 | 5341 | |
|---|
| 4366 | 5342 | x86_pmu.hw_config = hsw_hw_config; |
|---|
| 4367 | 5343 | x86_pmu.get_event_constraints = hsw_get_event_constraints; |
|---|
| 4368 | | - x86_pmu.cpu_events = get_hsw_events_attrs(); |
|---|
| 4369 | 5344 | x86_pmu.lbr_double_abort = true; |
|---|
| 4370 | 5345 | extra_attr = boot_cpu_has(X86_FEATURE_RTM) ? |
|---|
| 4371 | 5346 | hsw_format_attr : nhm_format_attr; |
|---|
| 5347 | + td_attr = hsw_events_attrs; |
|---|
| 5348 | + mem_attr = hsw_mem_events_attrs; |
|---|
| 5349 | + tsx_attr = hsw_tsx_events_attrs; |
|---|
| 4372 | 5350 | pr_cont("Haswell events, "); |
|---|
| 4373 | 5351 | name = "haswell"; |
|---|
| 4374 | 5352 | break; |
|---|
| 4375 | 5353 | |
|---|
| 4376 | | - case INTEL_FAM6_BROADWELL_CORE: |
|---|
| 4377 | | - case INTEL_FAM6_BROADWELL_XEON_D: |
|---|
| 4378 | | - case INTEL_FAM6_BROADWELL_GT3E: |
|---|
| 5354 | + case INTEL_FAM6_BROADWELL: |
|---|
| 5355 | + case INTEL_FAM6_BROADWELL_D: |
|---|
| 5356 | + case INTEL_FAM6_BROADWELL_G: |
|---|
| 4379 | 5357 | case INTEL_FAM6_BROADWELL_X: |
|---|
| 5358 | + x86_add_quirk(intel_pebs_isolation_quirk); |
|---|
| 4380 | 5359 | x86_pmu.late_ack = true; |
|---|
| 4381 | 5360 | memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids)); |
|---|
| 4382 | 5361 | memcpy(hw_cache_extra_regs, hsw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); |
|---|
| .. | .. |
|---|
| 4404 | 5383 | |
|---|
| 4405 | 5384 | x86_pmu.hw_config = hsw_hw_config; |
|---|
| 4406 | 5385 | x86_pmu.get_event_constraints = hsw_get_event_constraints; |
|---|
| 4407 | | - x86_pmu.cpu_events = get_hsw_events_attrs(); |
|---|
| 4408 | 5386 | x86_pmu.limit_period = bdw_limit_period; |
|---|
| 4409 | 5387 | extra_attr = boot_cpu_has(X86_FEATURE_RTM) ? |
|---|
| 4410 | 5388 | hsw_format_attr : nhm_format_attr; |
|---|
| 5389 | + td_attr = hsw_events_attrs; |
|---|
| 5390 | + mem_attr = hsw_mem_events_attrs; |
|---|
| 5391 | + tsx_attr = hsw_tsx_events_attrs; |
|---|
| 4411 | 5392 | pr_cont("Broadwell events, "); |
|---|
| 4412 | 5393 | name = "broadwell"; |
|---|
| 4413 | 5394 | break; |
|---|
| .. | .. |
|---|
| 4432 | 5413 | name = "knights-landing"; |
|---|
| 4433 | 5414 | break; |
|---|
| 4434 | 5415 | |
|---|
| 4435 | | - case INTEL_FAM6_SKYLAKE_MOBILE: |
|---|
| 4436 | | - case INTEL_FAM6_SKYLAKE_DESKTOP: |
|---|
| 4437 | 5416 | case INTEL_FAM6_SKYLAKE_X: |
|---|
| 4438 | | - case INTEL_FAM6_KABYLAKE_MOBILE: |
|---|
| 4439 | | - case INTEL_FAM6_KABYLAKE_DESKTOP: |
|---|
| 5417 | + pmem = true; |
|---|
| 5418 | + fallthrough; |
|---|
| 5419 | + case INTEL_FAM6_SKYLAKE_L: |
|---|
| 5420 | + case INTEL_FAM6_SKYLAKE: |
|---|
| 5421 | + case INTEL_FAM6_KABYLAKE_L: |
|---|
| 5422 | + case INTEL_FAM6_KABYLAKE: |
|---|
| 5423 | + case INTEL_FAM6_COMETLAKE_L: |
|---|
| 5424 | + case INTEL_FAM6_COMETLAKE: |
|---|
| 5425 | + x86_add_quirk(intel_pebs_isolation_quirk); |
|---|
| 4440 | 5426 | x86_pmu.late_ack = true; |
|---|
| 4441 | 5427 | memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids)); |
|---|
| 4442 | 5428 | memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); |
|---|
| .. | .. |
|---|
| 4461 | 5447 | x86_pmu.get_event_constraints = hsw_get_event_constraints; |
|---|
| 4462 | 5448 | extra_attr = boot_cpu_has(X86_FEATURE_RTM) ? |
|---|
| 4463 | 5449 | hsw_format_attr : nhm_format_attr; |
|---|
| 4464 | | - extra_attr = merge_attr(extra_attr, skl_format_attr); |
|---|
| 4465 | | - to_free = extra_attr; |
|---|
| 4466 | | - x86_pmu.cpu_events = get_hsw_events_attrs(); |
|---|
| 4467 | | - intel_pmu_pebs_data_source_skl( |
|---|
| 4468 | | - boot_cpu_data.x86_model == INTEL_FAM6_SKYLAKE_X); |
|---|
| 5450 | + extra_skl_attr = skl_format_attr; |
|---|
| 5451 | + td_attr = hsw_events_attrs; |
|---|
| 5452 | + mem_attr = hsw_mem_events_attrs; |
|---|
| 5453 | + tsx_attr = hsw_tsx_events_attrs; |
|---|
| 5454 | + intel_pmu_pebs_data_source_skl(pmem); |
|---|
| 4469 | 5455 | |
|---|
| 4470 | 5456 | if (boot_cpu_has(X86_FEATURE_TSX_FORCE_ABORT)) { |
|---|
| 4471 | 5457 | x86_pmu.flags |= PMU_FL_TFA; |
|---|
| 4472 | 5458 | x86_pmu.get_event_constraints = tfa_get_event_constraints; |
|---|
| 4473 | 5459 | x86_pmu.enable_all = intel_tfa_pmu_enable_all; |
|---|
| 4474 | 5460 | x86_pmu.commit_scheduling = intel_tfa_commit_scheduling; |
|---|
| 4475 | | - intel_pmu_attrs[1] = &dev_attr_allow_tsx_force_abort.attr.attr; |
|---|
| 4476 | 5461 | } |
|---|
| 4477 | 5462 | |
|---|
| 4478 | 5463 | pr_cont("Skylake events, "); |
|---|
| 4479 | 5464 | name = "skylake"; |
|---|
| 5465 | + break; |
|---|
| 5466 | + |
|---|
| 5467 | + case INTEL_FAM6_ICELAKE_X: |
|---|
| 5468 | + case INTEL_FAM6_ICELAKE_D: |
|---|
| 5469 | + pmem = true; |
|---|
| 5470 | + fallthrough; |
|---|
| 5471 | + case INTEL_FAM6_ICELAKE_L: |
|---|
| 5472 | + case INTEL_FAM6_ICELAKE: |
|---|
| 5473 | + case INTEL_FAM6_TIGERLAKE_L: |
|---|
| 5474 | + case INTEL_FAM6_TIGERLAKE: |
|---|
| 5475 | + x86_pmu.late_ack = true; |
|---|
| 5476 | + memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids)); |
|---|
| 5477 | + memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); |
|---|
| 5478 | + hw_cache_event_ids[C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = -1; |
|---|
| 5479 | + intel_pmu_lbr_init_skl(); |
|---|
| 5480 | + |
|---|
| 5481 | + x86_pmu.event_constraints = intel_icl_event_constraints; |
|---|
| 5482 | + x86_pmu.pebs_constraints = intel_icl_pebs_event_constraints; |
|---|
| 5483 | + x86_pmu.extra_regs = intel_icl_extra_regs; |
|---|
| 5484 | + x86_pmu.pebs_aliases = NULL; |
|---|
| 5485 | + x86_pmu.pebs_prec_dist = true; |
|---|
| 5486 | + x86_pmu.flags |= PMU_FL_HAS_RSP_1; |
|---|
| 5487 | + x86_pmu.flags |= PMU_FL_NO_HT_SHARING; |
|---|
| 5488 | + |
|---|
| 5489 | + x86_pmu.hw_config = hsw_hw_config; |
|---|
| 5490 | + x86_pmu.get_event_constraints = icl_get_event_constraints; |
|---|
| 5491 | + extra_attr = boot_cpu_has(X86_FEATURE_RTM) ? |
|---|
| 5492 | + hsw_format_attr : nhm_format_attr; |
|---|
| 5493 | + extra_skl_attr = skl_format_attr; |
|---|
| 5494 | + mem_attr = icl_events_attrs; |
|---|
| 5495 | + td_attr = icl_td_events_attrs; |
|---|
| 5496 | + tsx_attr = icl_tsx_events_attrs; |
|---|
| 5497 | + x86_pmu.rtm_abort_event = X86_CONFIG(.event=0xc9, .umask=0x04); |
|---|
| 5498 | + x86_pmu.lbr_pt_coexist = true; |
|---|
| 5499 | + intel_pmu_pebs_data_source_skl(pmem); |
|---|
| 5500 | + x86_pmu.update_topdown_event = icl_update_topdown_event; |
|---|
| 5501 | + x86_pmu.set_topdown_event_period = icl_set_topdown_event_period; |
|---|
| 5502 | + pr_cont("Icelake events, "); |
|---|
| 5503 | + name = "icelake"; |
|---|
| 4480 | 5504 | break; |
|---|
| 4481 | 5505 | |
|---|
| 4482 | 5506 | default: |
|---|
| .. | .. |
|---|
| 4497 | 5521 | } |
|---|
| 4498 | 5522 | } |
|---|
| 4499 | 5523 | |
|---|
| 4500 | | - snprintf(pmu_name_str, sizeof pmu_name_str, "%s", name); |
|---|
| 5524 | + snprintf(pmu_name_str, sizeof(pmu_name_str), "%s", name); |
|---|
| 4501 | 5525 | |
|---|
| 4502 | | - if (version >= 2 && extra_attr) { |
|---|
| 4503 | | - x86_pmu.format_attrs = merge_attr(intel_arch3_formats_attr, |
|---|
| 4504 | | - extra_attr); |
|---|
| 4505 | | - WARN_ON(!x86_pmu.format_attrs); |
|---|
| 4506 | | - } |
|---|
| 5526 | + |
|---|
| 5527 | + group_events_td.attrs = td_attr; |
|---|
| 5528 | + group_events_mem.attrs = mem_attr; |
|---|
| 5529 | + group_events_tsx.attrs = tsx_attr; |
|---|
| 5530 | + group_format_extra.attrs = extra_attr; |
|---|
| 5531 | + group_format_extra_skl.attrs = extra_skl_attr; |
|---|
| 5532 | + |
|---|
| 5533 | + x86_pmu.attr_update = attr_update; |
|---|
| 4507 | 5534 | |
|---|
| 4508 | 5535 | if (x86_pmu.num_counters > INTEL_PMC_MAX_GENERIC) { |
|---|
| 4509 | 5536 | WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!", |
|---|
| .. | .. |
|---|
| 4521 | 5548 | x86_pmu.intel_ctrl |= |
|---|
| 4522 | 5549 | ((1LL << x86_pmu.num_counters_fixed)-1) << INTEL_PMC_IDX_FIXED; |
|---|
| 4523 | 5550 | |
|---|
| 5551 | + /* AnyThread may be deprecated on arch perfmon v5 or later */ |
|---|
| 5552 | + if (x86_pmu.intel_cap.anythread_deprecated) |
|---|
| 5553 | + x86_pmu.format_attrs = intel_arch_formats_attr; |
|---|
| 5554 | + |
|---|
| 4524 | 5555 | if (x86_pmu.event_constraints) { |
|---|
| 4525 | 5556 | /* |
|---|
| 4526 | 5557 | * event on fixed counter2 (REF_CYCLES) only works on this |
|---|
| 4527 | 5558 | * counter, so do not extend mask to generic counters |
|---|
| 4528 | 5559 | */ |
|---|
| 4529 | 5560 | for_each_event_constraint(c, x86_pmu.event_constraints) { |
|---|
| 5561 | + /* |
|---|
| 5562 | + * Don't extend the topdown slots and metrics |
|---|
| 5563 | + * events to the generic counters. |
|---|
| 5564 | + */ |
|---|
| 5565 | + if (c->idxmsk64 & INTEL_PMC_MSK_TOPDOWN) { |
|---|
| 5566 | + c->weight = hweight64(c->idxmsk64); |
|---|
| 5567 | + continue; |
|---|
| 5568 | + } |
|---|
| 5569 | + |
|---|
| 4530 | 5570 | if (c->cmask == FIXED_EVENT_FLAGS |
|---|
| 4531 | 5571 | && c->idxmsk64 != INTEL_PMC_MSK_FIXED_REF_CYCLES) { |
|---|
| 4532 | 5572 | c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1; |
|---|
| .. | .. |
|---|
| 4543 | 5583 | * Check all LBT MSR here. |
|---|
| 4544 | 5584 | * Disable LBR access if any LBR MSRs can not be accessed. |
|---|
| 4545 | 5585 | */ |
|---|
| 4546 | | - if (x86_pmu.lbr_nr && !check_msr(x86_pmu.lbr_tos, 0x3UL)) |
|---|
| 5586 | + if (x86_pmu.lbr_tos && !check_msr(x86_pmu.lbr_tos, 0x3UL)) |
|---|
| 4547 | 5587 | x86_pmu.lbr_nr = 0; |
|---|
| 4548 | 5588 | for (i = 0; i < x86_pmu.lbr_nr; i++) { |
|---|
| 4549 | 5589 | if (!(check_msr(x86_pmu.lbr_from + i, 0xffffUL) && |
|---|
| .. | .. |
|---|
| 4551 | 5591 | x86_pmu.lbr_nr = 0; |
|---|
| 4552 | 5592 | } |
|---|
| 4553 | 5593 | |
|---|
| 4554 | | - x86_pmu.caps_attrs = intel_pmu_caps_attrs; |
|---|
| 4555 | | - |
|---|
| 4556 | | - if (x86_pmu.lbr_nr) { |
|---|
| 4557 | | - x86_pmu.caps_attrs = merge_attr(x86_pmu.caps_attrs, lbr_attrs); |
|---|
| 5594 | + if (x86_pmu.lbr_nr) |
|---|
| 4558 | 5595 | pr_cont("%d-deep LBR, ", x86_pmu.lbr_nr); |
|---|
| 4559 | | - } |
|---|
| 4560 | 5596 | |
|---|
| 4561 | 5597 | /* |
|---|
| 4562 | 5598 | * Access extra MSR may cause #GP under certain circumstances. |
|---|
| .. | .. |
|---|
| 4579 | 5615 | pr_cont("full-width counters, "); |
|---|
| 4580 | 5616 | } |
|---|
| 4581 | 5617 | |
|---|
| 4582 | | - kfree(to_free); |
|---|
| 5618 | + /* |
|---|
| 5619 | + * For arch perfmon 4 use counter freezing to avoid |
|---|
| 5620 | + * several MSR accesses in the PMI. |
|---|
| 5621 | + */ |
|---|
| 5622 | + if (x86_pmu.counter_freezing) |
|---|
| 5623 | + x86_pmu.handle_irq = intel_pmu_handle_irq_v4; |
|---|
| 5624 | + |
|---|
| 5625 | + if (x86_pmu.intel_cap.perf_metrics) |
|---|
| 5626 | + x86_pmu.intel_ctrl |= 1ULL << GLOBAL_CTRL_EN_PERF_METRICS; |
|---|
| 5627 | + |
|---|
| 4583 | 5628 | return 0; |
|---|
| 4584 | 5629 | } |
|---|
| 4585 | 5630 | |
|---|