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:
"Various fixes, most of them related to bugs perf fuzzing found in the
x86 code"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/x86/regs: Use PERF_REG_EXTENDED_MASK
perf/x86: Remove pmu->pebs_no_xmm_regs
perf/x86: Clean up PEBS_XMM_REGS
perf/x86/regs: Check reserved bits
perf/x86: Disable extended registers for non-supported PMUs
perf/ioctl: Add check for the sample_period value
perf/core: Fix perf_sample_regs_user() mm check

+48 -38
+3 -3
arch/x86/events/core.c
··· 561 561 } 562 562 563 563 /* sample_regs_user never support XMM registers */ 564 - if (unlikely(event->attr.sample_regs_user & PEBS_XMM_REGS)) 564 + if (unlikely(event->attr.sample_regs_user & PERF_REG_EXTENDED_MASK)) 565 565 return -EINVAL; 566 566 /* 567 567 * Besides the general purpose registers, XMM registers may 568 568 * be collected in PEBS on some platforms, e.g. Icelake 569 569 */ 570 - if (unlikely(event->attr.sample_regs_intr & PEBS_XMM_REGS)) { 571 - if (x86_pmu.pebs_no_xmm_regs) 570 + if (unlikely(event->attr.sample_regs_intr & PERF_REG_EXTENDED_MASK)) { 571 + if (!(event->pmu->capabilities & PERF_PMU_CAP_EXTENDED_REGS)) 572 572 return -EINVAL; 573 573 574 574 if (!event->attr.precise_ip)
+4 -5
arch/x86/events/intel/ds.c
··· 987 987 pebs_data_cfg |= PEBS_DATACFG_GP; 988 988 989 989 if ((sample_type & PERF_SAMPLE_REGS_INTR) && 990 - (attr->sample_regs_intr & PEBS_XMM_REGS)) 990 + (attr->sample_regs_intr & PERF_REG_EXTENDED_MASK)) 991 991 pebs_data_cfg |= PEBS_DATACFG_XMMS; 992 992 993 993 if (sample_type & PERF_SAMPLE_BRANCH_STACK) { ··· 1964 1964 x86_pmu.bts = boot_cpu_has(X86_FEATURE_BTS); 1965 1965 x86_pmu.pebs = boot_cpu_has(X86_FEATURE_PEBS); 1966 1966 x86_pmu.pebs_buffer_size = PEBS_BUFFER_SIZE; 1967 - if (x86_pmu.version <= 4) { 1967 + if (x86_pmu.version <= 4) 1968 1968 x86_pmu.pebs_no_isolation = 1; 1969 - x86_pmu.pebs_no_xmm_regs = 1; 1970 - } 1969 + 1971 1970 if (x86_pmu.pebs) { 1972 1971 char pebs_type = x86_pmu.intel_cap.pebs_trap ? '+' : '-'; 1973 1972 char *pebs_qual = ""; ··· 2019 2020 PERF_SAMPLE_TIME; 2020 2021 x86_pmu.flags |= PMU_FL_PEBS_ALL; 2021 2022 pebs_qual = "-baseline"; 2023 + x86_get_pmu()->capabilities |= PERF_PMU_CAP_EXTENDED_REGS; 2022 2024 } else { 2023 2025 /* Only basic record supported */ 2024 - x86_pmu.pebs_no_xmm_regs = 1; 2025 2026 x86_pmu.large_pebs_flags &= 2026 2027 ~(PERF_SAMPLE_ADDR | 2027 2028 PERF_SAMPLE_TIME |
+1 -20
arch/x86/events/perf_event.h
··· 121 121 (1ULL << PERF_REG_X86_R14) | \ 122 122 (1ULL << PERF_REG_X86_R15)) 123 123 124 - #define PEBS_XMM_REGS \ 125 - ((1ULL << PERF_REG_X86_XMM0) | \ 126 - (1ULL << PERF_REG_X86_XMM1) | \ 127 - (1ULL << PERF_REG_X86_XMM2) | \ 128 - (1ULL << PERF_REG_X86_XMM3) | \ 129 - (1ULL << PERF_REG_X86_XMM4) | \ 130 - (1ULL << PERF_REG_X86_XMM5) | \ 131 - (1ULL << PERF_REG_X86_XMM6) | \ 132 - (1ULL << PERF_REG_X86_XMM7) | \ 133 - (1ULL << PERF_REG_X86_XMM8) | \ 134 - (1ULL << PERF_REG_X86_XMM9) | \ 135 - (1ULL << PERF_REG_X86_XMM10) | \ 136 - (1ULL << PERF_REG_X86_XMM11) | \ 137 - (1ULL << PERF_REG_X86_XMM12) | \ 138 - (1ULL << PERF_REG_X86_XMM13) | \ 139 - (1ULL << PERF_REG_X86_XMM14) | \ 140 - (1ULL << PERF_REG_X86_XMM15)) 141 - 142 124 /* 143 125 * Per register state. 144 126 */ ··· 650 668 pebs_broken :1, 651 669 pebs_prec_dist :1, 652 670 pebs_no_tlb :1, 653 - pebs_no_isolation :1, 654 - pebs_no_xmm_regs :1; 671 + pebs_no_isolation :1; 655 672 int pebs_record_size; 656 673 int pebs_buffer_size; 657 674 int max_pebs_events;
+3
arch/x86/include/uapi/asm/perf_regs.h
··· 52 52 /* These include both GPRs and XMMX registers */ 53 53 PERF_REG_X86_XMM_MAX = PERF_REG_X86_XMM15 + 2, 54 54 }; 55 + 56 + #define PERF_REG_EXTENDED_MASK (~((1ULL << PERF_REG_X86_XMM0) - 1)) 57 + 55 58 #endif /* _ASM_X86_PERF_REGS_H */
+5 -2
arch/x86/kernel/perf_regs.c
··· 74 74 return regs_get_register(regs, pt_regs_offset[idx]); 75 75 } 76 76 77 + #define PERF_REG_X86_RESERVED (((1ULL << PERF_REG_X86_XMM0) - 1) & \ 78 + ~((1ULL << PERF_REG_X86_MAX) - 1)) 79 + 77 80 #ifdef CONFIG_X86_32 78 81 #define REG_NOSUPPORT ((1ULL << PERF_REG_X86_R8) | \ 79 82 (1ULL << PERF_REG_X86_R9) | \ ··· 89 86 90 87 int perf_reg_validate(u64 mask) 91 88 { 92 - if (!mask || (mask & REG_NOSUPPORT)) 89 + if (!mask || (mask & (REG_NOSUPPORT | PERF_REG_X86_RESERVED))) 93 90 return -EINVAL; 94 91 95 92 return 0; ··· 115 112 116 113 int perf_reg_validate(u64 mask) 117 114 { 118 - if (!mask || (mask & REG_NOSUPPORT)) 115 + if (!mask || (mask & (REG_NOSUPPORT | PERF_REG_X86_RESERVED))) 119 116 return -EINVAL; 120 117 121 118 return 0;
+1
include/linux/perf_event.h
··· 241 241 #define PERF_PMU_CAP_NO_INTERRUPT 0x01 242 242 #define PERF_PMU_CAP_NO_NMI 0x02 243 243 #define PERF_PMU_CAP_AUX_NO_SG 0x04 244 + #define PERF_PMU_CAP_EXTENDED_REGS 0x08 244 245 #define PERF_PMU_CAP_EXCLUSIVE 0x10 245 246 #define PERF_PMU_CAP_ITRACE 0x20 246 247 #define PERF_PMU_CAP_HETEROGENEOUS_CPUS 0x40
+8
include/linux/perf_regs.h
··· 11 11 12 12 #ifdef CONFIG_HAVE_PERF_REGS 13 13 #include <asm/perf_regs.h> 14 + 15 + #ifndef PERF_REG_EXTENDED_MASK 16 + #define PERF_REG_EXTENDED_MASK 0 17 + #endif 18 + 14 19 u64 perf_reg_value(struct pt_regs *regs, int idx); 15 20 int perf_reg_validate(u64 mask); 16 21 u64 perf_reg_abi(struct task_struct *task); ··· 23 18 struct pt_regs *regs, 24 19 struct pt_regs *regs_user_copy); 25 20 #else 21 + 22 + #define PERF_REG_EXTENDED_MASK 0 23 + 26 24 static inline u64 perf_reg_value(struct pt_regs *regs, int idx) 27 25 { 28 26 return 0;
+18 -5
kernel/events/core.c
··· 5005 5005 if (perf_event_check_period(event, value)) 5006 5006 return -EINVAL; 5007 5007 5008 + if (!event->attr.freq && (value & (1ULL << 63))) 5009 + return -EINVAL; 5010 + 5008 5011 event_function_call(event, __perf_event_period, &value); 5009 5012 5010 5013 return 0; ··· 5926 5923 if (user_mode(regs)) { 5927 5924 regs_user->abi = perf_reg_abi(current); 5928 5925 regs_user->regs = regs; 5929 - } else if (current->mm) { 5926 + } else if (!(current->flags & PF_KTHREAD)) { 5930 5927 perf_get_regs_user(regs_user, regs, regs_user_copy); 5931 5928 } else { 5932 5929 regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE; ··· 10036 10033 } 10037 10034 EXPORT_SYMBOL_GPL(perf_pmu_unregister); 10038 10035 10036 + static inline bool has_extended_regs(struct perf_event *event) 10037 + { 10038 + return (event->attr.sample_regs_user & PERF_REG_EXTENDED_MASK) || 10039 + (event->attr.sample_regs_intr & PERF_REG_EXTENDED_MASK); 10040 + } 10041 + 10039 10042 static int perf_try_init_event(struct pmu *pmu, struct perf_event *event) 10040 10043 { 10041 10044 struct perf_event_context *ctx = NULL; ··· 10073 10064 perf_event_ctx_unlock(event->group_leader, ctx); 10074 10065 10075 10066 if (!ret) { 10067 + if (!(pmu->capabilities & PERF_PMU_CAP_EXTENDED_REGS) && 10068 + has_extended_regs(event)) 10069 + ret = -EOPNOTSUPP; 10070 + 10076 10071 if (pmu->capabilities & PERF_PMU_CAP_NO_EXCLUDE && 10077 - event_has_any_exclude_flag(event)) { 10078 - if (event->destroy) 10079 - event->destroy(event); 10072 + event_has_any_exclude_flag(event)) 10080 10073 ret = -EINVAL; 10081 - } 10074 + 10075 + if (ret && event->destroy) 10076 + event->destroy(event); 10082 10077 } 10083 10078 10084 10079 if (ret)
+3
tools/arch/x86/include/uapi/asm/perf_regs.h
··· 52 52 /* These include both GPRs and XMMX registers */ 53 53 PERF_REG_X86_XMM_MAX = PERF_REG_X86_XMM15 + 2, 54 54 }; 55 + 56 + #define PERF_REG_EXTENDED_MASK (~((1ULL << PERF_REG_X86_XMM0) - 1)) 57 + 55 58 #endif /* _ASM_X86_PERF_REGS_H */
-1
tools/perf/arch/x86/include/perf_regs.h
··· 9 9 void perf_regs_load(u64 *regs); 10 10 11 11 #define PERF_REGS_MAX PERF_REG_X86_XMM_MAX 12 - #define PERF_XMM_REGS_MASK (~((1ULL << PERF_REG_X86_XMM0) - 1)) 13 12 #ifndef HAVE_ARCH_X86_64_SUPPORT 14 13 #define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1) 15 14 #define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32
+2 -2
tools/perf/arch/x86/util/perf_regs.c
··· 277 277 .type = PERF_TYPE_HARDWARE, 278 278 .config = PERF_COUNT_HW_CPU_CYCLES, 279 279 .sample_type = PERF_SAMPLE_REGS_INTR, 280 - .sample_regs_intr = PERF_XMM_REGS_MASK, 280 + .sample_regs_intr = PERF_REG_EXTENDED_MASK, 281 281 .precise_ip = 1, 282 282 .disabled = 1, 283 283 .exclude_kernel = 1, ··· 293 293 fd = sys_perf_event_open(&attr, 0, -1, -1, 0); 294 294 if (fd != -1) { 295 295 close(fd); 296 - return (PERF_XMM_REGS_MASK | PERF_REGS_MASK); 296 + return (PERF_REG_EXTENDED_MASK | PERF_REGS_MASK); 297 297 } 298 298 299 299 return PERF_REGS_MASK;