[PATCH 18/18] KVM: ARM64: Add KVM_CAP_ARM_PMU and KVM_ARM_PMU_SET_IRQ
shannon.zhao at linaro.org
shannon.zhao at linaro.org
Sun Jul 5 19:17:48 PDT 2015
From: Shannon Zhao <shannon.zhao at linaro.org>
Add KVM_CAP_ARM_PMU for userspace to check whether KVM supports PMU. Add
KVM_ARM_PMU_SET_IRQ for userspace to set PMU IRQ number.
Signed-off-by: Shannon Zhao <shannon.zhao at linaro.org>
---
arch/arm/kvm/arm.c | 8 ++++++++
include/kvm/arm_pmu.h | 5 +++++
include/uapi/linux/kvm.h | 4 ++++
virt/kvm/arm/pmu.c | 9 +++++++++
4 files changed, 26 insertions(+)
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 41eb063..350866e 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -182,6 +182,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_ARM_PSCI_0_2:
case KVM_CAP_READONLY_MEM:
case KVM_CAP_MP_STATE:
+ case KVM_CAP_ARM_PMU:
r = 1;
break;
case KVM_CAP_COALESCED_MMIO:
@@ -816,6 +817,13 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
return -E2BIG;
return kvm_arm_copy_reg_indices(vcpu, user_list->reg);
}
+ case KVM_ARM_PMU_SET_IRQ: {
+ uint32_t irq;
+
+ if (copy_from_user(&irq, argp, sizeof(irq)))
+ return -EFAULT;
+ return kvm_pmu_set_irq_num(vcpu, irq);
+ }
default:
return -EINVAL;
}
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index 5bcf27b..1a93f53 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -58,6 +58,7 @@ void kvm_pmu_enable_interrupt(struct kvm_vcpu *vcpu, unsigned long val);
void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, unsigned long val);
void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long data,
unsigned long select_idx);
+int kvm_pmu_set_irq_num(struct kvm_vcpu *vcpu, u32 irq);
void kvm_pmu_init(struct kvm_vcpu *vcpu);
#else
void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu) {}
@@ -76,6 +77,10 @@ void kvm_pmu_enable_interrupt(struct kvm_vcpu *vcpu, unsigned long val) {}
void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, unsigned long val) {}
void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long data,
unsigned long select_idx) {}
+int kvm_pmu_set_irq_num(struct kvm_vcpu *vcpu, u32 irq)
+{
+ return -ENXIO;
+}
static inline void kvm_pmu_init(struct kvm_vcpu *vcpu) {}
#endif
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 716ad4a..90f5e73 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -817,6 +817,7 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_DISABLE_QUIRKS 116
#define KVM_CAP_X86_SMM 117
#define KVM_CAP_MULTI_ADDRESS_SPACE 118
+#define KVM_CAP_ARM_PMU 119
#ifdef KVM_CAP_IRQ_ROUTING
@@ -1205,6 +1206,9 @@ struct kvm_s390_ucas_mapping {
/* Available with KVM_CAP_X86_SMM */
#define KVM_SMI _IO(KVMIO, 0xb7)
+/* Available with KVM_CAP_ARM_PMU */
+#define KVM_ARM_PMU_SET_IRQ _IOW(KVMIO, 0xb8, __u32)
+
#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
#define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1)
#define KVM_DEV_ASSIGN_MASK_INTX (1 << 2)
diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
index f957b85..57585e1 100644
--- a/virt/kvm/arm/pmu.c
+++ b/virt/kvm/arm/pmu.c
@@ -381,6 +381,15 @@ void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long data,
pmc->perf_event = event;
}
+int kvm_pmu_set_irq_num(struct kvm_vcpu *vcpu, u32 irq)
+{
+ struct kvm_pmu *pmu = &vcpu->arch.pmu;
+
+ kvm_info("kvm_arm_set_pmu_irq: irq: %u\n", irq);
+ pmu->irq_num = irq;
+ return 0;
+}
+
/**
* kvm_pmu_init - Initialize global PMU state for per vcpu
* @vcpu: The vcpu pointer
--
2.1.0
More information about the linux-arm-kernel
mailing list