aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/events
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-12-12 03:09:03 -0500
committerIngo Molnar <mingo@kernel.org>2014-12-12 03:09:03 -0500
commit3459f0d78ffe27a1b341c22eb158b622eaaea3fc (patch)
tree715b0575eec541d0181876ad367ca5480cdcecf3 /kernel/events
parent9fc81d87420d0d3fd62d5e5529972c0ad9eab9cc (diff)
parentbee2782f30f66898be3f74ad02e4d1f87a969694 (diff)
Merge branch 'linus' into perf/urgent, to pick up the upstream merged bits
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/events')
-rw-r--r--kernel/events/core.c60
1 files changed, 51 insertions, 9 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 2ab023803945..af0a5ba4e21d 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4460,7 +4460,7 @@ perf_output_sample_regs(struct perf_output_handle *handle,
4460 } 4460 }
4461} 4461}
4462 4462
4463static void perf_sample_regs_user(struct perf_regs_user *regs_user, 4463static void perf_sample_regs_user(struct perf_regs *regs_user,
4464 struct pt_regs *regs) 4464 struct pt_regs *regs)
4465{ 4465{
4466 if (!user_mode(regs)) { 4466 if (!user_mode(regs)) {
@@ -4471,11 +4471,22 @@ static void perf_sample_regs_user(struct perf_regs_user *regs_user,
4471 } 4471 }
4472 4472
4473 if (regs) { 4473 if (regs) {
4474 regs_user->regs = regs;
4475 regs_user->abi = perf_reg_abi(current); 4474 regs_user->abi = perf_reg_abi(current);
4475 regs_user->regs = regs;
4476 } else {
4477 regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE;
4478 regs_user->regs = NULL;
4476 } 4479 }
4477} 4480}
4478 4481
4482static void perf_sample_regs_intr(struct perf_regs *regs_intr,
4483 struct pt_regs *regs)
4484{
4485 regs_intr->regs = regs;
4486 regs_intr->abi = perf_reg_abi(current);
4487}
4488
4489
4479/* 4490/*
4480 * Get remaining task size from user stack pointer. 4491 * Get remaining task size from user stack pointer.
4481 * 4492 *
@@ -4857,6 +4868,23 @@ void perf_output_sample(struct perf_output_handle *handle,
4857 if (sample_type & PERF_SAMPLE_TRANSACTION) 4868 if (sample_type & PERF_SAMPLE_TRANSACTION)
4858 perf_output_put(handle, data->txn); 4869 perf_output_put(handle, data->txn);
4859 4870
4871 if (sample_type & PERF_SAMPLE_REGS_INTR) {
4872 u64 abi = data->regs_intr.abi;
4873 /*
4874 * If there are no regs to dump, notice it through
4875 * first u64 being zero (PERF_SAMPLE_REGS_ABI_NONE).
4876 */
4877 perf_output_put(handle, abi);
4878
4879 if (abi) {
4880 u64 mask = event->attr.sample_regs_intr;
4881
4882 perf_output_sample_regs(handle,
4883 data->regs_intr.regs,
4884 mask);
4885 }
4886 }
4887
4860 if (!event->attr.watermark) { 4888 if (!event->attr.watermark) {
4861 int wakeup_events = event->attr.wakeup_events; 4889 int wakeup_events = event->attr.wakeup_events;
4862 4890
@@ -4922,12 +4950,13 @@ void perf_prepare_sample(struct perf_event_header *header,
4922 header->size += size; 4950 header->size += size;
4923 } 4951 }
4924 4952
4953 if (sample_type & (PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER))
4954 perf_sample_regs_user(&data->regs_user, regs);
4955
4925 if (sample_type & PERF_SAMPLE_REGS_USER) { 4956 if (sample_type & PERF_SAMPLE_REGS_USER) {
4926 /* regs dump ABI info */ 4957 /* regs dump ABI info */
4927 int size = sizeof(u64); 4958 int size = sizeof(u64);
4928 4959
4929 perf_sample_regs_user(&data->regs_user, regs);
4930
4931 if (data->regs_user.regs) { 4960 if (data->regs_user.regs) {
4932 u64 mask = event->attr.sample_regs_user; 4961 u64 mask = event->attr.sample_regs_user;
4933 size += hweight64(mask) * sizeof(u64); 4962 size += hweight64(mask) * sizeof(u64);
@@ -4943,15 +4972,11 @@ void perf_prepare_sample(struct perf_event_header *header,
4943 * in case new sample type is added, because we could eat 4972 * in case new sample type is added, because we could eat
4944 * up the rest of the sample size. 4973 * up the rest of the sample size.
4945 */ 4974 */
4946 struct perf_regs_user *uregs = &data->regs_user;
4947 u16 stack_size = event->attr.sample_stack_user; 4975 u16 stack_size = event->attr.sample_stack_user;
4948 u16 size = sizeof(u64); 4976 u16 size = sizeof(u64);
4949 4977
4950 if (!uregs->abi)
4951 perf_sample_regs_user(uregs, regs);
4952
4953 stack_size = perf_sample_ustack_size(stack_size, header->size, 4978 stack_size = perf_sample_ustack_size(stack_size, header->size,
4954 uregs->regs); 4979 data->regs_user.regs);
4955 4980
4956 /* 4981 /*
4957 * If there is something to dump, add space for the dump 4982 * If there is something to dump, add space for the dump
@@ -4964,6 +4989,21 @@ void perf_prepare_sample(struct perf_event_header *header,
4964 data->stack_user_size = stack_size; 4989 data->stack_user_size = stack_size;
4965 header->size += size; 4990 header->size += size;
4966 } 4991 }
4992
4993 if (sample_type & PERF_SAMPLE_REGS_INTR) {
4994 /* regs dump ABI info */
4995 int size = sizeof(u64);
4996
4997 perf_sample_regs_intr(&data->regs_intr, regs);
4998
4999 if (data->regs_intr.regs) {
5000 u64 mask = event->attr.sample_regs_intr;
5001
5002 size += hweight64(mask) * sizeof(u64);
5003 }
5004
5005 header->size += size;
5006 }
4967} 5007}
4968 5008
4969static void perf_event_output(struct perf_event *event, 5009static void perf_event_output(struct perf_event *event,
@@ -7151,6 +7191,8 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr,
7151 ret = -EINVAL; 7191 ret = -EINVAL;
7152 } 7192 }
7153 7193
7194 if (attr->sample_type & PERF_SAMPLE_REGS_INTR)
7195 ret = perf_reg_validate(attr->sample_regs_intr);
7154out: 7196out:
7155 return ret; 7197 return ret;
7156 7198