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>
This commit is contained in:
parent
443d4beb82
commit
443e802bab
@ -42,6 +42,12 @@ extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
|
|||||||
extern unsigned long perf_misc_flags(struct pt_regs *regs);
|
extern unsigned long perf_misc_flags(struct pt_regs *regs);
|
||||||
#define perf_misc_flags(regs) perf_misc_flags(regs)
|
#define perf_misc_flags(regs) perf_misc_flags(regs)
|
||||||
|
|
||||||
|
/* Perf pt_regs extension for sample-data-entry indicators */
|
||||||
|
struct perf_sf_sde_regs {
|
||||||
|
unsigned char in_guest:1; /* guest sample */
|
||||||
|
unsigned long reserved:63; /* reserved */
|
||||||
|
};
|
||||||
|
|
||||||
/* Perf PMU definitions for the counter facility */
|
/* Perf PMU definitions for the counter facility */
|
||||||
#define PERF_CPUM_CF_MAX_CTR 256
|
#define PERF_CPUM_CF_MAX_CTR 256
|
||||||
|
|
||||||
|
@ -840,6 +840,7 @@ static int perf_push_sample(struct perf_event *event,
|
|||||||
{
|
{
|
||||||
int overflow;
|
int overflow;
|
||||||
struct pt_regs regs;
|
struct pt_regs regs;
|
||||||
|
struct perf_sf_sde_regs *sde_regs;
|
||||||
struct perf_sample_data data;
|
struct perf_sample_data data;
|
||||||
|
|
||||||
/* Skip samples that are invalid or for which the instruction address
|
/* 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);
|
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(®s, 0, sizeof(regs));
|
memset(®s, 0, sizeof(regs));
|
||||||
|
regs.int_code = 0x1407;
|
||||||
|
regs.int_parm = CPU_MF_INT_SF_PRA;
|
||||||
|
sde_regs = (struct perf_sf_sde_regs *) ®s.int_parm_long;
|
||||||
|
|
||||||
regs.psw.addr = sample->ia;
|
regs.psw.addr = sample->ia;
|
||||||
if (sample->T)
|
if (sample->T)
|
||||||
regs.psw.mask |= PSW_MASK_DAT;
|
regs.psw.mask |= PSW_MASK_DAT;
|
||||||
@ -873,6 +883,16 @@ static int perf_push_sample(struct perf_event *event,
|
|||||||
break;
|
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;
|
overflow = 0;
|
||||||
if (perf_event_overflow(event, &data, ®s)) {
|
if (perf_event_overflow(event, &data, ®s)) {
|
||||||
overflow = 1;
|
overflow = 1;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Performance event support for s390x
|
* Performance event support for s390x
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2012
|
* Copyright IBM Corp. 2012, 2013
|
||||||
* Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
* Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@ -89,8 +89,31 @@ static unsigned long perf_misc_guest_flags(struct pt_regs *regs)
|
|||||||
: PERF_RECORD_MISC_GUEST_KERNEL;
|
: PERF_RECORD_MISC_GUEST_KERNEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long perf_misc_flags_sf(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
struct perf_sf_sde_regs *sde_regs;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
sde_regs = (struct perf_sf_sde_regs *) ®s->int_parm_long;
|
||||||
|
if (sde_regs->in_guest)
|
||||||
|
flags = user_mode(regs) ? PERF_RECORD_MISC_GUEST_USER
|
||||||
|
: PERF_RECORD_MISC_GUEST_KERNEL;
|
||||||
|
else
|
||||||
|
flags = user_mode(regs) ? PERF_RECORD_MISC_USER
|
||||||
|
: PERF_RECORD_MISC_KERNEL;
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long perf_misc_flags(struct pt_regs *regs)
|
unsigned long perf_misc_flags(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
|
/* Check if the cpum_sf PMU has created the pt_regs structure.
|
||||||
|
* In this case, perf misc flags can be easily extracted. Otherwise,
|
||||||
|
* do regular checks on the pt_regs content.
|
||||||
|
*/
|
||||||
|
if (regs->int_code == 0x1407 && regs->int_parm == CPU_MF_INT_SF_PRA)
|
||||||
|
if (!regs->gprs[15])
|
||||||
|
return perf_misc_flags_sf(regs);
|
||||||
|
|
||||||
if (is_in_guest(regs))
|
if (is_in_guest(regs))
|
||||||
return perf_misc_guest_flags(regs);
|
return perf_misc_guest_flags(regs);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user