Set the address of the IRS for the basic `gicv5` config, which is required to correctly initialise the GIC once the KVM IRS support has been introduced. This change enables SPIs and LPIs to be used with a GICv5 guest. MSIs are not supported. Note: the FDT changes to add the IRS node are still to come. Signed-off-by: Sascha Bischoff --- arm64/gic.c | 20 ++++++++++++++++++-- arm64/include/kvm/kvm-arch.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/arm64/gic.c b/arm64/gic.c index a49bc9b9..5cb195ac 100644 --- a/arm64/gic.c +++ b/arm64/gic.c @@ -16,6 +16,8 @@ static int gic_fd = -1; static u64 gic_redists_base; static u64 gic_redists_size; +static u64 gicv5_irs_base; +static u64 gicv5_irs_size; static u64 gic_msi_base; static u64 gic_msi_size = 0; static bool vgic_is_init = false; @@ -178,6 +180,11 @@ static int gic__create_device(struct kvm *kvm, enum irqchip_type type) .attr = KVM_VGIC_V3_ADDR_TYPE_REDIST, .addr = (u64)(unsigned long)&gic_redists_base, }; + struct kvm_device_attr gicv5_irs_attr = { + .group = KVM_DEV_ARM_VGIC_GRP_ADDR, + .attr = KVM_VGIC_V5_ADDR_TYPE_IRS, + .addr = (u64)(unsigned long)&gicv5_irs_base, + }; switch (type) { case IRQCHIP_GICV2M: @@ -213,6 +220,7 @@ static int gic__create_device(struct kvm *kvm, enum irqchip_type type) err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &redist_attr); break; case IRQCHIP_GICV5: + err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &gicv5_irs_attr); break; case IRQCHIP_AUTO: return -ENODEV; @@ -314,6 +322,8 @@ int gic__create(struct kvm *kvm, enum irqchip_type type) gic_msi_base = gic_redists_base - gic_msi_size; break; case IRQCHIP_GICV5: + gicv5_irs_base = ARM_GICV5_IRS_BASE; + gicv5_irs_size = ARM_GICV5_IRS_SIZE; break; default: return -ENODEV; @@ -335,8 +345,14 @@ 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; u32 maint_irq = GIC_MAINT_IRQ + 16; /* PPI */ + u32 nr_irqs; + + if ((kvm->cfg.arch.irqchip != IRQCHIP_GICV5)) + nr_irqs = ALIGN(lines, 32) + GIC_SPI_IRQ_BASE; + else + nr_irqs = roundup_pow_of_two(lines); + struct kvm_device_attr nr_irqs_attr = { .group = KVM_DEV_ARM_VGIC_GRP_NR_IRQS, .addr = (u64)(unsigned long)&nr_irqs, @@ -495,7 +511,7 @@ void kvm__irq_line(struct kvm *kvm, int irq, int level) .level = !!level, }; - if (irq < GIC_SPI_IRQ_BASE || irq > GIC_MAX_IRQ) + if (!gic__is_v5() && (irq < GIC_SPI_IRQ_BASE || irq > GIC_MAX_IRQ)) pr_warning("Ignoring invalid GIC IRQ %d", irq); else if (ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level) < 0) pr_warning("Could not KVM_IRQ_LINE for irq %d", irq); diff --git a/arm64/include/kvm/kvm-arch.h b/arm64/include/kvm/kvm-arch.h index 8f508ef8..717a7360 100644 --- a/arm64/include/kvm/kvm-arch.h +++ b/arm64/include/kvm/kvm-arch.h @@ -57,6 +57,36 @@ #define ARM_GIC_CPUI_SIZE 0x20000 +/* + * GICv5-specific definitions for the various MMIO frames. + * + * Base for the IRS, ITS. These live at the end of the MMIO area. + * + * The IRS assumes back-to-back CONFIG and SETLPI frames. + * The ITS assumes back-to-back CONFIG and TRANSLATE frames. + * + * REST OF MMIO AREA + * ***************************************** + * ITS FRAMES (128K) + * ***************************************** + * IRS FRAMES (128K) + * ***************************************** + * ARM_AXI_AREA + */ +#define ARM_GICV5_IRS_BASE (ARM_AXI_AREA - ARM_GICV5_IRS_SIZE) +#define ARM_GICV5_IRS_SIZE (ARM_GICV5_IRS_CONFIG_SIZE + ARM_GICV5_IRS_SETLPI_SIZE) +#define ARM_GICV5_IRS_CONFIG_BASE ARM_GICV5_IRS_BASE +#define ARM_GICV5_IRS_CONFIG_SIZE 0x10000 +#define ARM_GICV5_IRS_SETLPI_BASE (ARM_GICV5_IRS_BASE + ARM_GICV5_IRS_SETLPI_SIZE) +#define ARM_GICV5_IRS_SETLPI_SIZE 0x10000 +#define ARM_GICV5_ITS_BASE (ARM_GICV5_IRS_BASE - ARM_GICV5_ITS_SIZE) +#define ARM_GICV5_ITS_SIZE (ARM_GICV5_ITS_CONFIG_SIZE + ARM_GICV5_ITS_TRANSL_SIZE) +#define ARM_GICV5_ITS_CONFIG_BASE ARM_GICV5_ITS_BASE +#define ARM_GICV5_ITS_CONFIG_SIZE 0x10000 +#define ARM_GICV5_ITS_TRANSL_BASE (ARM_GICV5_ITS_BASE + ARM_GICV5_ITS_TRANSL_SIZE) +#define ARM_GICV5_ITS_TRANSL_SIZE 0x10000 + + #define KVM_PCI_CFG_AREA ARM_AXI_AREA #define ARM_PCI_CFG_SIZE (1ULL << 28) #define KVM_PCI_MMIO_AREA (KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE) -- 2.34.1