diff options
Diffstat (limited to 'arch/x86/events/core.c')
| -rw-r--r-- | arch/x86/events/core.c | 12 | 
1 files changed, 9 insertions, 3 deletions
| diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index a6006e7bb729..5f4829f10129 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -27,6 +27,7 @@  #include <linux/cpu.h>  #include <linux/bitops.h>  #include <linux/device.h> +#include <linux/nospec.h>  #include <asm/apic.h>  #include <asm/stacktrace.h> @@ -304,17 +305,20 @@ set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event *event)  	config = attr->config; -	cache_type = (config >>  0) & 0xff; +	cache_type = (config >> 0) & 0xff;  	if (cache_type >= PERF_COUNT_HW_CACHE_MAX)  		return -EINVAL; +	cache_type = array_index_nospec(cache_type, PERF_COUNT_HW_CACHE_MAX);  	cache_op = (config >>  8) & 0xff;  	if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)  		return -EINVAL; +	cache_op = array_index_nospec(cache_op, PERF_COUNT_HW_CACHE_OP_MAX);  	cache_result = (config >> 16) & 0xff;  	if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)  		return -EINVAL; +	cache_result = array_index_nospec(cache_result, PERF_COUNT_HW_CACHE_RESULT_MAX);  	val = hw_cache_event_ids[cache_type][cache_op][cache_result]; @@ -421,6 +425,8 @@ int x86_setup_perfctr(struct perf_event *event)  	if (attr->config >= x86_pmu.max_events)  		return -EINVAL; +	attr->config = array_index_nospec((unsigned long)attr->config, x86_pmu.max_events); +  	/*  	 * The generic map:  	 */ @@ -1631,7 +1637,7 @@ __init struct attribute **merge_attr(struct attribute **a, struct attribute **b)  		j++;  	j++; -	new = kmalloc(sizeof(struct attribute *) * j, GFP_KERNEL); +	new = kmalloc_array(j, sizeof(struct attribute *), GFP_KERNEL);  	if (!new)  		return NULL; @@ -2391,7 +2397,7 @@ static unsigned long get_segment_base(unsigned int segment)  #ifdef CONFIG_IA32_EMULATION -#include <asm/compat.h> +#include <linux/compat.h>  static inline int  perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *entry) |