aboutsummaryrefslogtreecommitdiffstats
path: root/arm
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2015-07-03 12:26:33 +0100
committerWill Deacon <will.deacon@arm.com>2015-07-08 17:39:32 +0100
commitb57903027999ac71b7c707f33a22e357d2e946c0 (patch)
treeb3588d23a2de347e6f1d8a405206293dc05e36b7 /arm
parentbed2bd9e1fbef5819090feeada7b86eed97ca5e2 (diff)
downloadkvmtool-b57903027999ac71b7c707f33a22e357d2e946c0.tar.gz
arm: finish VGIC initialisation explicitly
Since Linux 3.19-rc1 there is a new API to explicitly initialise the in-kernel GIC emulation by a userland KVM device call. Use that to tell the kernel we are finished with the GIC initialisation, since the automatic GIC init will only be provided as a legacy functionality in the future. Signed-off-by: Andre Przywara <andre.przywara@arm.com> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arm')
-rw-r--r--arm/gic.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/arm/gic.c b/arm/gic.c
index 8560c9b4..99f0d2ba 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -98,24 +98,43 @@ int gic__create(struct kvm *kvm)
return err;
}
+/*
+ * Sets the number of used interrupts and finalizes the GIC init explicitly.
+ */
static int gic__init_gic(struct kvm *kvm)
{
+ int ret;
+
int lines = irq__get_nr_allocated_lines();
u32 nr_irqs = ALIGN(lines, 32) + GIC_SPI_IRQ_BASE;
struct kvm_device_attr nr_irqs_attr = {
.group = KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
.addr = (u64)(unsigned long)&nr_irqs,
};
+ struct kvm_device_attr vgic_init_attr = {
+ .group = KVM_DEV_ARM_VGIC_GRP_CTRL,
+ .attr = KVM_DEV_ARM_VGIC_CTRL_INIT,
+ };
/*
* If we didn't use the KVM_CREATE_DEVICE method, KVM will
- * give us some default number of interrupts.
+ * give us some default number of interrupts. The GIC initialization
+ * will be done automatically in this case.
*/
if (gic_fd < 0)
return 0;
- if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, &nr_irqs_attr))
- return ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &nr_irqs_attr);
+ if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, &nr_irqs_attr)) {
+ ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &nr_irqs_attr);
+ if (ret)
+ return ret;
+ }
+
+ if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, &vgic_init_attr)) {
+ ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &vgic_init_attr);
+ if (ret)
+ return ret;
+ }
return 0;
}