From: Christoffer Dall <cdall@linaro.org>
To: kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org
Cc: Marc Zyngier <marc.zyngier@arm.com>,
kvm@vger.kernel.org, Christoffer Dall <cdall@linaro.org>
Subject: [PATCH v3 1/9] KVM: arm64: Allow creating the PMU without the in-kernel GIC
Date: Thu, 8 Jun 2017 15:34:38 +0200 [thread overview]
Message-ID: <20170608133446.3875-2-cdall@linaro.org> (raw)
In-Reply-To: <20170608133446.3875-1-cdall@linaro.org>
Since we got support for devices in userspace which allows reporting the
PMU overflow output status to userspace, we should actually allow
creating the PMU on systems without an in-kernel irqchip, which in turn
requires us to slightly clarify error codes for the ABI and move things
around for the initialization phase.
Signed-off-by: Christoffer Dall <cdall@linaro.org>
---
Documentation/virtual/kvm/devices/vcpu.txt | 16 ++++++----
include/kvm/arm_pmu.h | 6 ++++
virt/kvm/arm/arm.c | 4 +++
virt/kvm/arm/pmu.c | 51 +++++++++++++++++++++++-------
4 files changed, 58 insertions(+), 19 deletions(-)
diff --git a/Documentation/virtual/kvm/devices/vcpu.txt b/Documentation/virtual/kvm/devices/vcpu.txt
index 02f5068..d7236a3 100644
--- a/Documentation/virtual/kvm/devices/vcpu.txt
+++ b/Documentation/virtual/kvm/devices/vcpu.txt
@@ -16,7 +16,9 @@ Parameters: in kvm_device_attr.addr the address for PMU overflow interrupt is a
Returns: -EBUSY: The PMU overflow interrupt is already set
-ENXIO: The overflow interrupt not set when attempting to get it
-ENODEV: PMUv3 not supported
- -EINVAL: Invalid PMU overflow interrupt number supplied
+ -EINVAL: Invalid PMU overflow interrupt number supplied or
+ trying to set the IRQ number without using an in-kernel
+ irqchip.
A value describing the PMUv3 (Performance Monitor Unit v3) overflow interrupt
number for this vcpu. This interrupt could be a PPI or SPI, but the interrupt
@@ -25,11 +27,11 @@ all vcpus, while as an SPI it must be a separate number per vcpu.
1.2 ATTRIBUTE: KVM_ARM_VCPU_PMU_V3_INIT
Parameters: no additional parameter in kvm_device_attr.addr
-Returns: -ENODEV: PMUv3 not supported
- -ENXIO: PMUv3 not properly configured as required prior to calling this
- attribute
+Returns: -ENODEV: PMUv3 not supported or GIC not initialized
+ -ENXIO: PMUv3 not properly configured or in-kernel irqchip not
+ configured as required prior to calling this attribute
-EBUSY: PMUv3 already initialized
-Request the initialization of the PMUv3. This must be done after creating the
-in-kernel irqchip. Creating a PMU with a userspace irqchip is currently not
-supported.
+Request the initialization of the PMUv3. If using the PMUv3 with an in-kernel
+virtual GIC implementation, this must be done after initializing the in-kernel
+irqchip.
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index 1ab4633..f6e0306 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -35,6 +35,7 @@ struct kvm_pmu {
int irq_num;
struct kvm_pmc pmc[ARMV8_PMU_MAX_COUNTERS];
bool ready;
+ bool created;
bool irq_level;
};
@@ -63,6 +64,7 @@ int kvm_arm_pmu_v3_get_attr(struct kvm_vcpu *vcpu,
struct kvm_device_attr *attr);
int kvm_arm_pmu_v3_has_attr(struct kvm_vcpu *vcpu,
struct kvm_device_attr *attr);
+int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu);
#else
struct kvm_pmu {
};
@@ -112,6 +114,10 @@ static inline int kvm_arm_pmu_v3_has_attr(struct kvm_vcpu *vcpu,
{
return -ENXIO;
}
+static inline int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu)
+{
+ return 0;
+}
#endif
#endif
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index cac5c2f..72816d3 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -527,6 +527,10 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
}
ret = kvm_timer_enable(vcpu);
+ if (ret)
+ return ret;
+
+ ret = kvm_arm_pmu_v3_enable(vcpu);
return ret;
}
diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
index 2451607..96a9cab 100644
--- a/virt/kvm/arm/pmu.c
+++ b/virt/kvm/arm/pmu.c
@@ -449,29 +449,50 @@ bool kvm_arm_support_pmu_v3(void)
return (perf_num_counters() > 0);
}
-static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu)
+int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu)
{
- if (!kvm_arm_support_pmu_v3())
- return -ENODEV;
+ if (!vcpu->arch.pmu.created)
+ return 0;
/*
- * We currently require an in-kernel VGIC to use the PMU emulation,
- * because we do not support forwarding PMU overflow interrupts to
- * userspace yet.
+ * A valid interrupt configuration for the PMU is either to have a
+ * properly configured interrupt number and using an in-kernel
+ * irqchip, or to neither set an IRQ nor create an in-kernel irqchip.
*/
- if (!irqchip_in_kernel(vcpu->kvm) || !vgic_initialized(vcpu->kvm))
+ if (kvm_arm_pmu_irq_initialized(vcpu) != irqchip_in_kernel(vcpu->kvm))
+ return -EINVAL;
+
+ kvm_pmu_vcpu_reset(vcpu);
+ vcpu->arch.pmu.ready = true;
+
+ return 0;
+}
+
+static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu)
+{
+ if (!kvm_arm_support_pmu_v3())
return -ENODEV;
- if (!test_bit(KVM_ARM_VCPU_PMU_V3, vcpu->arch.features) ||
- !kvm_arm_pmu_irq_initialized(vcpu))
+ if (!test_bit(KVM_ARM_VCPU_PMU_V3, vcpu->arch.features))
return -ENXIO;
- if (kvm_arm_pmu_v3_ready(vcpu))
+ if (vcpu->arch.pmu.created)
return -EBUSY;
- kvm_pmu_vcpu_reset(vcpu);
- vcpu->arch.pmu.ready = true;
+ if (irqchip_in_kernel(vcpu->kvm)) {
+ /*
+ * If using the PMU with an in-kernel virtual GIC
+ * implementation, we require the GIC to be already
+ * initialized when initializing the PMU.
+ */
+ if (!vgic_initialized(vcpu->kvm))
+ return -ENODEV;
+
+ if (!kvm_arm_pmu_irq_initialized(vcpu))
+ return -ENXIO;
+ }
+ vcpu->arch.pmu.created = true;
return 0;
}
@@ -510,6 +531,9 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
int __user *uaddr = (int __user *)(long)attr->addr;
int irq;
+ if (!irqchip_in_kernel(vcpu->kvm))
+ return -EINVAL;
+
if (!test_bit(KVM_ARM_VCPU_PMU_V3, vcpu->arch.features))
return -ENODEV;
@@ -544,6 +568,9 @@ int kvm_arm_pmu_v3_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
int __user *uaddr = (int __user *)(long)attr->addr;
int irq;
+ if (!irqchip_in_kernel(vcpu->kvm))
+ return -EINVAL;
+
if (!test_bit(KVM_ARM_VCPU_PMU_V3, vcpu->arch.features))
return -ENODEV;
--
2.9.0
next prev parent reply other threads:[~2017-06-08 13:30 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-08 13:34 [PATCH v3 0/9] Userspace timer IRQ number control and PMU with userspace-gic Christoffer Dall
2017-06-08 13:34 ` Christoffer Dall [this message]
2017-06-08 14:00 ` [PATCH v3 1/9] KVM: arm64: Allow creating the PMU without the in-kernel GIC Marc Zyngier
2017-06-08 13:34 ` [PATCH v3 2/9] KVM: arm: Handle VCPU device attributes in guest.c Christoffer Dall
2017-06-08 13:34 ` [PATCH v3 3/9] KVM: arm/arm64: Move irq_is_ppi() to header file Christoffer Dall
2017-06-08 13:34 ` [PATCH v3 4/9] KVM: arm/arm64: Move timer IRQ default init to arch_timer.c Christoffer Dall
2017-06-08 13:34 ` [PATCH v3 5/9] KVM: arm/arm64: Allow setting the timer IRQ numbers from userspace Christoffer Dall
2017-06-08 13:34 ` [PATCH v3 6/9] KVM: arm/arm64: Introduce an allocator for in-kernel irq lines Christoffer Dall
2017-06-08 14:07 ` Marc Zyngier
2017-06-08 14:59 ` Christoffer Dall
2017-06-08 15:09 ` Marc Zyngier
2017-06-08 13:34 ` [PATCH v3 7/9] KVM: arm/arm64: Check if irq lines to the GIC are already used Christoffer Dall
2017-06-08 14:12 ` Marc Zyngier
2017-06-08 13:34 ` [PATCH v3 8/9] KVM: arm/arm64: Disallow userspace control of in-kernel IRQ lines Christoffer Dall
2017-06-08 14:14 ` Marc Zyngier
2017-06-08 13:34 ` [PATCH v3 9/9] KVM: arm/arm64: Don't assume initialized vgic when setting PMU IRQ Christoffer Dall
2017-06-08 14:35 ` Marc Zyngier
2017-06-08 15:18 ` Christoffer Dall
2017-06-08 15:40 ` Marc Zyngier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170608133446.3875-2-cdall@linaro.org \
--to=cdall@linaro.org \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=marc.zyngier@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox