17c0e8b0cSWill Deacon #include "kvm/fdt.h" 2bed2bd9eSMarc Zyngier #include "kvm/irq.h" 37c0e8b0cSWill Deacon #include "kvm/kvm.h" 47c0e8b0cSWill Deacon #include "kvm/virtio.h" 57c0e8b0cSWill Deacon 67c0e8b0cSWill Deacon #include "arm-common/gic.h" 77c0e8b0cSWill Deacon 87c0e8b0cSWill Deacon #include <linux/byteorder.h> 9bed2bd9eSMarc Zyngier #include <linux/kernel.h> 107c0e8b0cSWill Deacon #include <linux/kvm.h> 1112ca1401SAndre Przywara #include <linux/sizes.h> 127c0e8b0cSWill Deacon 1369b9a17aSMarc Zyngier static int gic_fd = -1; 14bfb2c703SAndre Przywara static u64 gic_redists_base; 15bfb2c703SAndre Przywara static u64 gic_redists_size; 1612ca1401SAndre Przywara static u64 gic_msi_base; 1712ca1401SAndre Przywara static u64 gic_msi_size = 0; 1869b9a17aSMarc Zyngier 1943d2781cSAndre Przywara int irqchip_parser(const struct option *opt, const char *arg, int unset) 2043d2781cSAndre Przywara { 2143d2781cSAndre Przywara enum irqchip_type *type = opt->value; 2243d2781cSAndre Przywara 2343d2781cSAndre Przywara if (!strcmp(arg, "gicv2")) { 2443d2781cSAndre Przywara *type = IRQCHIP_GICV2; 2543d2781cSAndre Przywara } else if (!strcmp(arg, "gicv3")) { 2643d2781cSAndre Przywara *type = IRQCHIP_GICV3; 2743d2781cSAndre Przywara } else { 2843d2781cSAndre Przywara pr_err("irqchip: unknown type \"%s\"\n", arg); 2943d2781cSAndre Przywara return -1; 3043d2781cSAndre Przywara } 3143d2781cSAndre Przywara 3243d2781cSAndre Przywara return 0; 3343d2781cSAndre Przywara } 3443d2781cSAndre Przywara 3512ca1401SAndre Przywara static int gic__create_its_frame(struct kvm *kvm, u64 its_frame_addr) 3612ca1401SAndre Przywara { 3712ca1401SAndre Przywara struct kvm_create_device its_device = { 3812ca1401SAndre Przywara .type = KVM_DEV_TYPE_ARM_VGIC_ITS, 3912ca1401SAndre Przywara .flags = 0, 4012ca1401SAndre Przywara }; 4112ca1401SAndre Przywara struct kvm_device_attr its_attr = { 4212ca1401SAndre Przywara .group = KVM_DEV_ARM_VGIC_GRP_ADDR, 4312ca1401SAndre Przywara .attr = KVM_VGIC_ITS_ADDR_TYPE, 4412ca1401SAndre Przywara .addr = (u64)(unsigned long)&its_frame_addr, 4512ca1401SAndre Przywara }; 4612ca1401SAndre Przywara struct kvm_device_attr its_init_attr = { 4712ca1401SAndre Przywara .group = KVM_DEV_ARM_VGIC_GRP_CTRL, 4812ca1401SAndre Przywara .attr = KVM_DEV_ARM_VGIC_CTRL_INIT, 4912ca1401SAndre Przywara }; 5012ca1401SAndre Przywara int err; 5112ca1401SAndre Przywara 5212ca1401SAndre Przywara err = ioctl(kvm->vm_fd, KVM_CREATE_DEVICE, &its_device); 5312ca1401SAndre Przywara if (err) { 5412ca1401SAndre Przywara fprintf(stderr, 5512ca1401SAndre Przywara "GICv3 ITS requested, but kernel does not support it.\n"); 5612ca1401SAndre Przywara fprintf(stderr, "Try --irqchip=gicv3 instead\n"); 5712ca1401SAndre Przywara return err; 5812ca1401SAndre Przywara } 5912ca1401SAndre Przywara 6012ca1401SAndre Przywara err = ioctl(its_device.fd, KVM_HAS_DEVICE_ATTR, &its_attr); 6112ca1401SAndre Przywara if (err) { 6212ca1401SAndre Przywara close(its_device.fd); 6312ca1401SAndre Przywara its_device.fd = -1; 6412ca1401SAndre Przywara return err; 6512ca1401SAndre Przywara } 6612ca1401SAndre Przywara 6712ca1401SAndre Przywara err = ioctl(its_device.fd, KVM_SET_DEVICE_ATTR, &its_attr); 6812ca1401SAndre Przywara if (err) 6912ca1401SAndre Przywara return err; 7012ca1401SAndre Przywara 7112ca1401SAndre Przywara return ioctl(its_device.fd, KVM_SET_DEVICE_ATTR, &its_init_attr); 7212ca1401SAndre Przywara } 7312ca1401SAndre Przywara 7412ca1401SAndre Przywara static int gic__create_msi_frame(struct kvm *kvm, enum irqchip_type type, 7512ca1401SAndre Przywara u64 msi_frame_addr) 7612ca1401SAndre Przywara { 7712ca1401SAndre Przywara switch (type) { 7812ca1401SAndre Przywara case IRQCHIP_GICV3_ITS: 7912ca1401SAndre Przywara return gic__create_its_frame(kvm, msi_frame_addr); 8012ca1401SAndre Przywara default: /* No MSI frame needed */ 8112ca1401SAndre Przywara return 0; 8212ca1401SAndre Przywara } 8312ca1401SAndre Przywara } 8412ca1401SAndre Przywara 8502017c1dSAndre Przywara static int gic__create_device(struct kvm *kvm, enum irqchip_type type) 8669b9a17aSMarc Zyngier { 8769b9a17aSMarc Zyngier int err; 8869b9a17aSMarc Zyngier u64 cpu_if_addr = ARM_GIC_CPUI_BASE; 8969b9a17aSMarc Zyngier u64 dist_addr = ARM_GIC_DIST_BASE; 9069b9a17aSMarc Zyngier struct kvm_create_device gic_device = { 9102017c1dSAndre Przywara .flags = 0, 9269b9a17aSMarc Zyngier }; 9369b9a17aSMarc Zyngier struct kvm_device_attr cpu_if_attr = { 9469b9a17aSMarc Zyngier .group = KVM_DEV_ARM_VGIC_GRP_ADDR, 9569b9a17aSMarc Zyngier .attr = KVM_VGIC_V2_ADDR_TYPE_CPU, 9669b9a17aSMarc Zyngier .addr = (u64)(unsigned long)&cpu_if_addr, 9769b9a17aSMarc Zyngier }; 9869b9a17aSMarc Zyngier struct kvm_device_attr dist_attr = { 9969b9a17aSMarc Zyngier .group = KVM_DEV_ARM_VGIC_GRP_ADDR, 10069b9a17aSMarc Zyngier .addr = (u64)(unsigned long)&dist_addr, 10169b9a17aSMarc Zyngier }; 102bfb2c703SAndre Przywara struct kvm_device_attr redist_attr = { 103bfb2c703SAndre Przywara .group = KVM_DEV_ARM_VGIC_GRP_ADDR, 104bfb2c703SAndre Przywara .attr = KVM_VGIC_V3_ADDR_TYPE_REDIST, 105bfb2c703SAndre Przywara .addr = (u64)(unsigned long)&gic_redists_base, 106bfb2c703SAndre Przywara }; 10769b9a17aSMarc Zyngier 10802017c1dSAndre Przywara switch (type) { 10902017c1dSAndre Przywara case IRQCHIP_GICV2: 11002017c1dSAndre Przywara gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V2; 11102017c1dSAndre Przywara dist_attr.attr = KVM_VGIC_V2_ADDR_TYPE_DIST; 11202017c1dSAndre Przywara break; 113bfb2c703SAndre Przywara case IRQCHIP_GICV3: 11412ca1401SAndre Przywara case IRQCHIP_GICV3_ITS: 115bfb2c703SAndre Przywara gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V3; 116bfb2c703SAndre Przywara dist_attr.attr = KVM_VGIC_V3_ADDR_TYPE_DIST; 117bfb2c703SAndre Przywara break; 11802017c1dSAndre Przywara } 11902017c1dSAndre Przywara 12069b9a17aSMarc Zyngier err = ioctl(kvm->vm_fd, KVM_CREATE_DEVICE, &gic_device); 12169b9a17aSMarc Zyngier if (err) 12269b9a17aSMarc Zyngier return err; 12369b9a17aSMarc Zyngier 12469b9a17aSMarc Zyngier gic_fd = gic_device.fd; 12569b9a17aSMarc Zyngier 12602017c1dSAndre Przywara switch (type) { 12702017c1dSAndre Przywara case IRQCHIP_GICV2: 12869b9a17aSMarc Zyngier err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &cpu_if_attr); 12902017c1dSAndre Przywara break; 13012ca1401SAndre Przywara case IRQCHIP_GICV3_ITS: 131bfb2c703SAndre Przywara case IRQCHIP_GICV3: 132bfb2c703SAndre Przywara err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &redist_attr); 133bfb2c703SAndre Przywara break; 13402017c1dSAndre Przywara } 13569b9a17aSMarc Zyngier if (err) 13669b9a17aSMarc Zyngier goto out_err; 13769b9a17aSMarc Zyngier 13869b9a17aSMarc Zyngier err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &dist_attr); 13969b9a17aSMarc Zyngier if (err) 14069b9a17aSMarc Zyngier goto out_err; 14169b9a17aSMarc Zyngier 14212ca1401SAndre Przywara err = gic__create_msi_frame(kvm, type, gic_msi_base); 14312ca1401SAndre Przywara if (err) 14412ca1401SAndre Przywara goto out_err; 14512ca1401SAndre Przywara 14669b9a17aSMarc Zyngier return 0; 14769b9a17aSMarc Zyngier 14869b9a17aSMarc Zyngier out_err: 14969b9a17aSMarc Zyngier close(gic_fd); 15069b9a17aSMarc Zyngier gic_fd = -1; 15169b9a17aSMarc Zyngier return err; 15269b9a17aSMarc Zyngier } 15369b9a17aSMarc Zyngier 15469b9a17aSMarc Zyngier static int gic__create_irqchip(struct kvm *kvm) 1557c0e8b0cSWill Deacon { 1567c0e8b0cSWill Deacon int err; 157aa7a0e79SWill Deacon struct kvm_arm_device_addr gic_addr[] = { 1587c0e8b0cSWill Deacon [0] = { 159aa7a0e79SWill Deacon .id = KVM_VGIC_V2_ADDR_TYPE_DIST | 160aa7a0e79SWill Deacon (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT), 1617c0e8b0cSWill Deacon .addr = ARM_GIC_DIST_BASE, 1627c0e8b0cSWill Deacon }, 1637c0e8b0cSWill Deacon [1] = { 164aa7a0e79SWill Deacon .id = KVM_VGIC_V2_ADDR_TYPE_CPU | 165aa7a0e79SWill Deacon (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT), 1667c0e8b0cSWill Deacon .addr = ARM_GIC_CPUI_BASE, 1677c0e8b0cSWill Deacon } 1687c0e8b0cSWill Deacon }; 1697c0e8b0cSWill Deacon 1707c0e8b0cSWill Deacon err = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP); 1717c0e8b0cSWill Deacon if (err) 1727c0e8b0cSWill Deacon return err; 1737c0e8b0cSWill Deacon 174aa7a0e79SWill Deacon err = ioctl(kvm->vm_fd, KVM_ARM_SET_DEVICE_ADDR, &gic_addr[0]); 1757c0e8b0cSWill Deacon if (err) 1767c0e8b0cSWill Deacon return err; 1777c0e8b0cSWill Deacon 178aa7a0e79SWill Deacon err = ioctl(kvm->vm_fd, KVM_ARM_SET_DEVICE_ADDR, &gic_addr[1]); 1797c0e8b0cSWill Deacon return err; 1807c0e8b0cSWill Deacon } 1817c0e8b0cSWill Deacon 18202017c1dSAndre Przywara int gic__create(struct kvm *kvm, enum irqchip_type type) 18369b9a17aSMarc Zyngier { 18469b9a17aSMarc Zyngier int err; 18569b9a17aSMarc Zyngier 18602017c1dSAndre Przywara switch (type) { 18702017c1dSAndre Przywara case IRQCHIP_GICV2: 18802017c1dSAndre Przywara break; 18912ca1401SAndre Przywara case IRQCHIP_GICV3_ITS: 19012ca1401SAndre Przywara /* We reserve the 64K page with the doorbell as well. */ 19112ca1401SAndre Przywara gic_msi_size = KVM_VGIC_V3_ITS_SIZE + SZ_64K; 19212ca1401SAndre Przywara /* fall through */ 193bfb2c703SAndre Przywara case IRQCHIP_GICV3: 194bfb2c703SAndre Przywara gic_redists_size = kvm->cfg.nrcpus * ARM_GIC_REDIST_SIZE; 195bfb2c703SAndre Przywara gic_redists_base = ARM_GIC_DIST_BASE - gic_redists_size; 19612ca1401SAndre Przywara gic_msi_base = gic_redists_base - gic_msi_size; 197bfb2c703SAndre Przywara break; 19802017c1dSAndre Przywara default: 19902017c1dSAndre Przywara return -ENODEV; 20002017c1dSAndre Przywara } 20102017c1dSAndre Przywara 20269b9a17aSMarc Zyngier /* Try the new way first, and fallback on legacy method otherwise */ 20302017c1dSAndre Przywara err = gic__create_device(kvm, type); 20402017c1dSAndre Przywara if (err && type == IRQCHIP_GICV2) 20569b9a17aSMarc Zyngier err = gic__create_irqchip(kvm); 20669b9a17aSMarc Zyngier 20769b9a17aSMarc Zyngier return err; 20869b9a17aSMarc Zyngier } 20969b9a17aSMarc Zyngier 210b5790302SAndre Przywara /* 211b5790302SAndre Przywara * Sets the number of used interrupts and finalizes the GIC init explicitly. 212b5790302SAndre Przywara */ 213bed2bd9eSMarc Zyngier static int gic__init_gic(struct kvm *kvm) 214bed2bd9eSMarc Zyngier { 215b5790302SAndre Przywara int ret; 216b5790302SAndre Przywara 217bed2bd9eSMarc Zyngier int lines = irq__get_nr_allocated_lines(); 218bed2bd9eSMarc Zyngier u32 nr_irqs = ALIGN(lines, 32) + GIC_SPI_IRQ_BASE; 219bed2bd9eSMarc Zyngier struct kvm_device_attr nr_irqs_attr = { 220bed2bd9eSMarc Zyngier .group = KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 221bed2bd9eSMarc Zyngier .addr = (u64)(unsigned long)&nr_irqs, 222bed2bd9eSMarc Zyngier }; 223b5790302SAndre Przywara struct kvm_device_attr vgic_init_attr = { 224b5790302SAndre Przywara .group = KVM_DEV_ARM_VGIC_GRP_CTRL, 225b5790302SAndre Przywara .attr = KVM_DEV_ARM_VGIC_CTRL_INIT, 226b5790302SAndre Przywara }; 227bed2bd9eSMarc Zyngier 228bed2bd9eSMarc Zyngier /* 229bed2bd9eSMarc Zyngier * If we didn't use the KVM_CREATE_DEVICE method, KVM will 230b5790302SAndre Przywara * give us some default number of interrupts. The GIC initialization 231b5790302SAndre Przywara * will be done automatically in this case. 232bed2bd9eSMarc Zyngier */ 233bed2bd9eSMarc Zyngier if (gic_fd < 0) 234bed2bd9eSMarc Zyngier return 0; 235bed2bd9eSMarc Zyngier 236b5790302SAndre Przywara if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, &nr_irqs_attr)) { 237b5790302SAndre Przywara ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &nr_irqs_attr); 238b5790302SAndre Przywara if (ret) 239b5790302SAndre Przywara return ret; 240b5790302SAndre Przywara } 241b5790302SAndre Przywara 242b5790302SAndre Przywara if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, &vgic_init_attr)) { 243b5790302SAndre Przywara ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &vgic_init_attr); 244b5790302SAndre Przywara if (ret) 245b5790302SAndre Przywara return ret; 246b5790302SAndre Przywara } 247bed2bd9eSMarc Zyngier 248bed2bd9eSMarc Zyngier return 0; 249bed2bd9eSMarc Zyngier } 250bed2bd9eSMarc Zyngier late_init(gic__init_gic) 251bed2bd9eSMarc Zyngier 2520063d50cSAndre Przywara void gic__generate_fdt_nodes(void *fdt, enum irqchip_type type) 2537c0e8b0cSWill Deacon { 254*14421de9SAndre Przywara const char *compatible, *msi_compatible = NULL; 255*14421de9SAndre Przywara u64 msi_prop[2]; 2567c0e8b0cSWill Deacon u64 reg_prop[] = { 2577c0e8b0cSWill Deacon cpu_to_fdt64(ARM_GIC_DIST_BASE), cpu_to_fdt64(ARM_GIC_DIST_SIZE), 258bfb2c703SAndre Przywara 0, 0, /* to be filled */ 2597c0e8b0cSWill Deacon }; 2607c0e8b0cSWill Deacon 26102017c1dSAndre Przywara switch (type) { 26202017c1dSAndre Przywara case IRQCHIP_GICV2: 26302017c1dSAndre Przywara compatible = "arm,cortex-a15-gic"; 264bfb2c703SAndre Przywara reg_prop[2] = cpu_to_fdt64(ARM_GIC_CPUI_BASE); 265bfb2c703SAndre Przywara reg_prop[3] = cpu_to_fdt64(ARM_GIC_CPUI_SIZE); 266bfb2c703SAndre Przywara break; 267*14421de9SAndre Przywara case IRQCHIP_GICV3_ITS: 268*14421de9SAndre Przywara msi_compatible = "arm,gic-v3-its"; 269*14421de9SAndre Przywara /* fall-through */ 270bfb2c703SAndre Przywara case IRQCHIP_GICV3: 271bfb2c703SAndre Przywara compatible = "arm,gic-v3"; 272bfb2c703SAndre Przywara reg_prop[2] = cpu_to_fdt64(gic_redists_base); 273bfb2c703SAndre Przywara reg_prop[3] = cpu_to_fdt64(gic_redists_size); 27402017c1dSAndre Przywara break; 27502017c1dSAndre Przywara default: 27602017c1dSAndre Przywara return; 27702017c1dSAndre Przywara } 27802017c1dSAndre Przywara 2797c0e8b0cSWill Deacon _FDT(fdt_begin_node(fdt, "intc")); 28002017c1dSAndre Przywara _FDT(fdt_property_string(fdt, "compatible", compatible)); 2817c0e8b0cSWill Deacon _FDT(fdt_property_cell(fdt, "#interrupt-cells", GIC_FDT_IRQ_NUM_CELLS)); 2827c0e8b0cSWill Deacon _FDT(fdt_property(fdt, "interrupt-controller", NULL, 0)); 2837c0e8b0cSWill Deacon _FDT(fdt_property(fdt, "reg", reg_prop, sizeof(reg_prop))); 2840063d50cSAndre Przywara _FDT(fdt_property_cell(fdt, "phandle", PHANDLE_GIC)); 285*14421de9SAndre Przywara _FDT(fdt_property_cell(fdt, "#address-cells", 2)); 286*14421de9SAndre Przywara _FDT(fdt_property_cell(fdt, "#size-cells", 2)); 287*14421de9SAndre Przywara 288*14421de9SAndre Przywara if (msi_compatible) { 289*14421de9SAndre Przywara _FDT(fdt_property(fdt, "ranges", NULL, 0)); 290*14421de9SAndre Przywara 291*14421de9SAndre Przywara _FDT(fdt_begin_node(fdt, "msic")); 292*14421de9SAndre Przywara _FDT(fdt_property_string(fdt, "compatible", msi_compatible)); 293*14421de9SAndre Przywara _FDT(fdt_property(fdt, "msi-controller", NULL, 0)); 294*14421de9SAndre Przywara _FDT(fdt_property_cell(fdt, "phandle", PHANDLE_MSI)); 295*14421de9SAndre Przywara msi_prop[0] = cpu_to_fdt64(gic_msi_base); 296*14421de9SAndre Przywara msi_prop[1] = cpu_to_fdt64(gic_msi_size); 297*14421de9SAndre Przywara _FDT(fdt_property(fdt, "reg", msi_prop, sizeof(msi_prop))); 298*14421de9SAndre Przywara _FDT(fdt_end_node(fdt)); 299*14421de9SAndre Przywara } 300*14421de9SAndre Przywara 3017c0e8b0cSWill Deacon _FDT(fdt_end_node(fdt)); 3027c0e8b0cSWill Deacon } 3037c0e8b0cSWill Deacon 3047c0e8b0cSWill Deacon #define KVM_IRQCHIP_IRQ(x) (KVM_ARM_IRQ_TYPE_SPI << KVM_ARM_IRQ_TYPE_SHIFT) |\ 3057c0e8b0cSWill Deacon ((x) & KVM_ARM_IRQ_NUM_MASK) 3067c0e8b0cSWill Deacon 3077c0e8b0cSWill Deacon void kvm__irq_line(struct kvm *kvm, int irq, int level) 3087c0e8b0cSWill Deacon { 3097c0e8b0cSWill Deacon struct kvm_irq_level irq_level = { 3107c0e8b0cSWill Deacon .irq = KVM_IRQCHIP_IRQ(irq), 3117c0e8b0cSWill Deacon .level = !!level, 3127c0e8b0cSWill Deacon }; 3137c0e8b0cSWill Deacon 3147c0e8b0cSWill Deacon if (irq < GIC_SPI_IRQ_BASE || irq > GIC_MAX_IRQ) 3157c0e8b0cSWill Deacon pr_warning("Ignoring invalid GIC IRQ %d", irq); 3167c0e8b0cSWill Deacon else if (ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level) < 0) 3177c0e8b0cSWill Deacon pr_warning("Could not KVM_IRQ_LINE for irq %d", irq); 3187c0e8b0cSWill Deacon } 3197c0e8b0cSWill Deacon 3207c0e8b0cSWill Deacon void kvm__irq_trigger(struct kvm *kvm, int irq) 3217c0e8b0cSWill Deacon { 3227c0e8b0cSWill Deacon kvm__irq_line(kvm, irq, VIRTIO_IRQ_HIGH); 3237c0e8b0cSWill Deacon kvm__irq_line(kvm, irq, VIRTIO_IRQ_LOW); 3247c0e8b0cSWill Deacon } 325