GICv5 SPIs start at zero, while earlier GICs use an offset of 32. Allow the offset to be changed before any line is allocated and set it to zero when creating a GICv5 VM. Signed-off-by: Sascha Bischoff --- arm64/gic.c | 6 ++++++ include/kvm/irq.h | 1 + irq.c | 15 ++++++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/arm64/gic.c b/arm64/gic.c index c1bd0771..23c68862 100644 --- a/arm64/gic.c +++ b/arm64/gic.c @@ -236,6 +236,12 @@ static int gic__create_device(struct kvm *kvm, enum irqchip_type type) if (err) goto out_err; + /* GICv5 SPIs start at zero. Set this before allocating IRQs. */ + if (type == IRQCHIP_GICV5) { + err = irq__init_irq_offset(0); + if (err) + goto out_err; + } vgic_is_v5 = type == IRQCHIP_GICV5; return 0; diff --git a/include/kvm/irq.h b/include/kvm/irq.h index 2a3f8c9d..17113979 100644 --- a/include/kvm/irq.h +++ b/include/kvm/irq.h @@ -23,6 +23,7 @@ extern struct msi_routing_ops *msi_routing_ops; extern struct kvm_irq_routing *irq_routing; extern int next_gsi; +int irq__init_irq_offset(u8 offset); int irq__alloc_line(void); int irq__get_nr_allocated_lines(void); diff --git a/irq.c b/irq.c index cdcf9923..7c4bfec4 100644 --- a/irq.c +++ b/irq.c @@ -8,6 +8,7 @@ #include "kvm/irq.h" #include "kvm/kvm-arch.h" +static u8 irq_offset = KVM_IRQ_OFFSET; static u8 next_line = KVM_IRQ_OFFSET; static int allocated_gsis = 0; @@ -18,6 +19,18 @@ struct msi_routing_ops *msi_routing_ops = &irq__default_routing_ops; struct kvm_irq_routing *irq_routing = NULL; +/* Override the default offset before the first IRQ allocation. */ +int irq__init_irq_offset(u8 offset) +{ + if (irq__get_nr_allocated_lines()) + return -EBUSY; + + irq_offset = offset; + next_line = offset; + + return 0; +} + int irq__alloc_line(void) { return next_line++; @@ -25,7 +38,7 @@ int irq__alloc_line(void) int irq__get_nr_allocated_lines(void) { - return next_line - KVM_IRQ_OFFSET; + return next_line - irq_offset; } int irq__allocate_routing_entry(void) -- 2.34.1