aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kvm
diff options
context:
space:
mode:
authorShannon Zhao <shannon.zhao@linaro.org>2016-02-26 06:29:19 -0500
committerMarc Zyngier <marc.zyngier@arm.com>2016-02-29 13:34:21 -0500
commitb02386eb7dac7555a208d81aef2a0e5c6f0f8085 (patch)
treea3a06d842810134ac014da93fe78a161918cf2d1 /arch/arm/kvm
parentd692b8ad6ec4814ddd9a37ce5c9c9d971e741088 (diff)
arm64: KVM: Add PMU overflow interrupt routing
When calling perf_event_create_kernel_counter to create perf_event, assign a overflow handler. Then when the perf event overflows, set the corresponding bit of guest PMOVSSET register. If this counter is enabled and its interrupt is enabled as well, kick the vcpu to sync the interrupt. On VM entry, if there is counter overflowed and interrupt level is changed, inject the interrupt with corresponding level. On VM exit, sync the interrupt level as well if it has been changed. Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> Reviewed-by: Andrew Jones <drjones@redhat.com> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'arch/arm/kvm')
-rw-r--r--arch/arm/kvm/arm.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 686350d05174..c5e959187abd 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -28,6 +28,7 @@
28#include <linux/sched.h> 28#include <linux/sched.h>
29#include <linux/kvm.h> 29#include <linux/kvm.h>
30#include <trace/events/kvm.h> 30#include <trace/events/kvm.h>
31#include <kvm/arm_pmu.h>
31 32
32#define CREATE_TRACE_POINTS 33#define CREATE_TRACE_POINTS
33#include "trace.h" 34#include "trace.h"
@@ -577,6 +578,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
577 * non-preemptible context. 578 * non-preemptible context.
578 */ 579 */
579 preempt_disable(); 580 preempt_disable();
581 kvm_pmu_flush_hwstate(vcpu);
580 kvm_timer_flush_hwstate(vcpu); 582 kvm_timer_flush_hwstate(vcpu);
581 kvm_vgic_flush_hwstate(vcpu); 583 kvm_vgic_flush_hwstate(vcpu);
582 584
@@ -593,6 +595,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
593 if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) || 595 if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) ||
594 vcpu->arch.power_off || vcpu->arch.pause) { 596 vcpu->arch.power_off || vcpu->arch.pause) {
595 local_irq_enable(); 597 local_irq_enable();
598 kvm_pmu_sync_hwstate(vcpu);
596 kvm_timer_sync_hwstate(vcpu); 599 kvm_timer_sync_hwstate(vcpu);
597 kvm_vgic_sync_hwstate(vcpu); 600 kvm_vgic_sync_hwstate(vcpu);
598 preempt_enable(); 601 preempt_enable();
@@ -642,10 +645,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
642 trace_kvm_exit(ret, kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu)); 645 trace_kvm_exit(ret, kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
643 646
644 /* 647 /*
645 * We must sync the timer state before the vgic state so that 648 * We must sync the PMU and timer state before the vgic state so
646 * the vgic can properly sample the updated state of the 649 * that the vgic can properly sample the updated state of the
647 * interrupt line. 650 * interrupt line.
648 */ 651 */
652 kvm_pmu_sync_hwstate(vcpu);
649 kvm_timer_sync_hwstate(vcpu); 653 kvm_timer_sync_hwstate(vcpu);
650 654
651 kvm_vgic_sync_hwstate(vcpu); 655 kvm_vgic_sync_hwstate(vcpu);