linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 1/1] KVM: ARM64: Fix the issues when guest PMCCFILTR is configured
@ 2016-11-16 17:09 Wei Huang
  2016-11-17 13:30 ` Will Deacon
  0 siblings, 1 reply; 3+ messages in thread
From: Wei Huang @ 2016-11-16 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

KVM calls kvm_pmu_set_counter_event_type() when PMCCFILTR is configured.
But this function can't deals with PMCCFILTR correctly because the evtCount
bits of PMCCFILTR, which is reserved 0, conflits with the SW_INCR event
type of other PMXEVTYPER<n> registers. To fix it, when eventsel == 0, this
function shouldn't return immediately; instead it needs to check further
if select_idx is ARMV8_PMU_CYCLE_IDX.

Another issue is that KVM shouldn't copy the eventsel bits of PMCCFILTER
blindly to attr.config. Instead it ought to convert the request to the
"cpu cycle" event type (i.e. 0x11).

To support this patch and to prevent duplicated definitions, a limited
set of ARMv8 perf event types were relocated from perf_event.c to
asm/perf_event.h.

Signed-off-by: Wei Huang <wei@redhat.com>
---
 arch/arm64/include/asm/perf_event.h | 10 +++++++++-
 arch/arm64/kernel/perf_event.c      | 10 +---------
 virt/kvm/arm/pmu.c                  |  8 +++++---
 3 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/include/asm/perf_event.h b/arch/arm64/include/asm/perf_event.h
index 2065f46..38b6a2b 100644
--- a/arch/arm64/include/asm/perf_event.h
+++ b/arch/arm64/include/asm/perf_event.h
@@ -46,7 +46,15 @@
 #define	ARMV8_PMU_EVTYPE_MASK	0xc800ffff	/* Mask for writable bits */
 #define	ARMV8_PMU_EVTYPE_EVENT	0xffff		/* Mask for EVENT bits */
 
-#define ARMV8_PMU_EVTYPE_EVENT_SW_INCR	0	/* Software increment event */
+/*
+ * PMUv3 event types: required events
+ */
+#define ARMV8_PMUV3_PERFCTR_SW_INCR				0x00
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL			0x03
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE				0x04
+#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED				0x10
+#define ARMV8_PMUV3_PERFCTR_CPU_CYCLES				0x11
+#define ARMV8_PMUV3_PERFCTR_BR_PRED				0x12
 
 /*
  * Event filters for PMUv3
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index a9310a6..57ae9d9 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -31,17 +31,9 @@
 
 /*
  * ARMv8 PMUv3 Performance Events handling code.
- * Common event types.
+ * Common event types (some are defined in asm/perf_event.h).
  */
 
-/* Required events. */
-#define ARMV8_PMUV3_PERFCTR_SW_INCR				0x00
-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL			0x03
-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE				0x04
-#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED				0x10
-#define ARMV8_PMUV3_PERFCTR_CPU_CYCLES				0x11
-#define ARMV8_PMUV3_PERFCTR_BR_PRED				0x12
-
 /* At least one of the following is required. */
 #define ARMV8_PMUV3_PERFCTR_INST_RETIRED			0x08
 #define ARMV8_PMUV3_PERFCTR_INST_SPEC				0x1B
diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
index 6e9c40e..69ccce3 100644
--- a/virt/kvm/arm/pmu.c
+++ b/virt/kvm/arm/pmu.c
@@ -305,7 +305,7 @@ void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val)
 			continue;
 		type = vcpu_sys_reg(vcpu, PMEVTYPER0_EL0 + i)
 		       & ARMV8_PMU_EVTYPE_EVENT;
-		if ((type == ARMV8_PMU_EVTYPE_EVENT_SW_INCR)
+		if ((type == ARMV8_PMUV3_PERFCTR_SW_INCR)
 		    && (enable & BIT(i))) {
 			reg = vcpu_sys_reg(vcpu, PMEVCNTR0_EL0 + i) + 1;
 			reg = lower_32_bits(reg);
@@ -379,7 +379,8 @@ void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data,
 	eventsel = data & ARMV8_PMU_EVTYPE_EVENT;
 
 	/* Software increment event does't need to be backed by a perf event */
-	if (eventsel == ARMV8_PMU_EVTYPE_EVENT_SW_INCR)
+	if (eventsel == ARMV8_PMUV3_PERFCTR_SW_INCR &&
+	    select_idx != ARMV8_PMU_CYCLE_IDX)
 		return;
 
 	memset(&attr, 0, sizeof(struct perf_event_attr));
@@ -391,7 +392,8 @@ void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data,
 	attr.exclude_kernel = data & ARMV8_PMU_EXCLUDE_EL1 ? 1 : 0;
 	attr.exclude_hv = 1; /* Don't count EL2 events */
 	attr.exclude_host = 1; /* Don't count host events */
-	attr.config = eventsel;
+	attr.config = (select_idx == ARMV8_PMU_CYCLE_IDX) ?
+		ARMV8_PMUV3_PERFCTR_CPU_CYCLES : eventsel;
 
 	counter = kvm_pmu_get_counter_value(vcpu, select_idx);
 	/* The initial sample period (overflow count) of an event. */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v3 1/1] KVM: ARM64: Fix the issues when guest PMCCFILTR is configured
  2016-11-16 17:09 [PATCH v3 1/1] KVM: ARM64: Fix the issues when guest PMCCFILTR is configured Wei Huang
@ 2016-11-17 13:30 ` Will Deacon
  2016-11-17 13:38   ` Marc Zyngier
  0 siblings, 1 reply; 3+ messages in thread
From: Will Deacon @ 2016-11-17 13:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Nov 16, 2016 at 11:09:20AM -0600, Wei Huang wrote:
> KVM calls kvm_pmu_set_counter_event_type() when PMCCFILTR is configured.
> But this function can't deals with PMCCFILTR correctly because the evtCount
> bits of PMCCFILTR, which is reserved 0, conflits with the SW_INCR event
> type of other PMXEVTYPER<n> registers. To fix it, when eventsel == 0, this
> function shouldn't return immediately; instead it needs to check further
> if select_idx is ARMV8_PMU_CYCLE_IDX.
> 
> Another issue is that KVM shouldn't copy the eventsel bits of PMCCFILTER
> blindly to attr.config. Instead it ought to convert the request to the
> "cpu cycle" event type (i.e. 0x11).
> 
> To support this patch and to prevent duplicated definitions, a limited
> set of ARMv8 perf event types were relocated from perf_event.c to
> asm/perf_event.h.
> 
> Signed-off-by: Wei Huang <wei@redhat.com>
> ---
>  arch/arm64/include/asm/perf_event.h | 10 +++++++++-
>  arch/arm64/kernel/perf_event.c      | 10 +---------
>  virt/kvm/arm/pmu.c                  |  8 +++++---
>  3 files changed, 15 insertions(+), 13 deletions(-)

Acked-by: Will Deacon <will.deacon@arm.com>

I'm assuming this will go via kvm-arm.

Will

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH v3 1/1] KVM: ARM64: Fix the issues when guest PMCCFILTR is configured
  2016-11-17 13:30 ` Will Deacon
