Re: [PATCH v2 2/3] perf kvm: enable record|report feature on powerpc

2016-02-09 Thread Ravi Bangoria

Hi acme,

On Tuesday 02 February 2016 02:36 PM, Ravi Bangoria wrote:

HI acme,

On Tuesday 02 February 2016 02:36 AM, Arnaldo Carvalho de Melo wrote:

Em Fri, Jan 22, 2016 at 11:28:11AM +0530, Ravi Bangoria escreveu:

+return event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+}

This hunk and the next should be on the previous patch, that is not even
compiling...

You have to compile patch by patch, we can't just test at the end of a
patchkit like this, this destroys bisection ;-\


Didn't aware about that. Will take care of compiling each patch
separately next time onwards.


Also you first need to put in place a way to override how to obtain the
cpumode, then you should use it.

Also this mode doesn't look feasible at all, think about processing
perf.data files generated in !powerpc systems being analysed in a
powerpc system. This has to be dependend on the architecture of the
machine where the perf.data file was recorded, not on the archictecture
of the machine the binary was built for.


Valid point.

I'll re-think about approach in this case.



I've analyzed the approach. Here is my observations:

1. With the current approach, record on !powerpc and report on powerpc
will work as we are solely dependent on tracepoint; so we don't change ip
and cpumode of sample if it's not of kvm_hv:kvm_guest_exit.

2. However, record on powerpc and report on !powerpc won't work with the
current approach. To enable that, we have two options:

Option A. Change ip and cpumode of sample at a time of record.
This will add overhead at a time of recording data and it may have
bad effect like data lost.

Option B. Extension to current approach (change ip and cpumode at
report time only).
I'll need to move 'most of' the code from arch/powerpc/util/kvm.c into
some common code which is included on all architectures. And use
this code to make decision about changing ip and cpumode of sample
at run time. So these functions needs to be present in a binary,
no matter which platform it's compiled on.

I want your suggestions here, how best we can achieve that?

Regards,
Ravi



Re: [PATCH v2 2/3] perf kvm: enable record|report feature on powerpc

2016-02-09 Thread Ravi Bangoria

Hi acme,

On Tuesday 02 February 2016 02:36 PM, Ravi Bangoria wrote:

HI acme,

On Tuesday 02 February 2016 02:36 AM, Arnaldo Carvalho de Melo wrote:

Em Fri, Jan 22, 2016 at 11:28:11AM +0530, Ravi Bangoria escreveu:

+return event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+}

This hunk and the next should be on the previous patch, that is not even
compiling...

You have to compile patch by patch, we can't just test at the end of a
patchkit like this, this destroys bisection ;-\


Didn't aware about that. Will take care of compiling each patch
separately next time onwards.


Also you first need to put in place a way to override how to obtain the
cpumode, then you should use it.

Also this mode doesn't look feasible at all, think about processing
perf.data files generated in !powerpc systems being analysed in a
powerpc system. This has to be dependend on the architecture of the
machine where the perf.data file was recorded, not on the archictecture
of the machine the binary was built for.


Valid point.

I'll re-think about approach in this case.



I've analyzed the approach. Here is my observations:

1. With the current approach, record on !powerpc and report on powerpc
will work as we are solely dependent on tracepoint; so we don't change ip
and cpumode of sample if it's not of kvm_hv:kvm_guest_exit.

2. However, record on powerpc and report on !powerpc won't work with the
current approach. To enable that, we have two options:

Option A. Change ip and cpumode of sample at a time of record.
This will add overhead at a time of recording data and it may have
bad effect like data lost.

Option B. Extension to current approach (change ip and cpumode at
report time only).
I'll need to move 'most of' the code from arch/powerpc/util/kvm.c into
some common code which is included on all architectures. And use
this code to make decision about changing ip and cpumode of sample
at run time. So these functions needs to be present in a binary,
no matter which platform it's compiled on.

I want your suggestions here, how best we can achieve that?

Regards,
Ravi



Re: [PATCH v2 2/3] perf kvm: enable record|report feature on powerpc

2016-02-02 Thread Ravi Bangoria

HI acme,

On Tuesday 02 February 2016 02:36 AM, Arnaldo Carvalho de Melo wrote:

Em Fri, Jan 22, 2016 at 11:28:11AM +0530, Ravi Bangoria escreveu:

+   return event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+}

