Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Ingo Molnar:
"Mostly tooling fixes, but also breakpoint and x86 PMU driver fixes"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (23 commits)
perf tools: Fix maps__find_symbol_by_name()
tools headers uapi: Update tools's copy of linux/if_link.h
tools headers uapi: Update tools's copy of linux/vhost.h
tools headers uapi: Update tools's copies of kvm headers
tools headers uapi: Update tools's copy of drm/drm.h
tools headers uapi: Update tools's copy of asm-generic/unistd.h
tools headers uapi: Update tools's copy of linux/perf_event.h
perf/core: Force USER_DS when recording user stack data
perf/UAPI: Clearly mark __PERF_SAMPLE_CALLCHAIN_EARLY as internal use
perf/x86/intel: Add support/quirk for the MISPREDICT bit on Knights Landing CPUs
perf annotate: Fix parsing aarch64 branch instructions after objdump update
perf probe powerpc: Ignore SyS symbols irrespective of endianness
perf event-parse: Use fixed size string for comms
perf util: Fix bad memory access in trace info.
perf tools: Streamline bpf examples and headers installation
perf evsel: Fix potential null pointer dereference in perf_evsel__new_idx()
perf arm64: Fix include path for asm-generic/unistd.h
perf/hw_breakpoint: Simplify breakpoint enable in perf_event_modify_breakpoint
perf/hw_breakpoint: Enable breakpoint in modify_user_hw_breakpoint
perf/hw_breakpoint: Remove superfluous bp->attr.disabled = 0
...

