diff options
Diffstat (limited to 'kernel/events/hw_breakpoint.c')
| -rw-r--r-- | kernel/events/hw_breakpoint.c | 11 | 
1 files changed, 10 insertions, 1 deletions
diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c index bb38c4d3ee1..9a7b487c6fe 100644 --- a/kernel/events/hw_breakpoint.c +++ b/kernel/events/hw_breakpoint.c @@ -453,7 +453,16 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att  	int old_type = bp->attr.bp_type;  	int err = 0; -	perf_event_disable(bp); +	/* +	 * modify_user_hw_breakpoint can be invoked with IRQs disabled and hence it +	 * will not be possible to raise IPIs that invoke __perf_event_disable. +	 * So call the function directly after making sure we are targeting the +	 * current task. +	 */ +	if (irqs_disabled() && bp->ctx && bp->ctx->task == current) +		__perf_event_disable(bp); +	else +		perf_event_disable(bp);  	bp->attr.bp_addr = attr->bp_addr;  	bp->attr.bp_type = attr->bp_type;  |