diff options
author | Andre Przywara <andre.przywara@arm.com> | 2015-07-03 12:26:33 +0100 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2015-07-08 17:39:32 +0100 |
commit | b57903027999ac71b7c707f33a22e357d2e946c0 (patch) | |
tree | b3588d23a2de347e6f1d8a405206293dc05e36b7 /arm | |
parent | bed2bd9e1fbef5819090feeada7b86eed97ca5e2 (diff) | |
download | kvmtool-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.c | 25 |
1 files changed, 22 insertions, 3 deletions
@@ -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; } |