@ 2016-11-17 13:38   ` Marc Zyngier
  0 siblings, 0 replies; 3+ messages in thread
From: Marc Zyngier @ 2016-11-17 13:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 17/11/16 13:30, Will Deacon wrote:
> On Wed, Nov 16, 2016 at 11:09:20AM -0600, Wei Huang wrote:
>> KVM calls kvm_pmu_set_counter_event_type() when PMCCFILTR is configured.
>> But this function can't deals with PMCCFILTR correctly because the evtCount
>> bits of PMCCFILTR, which is reserved 0, conflits with the SW_INCR event
>> type of other PMXEVTYPER<n> registers. To fix it, when eventsel == 0, this
>> function shouldn't return immediately; instead it needs to check further
>> if select_idx is ARMV8_PMU_CYCLE_IDX.
>>
>> Another issue is that KVM shouldn't copy the eventsel bits of PMCCFILTER
>> blindly to attr.config. Instead it ought to convert the request to the
>> "cpu cycle" event type (i.e. 0x11).
>>
>> To support this patch and to prevent duplicated definitions, a limited
>> set of ARMv8 perf event types were relocated from perf_event.c to
>> asm/perf_event.h.
>>
>> Signed-off-by: Wei Huang <wei@redhat.com>
>> ---
>>  arch/arm64/include/asm/perf_event.h | 10 +++++++++-
>>  arch/arm64/kernel/perf_event.c      | 10 +---------
>>  virt/kvm/arm/pmu.c                  |  8 +++++---
>>  3 files changed, 15 insertions(+), 13 deletions(-)
> 
> Acked-by: Will Deacon <will.deacon@arm.com>
> 
> I'm assuming this will go via kvm-arm.

Yup, I'll take it. Thanks.

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-11-17 13:38 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-16 17:09 [PATCH v3 1/1] KVM: ARM64: Fix the issues when guest PMCCFILTR is configured Wei Huang
2016-11-17 13:30 ` Will Deacon
2016-11-17 13:38   ` Marc Zyngier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).