diff --git a/arm/gic.c b/arm/gic.c index 1ff3663..8560c9b 100644 --- a/arm/gic.c +++ b/arm/gic.c @@ -1,10 +1,12 @@ #include "kvm/fdt.h" +#include "kvm/irq.h" #include "kvm/kvm.h" #include "kvm/virtio.h" #include "arm-common/gic.h" #include +#include #include static int gic_fd = -1; @@ -96,6 +98,29 @@ int gic__create(struct kvm *kvm) return err; } +static int gic__init_gic(struct kvm *kvm) +{ + 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, + }; + + /* + * If we didn't use the KVM_CREATE_DEVICE method, KVM will + * give us some default number of interrupts. + */ + 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); + + return 0; +} +late_init(gic__init_gic) + void gic__generate_fdt_nodes(void *fdt, u32 phandle) { u64 reg_prop[] = {