aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/perf_cpum_sf.c
diff options
context:
space:
mode:
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>2013-12-12 17:54:57 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-12-16 14:37:59 +0100
commit443e802bab16916f9a51a34f2213f4dee6e8762c (patch)
tree8481d35917b96ad1dfee837e52ad804e3459e018 /arch/s390/kernel/perf_cpum_sf.c
parents390/cpum_sf: Add helper to read TOD from trailer entries (diff)
downloadlinux-dev-443e802bab16916f9a51a34f2213f4dee6e8762c.tar.xz
linux-dev-443e802bab16916f9a51a34f2213f4dee6e8762c.zip
s390/cpum_sf: Detect KVM guest samples
The host-program-parameter (hpp) value of basic sample-data-entries designates a SIE control block that is set by the LPP instruction in sie64a(). Non-zero values indicate guest samples, a value of zero indicates a host sample. For perf samples, host and guest samples are distinguished using particular PERF_MISC_* flags. The perf layer calls perf_misc_flags() to set the flags based on the pt_regs content. For each sample-data-entry, the cpum_sf PMU creates a pt_regs structure with the sample-data information. An additional flag structure is added to easily distinguish between host and guest samples. Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/perf_cpum_sf.c')
-rw-r--r--arch/s390/kernel/perf_cpum_sf.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c
index 3ab7e67ee2e4..d611facae599 100644
--- a/arch/s390/kernel/perf_cpum_sf.c
+++ b/arch/s390/kernel/perf_cpum_sf.c
@@ -840,6 +840,7 @@ static int perf_push_sample(struct perf_event *event,
{
int overflow;
struct pt_regs regs;
+ struct perf_sf_sde_regs *sde_regs;
struct perf_sample_data data;
/* Skip samples that are invalid or for which the instruction address
@@ -850,7 +851,16 @@ static int perf_push_sample(struct perf_event *event,
perf_sample_data_init(&data, 0, event->hw.last_period);
+ /* Setup pt_regs to look like an CPU-measurement external interrupt
+ * using the Program Request Alert code. The regs.int_parm_long
+ * field which is unused contains additional sample-data-entry related
+ * indicators.
+ */
memset(&regs, 0, sizeof(regs));
+ regs.int_code = 0x1407;
+ regs.int_parm = CPU_MF_INT_SF_PRA;
+ sde_regs = (struct perf_sf_sde_regs *) &regs.int_parm_long;
+
regs.psw.addr = sample->ia;
if (sample->T)
regs.psw.mask |= PSW_MASK_DAT;
@@ -873,6 +883,16 @@ static int perf_push_sample(struct perf_event *event,
break;
}
+ /* The host-program-parameter (hpp) contains the sie control
+ * block that is set by sie64a() in entry64.S. Check if hpp
+ * refers to a valid control block and set sde_regs flags
+ * accordingly. This would allow to use hpp values for other
+ * purposes too.
+ * For now, simply use a non-zero value as guest indicator.
+ */
+ if (sample->hpp)
+ sde_regs->in_guest = 1;
+
overflow = 0;
if (perf_event_overflow(event, &data, &regs)) {
overflow = 1;