* [PATCH v5 1/4] arm64: arm_pmu: remove unnecessary isb instruction
2018-12-05 15:30 [PATCH v5 0/4] arm64: Support perf event modifiers :G and :H Andrew Murray
@ 2018-12-05 15:30 ` Andrew Murray
2018-12-05 15:30 ` [PATCH v5 2/4] arm64: KVM: add accessors to track guest/host only counters Andrew Murray
` (2 subsequent siblings)
3 siblings, 0 replies; 11+ messages in thread
From: Andrew Murray @ 2018-12-05 15:30 UTC (permalink / raw)
To: Christoffer Dall, Marc Zyngier, Catalin Marinas, Will Deacon,
Mark Rutland
Cc: Suzuki K Poulose, kvmarm, linux-arm-kernel, Julien Thierry
The armv8pmu_enable_event_counter function issues an isb instruction
after enabling a pair of counters - this doesn't provide any value
and is inconsistent with the armv8pmu_disable_event_counter.
In any case armv8pmu_enable_event_counter is always called with the
PMU stopped. Starting the PMU with armv8pmu_start results in an isb
instruction being issued prior to writing to PMCR_EL0.
Let's remove the unnecessary isb instruction.
Signed-off-by: Andrew Murray <andrew.murray@arm.com>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Acked-by: Mark Rutland <mark.rutland@arm.com>
---
arch/arm64/kernel/perf_event.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 8e38d52..de564ae 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -652,7 +652,6 @@ static inline void armv8pmu_enable_event_counter(struct perf_event *event)
armv8pmu_enable_counter(idx);
if (armv8pmu_event_is_chained(event))
armv8pmu_enable_counter(idx - 1);
- isb();
}
static inline int armv8pmu_disable_counter(int idx)
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v5 2/4] arm64: KVM: add accessors to track guest/host only counters
2018-12-05 15:30 [PATCH v5 0/4] arm64: Support perf event modifiers :G and :H Andrew Murray
2018-12-05 15:30 ` [PATCH v5 1/4] arm64: arm_pmu: remove unnecessary isb instruction Andrew Murray
@ 2018-12-05 15:30 ` Andrew Murray
2018-12-06 17:21 ` Suzuki K Poulose
2018-12-05 15:30 ` [PATCH v5 3/4] arm64: arm_pmu: Add support for exclude_host/exclude_guest attributes Andrew Murray
2018-12-05 15:30 ` [PATCH v5 4/4] arm64: KVM: Enable support for :G/:H perf event modifiers Andrew Murray
3 siblings, 1 reply; 11+ messages in thread
From: Andrew Murray @ 2018-12-05 15:30 UTC (permalink / raw)
To: Christoffer Dall, Marc Zyngier, Catalin Marinas, Will Deacon,
Mark Rutland
Cc: Suzuki K Poulose, kvmarm, linux-arm-kernel, Julien Thierry
In order to effeciently enable/disable guest/host only perf counters
at guest entry/exit we add bitfields to kvm_cpu_context for guest and
host events as well as accessors for updating them.
Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
arch/arm64/include/asm/kvm_host.h | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 1550192..800c87b 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -203,6 +203,8 @@ struct kvm_cpu_context {
};
struct kvm_vcpu *__hyp_running_vcpu;
+ u32 events_host;
+ u32 events_guest;
};
typedef struct kvm_cpu_context kvm_cpu_context_t;
@@ -467,11 +469,33 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu);
void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu);
+#define KVM_PMU_EVENTS_HOST 1
+#define KVM_PMU_EVENTS_GUEST 2
+
#ifdef CONFIG_KVM /* Avoid conflicts with core headers if CONFIG_KVM=n */
static inline int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
{
return kvm_arch_vcpu_run_map_fp(vcpu);
}
+static inline void kvm_set_pmu_events(u32 set, int flags)
+{
+ kvm_cpu_context_t *ctx = this_cpu_ptr(&kvm_host_cpu_state);
+
+ if (flags & KVM_PMU_EVENTS_HOST)
+ ctx->events_host |= set;
+ if (flags & KVM_PMU_EVENTS_GUEST)
+ ctx->events_guest |= set;
+}
+static inline void kvm_clr_pmu_events(u32 clr)
+{
+ kvm_cpu_context_t *ctx = this_cpu_ptr(&kvm_host_cpu_state);
+
+ ctx->events_host &= ~clr;
+ ctx->events_guest &= ~clr;
+}
+#else
+static inline void kvm_set_pmu_events(u32 set, int flags) {}
+static inline void kvm_clr_pmu_events(u32 clr) {}
#endif
static inline void kvm_arm_vhe_guest_enter(void)
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH v5 2/4] arm64: KVM: add accessors to track guest/host only counters
2018-12-05 15:30 ` [PATCH v5 2/4] arm64: KVM: add accessors to track guest/host only counters Andrew Murray
@ 2018-12-06 17:21 ` Suzuki K Poulose
2018-12-06 18:51 ` Suzuki K Poulose
0 siblings, 1 reply; 11+ messages in thread
From: Suzuki K Poulose @ 2018-12-06 17:21 UTC (permalink / raw)
To: Andrew Murray, Christoffer Dall, Marc Zyngier, Catalin Marinas,
Will Deacon, Mark Rutland
Cc: kvmarm, linux-arm-kernel, Julien Thierry
Hi Andrew,
On 05/12/2018 15:30, Andrew Murray wrote:
> In order to effeciently enable/disable guest/host only perf counters
> at guest entry/exit we add bitfields to kvm_cpu_context for guest and
> host events as well as accessors for updating them.
>
> Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> ---
> arch/arm64/include/asm/kvm_host.h | 24 ++++++++++++++++++++++++
> 1 file changed, 24 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 1550192..800c87b 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -203,6 +203,8 @@ struct kvm_cpu_context {
> };
>
> struct kvm_vcpu *__hyp_running_vcpu;
> + u32 events_host;
> + u32 events_guest;
> };
>
> typedef struct kvm_cpu_context kvm_cpu_context_t;
> @@ -467,11 +469,33 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
> void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu);
> void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu);
>
> +#define KVM_PMU_EVENTS_HOST 1
> +#define KVM_PMU_EVENTS_GUEST 2
> +
> #ifdef CONFIG_KVM /* Avoid conflicts with core headers if CONFIG_KVM=n */
> static inline int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
> {
> return kvm_arch_vcpu_run_map_fp(vcpu);
> }
> +static inline void kvm_set_pmu_events(u32 set, int flags)
> +{
> + kvm_cpu_context_t *ctx = this_cpu_ptr(&kvm_host_cpu_state);
> +
> + if (flags & KVM_PMU_EVENTS_HOST)
> + ctx->events_host |= set;
> + if (flags & KVM_PMU_EVENTS_GUEST)
> + ctx->events_guest |= set;
You seem to be passing a single flag at a time ever, in the next patch.
Either we can batch the calls in the next patch, or make this a real number and
not a flag. g.g, enum { HOST, GUEST } or even a bool.
I think the former sounds better.
Cheers
Suzuki
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH v5 2/4] arm64: KVM: add accessors to track guest/host only counters
2018-12-06 17:21 ` Suzuki K Poulose
@ 2018-12-06 18:51 ` Suzuki K Poulose
2018-12-06 19:21 ` Andrew Murray
0 siblings, 1 reply; 11+ messages in thread
From: Suzuki K Poulose @ 2018-12-06 18:51 UTC (permalink / raw)
To: Andrew Murray, Christoffer Dall, Marc Zyngier, Catalin Marinas,
Will Deacon, Mark Rutland
Cc: kvmarm, linux-arm-kernel, Julien Thierry
On 06/12/2018 17:21, Suzuki K Poulose wrote:
> Hi Andrew,
>
> On 05/12/2018 15:30, Andrew Murray wrote:
>> In order to effeciently enable/disable guest/host only perf counters
>> at guest entry/exit we add bitfields to kvm_cpu_context for guest and
>> host events as well as accessors for updating them.
>>
>> Signed-off-by: Andrew Murray <andrew.murray@arm.com>
>> ---
>> arch/arm64/include/asm/kvm_host.h | 24 ++++++++++++++++++++++++
>> 1 file changed, 24 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>> index 1550192..800c87b 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -203,6 +203,8 @@ struct kvm_cpu_context {
>> };
>>
>> struct kvm_vcpu *__hyp_running_vcpu;
>> + u32 events_host;
>> + u32 events_guest;
>> };
>>
>> typedef struct kvm_cpu_context kvm_cpu_context_t;
>> @@ -467,11 +469,33 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
>> void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu);
>> void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu);
>>
>> +#define KVM_PMU_EVENTS_HOST 1
>> +#define KVM_PMU_EVENTS_GUEST 2
>> +
>> #ifdef CONFIG_KVM /* Avoid conflicts with core headers if CONFIG_KVM=n */
>> static inline int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
>> {
>> return kvm_arch_vcpu_run_map_fp(vcpu);
>> }
>> +static inline void kvm_set_pmu_events(u32 set, int flags)
>> +{
>> + kvm_cpu_context_t *ctx = this_cpu_ptr(&kvm_host_cpu_state);
>> +
>> + if (flags & KVM_PMU_EVENTS_HOST)
>> + ctx->events_host |= set;
>> + if (flags & KVM_PMU_EVENTS_GUEST)
>> + ctx->events_guest |= set;
>
> You seem to be passing a single flag at a time ever, in the next patch.
> Either we can batch the calls in the next patch, or make this a real number and
> not a flag. g.g, enum { HOST, GUEST } or even a bool.
>
> I think the former sounds better.
Having another look at patch-3, we can never club set() calls for host & guest
events, we should go for the latter.
Suzuki
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH v5 2/4] arm64: KVM: add accessors to track guest/host only counters
2018-12-06 18:51 ` Suzuki K Poulose
@ 2018-12-06 19:21 ` Andrew Murray
2018-12-07 14:08 ` Suzuki K Poulose
0 siblings, 1 reply; 11+ messages in thread
From: Andrew Murray @ 2018-12-06 19:21 UTC (permalink / raw)
To: Suzuki K Poulose
Cc: Mark Rutland, Julien Thierry, Marc Zyngier, Catalin Marinas,
Will Deacon, Christoffer Dall, kvmarm, linux-arm-kernel
On Thu, Dec 06, 2018 at 06:51:37PM +0000, Suzuki K Poulose wrote:
>
>
> On 06/12/2018 17:21, Suzuki K Poulose wrote:
> > Hi Andrew,
> >
> > On 05/12/2018 15:30, Andrew Murray wrote:
> > > In order to effeciently enable/disable guest/host only perf counters
> > > at guest entry/exit we add bitfields to kvm_cpu_context for guest and
> > > host events as well as accessors for updating them.
> > >
> > > Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> > > ---
> > > arch/arm64/include/asm/kvm_host.h | 24 ++++++++++++++++++++++++
> > > 1 file changed, 24 insertions(+)
> > >
> > > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > > index 1550192..800c87b 100644
> > > --- a/arch/arm64/include/asm/kvm_host.h
> > > +++ b/arch/arm64/include/asm/kvm_host.h
> > > @@ -203,6 +203,8 @@ struct kvm_cpu_context {
> > > };
> > > struct kvm_vcpu *__hyp_running_vcpu;
> > > + u32 events_host;
> > > + u32 events_guest;
> > > };
> > > typedef struct kvm_cpu_context kvm_cpu_context_t;
> > > @@ -467,11 +469,33 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
> > > void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu);
> > > void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu);
> > > +#define KVM_PMU_EVENTS_HOST 1
> > > +#define KVM_PMU_EVENTS_GUEST 2
> > > +
> > > #ifdef CONFIG_KVM /* Avoid conflicts with core headers if CONFIG_KVM=n */
> > > static inline int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
> > > {
> > > return kvm_arch_vcpu_run_map_fp(vcpu);
> > > }
> > > +static inline void kvm_set_pmu_events(u32 set, int flags)
> > > +{
> > > + kvm_cpu_context_t *ctx = this_cpu_ptr(&kvm_host_cpu_state);
> > > +
> > > + if (flags & KVM_PMU_EVENTS_HOST)
> > > + ctx->events_host |= set;
> > > + if (flags & KVM_PMU_EVENTS_GUEST)
> > > + ctx->events_guest |= set;
> >
> > You seem to be passing a single flag at a time ever, in the next patch.
> > Either we can batch the calls in the next patch, or make this a real number and
> > not a flag. g.g, enum { HOST, GUEST } or even a bool.
> >
> > I think the former sounds better.
>
> Having another look at patch-3, we can never club set() calls for host &
> guest events, we should go for the latter.
Well we could always do this..
u32 flags = 0;
if (!attr->exclude_host)
flags |= KVM_PMU_EVENTS_HOST;
if (!attr->exclude_guest)
flags |= KVM_PMU_EVENTS_GUEST;
kvm_set_pmu_events(counter_bits, flags);
Thanks,
Andrew Murray
>
> Suzuki
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH v5 2/4] arm64: KVM: add accessors to track guest/host only counters
2018-12-06 19:21 ` Andrew Murray
@ 2018-12-07 14:08 ` Suzuki K Poulose
0 siblings, 0 replies; 11+ messages in thread
From: Suzuki K Poulose @ 2018-12-07 14:08 UTC (permalink / raw)
To: Andrew Murray
Cc: Mark Rutland, Julien Thierry, Marc Zyngier, Catalin Marinas,
Will Deacon, Christoffer Dall, kvmarm, linux-arm-kernel
On 06/12/2018 19:21, Andrew Murray wrote:
> On Thu, Dec 06, 2018 at 06:51:37PM +0000, Suzuki K Poulose wrote:
>>
>>
>> On 06/12/2018 17:21, Suzuki K Poulose wrote:
>>> Hi Andrew,
>>>
>>> On 05/12/2018 15:30, Andrew Murray wrote:
>>>> In order to effeciently enable/disable guest/host only perf counters
>>>> at guest entry/exit we add bitfields to kvm_cpu_context for guest and
>>>> host events as well as accessors for updating them.
>>>>
>>>> Signed-off-by: Andrew Murray <andrew.murray@arm.com>
>>>> ---
>>>> arch/arm64/include/asm/kvm_host.h | 24 ++++++++++++++++++++++++
>>>> 1 file changed, 24 insertions(+)
>>>>
>>>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>>>> index 1550192..800c87b 100644
>>>> --- a/arch/arm64/include/asm/kvm_host.h
>>>> +++ b/arch/arm64/include/asm/kvm_host.h
>>>> @@ -203,6 +203,8 @@ struct kvm_cpu_context {
>>>> };
>>>> struct kvm_vcpu *__hyp_running_vcpu;
>>>> + u32 events_host;
>>>> + u32 events_guest;
>>>> };
>>>> typedef struct kvm_cpu_context kvm_cpu_context_t;
>>>> @@ -467,11 +469,33 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
>>>> void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu);
>>>> void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu);
>>>> +#define KVM_PMU_EVENTS_HOST 1
>>>> +#define KVM_PMU_EVENTS_GUEST 2
>>>> +
>>>> #ifdef CONFIG_KVM /* Avoid conflicts with core headers if CONFIG_KVM=n */
>>>> static inline int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
>>>> {
>>>> return kvm_arch_vcpu_run_map_fp(vcpu);
>>>> }
>>>> +static inline void kvm_set_pmu_events(u32 set, int flags)
>>>> +{
>>>> + kvm_cpu_context_t *ctx = this_cpu_ptr(&kvm_host_cpu_state);
>>>> +
>>>> + if (flags & KVM_PMU_EVENTS_HOST)
>>>> + ctx->events_host |= set;
>>>> + if (flags & KVM_PMU_EVENTS_GUEST)
>>>> + ctx->events_guest |= set;
>>>
>>> You seem to be passing a single flag at a time ever, in the next patch.
>>> Either we can batch the calls in the next patch, or make this a real number and
>>> not a flag. g.g, enum { HOST, GUEST } or even a bool.
>>>
>>> I think the former sounds better.
>>
>> Having another look at patch-3, we can never club set() calls for host &
>> guest events, we should go for the latter.
>
> Well we could always do this..
>
> u32 flags = 0;
> if (!attr->exclude_host)
> flags |= KVM_PMU_EVENTS_HOST;
> if (!attr->exclude_guest)
> flags |= KVM_PMU_EVENTS_GUEST;
>
> kvm_set_pmu_events(counter_bits, flags);
Yes, I think this should be fine.
Cheers
Suzuki
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v5 3/4] arm64: arm_pmu: Add support for exclude_host/exclude_guest attributes
2018-12-05 15:30 [PATCH v5 0/4] arm64: Support perf event modifiers :G and :H Andrew Murray
2018-12-05 15:30 ` [PATCH v5 1/4] arm64: arm_pmu: remove unnecessary isb instruction Andrew Murray
2018-12-05 15:30 ` [PATCH v5 2/4] arm64: KVM: add accessors to track guest/host only counters Andrew Murray
@ 2018-12-05 15:30 ` Andrew Murray
2018-12-06 18:49 ` Suzuki K Poulose
2018-12-05 15:30 ` [PATCH v5 4/4] arm64: KVM: Enable support for :G/:H perf event modifiers Andrew Murray
3 siblings, 1 reply; 11+ messages in thread
From: Andrew Murray @ 2018-12-05 15:30 UTC (permalink / raw)
To: Christoffer Dall, Marc Zyngier, Catalin Marinas, Will Deacon,
Mark Rutland
Cc: Suzuki K Poulose, kvmarm, linux-arm-kernel, Julien Thierry
Add support for the :G and :H attributes in perf by handling the
exclude_host/exclude_guest event attributes.
We notify KVM of counters that we wish to be enabled or disabled on
guest entry/exit and thus defer from starting or stopping :G events
as per the events exclude_host attribute.
With both VHE and non-VHE we switch the counters between host/guest
at EL2. We are able to eliminate counters counting host events on
the boundaries of guest entry/exit when using :G by filtering out
EL2 for exclude_host. However when using :H unless exclude_hv is set
on non-VHE then there is a small blackout window at the guest
entry/exit where host events are not captured.
Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
arch/arm64/kernel/perf_event.c | 48 ++++++++++++++++++++++++++++++++++++------
1 file changed, 41 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index de564ae..a5bd626 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -26,6 +26,7 @@
#include <linux/acpi.h>
#include <linux/clocksource.h>
+#include <linux/kvm_host.h>
#include <linux/of.h>
#include <linux/perf/arm_pmu.h>
#include <linux/platform_device.h>
@@ -647,11 +648,23 @@ static inline int armv8pmu_enable_counter(int idx)
static inline void armv8pmu_enable_event_counter(struct perf_event *event)
{
+ struct perf_event_attr *attr = &event->attr;
int idx = event->hw.idx;
+ u32 counter_bits = BIT(ARMV8_IDX_TO_COUNTER(idx));
- armv8pmu_enable_counter(idx);
if (armv8pmu_event_is_chained(event))
- armv8pmu_enable_counter(idx - 1);
+ counter_bits |= BIT(ARMV8_IDX_TO_COUNTER(idx - 1));
+
+ if (!attr->exclude_host)
+ kvm_set_pmu_events(counter_bits, KVM_PMU_EVENTS_HOST);
+ if (!attr->exclude_guest)
+ kvm_set_pmu_events(counter_bits, KVM_PMU_EVENTS_GUEST);
+
+ if (!attr->exclude_host) {
+ armv8pmu_enable_counter(idx);
+ if (armv8pmu_event_is_chained(event))
+ armv8pmu_enable_counter(idx - 1);
+ }
}
static inline int armv8pmu_disable_counter(int idx)
@@ -664,11 +677,20 @@ static inline int armv8pmu_disable_counter(int idx)
static inline void armv8pmu_disable_event_counter(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
+ struct perf_event_attr *attr = &event->attr;
int idx = hwc->idx;
+ u32 counter_bits = BIT(ARMV8_IDX_TO_COUNTER(idx));
if (armv8pmu_event_is_chained(event))
- armv8pmu_disable_counter(idx - 1);
- armv8pmu_disable_counter(idx);
+ counter_bits |= BIT(ARMV8_IDX_TO_COUNTER(idx - 1));
+
+ kvm_clr_pmu_events(counter_bits);
+
+ if (!attr->exclude_host) {
+ if (armv8pmu_event_is_chained(event))
+ armv8pmu_disable_counter(idx - 1);
+ armv8pmu_disable_counter(idx);
+ }
}
static inline int armv8pmu_enable_intens(int idx)
@@ -943,16 +965,25 @@ static int armv8pmu_set_event_filter(struct hw_perf_event *event,
* Therefore we ignore exclude_hv in this configuration, since
* there's no hypervisor to sample anyway. This is consistent
* with other architectures (x86 and Power).
+ *
+ * To eliminate counting host events on the boundaries of
+ * guest entry/exit we ensure EL2 is not included in hyp mode
+ * with !exclude_host.
*/
if (is_kernel_in_hyp_mode()) {
- if (!attr->exclude_kernel)
+ if (!attr->exclude_kernel && !attr->exclude_host)
config_base |= ARMV8_PMU_INCLUDE_EL2;
} else {
- if (attr->exclude_kernel)
- config_base |= ARMV8_PMU_EXCLUDE_EL1;
if (!attr->exclude_hv)
config_base |= ARMV8_PMU_INCLUDE_EL2;
}
+
+ /*
+ * Filter out !VHE kernels and guest kernels
+ */
+ if (attr->exclude_kernel)
+ config_base |= ARMV8_PMU_EXCLUDE_EL1;
+
if (attr->exclude_user)
config_base |= ARMV8_PMU_EXCLUDE_EL0;
@@ -976,6 +1007,9 @@ static void armv8pmu_reset(void *info)
armv8pmu_disable_intens(idx);
}
+ /* Clear the counters we flip at guest entry/exit */
+ kvm_clr_pmu_events(U32_MAX);
+
/*
* Initialize & Reset PMNC. Request overflow interrupt for
* 64 bit cycle counter but cheat in armv8pmu_write_counter().
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH v5 3/4] arm64: arm_pmu: Add support for exclude_host/exclude_guest attributes
2018-12-05 15:30 ` [PATCH v5 3/4] arm64: arm_pmu: Add support for exclude_host/exclude_guest attributes Andrew Murray
@ 2018-12-06 18:49 ` Suzuki K Poulose
0 siblings, 0 replies; 11+ messages in thread
From: Suzuki K Poulose @ 2018-12-06 18:49 UTC (permalink / raw)
To: Andrew Murray, Christoffer Dall, Marc Zyngier, Catalin Marinas,
Will Deacon, Mark Rutland
Cc: kvmarm, linux-arm-kernel, Julien Thierry
On 05/12/2018 15:30, Andrew Murray wrote:
> Add support for the :G and :H attributes in perf by handling the
> exclude_host/exclude_guest event attributes.
>
> We notify KVM of counters that we wish to be enabled or disabled on
> guest entry/exit and thus defer from starting or stopping :G events
> as per the events exclude_host attribute.
>
> With both VHE and non-VHE we switch the counters between host/guest
> at EL2. We are able to eliminate counters counting host events on
> the boundaries of guest entry/exit when using :G by filtering out
> EL2 for exclude_host. However when using :H unless exclude_hv is set
> on non-VHE then there is a small blackout window at the guest
> entry/exit where host events are not captured.
>
> Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> ---
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v5 4/4] arm64: KVM: Enable support for :G/:H perf event modifiers
2018-12-05 15:30 [PATCH v5 0/4] arm64: Support perf event modifiers :G and :H Andrew Murray
` (2 preceding siblings ...)
2018-12-05 15:30 ` [PATCH v5 3/4] arm64: arm_pmu: Add support for exclude_host/exclude_guest attributes Andrew Murray
@ 2018-12-05 15:30 ` Andrew Murray
2018-12-07 14:24 ` Suzuki K Poulose
3 siblings, 1 reply; 11+ messages in thread
From: Andrew Murray @ 2018-12-05 15:30 UTC (permalink / raw)
To: Christoffer Dall, Marc Zyngier, Catalin Marinas, Will Deacon,
Mark Rutland
Cc: Suzuki K Poulose, kvmarm, linux-arm-kernel, Julien Thierry
Enable/disable event counters as appropriate when entering and exiting
the guest to enable support for guest or host only event counting.
For both VHE and non-VHE we switch the counters between host/guest at
EL2. EL2 is filtered out by the PMU when we are using the :G modifier.
The PMU may be on when we change which counters are enabled however
we avoid adding an isb as we instead rely on existing context
synchronisation events: the isb in kvm_arm_vhe_guest_exit for VHE and
the eret from the hvc in kvm_call_hyp.
Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
arch/arm64/kvm/hyp/switch.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index d496ef5..e505cad 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -373,6 +373,32 @@ static bool __hyp_text __hyp_switch_fpsimd(struct kvm_vcpu *vcpu)
return true;
}
+static bool __hyp_text __pmu_switch_to_guest(struct kvm_cpu_context *host_ctxt)
+{
+ u32 clr = host_ctxt->events_host & ~host_ctxt->events_guest;
+ u32 set = host_ctxt->events_guest & ~host_ctxt->events_host;
+
+ if (clr)
+ write_sysreg(clr, pmcntenclr_el0);
+
+ if (set)
+ write_sysreg(set, pmcntenset_el0);
+
+ return (clr || set);
+}
+
+static void __hyp_text __pmu_switch_to_host(struct kvm_cpu_context *host_ctxt)
+{
+ u32 clr = host_ctxt->events_guest & ~host_ctxt->events_host;
+ u32 set = host_ctxt->events_host & ~host_ctxt->events_guest;
+
+ if (clr)
+ write_sysreg(clr, pmcntenclr_el0);
+
+ if (set)
+ write_sysreg(set, pmcntenset_el0);
+}
+
/*
* Return true when we were able to fixup the guest exit and should return to
* the guest, false when we should restore the host state and return to the
@@ -488,12 +514,15 @@ int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
{
struct kvm_cpu_context *host_ctxt;
struct kvm_cpu_context *guest_ctxt;
+ bool pmu_switch_needed;
u64 exit_code;
host_ctxt = vcpu->arch.host_cpu_context;
host_ctxt->__hyp_running_vcpu = vcpu;
guest_ctxt = &vcpu->arch.ctxt;
+ pmu_switch_needed = __pmu_switch_to_guest(host_ctxt);
+
sysreg_save_host_state_vhe(host_ctxt);
__activate_traps(vcpu);
@@ -524,6 +553,9 @@ int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
__debug_switch_to_host(vcpu);
+ if (pmu_switch_needed)
+ __pmu_switch_to_host(host_ctxt);
+
return exit_code;
}
@@ -532,6 +564,7 @@ int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu)
{
struct kvm_cpu_context *host_ctxt;
struct kvm_cpu_context *guest_ctxt;
+ bool pmu_switch_needed;
u64 exit_code;
vcpu = kern_hyp_va(vcpu);
@@ -540,6 +573,8 @@ int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu)
host_ctxt->__hyp_running_vcpu = vcpu;
guest_ctxt = &vcpu->arch.ctxt;
+ pmu_switch_needed = __pmu_switch_to_guest(host_ctxt);
+
__sysreg_save_state_nvhe(host_ctxt);
__activate_traps(vcpu);
@@ -586,6 +621,9 @@ int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu)
*/
__debug_switch_to_host(vcpu);
+ if (pmu_switch_needed)
+ __pmu_switch_to_host(host_ctxt);
+
return exit_code;
}
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH v5 4/4] arm64: KVM: Enable support for :G/:H perf event modifiers
2018-12-05 15:30 ` [PATCH v5 4/4] arm64: KVM: Enable support for :G/:H perf event modifiers Andrew Murray
@ 2018-12-07 14:24 ` Suzuki K Poulose
0 siblings, 0 replies; 11+ messages in thread
From: Suzuki K Poulose @ 2018-12-07 14:24 UTC (permalink / raw)
To: Andrew Murray, Christoffer Dall, Marc Zyngier, Catalin Marinas,
Will Deacon, Mark Rutland
Cc: kvmarm, linux-arm-kernel, Julien Thierry
On 05/12/2018 15:30, Andrew Murray wrote:
> Enable/disable event counters as appropriate when entering and exiting
> the guest to enable support for guest or host only event counting.
>
> For both VHE and non-VHE we switch the counters between host/guest at
> EL2. EL2 is filtered out by the PMU when we are using the :G modifier.
>
> The PMU may be on when we change which counters are enabled however
> we avoid adding an isb as we instead rely on existing context
> synchronisation events: the isb in kvm_arm_vhe_guest_exit for VHE and
> the eret from the hvc in kvm_call_hyp.
>
> Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> ---
> arch/arm64/kvm/hyp/switch.c | 38 ++++++++++++++++++++++++++++++++++++++
> 1 file changed, 38 insertions(+)
>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 11+ messages in thread