diff options
author | Ingo Molnar <mingo@kernel.org> | 2015-01-28 09:48:59 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-01-28 09:48:59 -0500 |
commit | b3890e4704594fa23abe1395d1fafc97d3214be8 (patch) | |
tree | 23e2659713e01779e8854363eb7d1fac49683d32 | |
parent | 29bf4dbc9841366577ba44175b00c543ad1712d6 (diff) | |
parent | 2a2662bf88e693d477ef08351d03934f7bc0b51c (diff) |
Merge branch 'perf/hw_breakpoints' into perf/core
The new hw_breakpoint bits are now ready for v3.20, merge them
into the main branch, to avoid conflicts.
Conflicts:
tools/perf/Documentation/perf-record.txt
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/include/asm/cpufeature.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/debugreg.h | 5 | ||||
-rw-r--r-- | arch/x86/include/asm/hw_breakpoint.h | 1 | ||||
-rw-r--r-- | arch/x86/include/uapi/asm/msr-index.h | 4 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/amd.c | 19 | ||||
-rw-r--r-- | arch/x86/kernel/hw_breakpoint.c | 45 | ||||
-rw-r--r-- | tools/perf/Documentation/perf-record.txt | 7 | ||||
-rw-r--r-- | tools/perf/tests/parse-events.c | 58 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 21 | ||||
-rw-r--r-- | tools/perf/util/parse-events.h | 2 | ||||
-rw-r--r-- | tools/perf/util/parse-events.l | 1 | ||||
-rw-r--r-- | tools/perf/util/parse-events.y | 26 |
12 files changed, 148 insertions, 43 deletions
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index aede2c347bde..90a54851aedc 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
@@ -174,6 +174,7 @@ | |||
174 | #define X86_FEATURE_TOPOEXT ( 6*32+22) /* topology extensions CPUID leafs */ | 174 | #define X86_FEATURE_TOPOEXT ( 6*32+22) /* topology extensions CPUID leafs */ |
175 | #define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */ | 175 | #define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */ |
176 | #define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */ | 176 | #define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */ |
177 | #define X86_FEATURE_BPEXT (6*32+26) /* data breakpoint extension */ | ||
177 | #define X86_FEATURE_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */ | 178 | #define X86_FEATURE_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */ |
178 | 179 | ||
179 | /* | 180 | /* |
@@ -388,6 +389,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; | |||
388 | #define cpu_has_cx16 boot_cpu_has(X86_FEATURE_CX16) | 389 | #define cpu_has_cx16 boot_cpu_has(X86_FEATURE_CX16) |
389 | #define cpu_has_eager_fpu boot_cpu_has(X86_FEATURE_EAGER_FPU) | 390 | #define cpu_has_eager_fpu boot_cpu_has(X86_FEATURE_EAGER_FPU) |
390 | #define cpu_has_topoext boot_cpu_has(X86_FEATURE_TOPOEXT) | 391 | #define cpu_has_topoext boot_cpu_has(X86_FEATURE_TOPOEXT) |
392 | #define cpu_has_bpext boot_cpu_has(X86_FEATURE_BPEXT) | ||
391 | 393 | ||
392 | #if __GNUC__ >= 4 | 394 | #if __GNUC__ >= 4 |
393 | extern void warn_pre_alternatives(void); | 395 | extern void warn_pre_alternatives(void); |
diff --git a/arch/x86/include/asm/debugreg.h b/arch/x86/include/asm/debugreg.h index 61fd18b83b6c..12cb66f6d3a5 100644 --- a/arch/x86/include/asm/debugreg.h +++ b/arch/x86/include/asm/debugreg.h | |||
@@ -114,5 +114,10 @@ static inline void debug_stack_usage_inc(void) { } | |||
114 | static inline void debug_stack_usage_dec(void) { } | 114 | static inline void debug_stack_usage_dec(void) { } |
115 | #endif /* X86_64 */ | 115 | #endif /* X86_64 */ |
116 | 116 | ||
117 | #ifdef CONFIG_CPU_SUP_AMD | ||
118 | extern void set_dr_addr_mask(unsigned long mask, int dr); | ||
119 | #else | ||
120 | static inline void set_dr_addr_mask(unsigned long mask, int dr) { } | ||
121 | #endif | ||
117 | 122 | ||
118 | #endif /* _ASM_X86_DEBUGREG_H */ | 123 | #endif /* _ASM_X86_DEBUGREG_H */ |
diff --git a/arch/x86/include/asm/hw_breakpoint.h b/arch/x86/include/asm/hw_breakpoint.h index ef1c4d2d41ec..6c98be864a75 100644 --- a/arch/x86/include/asm/hw_breakpoint.h +++ b/arch/x86/include/asm/hw_breakpoint.h | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | struct arch_hw_breakpoint { | 13 | struct arch_hw_breakpoint { |
14 | unsigned long address; | 14 | unsigned long address; |
15 | unsigned long mask; | ||
15 | u8 len; | 16 | u8 len; |
16 | u8 type; | 17 | u8 type; |
17 | }; | 18 | }; |
diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index c8aa65d56027..d979e5abae55 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h | |||
@@ -251,6 +251,10 @@ | |||
251 | /* Fam 16h MSRs */ | 251 | /* Fam 16h MSRs */ |
252 | #define MSR_F16H_L2I_PERF_CTL 0xc0010230 | 252 | #define MSR_F16H_L2I_PERF_CTL 0xc0010230 |
253 | #define MSR_F16H_L2I_PERF_CTR 0xc0010231 | 253 | #define MSR_F16H_L2I_PERF_CTR 0xc0010231 |
254 | #define MSR_F16H_DR1_ADDR_MASK 0xc0011019 | ||
255 | #define MSR_F16H_DR2_ADDR_MASK 0xc001101a | ||
256 | #define MSR_F16H_DR3_ADDR_MASK 0xc001101b | ||
257 | #define MSR_F16H_DR0_ADDR_MASK 0xc0011027 | ||
254 | 258 | ||
255 | /* Fam 15h MSRs */ | 259 | /* Fam 15h MSRs */ |
256 | #define MSR_F15H_PERF_CTL 0xc0010200 | 260 | #define MSR_F15H_PERF_CTL 0xc0010200 |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 15c5df92f74e..a220239cea65 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -869,3 +869,22 @@ static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) | |||
869 | 869 | ||
870 | return false; | 870 | return false; |
871 | } | 871 | } |
872 | |||
873 | void set_dr_addr_mask(unsigned long mask, int dr) | ||
874 | { | ||
875 | if (!cpu_has_bpext) | ||
876 | return; | ||
877 | |||
878 | switch (dr) { | ||
879 | case 0: | ||
880 | wrmsr(MSR_F16H_DR0_ADDR_MASK, mask, 0); | ||
881 | break; | ||
882 | case 1: | ||
883 | case 2: | ||
884 | case 3: | ||
885 | wrmsr(MSR_F16H_DR1_ADDR_MASK - 1 + dr, mask, 0); | ||
886 | break; | ||
887 | default: | ||
888 | break; | ||
889 | } | ||
890 | } | ||
diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index 3d5fb509bdeb..7114ba220fd4 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c | |||
@@ -126,6 +126,8 @@ int arch_install_hw_breakpoint(struct perf_event *bp) | |||
126 | *dr7 |= encode_dr7(i, info->len, info->type); | 126 | *dr7 |= encode_dr7(i, info->len, info->type); |
127 | 127 | ||
128 | set_debugreg(*dr7, 7); | 128 | set_debugreg(*dr7, 7); |
129 | if (info->mask) | ||
130 | set_dr_addr_mask(info->mask, i); | ||
129 | 131 | ||
130 | return 0; | 132 | return 0; |
131 | } | 133 | } |
@@ -161,29 +163,8 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp) | |||
161 | *dr7 &= ~__encode_dr7(i, info->len, info->type); | 163 | *dr7 &= ~__encode_dr7(i, info->len, info->type); |
162 | 164 | ||
163 | set_debugreg(*dr7, 7); | 165 | set_debugreg(*dr7, 7); |
164 | } | 166 | if (info->mask) |
165 | 167 | set_dr_addr_mask(0, i); | |
166 | static int get_hbp_len(u8 hbp_len) | ||
167 | { | ||
168 | unsigned int len_in_bytes = 0; | ||
169 | |||
170 | switch (hbp_len) { | ||
171 | case X86_BREAKPOINT_LEN_1: | ||
172 | len_in_bytes = 1; | ||
173 | break; | ||
174 | case X86_BREAKPOINT_LEN_2: | ||
175 | len_in_bytes = 2; | ||
176 | break; | ||
177 | case X86_BREAKPOINT_LEN_4: | ||
178 | len_in_bytes = 4; | ||
179 | break; | ||
180 | #ifdef CONFIG_X86_64 | ||
181 | case X86_BREAKPOINT_LEN_8: | ||
182 | len_in_bytes = 8; | ||
183 | break; | ||
184 | #endif | ||
185 | } | ||
186 | return len_in_bytes; | ||
187 | } | 168 | } |
188 | 169 | ||
189 | /* | 170 | /* |
@@ -196,7 +177,7 @@ int arch_check_bp_in_kernelspace(struct perf_event *bp) | |||
196 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | 177 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); |
197 | 178 | ||
198 | va = info->address; | 179 | va = info->address; |
199 | len = get_hbp_len(info->len); | 180 | len = bp->attr.bp_len; |
200 | 181 | ||
201 | return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE); | 182 | return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE); |
202 | } | 183 | } |
@@ -277,6 +258,8 @@ static int arch_build_bp_info(struct perf_event *bp) | |||
277 | } | 258 | } |
278 | 259 | ||
279 | /* Len */ | 260 | /* Len */ |
261 | info->mask = 0; | ||
262 | |||
280 | switch (bp->attr.bp_len) { | 263 | switch (bp->attr.bp_len) { |
281 | case HW_BREAKPOINT_LEN_1: | 264 | case HW_BREAKPOINT_LEN_1: |
282 | info->len = X86_BREAKPOINT_LEN_1; | 265 | info->len = X86_BREAKPOINT_LEN_1; |
@@ -293,11 +276,17 @@ static int arch_build_bp_info(struct perf_event *bp) | |||
293 | break; | 276 | break; |
294 | #endif | 277 | #endif |
295 | default: | 278 | default: |
296 | return -EINVAL; | 279 | if (!is_power_of_2(bp->attr.bp_len)) |
280 | return -EINVAL; | ||
281 | if (!cpu_has_bpext) | ||
282 | return -EOPNOTSUPP; | ||
283 | info->mask = bp->attr.bp_len - 1; | ||
284 | info->len = X86_BREAKPOINT_LEN_1; | ||
297 | } | 285 | } |
298 | 286 | ||
299 | return 0; | 287 | return 0; |
300 | } | 288 | } |
289 | |||
301 | /* | 290 | /* |
302 | * Validate the arch-specific HW Breakpoint register settings | 291 | * Validate the arch-specific HW Breakpoint register settings |
303 | */ | 292 | */ |
@@ -312,11 +301,11 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) | |||
312 | if (ret) | 301 | if (ret) |
313 | return ret; | 302 | return ret; |
314 | 303 | ||
315 | ret = -EINVAL; | ||
316 | |||
317 | switch (info->len) { | 304 | switch (info->len) { |
318 | case X86_BREAKPOINT_LEN_1: | 305 | case X86_BREAKPOINT_LEN_1: |
319 | align = 0; | 306 | align = 0; |
307 | if (info->mask) | ||
308 | align = info->mask; | ||
320 | break; | 309 | break; |
321 | case X86_BREAKPOINT_LEN_2: | 310 | case X86_BREAKPOINT_LEN_2: |
322 | align = 1; | 311 | align = 1; |
@@ -330,7 +319,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) | |||
330 | break; | 319 | break; |
331 | #endif | 320 | #endif |
332 | default: | 321 | default: |
333 | return ret; | 322 | WARN_ON_ONCE(1); |
334 | } | 323 | } |
335 | 324 | ||
336 | /* | 325 | /* |
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 7d8df2e5edd8..31e977459c51 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt | |||
@@ -45,12 +45,15 @@ OPTIONS | |||
45 | param1 and param2 are defined as formats for the PMU in: | 45 | param1 and param2 are defined as formats for the PMU in: |
46 | /sys/bus/event_sources/devices/<pmu>/format/* | 46 | /sys/bus/event_sources/devices/<pmu>/format/* |
47 | 47 | ||
48 | - a hardware breakpoint event in the form of '\mem:addr[:access]' | 48 | - a hardware breakpoint event in the form of '\mem:addr[/len][:access]' |
49 | where addr is the address in memory you want to break in. | 49 | where addr is the address in memory you want to break in. |
50 | Access is the memory access type (read, write, execute) it can | 50 | Access is the memory access type (read, write, execute) it can |
51 | be passed as follows: '\mem:addr[:[r][w][x]]'. | 51 | be passed as follows: '\mem:addr[:[r][w][x]]'. len is the range, |
52 | number of bytes from specified addr, which the breakpoint will cover. | ||
52 | If you want to profile read-write accesses in 0x1000, just set | 53 | If you want to profile read-write accesses in 0x1000, just set |
53 | 'mem:0x1000:rw'. | 54 | 'mem:0x1000:rw'. |
55 | If you want to profile write accesses in [0x1000~1008), just set | ||
56 | 'mem:0x1000/8:w'. | ||
54 | 57 | ||
55 | --filter=<filter>:: | 58 | --filter=<filter>:: |
56 | Event filter. | 59 | Event filter. |
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index d188e20d958f..1cdab0ce00e2 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c | |||
@@ -1145,6 +1145,49 @@ static int test__pinned_group(struct perf_evlist *evlist) | |||
1145 | return 0; | 1145 | return 0; |
1146 | } | 1146 | } |
1147 | 1147 | ||
1148 | static int test__checkevent_breakpoint_len(struct perf_evlist *evlist) | ||
1149 | { | ||
1150 | struct perf_evsel *evsel = perf_evlist__first(evlist); | ||
1151 | |||
1152 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
1153 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); | ||
1154 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | ||
1155 | TEST_ASSERT_VAL("wrong bp_type", (HW_BREAKPOINT_R | HW_BREAKPOINT_W) == | ||
1156 | evsel->attr.bp_type); | ||
1157 | TEST_ASSERT_VAL("wrong bp_len", HW_BREAKPOINT_LEN_1 == | ||
1158 | evsel->attr.bp_len); | ||
1159 | |||
1160 | return 0; | ||
1161 | } | ||
1162 | |||
1163 | static int test__checkevent_breakpoint_len_w(struct perf_evlist *evlist) | ||
1164 | { | ||
1165 | struct perf_evsel *evsel = perf_evlist__first(evlist); | ||
1166 | |||
1167 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
1168 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); | ||
1169 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | ||
1170 | TEST_ASSERT_VAL("wrong bp_type", HW_BREAKPOINT_W == | ||
1171 | evsel->attr.bp_type); | ||
1172 | TEST_ASSERT_VAL("wrong bp_len", HW_BREAKPOINT_LEN_2 == | ||
1173 | evsel->attr.bp_len); | ||
1174 | |||
1175 | return 0; | ||
1176 | } | ||
1177 | |||
1178 | static int | ||
1179 | test__checkevent_breakpoint_len_rw_modifier(struct perf_evlist *evlist) | ||
1180 | { | ||
1181 | struct perf_evsel *evsel = perf_evlist__first(evlist); | ||
1182 | |||
1183 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | ||
1184 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | ||
1185 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
1186 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
1187 | |||
1188 | return test__checkevent_breakpoint_rw(evlist); | ||
1189 | } | ||
1190 | |||
1148 | static int count_tracepoints(void) | 1191 | static int count_tracepoints(void) |
1149 | { | 1192 | { |
1150 | char events_path[PATH_MAX]; | 1193 | char events_path[PATH_MAX]; |
@@ -1420,6 +1463,21 @@ static struct evlist_test test__events[] = { | |||
1420 | .check = test__pinned_group, | 1463 | .check = test__pinned_group, |
1421 | .id = 41, | 1464 | .id = 41, |
1422 | }, | 1465 | }, |
1466 | { | ||
1467 | .name = "mem:0/1", | ||
1468 | .check = test__checkevent_breakpoint_len, | ||
1469 | .id = 42, | ||
1470 | }, | ||
1471 | { | ||
1472 | .name = "mem:0/2:w", | ||
1473 | .check = test__checkevent_breakpoint_len_w, | ||
1474 | .id = 43, | ||
1475 | }, | ||
1476 | { | ||
1477 | .name = "mem:0/4:rw:u", | ||
1478 | .check = test__checkevent_breakpoint_len_rw_modifier, | ||
1479 | .id = 44 | ||
1480 | }, | ||
1423 | #if defined(__s390x__) | 1481 | #if defined(__s390x__) |
1424 | { | 1482 | { |
1425 | .name = "kvm-s390:kvm_s390_create_vm", | 1483 | .name = "kvm-s390:kvm_s390_create_vm", |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index f36b80ecaf52..7f8ec6ce2823 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -526,7 +526,7 @@ do { \ | |||
526 | } | 526 | } |
527 | 527 | ||
528 | int parse_events_add_breakpoint(struct list_head *list, int *idx, | 528 | int parse_events_add_breakpoint(struct list_head *list, int *idx, |
529 | void *ptr, char *type) | 529 | void *ptr, char *type, u64 len) |
530 | { | 530 | { |
531 | struct perf_event_attr attr; | 531 | struct perf_event_attr attr; |
532 | 532 | ||
@@ -536,14 +536,15 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx, | |||
536 | if (parse_breakpoint_type(type, &attr)) | 536 | if (parse_breakpoint_type(type, &attr)) |
537 | return -EINVAL; | 537 | return -EINVAL; |
538 | 538 | ||
539 | /* | 539 | /* Provide some defaults if len is not specified */ |
540 | * We should find a nice way to override the access length | 540 | if (!len) { |
541 | * Provide some defaults for now | 541 | if (attr.bp_type == HW_BREAKPOINT_X) |
542 | */ | 542 | len = sizeof(long); |
543 | if (attr.bp_type == HW_BREAKPOINT_X) | 543 | else |
544 | attr.bp_len = sizeof(long); | 544 | len = HW_BREAKPOINT_LEN_4; |
545 | else | 545 | } |
546 | attr.bp_len = HW_BREAKPOINT_LEN_4; | 546 | |
547 | attr.bp_len = len; | ||
547 | 548 | ||
548 | attr.type = PERF_TYPE_BREAKPOINT; | 549 | attr.type = PERF_TYPE_BREAKPOINT; |
549 | attr.sample_period = 1; | 550 | attr.sample_period = 1; |
@@ -1366,7 +1367,7 @@ void print_events(const char *event_glob, bool name_only) | |||
1366 | printf("\n"); | 1367 | printf("\n"); |
1367 | 1368 | ||
1368 | printf(" %-50s [%s]\n", | 1369 | printf(" %-50s [%s]\n", |
1369 | "mem:<addr>[:access]", | 1370 | "mem:<addr>[/len][:access]", |
1370 | event_type_descriptors[PERF_TYPE_BREAKPOINT]); | 1371 | event_type_descriptors[PERF_TYPE_BREAKPOINT]); |
1371 | printf("\n"); | 1372 | printf("\n"); |
1372 | } | 1373 | } |
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index ca226cef8460..ff6e1fa4111e 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h | |||
@@ -105,7 +105,7 @@ int parse_events_add_numeric(struct list_head *list, int *idx, | |||
105 | int parse_events_add_cache(struct list_head *list, int *idx, | 105 | int parse_events_add_cache(struct list_head *list, int *idx, |
106 | char *type, char *op_result1, char *op_result2); | 106 | char *type, char *op_result1, char *op_result2); |
107 | int parse_events_add_breakpoint(struct list_head *list, int *idx, | 107 | int parse_events_add_breakpoint(struct list_head *list, int *idx, |
108 | void *ptr, char *type); | 108 | void *ptr, char *type, u64 len); |
109 | int parse_events_add_pmu(struct list_head *list, int *idx, | 109 | int parse_events_add_pmu(struct list_head *list, int *idx, |
110 | char *pmu , struct list_head *head_config); | 110 | char *pmu , struct list_head *head_config); |
111 | enum perf_pmu_event_symbol_type | 111 | enum perf_pmu_event_symbol_type |
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 906630bbf8eb..94eacb6c1ef7 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l | |||
@@ -159,6 +159,7 @@ branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE | |||
159 | <mem>{ | 159 | <mem>{ |
160 | {modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); } | 160 | {modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); } |
161 | : { return ':'; } | 161 | : { return ':'; } |
162 | "/" { return '/'; } | ||
162 | {num_dec} { return value(yyscanner, 10); } | 163 | {num_dec} { return value(yyscanner, 10); } |
163 | {num_hex} { return value(yyscanner, 16); } | 164 | {num_hex} { return value(yyscanner, 16); } |
164 | /* | 165 | /* |
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 93c4c9fbc922..72def077dbbf 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y | |||
@@ -326,6 +326,28 @@ PE_NAME_CACHE_TYPE | |||
326 | } | 326 | } |
327 | 327 | ||
328 | event_legacy_mem: | 328 | event_legacy_mem: |
329 | PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc | ||
330 | { | ||
331 | struct parse_events_evlist *data = _data; | ||
332 | struct list_head *list; | ||
333 | |||
334 | ALLOC_LIST(list); | ||
335 | ABORT_ON(parse_events_add_breakpoint(list, &data->idx, | ||
336 | (void *) $2, $6, $4)); | ||
337 | $$ = list; | ||
338 | } | ||
339 | | | ||
340 | PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc | ||
341 | { | ||
342 | struct parse_events_evlist *data = _data; | ||
343 | struct list_head *list; | ||
344 | |||
345 | ALLOC_LIST(list); | ||
346 | ABORT_ON(parse_events_add_breakpoint(list, &data->idx, | ||
347 | (void *) $2, NULL, $4)); | ||
348 | $$ = list; | ||
349 | } | ||
350 | | | ||
329 | PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc | 351 | PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc |
330 | { | 352 | { |
331 | struct parse_events_evlist *data = _data; | 353 | struct parse_events_evlist *data = _data; |
@@ -333,7 +355,7 @@ PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc | |||
333 | 355 | ||
334 | ALLOC_LIST(list); | 356 | ALLOC_LIST(list); |
335 | ABORT_ON(parse_events_add_breakpoint(list, &data->idx, | 357 | ABORT_ON(parse_events_add_breakpoint(list, &data->idx, |
336 | (void *) $2, $4)); | 358 | (void *) $2, $4, 0)); |
337 | $$ = list; | 359 | $$ = list; |
338 | } | 360 | } |
339 | | | 361 | | |
@@ -344,7 +366,7 @@ PE_PREFIX_MEM PE_VALUE sep_dc | |||
344 | 366 | ||
345 | ALLOC_LIST(list); | 367 | ALLOC_LIST(list); |
346 | ABORT_ON(parse_events_add_breakpoint(list, &data->idx, | 368 | ABORT_ON(parse_events_add_breakpoint(list, &data->idx, |
347 | (void *) $2, NULL)); | 369 | (void *) $2, NULL, 0)); |
348 | $$ = list; | 370 | $$ = list; |
349 | } | 371 | } |
350 | 372 | ||