+423 -43
+4
arch/x86/events/intel/lbr.c
··· 1272 1272 1273 1273 x86_pmu.lbr_sel_mask = LBR_SEL_MASK; 1274 1274 x86_pmu.lbr_sel_map = snb_lbr_sel_map; 1275 + 1276 + /* Knights Landing does have MISPREDICT bit */ 1277 + if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_LIP) 1278 + x86_pmu.intel_cap.lbr_format = LBR_FORMAT_EIP_FLAGS; 1275 1279 }
+1 -1
include/uapi/linux/perf_event.h
··· 144 144 145 145 PERF_SAMPLE_MAX = 1U << 20, /* non-ABI */ 146 146 147 - __PERF_SAMPLE_CALLCHAIN_EARLY = 1ULL << 63, 147 + __PERF_SAMPLE_CALLCHAIN_EARLY = 1ULL << 63, /* non-ABI; internal use */ 148 148 }; 149 149 150 150 /*
+7 -8
kernel/events/core.c
··· 2867 2867 _perf_event_disable(bp); 2868 2868 2869 2869 err = modify_user_hw_breakpoint_check(bp, attr, true); 2870 - if (err) { 2871 - if (!bp->attr.disabled) 2872 - _perf_event_enable(bp); 2873 2870 2874 - return err; 2875 - } 2876 - 2877 - if (!attr->disabled) 2871 + if (!bp->attr.disabled) 2878 2872 _perf_event_enable(bp); 2879 - return 0; 2873 + 2874 + return err; 2880 2875 } 2881 2876 2882 2877 static int perf_event_modify_attr(struct perf_event *event, ··· 5943 5948 unsigned long sp; 5944 5949 unsigned int rem; 5945 5950 u64 dyn_size; 5951 + mm_segment_t fs; 5946 5952 5947 5953 /* 5948 5954 * We dump: ··· 5961 5965 5962 5966 /* Data. */ 5963 5967 sp = perf_user_stack_pointer(regs); 5968 + fs = get_fs(); 5969 + set_fs(USER_DS); 5964 5970 rem = __output_copy_user(handle, (void *) sp, dump_size); 5971 + set_fs(fs); 5965 5972 dyn_size = dump_size - rem; 5966 5973 5967 5974 perf_output_skip(handle, rem);
+6 -7
kernel/events/hw_breakpoint.c
··· 509 509 */ 510 510 int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr) 511 511 { 512 + int err; 513 + 512 514 /* 513 515 * modify_user_hw_breakpoint can be invoked with IRQs disabled and hence it 514 516 * will not be possible to raise IPIs that invoke __perf_event_disable. ··· 522 520 else 523 521 perf_event_disable(bp); 524 522 525 - if (!attr->disabled) { 526 - int err = modify_user_hw_breakpoint_check(bp, attr, false); 523 + err = modify_user_hw_breakpoint_check(bp, attr, false); 527 524 528 - if (err) 529 - return err; 525 + if (!bp->attr.disabled) 530 526 perf_event_enable(bp); 531 - bp->attr.disabled = 0; 532 - } 533 - return 0; 527 + 528 + return err; 534 529 } 535 530 EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint); 536 531
+13
tools/arch/arm/include/uapi/asm/kvm.h
··· 27 27 #define __KVM_HAVE_GUEST_DEBUG 28 28 #define __KVM_HAVE_IRQ_LINE 29 29 #define __KVM_HAVE_READONLY_MEM 30 + #define __KVM_HAVE_VCPU_EVENTS 30 31 31 32 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 32 33 ··· 124 123 }; 125 124 126 125 struct kvm_arch_memory_slot { 126 + }; 127 + 128 + /* for KVM_GET/SET_VCPU_EVENTS */ 129 + struct kvm_vcpu_events { 130 + struct { 131 + __u8 serror_pending; 132 + __u8 serror_has_esr; 133 + /* Align it to 8 bytes */ 134 + __u8 pad[6]; 135 + __u64 serror_esr; 136 + } exception; 137 + __u32 reserved[12]; 127 138 }; 128 139 129 140 /* If you need to interpret the index values, here is the key: */
+13
tools/arch/arm64/include/uapi/asm/kvm.h
··· 39 39 #define __KVM_HAVE_GUEST_DEBUG 40 40 #define __KVM_HAVE_IRQ_LINE 41 41 #define __KVM_HAVE_READONLY_MEM 42 + #define __KVM_HAVE_VCPU_EVENTS 42 43 43 44 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 44 45 ··· 153 152 }; 154 153 155 154 struct kvm_arch_memory_slot { 155 + }; 156 + 157 + /* for KVM_GET/SET_VCPU_EVENTS */ 158 + struct kvm_vcpu_events { 159 + struct { 160 + __u8 serror_pending; 161 + __u8 serror_has_esr; 162 + /* Align it to 8 bytes */ 163 + __u8 pad[6]; 164 + __u64 serror_esr; 165 + } exception; 166 + __u32 reserved[12]; 156 167 }; 157 168 158 169 /* If you need to interpret the index values, here is the key: */
+4 -1
tools/arch/s390/include/uapi/asm/kvm.h
··· 4 4 /* 5 5 * KVM s390 specific structures and definitions 6 6 * 7 - * Copyright IBM Corp. 2008 7 + * Copyright IBM Corp. 2008, 2018 8 8 * 9 9 * Author(s): Carsten Otte <cotte@de.ibm.com> 10 10 * Christian Borntraeger <borntraeger@de.ibm.com> ··· 225 225 #define KVM_SYNC_FPRS (1UL << 8) 226 226 #define KVM_SYNC_GSCB (1UL << 9) 227 227 #define KVM_SYNC_BPBC (1UL << 10) 228 + #define KVM_SYNC_ETOKEN (1UL << 11) 228 229 /* length and alignment of the sdnx as a power of two */ 229 230 #define SDNXC 8 230 231 #define SDNXL (1UL << SDNXC) ··· 259 258 struct { 260 259 __u64 reserved1[2]; 261 260 __u64 gscb[4]; 261 + __u64 etoken; 262 + __u64 etoken_extension; 262 263 }; 263 264 }; 264 265 };
+37
tools/arch/x86/include/uapi/asm/kvm.h
··· 378 378 #define KVM_X86_QUIRK_LINT0_REENABLED (1 << 0) 379 379 #define KVM_X86_QUIRK_CD_NW_CLEARED (1 << 1) 380 380 381 + #define KVM_STATE_NESTED_GUEST_MODE 0x00000001 382 + #define KVM_STATE_NESTED_RUN_PENDING 0x00000002 383 + 384 + #define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001 385 + #define KVM_STATE_NESTED_SMM_VMXON 0x00000002 386 + 387 + struct kvm_vmx_nested_state { 388 + __u64 vmxon_pa; 389 + __u64 vmcs_pa; 390 + 391 + struct { 392 + __u16 flags; 393 + } smm; 394 + }; 395 + 396 + /* for KVM_CAP_NESTED_STATE */ 397 + struct kvm_nested_state { 398 + /* KVM_STATE_* flags */ 399 + __u16 flags; 400 + 401 + /* 0 for VMX, 1 for SVM. */ 402 + __u16 format; 403 + 404 + /* 128 for SVM, 128 + VMCS size for VMX. */ 405 + __u32 size; 406 + 407 + union { 408 + /* VMXON, VMCS */ 409 + struct kvm_vmx_nested_state vmx; 410 + 411 + /* Pad the header to 128 bytes. */ 412 + __u8 pad[120]; 413 + }; 414 + 415 + __u8 data[0]; 416 + }; 417 + 381 418 #endif /* _ASM_X86_KVM_H */
+3 -1
tools/include/uapi/asm-generic/unistd.h
··· 734 734 __SYSCALL(__NR_statx, sys_statx) 735 735 #define __NR_io_pgetevents 292 736 736 __SC_COMP(__NR_io_pgetevents, sys_io_pgetevents, compat_sys_io_pgetevents) 737 + #define __NR_rseq 293 738 + __SYSCALL(__NR_rseq, sys_rseq) 737 739 738 740 #undef __NR_syscalls 739 - #define __NR_syscalls 293 741 + #define __NR_syscalls 294 740 742 741 743 /* 742 744 * 32 bit systems traditionally used different
+9
tools/include/uapi/drm/drm.h
··· 687 687 */ 688 688 #define DRM_CLIENT_CAP_ASPECT_RATIO 4 689 689 690 + /** 691 + * DRM_CLIENT_CAP_WRITEBACK_CONNECTORS 692 + * 693 + * If set to 1, the DRM core will expose special connectors to be used for 694 + * writing back to memory the scene setup in the commit. Depends on client 695 + * also supporting DRM_CLIENT_CAP_ATOMIC 696 + */ 697 + #define DRM_CLIENT_CAP_WRITEBACK_CONNECTORS 5 698 + 690 699 /** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ 691 700 struct drm_set_client_cap { 692 701 __u64 capability;
+17
tools/include/uapi/linux/if_link.h
··· 164 164 IFLA_CARRIER_UP_COUNT, 165 165 IFLA_CARRIER_DOWN_COUNT, 166 166 IFLA_NEW_IFINDEX, 167 + IFLA_MIN_MTU, 168 + IFLA_MAX_MTU, 167 169 __IFLA_MAX 168 170 }; 169 171 ··· 336 334 IFLA_BRPORT_GROUP_FWD_MASK, 337 335 IFLA_BRPORT_NEIGH_SUPPRESS, 338 336 IFLA_BRPORT_ISOLATED, 337 + IFLA_BRPORT_BACKUP_PORT, 339 338 __IFLA_BRPORT_MAX 340 339 }; 341 340 #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) ··· 461 458 }; 462 459 463 460 #define IFLA_MACSEC_MAX (__IFLA_MACSEC_MAX - 1) 461 + 462 + /* XFRM section */ 463 + enum { 464 + IFLA_XFRM_UNSPEC, 465 + IFLA_XFRM_LINK, 466 + IFLA_XFRM_IF_ID, 467 + __IFLA_XFRM_MAX 468 + }; 469 + 470 + #define IFLA_XFRM_MAX (__IFLA_XFRM_MAX - 1) 464 471 465 472 enum macsec_validation_type { 466 473 MACSEC_VALIDATE_DISABLED = 0, ··· 933 920 XDP_ATTACHED_DRV, 934 921 XDP_ATTACHED_SKB, 935 922 XDP_ATTACHED_HW, 923 + XDP_ATTACHED_MULTI, 936 924 }; 937 925 938 926 enum { ··· 942 928 IFLA_XDP_ATTACHED, 943 929 IFLA_XDP_FLAGS, 944 930 IFLA_XDP_PROG_ID, 931 + IFLA_XDP_DRV_PROG_ID, 932 + IFLA_XDP_SKB_PROG_ID, 933 + IFLA_XDP_HW_PROG_ID, 945 934 __IFLA_XDP_MAX, 946 935 }; 947 936
+6
tools/include/uapi/linux/kvm.h
··· 949 949 #define KVM_CAP_GET_MSR_FEATURES 153 950 950 #define KVM_CAP_HYPERV_EVENTFD 154 951 951 #define KVM_CAP_HYPERV_TLBFLUSH 155 952 + #define KVM_CAP_S390_HPAGE_1M 156 953 + #define KVM_CAP_NESTED_STATE 157 954 + #define KVM_CAP_ARM_INJECT_SERROR_ESR 158 952 955 953 956 #ifdef KVM_CAP_IRQ_ROUTING 954 957 ··· 1394 1391 /* Available with KVM_CAP_HYPERV_EVENTFD */ 1395 1392 #define KVM_HYPERV_EVENTFD _IOW(KVMIO, 0xbd, struct kvm_hyperv_eventfd) 1396 1393 1394 + /* Available with KVM_CAP_NESTED_STATE */ 1395 + #define KVM_GET_NESTED_STATE _IOWR(KVMIO, 0xbe, struct kvm_nested_state) 1396 + #define KVM_SET_NESTED_STATE _IOW(KVMIO, 0xbf, struct kvm_nested_state) 1397 1397 1398 1398 /* Secure Encrypted Virtualization command */ 1399 1399 enum sev_cmd_id {
+1 -1
tools/include/uapi/linux/perf_event.h
··· 144 144 145 145 PERF_SAMPLE_MAX = 1U << 20, /* non-ABI */ 146 146 147 - __PERF_SAMPLE_CALLCHAIN_EARLY = 1ULL << 63, 147 + __PERF_SAMPLE_CALLCHAIN_EARLY = 1ULL << 63, /* non-ABI; internal use */ 148 148 }; 149 149 150 150 /*
+18
tools/include/uapi/linux/vhost.h
··· 65 65 }; 66 66 67 67 #define VHOST_IOTLB_MSG 0x1 68 + #define VHOST_IOTLB_MSG_V2 0x2 68 69 69 70 struct vhost_msg { 70 71 int type; 72 + union { 73 + struct vhost_iotlb_msg iotlb; 74 + __u8 padding[64]; 75 + }; 76 + }; 77 + 78 + struct vhost_msg_v2 { 79 + __u32 type; 80 + __u32 reserved; 71 81 union { 72 82 struct vhost_iotlb_msg iotlb; 73 83 __u8 padding[64]; ··· 169 159 /* Get busy loop timeout (in us) */ 170 160 #define VHOST_GET_VRING_BUSYLOOP_TIMEOUT _IOW(VHOST_VIRTIO, 0x24, \ 171 161 struct vhost_vring_state) 162 + 163 + /* Set or get vhost backend capability */ 164 + 165 + /* Use message type V2 */ 166 + #define VHOST_BACKEND_F_IOTLB_MSG_V2 0x1 167 + 168 + #define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64) 169 + #define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64) 172 170 173 171 /* VHOST_NET specific defines */ 174 172
+6 -8
tools/perf/Makefile.perf
··· 777 777 $(call QUIET_INSTALL, libexec) \ 778 778 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' 779 779 ifndef NO_LIBBPF 780 - $(call QUIET_INSTALL, lib) \ 781 - $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf' 782 - $(call QUIET_INSTALL, include/bpf) \ 783 - $(INSTALL) include/bpf/*.h '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf' 784 - $(call QUIET_INSTALL, lib) \ 785 - $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf' 786 - $(call QUIET_INSTALL, examples/bpf) \ 787 - $(INSTALL) examples/bpf/*.c '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf' 780 + $(call QUIET_INSTALL, bpf-headers) \ 781 + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'; \ 782 + $(INSTALL) include/bpf/*.h -t '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf' 783 + $(call QUIET_INSTALL, bpf-examples) \ 784 + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'; \ 785 + $(INSTALL) examples/bpf/*.c -t '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf' 788 786 endif 789 787 $(call QUIET_INSTALL, perf-archive) \ 790 788 $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
+3 -2
tools/perf/arch/arm64/Makefile
··· 11 11 12 12 out := $(OUTPUT)arch/arm64/include/generated/asm 13 13 header := $(out)/syscalls.c 14 - sysdef := $(srctree)/tools/include/uapi/asm-generic/unistd.h 14 + incpath := $(srctree)/tools 15 + sysdef := $(srctree)/tools/arch/arm64/include/uapi/asm/unistd.h 15 16 sysprf := $(srctree)/tools/perf/arch/arm64/entry/syscalls/ 16 17 systbl := $(sysprf)/mksyscalltbl 17 18 ··· 20 19 _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)') 21 20 22 21 $(header): $(sysdef) $(systbl) 23 - $(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(sysdef) > $@ 22 + $(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@ 24 23 25 24 clean:: 26 25 $(call QUIET_CLEAN, arm64) $(RM) $(header)
+3 -3
tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
··· 11 11 12 12 gcc=$1 13 13 hostcc=$2 14 - input=$3 14 + incpath=$3 15 + input=$4 15 16 16 17 if ! test -r $input; then 17 18 echo "Could not read input file" >&2 ··· 29 28 30 29 cat <<-_EoHEADER 31 30 #include <stdio.h> 32 - #define __ARCH_WANT_RENAMEAT 33 31 #include "$input" 34 32 int main(int argc, char *argv[]) 35 33 { ··· 42 42 printf "%s\n" " printf(\"#define SYSCALLTBL_ARM64_MAX_ID %d\\n\", __NR_$last_sc);" 43 43 printf "}\n" 44 44 45 - } | $hostcc -o $create_table_exe -x c - 45 + } | $hostcc -I $incpath/include/uapi -o $create_table_exe -x c - 46 46 47 47 $create_table_exe 48 48
+3 -1
tools/perf/arch/powerpc/util/sym-handling.c
··· 22 22 23 23 #endif 24 24 25 - #if !defined(_CALL_ELF) || _CALL_ELF != 2 26 25 int arch__choose_best_symbol(struct symbol *syma, 27 26 struct symbol *symb __maybe_unused) 28 27 { 29 28 char *sym = syma->name; 30 29 30 + #if !defined(_CALL_ELF) || _CALL_ELF != 2 31 31 /* Skip over any initial dot */ 32 32 if (*sym == '.') 33 33 sym++; 34 + #endif 34 35 35 36 /* Avoid "SyS" kernel syscall aliases */ 36 37 if (strlen(sym) >= 3 && !strncmp(sym, "SyS", 3)) ··· 42 41 return SYMBOL_A; 43 42 } 44 43 44 + #if !defined(_CALL_ELF) || _CALL_ELF != 2 45 45 /* Allow matching against dot variants */ 46 46 int arch__compare_symbol_names(const char *namea, const char *nameb) 47 47 {
+1
tools/perf/arch/x86/include/arch-tests.h
··· 9 9 int test__rdpmc(struct test *test __maybe_unused, int subtest); 10 10 int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest); 11 11 int test__insn_x86(struct test *test __maybe_unused, int subtest); 12 + int test__bp_modify(struct test *test, int subtest); 12 13 13 14 #ifdef HAVE_DWARF_UNWIND_SUPPORT 14 15 struct thread;
+1
tools/perf/arch/x86/tests/Build
··· 5 5 libperf-y += rdpmc.o 6 6 libperf-y += perf-time-to-tsc.o 7 7 libperf-$(CONFIG_AUXTRACE) += insn-x86.o 8 + libperf-$(CONFIG_X86_64) += bp-modify.o
+6
tools/perf/arch/x86/tests/arch-tests.c
··· 24 24 .func = test__insn_x86, 25 25 }, 26 26 #endif 27 + #if defined(__x86_64__) 28 + { 29 + .desc = "x86 bp modify", 30 + .func = test__bp_modify, 31 + }, 32 + #endif 27 33 { 28 34 .func = NULL, 29 35 },
+213
tools/perf/arch/x86/tests/bp-modify.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <linux/compiler.h> 3 + #include <sys/types.h> 4 + #include <sys/wait.h> 5 + #include <sys/user.h> 6 + #include <syscall.h> 7 + #include <unistd.h> 8 + #include <stdio.h> 9 + #include <stdlib.h> 10 + #include <sys/ptrace.h> 11 + #include <asm/ptrace.h> 12 + #include <errno.h> 13 + #include "debug.h" 14 + #include "tests/tests.h" 15 + #include "arch-tests.h" 16 + 17 + static noinline int bp_1(void) 18 + { 19 + pr_debug("in %s\n", __func__); 20 + return 0; 21 + } 22 + 23 + static noinline int bp_2(void) 24 + { 25 + pr_debug("in %s\n", __func__); 26 + return 0; 27 + } 28 + 29 + static int spawn_child(void) 30 + { 31 + int child = fork(); 32 + 33 + if (child == 0) { 34 + /* 35 + * The child sets itself for as tracee and 36 + * waits in signal for parent to trace it, 37 + * then it calls bp_1 and quits. 38 + */ 39 + int err = ptrace(PTRACE_TRACEME, 0, NULL, NULL); 40 + 41 + if (err) { 42 + pr_debug("failed to PTRACE_TRACEME\n"); 43 + exit(1); 44 + } 45 + 46 + raise(SIGCONT); 47 + bp_1(); 48 + exit(0); 49 + } 50 + 51 + return child; 52 + } 53 + 54 + /* 55 + * This tests creates HW breakpoint, tries to 56 + * change it and checks it was properly changed. 57 + */ 58 + static int bp_modify1(void) 59 + { 60 + pid_t child; 61 + int status; 62 + unsigned long rip = 0, dr7 = 1; 63 + 64 + child = spawn_child(); 65 + 66 + waitpid(child, &status, 0); 67 + if (WIFEXITED(status)) { 68 + pr_debug("tracee exited prematurely 1\n"); 69 + return TEST_FAIL; 70 + } 71 + 72 + /* 73 + * The parent does following steps: 74 + * - creates a new breakpoint (id 0) for bp_2 function 75 + * - changes that breakponit to bp_1 function 76 + * - waits for the breakpoint to hit and checks 77 + * it has proper rip of bp_1 function 78 + * - detaches the child 79 + */ 80 + if (ptrace(PTRACE_POKEUSER, child, 81 + offsetof(struct user, u_debugreg[0]), bp_2)) { 82 + pr_debug("failed to set breakpoint, 1st time: %s\n", 83 + strerror(errno)); 84 + goto out; 85 + } 86 + 87 + if (ptrace(PTRACE_POKEUSER, child, 88 + offsetof(struct user, u_debugreg[0]), bp_1)) { 89 + pr_debug("failed to set breakpoint, 2nd time: %s\n", 90 + strerror(errno)); 91 + goto out; 92 + } 93 + 94 + if (ptrace(PTRACE_POKEUSER, child, 95 + offsetof(struct user, u_debugreg[7]), dr7)) { 96 + pr_debug("failed to set dr7: %s\n", strerror(errno)); 97 + goto out; 98 + } 99 + 100 + if (ptrace(PTRACE_CONT, child, NULL, NULL)) { 101 + pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno)); 102 + goto out; 103 + } 104 + 105 + waitpid(child, &status, 0); 106 + if (WIFEXITED(status)) { 107 + pr_debug("tracee exited prematurely 2\n"); 108 + return TEST_FAIL; 109 + } 110 + 111 + rip = ptrace(PTRACE_PEEKUSER, child, 112 + offsetof(struct user_regs_struct, rip), NULL); 113 + if (rip == (unsigned long) -1) { 114 + pr_debug("failed to PTRACE_PEEKUSER: %s\n", 115 + strerror(errno)); 116 + goto out; 117 + } 118 + 119 + pr_debug("rip %lx, bp_1 %p\n", rip, bp_1); 120 + 121 + out: 122 + if (ptrace(PTRACE_DETACH, child, NULL, NULL)) { 123 + pr_debug("failed to PTRACE_DETACH: %s", strerror(errno)); 124 + return TEST_FAIL; 125 + } 126 + 127 + return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL; 128 + } 129 + 130 + /* 131 + * This tests creates HW breakpoint, tries to 132 + * change it to bogus value and checks the original 133 + * breakpoint is hit. 134 + */ 135 + static int bp_modify2(void) 136 + { 137 + pid_t child; 138 + int status; 139 + unsigned long rip = 0, dr7 = 1; 140 + 141 + child = spawn_child(); 142 + 143 + waitpid(child, &status, 0); 144 + if (WIFEXITED(status)) { 145 + pr_debug("tracee exited prematurely 1\n"); 146 + return TEST_FAIL; 147 + } 148 + 149 + /* 150 + * The parent does following steps: 151 + * - creates a new breakpoint (id 0) for bp_1 function 152 + * - tries to change that breakpoint to (-1) address 153 + * - waits for the breakpoint to hit and checks 154 + * it has proper rip of bp_1 function 155 + * - detaches the child 156 + */ 157 + if (ptrace(PTRACE_POKEUSER, child, 158 + offsetof(struct user, u_debugreg[0]), bp_1)) { 159 + pr_debug("failed to set breakpoint: %s\n", 160 + strerror(errno)); 161 + goto out; 162 + } 163 + 164 + if (ptrace(PTRACE_POKEUSER, child, 165 + offsetof(struct user, u_debugreg[7]), dr7)) { 166 + pr_debug("failed to set dr7: %s\n", strerror(errno)); 167 + goto out; 168 + } 169 + 170 + if (!ptrace(PTRACE_POKEUSER, child, 171 + offsetof(struct user, u_debugreg[0]), (unsigned long) (-1))) { 172 + pr_debug("failed, breakpoint set to bogus address\n"); 173 + goto out; 174 + } 175 + 176 + if (ptrace(PTRACE_CONT, child, NULL, NULL)) { 177 + pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno)); 178 + goto out; 179 + } 180 + 181 + waitpid(child, &status, 0); 182 + if (WIFEXITED(status)) { 183 + pr_debug("tracee exited prematurely 2\n"); 184 + return TEST_FAIL; 185 + } 186 + 187 + rip = ptrace(PTRACE_PEEKUSER, child, 188 + offsetof(struct user_regs_struct, rip), NULL); 189 + if (rip == (unsigned long) -1) { 190 + pr_debug("failed to PTRACE_PEEKUSER: %s\n", 191 + strerror(errno)); 192 + goto out; 193 + } 194 + 195 + pr_debug("rip %lx, bp_1 %p\n", rip, bp_1); 196 + 197 + out: 198 + if (ptrace(PTRACE_DETACH, child, NULL, NULL)) { 199 + pr_debug("failed to PTRACE_DETACH: %s", strerror(errno)); 200 + return TEST_FAIL; 201 + } 202 + 203 + return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL; 204 + } 205 + 206 + int test__bp_modify(struct test *test __maybe_unused, 207 + int subtest __maybe_unused) 208 + { 209 + TEST_ASSERT_VAL("modify test 1 failed\n", !bp_modify1()); 210 + TEST_ASSERT_VAL("modify test 2 failed\n", !bp_modify2()); 211 + 212 + return 0; 213 + }
+29 -3
tools/perf/util/annotate.c
··· 246 246 247 247 indirect_call: 248 248 tok = strchr(endptr, '*'); 249 - if (tok != NULL) 250 - ops->target.addr = strtoull(tok + 1, NULL, 16); 249 + if (tok != NULL) { 250 + endptr++; 251 + 252 + /* Indirect call can use a non-rip register and offset: callq *0x8(%rbx). 253 + * Do not parse such instruction. */ 254 + if (strstr(endptr, "(%r") == NULL) 255 + ops->target.addr = strtoull(endptr, NULL, 16); 256 + } 251 257 goto find_target; 252 258 } 253 259 ··· 282 276 return ins->ops == &call_ops || ins->ops == &s390_call_ops; 283 277 } 284 278 285 - static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map_symbol *ms) 279 + /* 280 + * Prevents from matching commas in the comment section, e.g.: 281 + * ffff200008446e70: b.cs ffff2000084470f4 <generic_exec_single+0x314> // b.hs, b.nlast 282 + */ 283 + static inline const char *validate_comma(const char *c, struct ins_operands *ops) 284 + { 285 + if (ops->raw_comment && c > ops->raw_comment) 286 + return NULL; 287 + 288 + return c; 289 + } 290 + 291 + static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms) 286 292 { 287 293 struct map *map = ms->map; 288 294 struct symbol *sym = ms->sym; ··· 303 285 }; 304 286 const char *c = strchr(ops->raw, ','); 305 287 u64 start, end; 288 + 289 + ops->raw_comment = strchr(ops->raw, arch->objdump.comment_char); 290 + c = validate_comma(c, ops); 291 + 306 292 /* 307 293 * Examples of lines to parse for the _cpp_lex_token@@Base 308 294 * function: ··· 326 304 ops->target.addr = strtoull(c, NULL, 16); 327 305 if (!ops->target.addr) { 328 306 c = strchr(c, ','); 307 + c = validate_comma(c, ops); 329 308 if (c++ != NULL) 330 309 ops->target.addr = strtoull(c, NULL, 16); 331 310 } ··· 384 361 return scnprintf(bf, size, "%-6s %s", ins->name, ops->target.sym->name); 385 362 386 363 c = strchr(ops->raw, ','); 364 + c = validate_comma(c, ops); 365 + 387 366 if (c != NULL) { 388 367 const char *c2 = strchr(c + 1, ','); 389 368 369 + c2 = validate_comma(c2, ops); 390 370 /* check for 3-op insn */ 391 371 if (c2 != NULL) 392 372 c = c2;
+1
tools/perf/util/annotate.h
··· 22 22 23 23 struct ins_operands { 24 24 char *raw; 25 + char *raw_comment; 25 26 struct { 26 27 char *raw; 27 28 char *name;
+3 -2
tools/perf/util/evsel.c
··· 251 251 { 252 252 struct perf_evsel *evsel = zalloc(perf_evsel__object.size); 253 253 254 - if (evsel != NULL) 255 - perf_evsel__init(evsel, attr, idx); 254 + if (!evsel) 255 + return NULL; 256 + perf_evsel__init(evsel, attr, idx); 256 257 257 258 if (perf_evsel__is_bpf_output(evsel)) { 258 259 evsel->attr.sample_type |= (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME |
+11
tools/perf/util/map.c
··· 576 576 return NULL; 577 577 } 578 578 579 + static bool map__contains_symbol(struct map *map, struct symbol *sym) 580 + { 581 + u64 ip = map->unmap_ip(map, sym->start); 582 + 583 + return ip >= map->start && ip < map->end; 584 + } 585 + 579 586 struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name, 580 587 struct map **mapp) 581 588 { ··· 598 591 599 592 if (sym == NULL) 600 593 continue; 594 + if (!map__contains_symbol(pos, sym)) { 595 + sym = NULL; 596 + continue; 597 + } 601 598 if (mapp != NULL) 602 599 *mapp = pos; 603 600 goto out;
+1 -1
tools/perf/util/trace-event-info.c
··· 377 377 378 378 static int record_saved_cmdline(void) 379 379 { 380 - unsigned int size; 380 + unsigned long long size; 381 381 char *path; 382 382 struct stat st; 383 383 int ret, err = 0;
+3 -4
tools/perf/util/trace-event-parse.c
··· 164 164 void parse_saved_cmdline(struct tep_handle *pevent, 165 165 char *file, unsigned int size __maybe_unused) 166 166 { 167 - char *comm; 167 + char comm[17]; /* Max comm length in the kernel is 16. */ 168 168 char *line; 169 169 char *next = NULL; 170 170 int pid; 171 171 172 172 line = strtok_r(file, "\n", &next); 173 173 while (line) { 174 - sscanf(line, "%d %ms", &pid, &comm); 175 - tep_register_comm(pevent, comm, pid); 176 - free(comm); 174 + if (sscanf(line, "%d %16s", &pid, comm) == 2) 175 + tep_register_comm(pevent, comm, pid); 177 176 line = strtok_r(NULL, "\n", &next); 178 177 } 179 178 }