This hunk and the next should be on the previous patch, that is not even
compiling...

You have to compile patch by patch, we can't just test at the end of a
patchkit like this, this destroys bisection ;-\


Didn't aware about that. Will take care of compiling each patch
separately next time onwards.


Also you first need to put in place a way to override how to obtain the
cpumode, then you should use it.

Also this mode doesn't look feasible at all, think about processing
perf.data files generated in !powerpc systems being analysed in a
powerpc system. This has to be dependend on the architecture of the
machine where the perf.data file was recorded, not on the archictecture
of the machine the binary was built for.


Valid point.

I'll re-think about approach in this case.


It is only when you do live analysis, like with 'perf trace' and 'perf
top' that its guaranteed to be all on the same machine.

IIRC in one of the patches in this series you introduce and use a
library function on the same patch, please break it into two patches as
well, lemme see what is the name...

Yeah, it is also in this patch:

perf_evlist__arch_add_default(struct perf_evlist *evlist)

Please add this in a separate patch, stating in the changeset comment
why it is needed and how architectures can override it.


Will do that. Thanks for reviewing.

Regards,
Ravi



Re: [PATCH v2 2/3] perf kvm: enable record|report feature on powerpc

2016-02-02 Thread Ravi Bangoria

HI acme,

On Tuesday 02 February 2016 02:36 AM, Arnaldo Carvalho de Melo wrote:

Em Fri, Jan 22, 2016 at 11:28:11AM +0530, Ravi Bangoria escreveu:

+   return event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+}

This hunk and the next should be on the previous patch, that is not even
compiling...

You have to compile patch by patch, we can't just test at the end of a
patchkit like this, this destroys bisection ;-\


Didn't aware about that. Will take care of compiling each patch
separately next time onwards.


Also you first need to put in place a way to override how to obtain the
cpumode, then you should use it.

Also this mode doesn't look feasible at all, think about processing
perf.data files generated in !powerpc systems being analysed in a
powerpc system. This has to be dependend on the architecture of the
machine where the perf.data file was recorded, not on the archictecture
of the machine the binary was built for.


Valid point.

I'll re-think about approach in this case.


It is only when you do live analysis, like with 'perf trace' and 'perf
top' that its guaranteed to be all on the same machine.

IIRC in one of the patches in this series you introduce and use a
library function on the same patch, please break it into two patches as
well, lemme see what is the name...

Yeah, it is also in this patch:

perf_evlist__arch_add_default(struct perf_evlist *evlist)

Please add this in a separate patch, stating in the changeset comment
why it is needed and how architectures can override it.


Will do that. Thanks for reviewing.

Regards,
Ravi



Re: [PATCH v2 2/3] perf kvm: enable record|report feature on powerpc

