diff options
Diffstat (limited to 'kernel/events/core.c')
-rw-r--r-- | kernel/events/core.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index 4c1ee7f2bebc..19efcf13375a 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -4461,18 +4461,14 @@ perf_output_sample_regs(struct perf_output_handle *handle, | |||
4461 | } | 4461 | } |
4462 | 4462 | ||
4463 | static void perf_sample_regs_user(struct perf_regs *regs_user, | 4463 | static void perf_sample_regs_user(struct perf_regs *regs_user, |
4464 | struct pt_regs *regs) | 4464 | struct pt_regs *regs, |
4465 | struct pt_regs *regs_user_copy) | ||
4465 | { | 4466 | { |
4466 | if (!user_mode(regs)) { | 4467 | if (user_mode(regs)) { |
4467 | if (current->mm) | 4468 | regs_user->abi = perf_reg_abi(current); |
4468 | regs = task_pt_regs(current); | ||
4469 | else | ||
4470 | regs = NULL; | ||
4471 | } | ||
4472 | |||
4473 | if (regs) { | ||
4474 | regs_user->abi = perf_reg_abi(current); | ||
4475 | regs_user->regs = regs; | 4469 | regs_user->regs = regs; |
4470 | } else if (current->mm) { | ||
4471 | perf_get_regs_user(regs_user, regs, regs_user_copy); | ||
4476 | } else { | 4472 | } else { |
4477 | regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE; | 4473 | regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE; |
4478 | regs_user->regs = NULL; | 4474 | regs_user->regs = NULL; |
@@ -4951,7 +4947,8 @@ void perf_prepare_sample(struct perf_event_header *header, | |||
4951 | } | 4947 | } |
4952 | 4948 | ||
4953 | if (sample_type & (PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER)) | 4949 | if (sample_type & (PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER)) |
4954 | perf_sample_regs_user(&data->regs_user, regs); | 4950 | perf_sample_regs_user(&data->regs_user, regs, |
4951 | &data->regs_user_copy); | ||
4955 | 4952 | ||
4956 | if (sample_type & PERF_SAMPLE_REGS_USER) { | 4953 | if (sample_type & PERF_SAMPLE_REGS_USER) { |
4957 | /* regs dump ABI info */ | 4954 | /* regs dump ABI info */ |
@@ -6779,7 +6776,6 @@ skip_type: | |||
6779 | __perf_event_init_context(&cpuctx->ctx); | 6776 | __perf_event_init_context(&cpuctx->ctx); |
6780 | lockdep_set_class(&cpuctx->ctx.mutex, &cpuctx_mutex); | 6777 | lockdep_set_class(&cpuctx->ctx.mutex, &cpuctx_mutex); |
6781 | lockdep_set_class(&cpuctx->ctx.lock, &cpuctx_lock); | 6778 | lockdep_set_class(&cpuctx->ctx.lock, &cpuctx_lock); |
6782 | cpuctx->ctx.type = cpu_context; | ||
6783 | cpuctx->ctx.pmu = pmu; | 6779 | cpuctx->ctx.pmu = pmu; |
6784 | 6780 | ||
6785 | __perf_cpu_hrtimer_init(cpuctx, cpu); | 6781 | __perf_cpu_hrtimer_init(cpuctx, cpu); |
@@ -7423,7 +7419,19 @@ SYSCALL_DEFINE5(perf_event_open, | |||
7423 | * task or CPU context: | 7419 | * task or CPU context: |
7424 | */ | 7420 | */ |
7425 | if (move_group) { | 7421 | if (move_group) { |
7426 | if (group_leader->ctx->type != ctx->type) | 7422 | /* |
7423 | * Make sure we're both on the same task, or both | ||
7424 | * per-cpu events. | ||
7425 | */ | ||
7426 | if (group_leader->ctx->task != ctx->task) | ||
7427 | goto err_context; | ||
7428 | |||
7429 | /* | ||
7430 | * Make sure we're both events for the same CPU; | ||
7431 | * grouping events for different CPUs is broken; since | ||
7432 | * you can never concurrently schedule them anyhow. | ||
7433 | */ | ||
7434 | if (group_leader->cpu != event->cpu) | ||
7427 | goto err_context; | 7435 | goto err_context; |
7428 | } else { | 7436 | } else { |
7429 | if (group_leader->ctx != ctx) | 7437 | if (group_leader->ctx != ctx) |