2016-02-01 Thread Arnaldo Carvalho de Melo
Em Fri, Jan 22, 2016 at 11:28:11AM +0530, Ravi Bangoria escreveu:
> This patch contains core logic for enabling perf kvm {record|report} on
> powerpc.
> 
> For perf kvm record,
> This patch will replace default event(cycle) with kvm_hv:kvm_guest_exit
> while recording guest data from host.
> 
> For perf kvm report,
> This patch makes use of the 'kvm_guest_exit' tracepoint and checks the
> exit reason for any kvm exit. If it is HV_DECREMENTER, then the
> instruction pointer dumped along with this tracepoint is retrieved and
> mapped with the guest kallsyms.
> 
> Signed-off-by: Ravi Bangoria 
> Signed-off-by: Hemant Kumar 
> ---
> changes in v2:
> - Breakdown of v1 patch into two sub patches
> - Merged parse-tp.c and evlist.c from tools/perf/arch/powerpc/util/ into
>   single file with name kvm.c
> 
>  tools/perf/arch/powerpc/util/Build |   1 +
>  tools/perf/arch/powerpc/util/kvm.c | 104 
> +
>  tools/perf/util/event.c|  12 -
>  tools/perf/util/evlist.c   |   9 
>  tools/perf/util/evlist.h   |   1 +
>  tools/perf/util/evsel.c|   7 +++
>  tools/perf/util/evsel.h|   4 ++
>  tools/perf/util/session.c  |   9 ++--
>  tools/perf/util/util.c |   5 ++
>  tools/perf/util/util.h |   1 +
>  10 files changed, 147 insertions(+), 6 deletions(-)
>  create mode 100644 tools/perf/arch/powerpc/util/kvm.c
> 
> diff --git a/tools/perf/arch/powerpc/util/Build 
> b/tools/perf/arch/powerpc/util/Build
> index 7b8b0d1..eb819e0 100644
> --- a/tools/perf/arch/powerpc/util/Build
> +++ b/tools/perf/arch/powerpc/util/Build
> @@ -1,5 +1,6 @@
>  libperf-y += header.o
>  libperf-y += sym-handling.o
> +libperf-y += kvm.o
>  
>  libperf-$(CONFIG_DWARF) += dwarf-regs.o
>  libperf-$(CONFIG_DWARF) += skip-callchain-idx.o
> diff --git a/tools/perf/arch/powerpc/util/kvm.c 
> b/tools/perf/arch/powerpc/util/kvm.c
> new file mode 100644
> index 000..317f29a
> --- /dev/null
> +++ b/tools/perf/arch/powerpc/util/kvm.c
> @@ -0,0 +1,104 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License, version 2, as
> + * published by the Free Software Foundation.
> + *
> + * Copyright (C) 2016 Hemant Kumar Shaw, IBM Corporation
> + * Copyright (C) 2016 Ravikumar B. Bangoria, IBM Corporation
> + */
> +
> +#include 
> +#include "../../../util/evsel.h"
> +#include "../../../util/evlist.h"
> +#include "../../../util/trace-event.h"
> +#include "../../../util/session.h"
> +#include "../../../util/util.h"
> +
> +#define KVMPPC_EXIT "kvm_hv:kvm_guest_exit"
> +#define HV_DECREMENTER 2432
> +#define HV_BIT 3
> +#define PR_BIT 49
> +#define PPC_MAX 63
> +
> +/*
> + * To sample for only guest, record kvm_hv:kvm_guest_exit.
> + * Otherwise go via normal way(cycles).
> + */
> +int perf_evlist__arch_add_default(struct perf_evlist *evlist)
> +{
> + struct perf_evsel *evsel;
> +
> + if (!perf_guest_only())
> + return -1;
> +
> + evsel = perf_evsel__newtp_idx("kvm_hv", "kvm_guest_exit", 0);
> + if (IS_ERR(evsel))
> + return PTR_ERR(evsel);
> +
> + perf_evlist__add(evlist, evsel);
> + return 0;
> +}
> +
> +static bool is_kvmppc_exit_event(struct perf_evsel *evsel)
> +{
> + static unsigned int kvmppc_exit;
> +
> + if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
> + return false;
> +
> + if (unlikely(kvmppc_exit == 0)) {
> + if (strcmp(KVMPPC_EXIT, evsel->name))
> + return false;
> + kvmppc_exit = evsel->attr.config;
> + } else if (kvmppc_exit != evsel->attr.config) {
> + return false;
> + }
> +
> + return true;
> +}
> +
> +static bool is_hv_dec_trap(struct perf_evsel *evsel, struct perf_sample 
> *sample)
> +{
> + int trap = perf_evsel__intval(evsel, sample, "trap");
> + return trap == HV_DECREMENTER;
> +}
> +
> +/*
> + * Get the instruction pointer from the tracepoint data
> + */
> +u64 arch__get_ip(struct perf_evsel *evsel, struct perf_sample *sample)
> +{
> + if (perf_guest_only() &&
> + is_kvmppc_exit_event(evsel) &&
> + is_hv_dec_trap(evsel, sample))
> + return perf_evsel__intval(evsel, sample, "pc");
> +
> + return sample->ip;
> +}
> +
> +/*
> + * Get the HV and PR bits and accordingly, determine the cpumode
> + */
> +u8 arch__get_cpumode(const union perf_event *event, struct perf_evsel *evsel,
> +  struct perf_sample *sample)
> +{
> + unsigned long hv, pr, msr;
> + u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
> +
> + if (!perf_guest_only() || !is_kvmppc_exit_event(evsel))
> + goto ret;
> +
> + if (sample->raw_data && is_hv_dec_trap(evsel, sample)) {
> + msr = perf_evsel__intval(evsel, sample, "msr");
> + hv = msr & ((unsigned long)1 << (PPC_MAX - HV_BIT));
> + pr = msr & 

Re: [PATCH v2 2/3] perf kvm: enable record|report feature on powerpc

2016-02-01 Thread Arnaldo Carvalho de Melo
Em Fri, Jan 22, 2016 at 11:28:11AM +0530, Ravi Bangoria escreveu:
> This patch contains core logic for enabling perf kvm {record|report} on
> powerpc.
> 
> For perf kvm record,
> This patch will replace default event(cycle) with kvm_hv:kvm_guest_exit
> while recording guest data from host.
> 
> For perf kvm report,
> This patch makes use of the 'kvm_guest_exit' tracepoint and checks the
> exit reason for any kvm exit. If it is HV_DECREMENTER, then the
> instruction pointer dumped along with this tracepoint is retrieved and
> mapped with the guest kallsyms.
> 
> Signed-off-by: Ravi Bangoria 
> Signed-off-by: Hemant Kumar 
> ---
> changes in v2:
> - Breakdown of v1 patch into two sub patches
> - Merged parse-tp.c and evlist.c from tools/perf/arch/powerpc/util/ into
>   single file with name kvm.c
> 
>  tools/perf/arch/powerpc/util/Build |   1 +
>  tools/perf/arch/powerpc/util/kvm.c | 104 
> +
>  tools/perf/util/event.c|  12 -
>  tools/perf/util/evlist.c   |   9 
>  tools/perf/util/evlist.h   |   1 +
>  tools/perf/util/evsel.c|   7 +++
>  tools/perf/util/evsel.h|   4 ++
>  tools/perf/util/session.c  |   9 ++--
>  tools/perf/util/util.c |   5 ++
>  tools/perf/util/util.h |   1 +
>  10 files changed, 147 insertions(+), 6 deletions(-)
>  create mode 100644 tools/perf/arch/powerpc/util/kvm.c
> 
> diff --git a/tools/perf/arch/powerpc/util/Build 
> b/tools/perf/arch/powerpc/util/Build
> index 7b8b0d1..eb819e0 100644
> --- a/tools/perf/arch/powerpc/util/Build
> +++ b/tools/perf/arch/powerpc/util/Build
> @@ -1,5 +1,6 @@
>  libperf-y += header.o
>  libperf-y += sym-handling.o
> +libperf-y += kvm.o
>  
>  libperf-$(CONFIG_DWARF) += dwarf-regs.o
>  libperf-$(CONFIG_DWARF) += skip-callchain-idx.o
> diff --git a/tools/perf/arch/powerpc/util/kvm.c 
> b/tools/perf/arch/powerpc/util/kvm.c
> new file mode 100644
> index 000..317f29a
> --- /dev/null
> +++ b/tools/perf/arch/powerpc/util/kvm.c
> @@ -0,0 +1,104 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License, version 2, as
> + * published by the Free Software Foundation.
> + *
> + * Copyright (C) 2016 Hemant Kumar Shaw, IBM Corporation
> + * Copyright (C) 2016 Ravikumar B. Bangoria, IBM Corporation
> + */
> +
> +#include 
> +#include "../../../util/evsel.h"
> +#include "../../../util/evlist.h"
> +#include "../../../util/trace-event.h"
> +#include "../../../util/session.h"
> +#include "../../../util/util.h"
> +
> +#define KVMPPC_EXIT "kvm_hv:kvm_guest_exit"
> +#define HV_DECREMENTER 2432
> +#define HV_BIT 3
> +#define PR_BIT 49
> +#define PPC_MAX 63
> +
> +/*
> + * To sample for only guest, record kvm_hv:kvm_guest_exit.
> + * Otherwise go via normal way(cycles).
> + */
> +int perf_evlist__arch_add_default(struct perf_evlist *evlist)
> +{
> + struct perf_evsel *evsel;
> +
> + if (!perf_guest_only())
> + return -1;
> +
> + evsel = perf_evsel__newtp_idx("kvm_hv", "kvm_guest_exit", 0);
> + if (IS_ERR(evsel))
> + return PTR_ERR(evsel);
> +
> + perf_evlist__add(evlist, evsel);
> + return 0;
> +}
> +
> +static bool is_kvmppc_exit_event(struct perf_evsel *evsel)
> +{
> + static unsigned int kvmppc_exit;
> +
> + if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
> + return false;
> +
> + if (unlikely(kvmppc_exit == 0)) {
> + if (strcmp(KVMPPC_EXIT, evsel->name))
> + return false;
> + kvmppc_exit = evsel->attr.config;
> + } else if (kvmppc_exit != evsel->attr.config) {
> + return false;
> + }
> +
> + return true;
> +}
> +
> +static bool is_hv_dec_trap(struct perf_evsel *evsel, struct perf_sample 
> *sample)
> +{
> + int trap = perf_evsel__intval(evsel, sample, "trap");
> + return trap == HV_DECREMENTER;
> +}
> +
> +/*
> + * Get the instruction pointer from the tracepoint data
> + */
> +u64 arch__get_ip(struct perf_evsel *evsel, struct perf_sample *sample)
> +{
> + if (perf_guest_only() &&
> + is_kvmppc_exit_event(evsel) &&
> + is_hv_dec_trap(evsel, sample))
> + return perf_evsel__intval(evsel, sample, "pc");
> +
> + return sample->ip;
> +}
> +
> +/*
> + * Get the HV and PR bits and accordingly, determine the cpumode
> + */
> +u8 arch__get_cpumode(const union perf_event *event, struct perf_evsel *evsel,
> +  struct perf_sample *sample)
> +{
> + unsigned long hv, pr, msr;
> + u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
> +
> + if (!perf_guest_only() || !is_kvmppc_exit_event(evsel))
> + goto ret;
> +
> + if (sample->raw_data && is_hv_dec_trap(evsel, sample)) {
> + msr = perf_evsel__intval(evsel, sample, "msr");
> + hv = msr & 

[PATCH v2 2/3] perf kvm: enable record|report feature on powerpc

2016-01-21 Thread Ravi Bangoria
This patch contains core logic for enabling perf kvm {record|report} on
powerpc.

For perf kvm record,
This patch will replace default event(cycle) with kvm_hv:kvm_guest_exit
while recording guest data from host.

For perf kvm report,
This patch makes use of the 'kvm_guest_exit' tracepoint and checks the
exit reason for any kvm exit. If it is HV_DECREMENTER, then the
instruction pointer dumped along with this tracepoint is retrieved and
mapped with the guest kallsyms.

Signed-off-by: Ravi Bangoria 
Signed-off-by: Hemant Kumar 
---
changes in v2:
- Breakdown of v1 patch into two sub patches
- Merged parse-tp.c and evlist.c from tools/perf/arch/powerpc/util/ into
  single file with name kvm.c

 tools/perf/arch/powerpc/util/Build |   1 +
 tools/perf/arch/powerpc/util/kvm.c | 104 +
 tools/perf/util/event.c|  12 -
 tools/perf/util/evlist.c   |   9 
 tools/perf/util/evlist.h   |   1 +
 tools/perf/util/evsel.c|   7 +++
 tools/perf/util/evsel.h|   4 ++
 tools/perf/util/session.c  |   9 ++--
 tools/perf/util/util.c |   5 ++
 tools/perf/util/util.h |   1 +
 10 files changed, 147 insertions(+), 6 deletions(-)
 create mode 100644 tools/perf/arch/powerpc/util/kvm.c

diff --git a/tools/perf/arch/powerpc/util/Build 
b/tools/perf/arch/powerpc/util/Build
index 7b8b0d1..eb819e0 100644
--- a/tools/perf/arch/powerpc/util/Build
+++ b/tools/perf/arch/powerpc/util/Build
@@ -1,5 +1,6 @@
 libperf-y += header.o
 libperf-y += sym-handling.o
+libperf-y += kvm.o
 
 libperf-$(CONFIG_DWARF) += dwarf-regs.o
 libperf-$(CONFIG_DWARF) += skip-callchain-idx.o
diff --git a/tools/perf/arch/powerpc/util/kvm.c 
b/tools/perf/arch/powerpc/util/kvm.c
new file mode 100644
index 000..317f29a
--- /dev/null
+++ b/tools/perf/arch/powerpc/util/kvm.c
@@ -0,0 +1,104 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * Copyright (C) 2016 Hemant Kumar Shaw, IBM Corporation
+ * Copyright (C) 2016 Ravikumar B. Bangoria, IBM Corporation
+ */
+
+#include 
+#include "../../../util/evsel.h"
+#include "../../../util/evlist.h"
+#include "../../../util/trace-event.h"
+#include "../../../util/session.h"
+#include "../../../util/util.h"
+
+#define KVMPPC_EXIT "kvm_hv:kvm_guest_exit"
+#define HV_DECREMENTER 2432
+#define HV_BIT 3
+#define PR_BIT 49
+#define PPC_MAX 63
+
+/*
+ * To sample for only guest, record kvm_hv:kvm_guest_exit.
+ * Otherwise go via normal way(cycles).
+ */
+int perf_evlist__arch_add_default(struct perf_evlist *evlist)
+{
+   struct perf_evsel *evsel;
+
+   if (!perf_guest_only())
+   return -1;
+
+   evsel = perf_evsel__newtp_idx("kvm_hv", "kvm_guest_exit", 0);
+   if (IS_ERR(evsel))
+   return PTR_ERR(evsel);
+
+   perf_evlist__add(evlist, evsel);
+   return 0;
+}
+
+static bool is_kvmppc_exit_event(struct perf_evsel *evsel)
+{
+   static unsigned int kvmppc_exit;
+
+   if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
+   return false;
+
+   if (unlikely(kvmppc_exit == 0)) {
+   if (strcmp(KVMPPC_EXIT, evsel->name))
+   return false;
+   kvmppc_exit = evsel->attr.config;
+   } else if (kvmppc_exit != evsel->attr.config) {
+   return false;
+   }
+
+   return true;
+}
+
+static bool is_hv_dec_trap(struct perf_evsel *evsel, struct perf_sample 
*sample)
+{
+   int trap = perf_evsel__intval(evsel, sample, "trap");
+   return trap == HV_DECREMENTER;
+}
+
+/*
+ * Get the instruction pointer from the tracepoint data
+ */
+u64 arch__get_ip(struct perf_evsel *evsel, struct perf_sample *sample)
+{
+   if (perf_guest_only() &&
+   is_kvmppc_exit_event(evsel) &&
+   is_hv_dec_trap(evsel, sample))
+   return perf_evsel__intval(evsel, sample, "pc");
+
+   return sample->ip;
+}
+
+/*
+ * Get the HV and PR bits and accordingly, determine the cpumode
+ */
+u8 arch__get_cpumode(const union perf_event *event, struct perf_evsel *evsel,
+struct perf_sample *sample)
+{
+   unsigned long hv, pr, msr;
+   u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+
+   if (!perf_guest_only() || !is_kvmppc_exit_event(evsel))
+   goto ret;
+
+   if (sample->raw_data && is_hv_dec_trap(evsel, sample)) {
+   msr = perf_evsel__intval(evsel, sample, "msr");
+   hv = msr & ((unsigned long)1 << (PPC_MAX - HV_BIT));
+   pr = msr & ((unsigned long)1 << (PPC_MAX - PR_BIT));
+
+   if (!hv && pr)
+   cpumode = PERF_RECORD_MISC_GUEST_USER;
+   else
+   cpumode = PERF_RECORD_MISC_GUEST_KERNEL;
+   }
+
+ret:
+   return cpumode;
+}
diff --git 

[PATCH v2 2/3] perf kvm: enable record|report feature on powerpc

2016-01-21 Thread Ravi Bangoria
This patch contains core logic for enabling perf kvm {record|report} on
powerpc.

For perf kvm record,
This patch will replace default event(cycle) with kvm_hv:kvm_guest_exit
while recording guest data from host.

For perf kvm report,
This patch makes use of the 'kvm_guest_exit' tracepoint and checks the
exit reason for any kvm exit. If it is HV_DECREMENTER, then the
instruction pointer dumped along with this tracepoint is retrieved and
mapped with the guest kallsyms.

Signed-off-by: Ravi Bangoria 
Signed-off-by: Hemant Kumar 
---
changes in v2:
- Breakdown of v1 patch into two sub patches
- Merged parse-tp.c and evlist.c from tools/perf/arch/powerpc/util/ into
  single file with name kvm.c

 tools/perf/arch/powerpc/util/Build |   1 +
 tools/perf/arch/powerpc/util/kvm.c | 104 +
 tools/perf/util/event.c|  12 -
 tools/perf/util/evlist.c   |   9 
 tools/perf/util/evlist.h   |   1 +
 tools/perf/util/evsel.c|   7 +++
 tools/perf/util/evsel.h|   4 ++
 tools/perf/util/session.c  |   9 ++--
 tools/perf/util/util.c |   5 ++
 tools/perf/util/util.h |   1 +
 10 files changed, 147 insertions(+), 6 deletions(-)
 create mode 100644 tools/perf/arch/powerpc/util/kvm.c

diff --git a/tools/perf/arch/powerpc/util/Build 
b/tools/perf/arch/powerpc/util/Build
index 7b8b0d1..eb819e0 100644
--- a/tools/perf/arch/powerpc/util/Build
+++ b/tools/perf/arch/powerpc/util/Build
@@ -1,5 +1,6 @@
 libperf-y += header.o
 libperf-y += sym-handling.o
+libperf-y += kvm.o
 
 libperf-$(CONFIG_DWARF) += dwarf-regs.o
 libperf-$(CONFIG_DWARF) += skip-callchain-idx.o
diff --git a/tools/perf/arch/powerpc/util/kvm.c 
b/tools/perf/arch/powerpc/util/kvm.c
new file mode 100644
index 000..317f29a
--- /dev/null
+++ b/tools/perf/arch/powerpc/util/kvm.c
@@ -0,0 +1,104 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * Copyright (C) 2016 Hemant Kumar Shaw, IBM Corporation
+ * Copyright (C) 2016 Ravikumar B. Bangoria, IBM Corporation
+ */
+
+#include 
+#include "../../../util/evsel.h"
+#include "../../../util/evlist.h"
+#include "../../../util/trace-event.h"
+#include "../../../util/session.h"
+#include "../../../util/util.h"
+
+#define KVMPPC_EXIT "kvm_hv:kvm_guest_exit"
+#define HV_DECREMENTER 2432
+#define HV_BIT 3
+#define PR_BIT 49
+#define PPC_MAX 63
+
+/*
+ * To sample for only guest, record kvm_hv:kvm_guest_exit.
+ * Otherwise go via normal way(cycles).
+ */
+int perf_evlist__arch_add_default(struct perf_evlist *evlist)
+{
+   struct perf_evsel *evsel;
+
+   if (!perf_guest_only())
+   return -1;
+
+   evsel = perf_evsel__newtp_idx("kvm_hv", "kvm_guest_exit", 0);
+   if (IS_ERR(evsel))
+   return PTR_ERR(evsel);
+
+   perf_evlist__add(evlist, evsel);
+   return 0;
+}
+
+static bool is_kvmppc_exit_event(struct perf_evsel *evsel)
+{
+   static unsigned int kvmppc_exit;
+
+   if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
+   return false;
+
+   if (unlikely(kvmppc_exit == 0)) {
+   if (strcmp(KVMPPC_EXIT, evsel->name))
+   return false;
+   kvmppc_exit = evsel->attr.config;
+   } else if (kvmppc_exit != evsel->attr.config) {
+   return false;
+   }
+
+   return true;
+}
+
+static bool is_hv_dec_trap(struct perf_evsel *evsel, struct perf_sample 
*sample)
+{
+   int trap = perf_evsel__intval(evsel, sample, "trap");
+   return trap == HV_DECREMENTER;
+}
+
+/*
+ * Get the instruction pointer from the tracepoint data
+ */
+u64 arch__get_ip(struct perf_evsel *evsel, struct perf_sample *sample)
+{
+   if (perf_guest_only() &&
+   is_kvmppc_exit_event(evsel) &&
+   is_hv_dec_trap(evsel, sample))
+   return perf_evsel__intval(evsel, sample, "pc");
+
+   return sample->ip;
+}
+
+/*
+ * Get the HV and PR bits and accordingly, determine the cpumode
+ */
+u8 arch__get_cpumode(const union perf_event *event, struct perf_evsel *evsel,
+struct perf_sample *sample)
+{
+   unsigned long hv, pr, msr;
+   u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+
+   if (!perf_guest_only() || !is_kvmppc_exit_event(evsel))
+   goto ret;
+
+   if (sample->raw_data && is_hv_dec_trap(evsel, sample)) {
+   msr = perf_evsel__intval(evsel, sample, "msr");
+   hv = msr & ((unsigned long)1 << (PPC_MAX - HV_BIT));
+   pr = msr & ((unsigned long)1 << (PPC_MAX - PR_BIT));
+
+   if (!hv && pr)
+   cpumode = PERF_RECORD_MISC_GUEST_USER;
+   else
+   cpumode = PERF_RECORD_MISC_GUEST_KERNEL;
+   }
+