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> 117c0e8b0cSWill Deacon 1269b9a17aSMarc Zyngier static int gic_fd = -1; 1369b9a17aSMarc Zyngier 14*02017c1dSAndre Przywara static int gic__create_device(struct kvm *kvm, enum irqchip_type type) 1569b9a17aSMarc Zyngier { 1669b9a17aSMarc Zyngier int err; 1769b9a17aSMarc Zyngier u64 cpu_if_addr = ARM_GIC_CPUI_BASE; 1869b9a17aSMarc Zyngier u64 dist_addr = ARM_GIC_DIST_BASE; 1969b9a17aSMarc Zyngier struct kvm_create_device gic_device = { 20*02017c1dSAndre Przywara .flags = 0, 2169b9a17aSMarc Zyngier }; 2269b9a17aSMarc Zyngier struct kvm_device_attr cpu_if_attr = { 2369b9a17aSMarc Zyngier .group = KVM_DEV_ARM_VGIC_GRP_ADDR, 2469b9a17aSMarc Zyngier .attr = KVM_VGIC_V2_ADDR_TYPE_CPU, 2569b9a17aSMarc Zyngier .addr = (u64)(unsigned long)&cpu_if_addr, 2669b9a17aSMarc Zyngier }; 2769b9a17aSMarc Zyngier struct kvm_device_attr dist_attr = { 2869b9a17aSMarc Zyngier .group = KVM_DEV_ARM_VGIC_GRP_ADDR, 2969b9a17aSMarc Zyngier .addr = (u64)(unsigned long)&dist_addr, 3069b9a17aSMarc Zyngier }; 3169b9a17aSMarc Zyngier 32*02017c1dSAndre Przywara switch (type) { 33*02017c1dSAndre Przywara case IRQCHIP_GICV2: 34*02017c1dSAndre Przywara gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V2; 35*02017c1dSAndre Przywara dist_attr.attr = KVM_VGIC_V2_ADDR_TYPE_DIST; 36*02017c1dSAndre Przywara break; 37*02017c1dSAndre Przywara } 38*02017c1dSAndre Przywara 3969b9a17aSMarc Zyngier err = ioctl(kvm->vm_fd, KVM_CREATE_DEVICE, &gic_device); 4069b9a17aSMarc Zyngier if (err) 4169b9a17aSMarc Zyngier return err; 4269b9a17aSMarc Zyngier 4369b9a17aSMarc Zyngier gic_fd = gic_device.fd; 4469b9a17aSMarc Zyngier 45*02017c1dSAndre Przywara switch (type) { 46*02017c1dSAndre Przywara case IRQCHIP_GICV2: 4769b9a17aSMarc Zyngier err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &cpu_if_attr); 48*02017c1dSAndre Przywara break; 49*02017c1dSAndre Przywara } 5069b9a17aSMarc Zyngier if (err) 5169b9a17aSMarc Zyngier goto out_err; 5269b9a17aSMarc Zyngier 5369b9a17aSMarc Zyngier err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &dist_attr); 5469b9a17aSMarc Zyngier if (err) 5569b9a17aSMarc Zyngier goto out_err; 5669b9a17aSMarc Zyngier 5769b9a17aSMarc Zyngier return 0; 5869b9a17aSMarc Zyngier 5969b9a17aSMarc Zyngier out_err: 6069b9a17aSMarc Zyngier close(gic_fd); 6169b9a17aSMarc Zyngier gic_fd = -1; 6269b9a17aSMarc Zyngier return err; 6369b9a17aSMarc Zyngier } 6469b9a17aSMarc Zyngier 6569b9a17aSMarc Zyngier static int gic__create_irqchip(struct kvm *kvm) 667c0e8b0cSWill Deacon { 677c0e8b0cSWill Deacon int err; 68aa7a0e79SWill Deacon struct kvm_arm_device_addr gic_addr[] = { 697c0e8b0cSWill Deacon [0] = { 70aa7a0e79SWill Deacon .id = KVM_VGIC_V2_ADDR_TYPE_DIST | 71aa7a0e79SWill Deacon (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT), 727c0e8b0cSWill Deacon .addr = ARM_GIC_DIST_BASE, 737c0e8b0cSWill Deacon }, 747c0e8b0cSWill Deacon [1] = { 75aa7a0e79SWill Deacon .id = KVM_VGIC_V2_ADDR_TYPE_CPU | 76aa7a0e79SWill Deacon (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT), 777c0e8b0cSWill Deacon .addr = ARM_GIC_CPUI_BASE, 787c0e8b0cSWill Deacon } 797c0e8b0cSWill Deacon }; 807c0e8b0cSWill Deacon 817c0e8b0cSWill Deacon err = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP); 827c0e8b0cSWill Deacon if (err) 837c0e8b0cSWill Deacon return err; 847c0e8b0cSWill Deacon 85aa7a0e79SWill Deacon err = ioctl(kvm->vm_fd, KVM_ARM_SET_DEVICE_ADDR, &gic_addr[0]); 867c0e8b0cSWill Deacon if (err) 877c0e8b0cSWill Deacon return err; 887c0e8b0cSWill Deacon 89aa7a0e79SWill Deacon err = ioctl(kvm->vm_fd, KVM_ARM_SET_DEVICE_ADDR, &gic_addr[1]); 907c0e8b0cSWill Deacon return err; 917c0e8b0cSWill Deacon } 927c0e8b0cSWill Deacon 93*02017c1dSAndre Przywara int gic__create(struct kvm *kvm, enum irqchip_type type) 9469b9a17aSMarc Zyngier { 9569b9a17aSMarc Zyngier int err; 9669b9a17aSMarc Zyngier 97*02017c1dSAndre Przywara switch (type) { 98*02017c1dSAndre Przywara case IRQCHIP_GICV2: 99*02017c1dSAndre Przywara break; 100*02017c1dSAndre Przywara default: 101*02017c1dSAndre Przywara return -ENODEV; 102*02017c1dSAndre Przywara } 103*02017c1dSAndre Przywara 10469b9a17aSMarc Zyngier /* Try the new way first, and fallback on legacy method otherwise */ 105*02017c1dSAndre Przywara err = gic__create_device(kvm, type); 106*02017c1dSAndre Przywara if (err && type == IRQCHIP_GICV2) 10769b9a17aSMarc Zyngier err = gic__create_irqchip(kvm); 10869b9a17aSMarc Zyngier 10969b9a17aSMarc Zyngier return err; 11069b9a17aSMarc Zyngier } 11169b9a17aSMarc Zyngier 112b5790302SAndre Przywara /* 113b5790302SAndre Przywara * Sets the number of used interrupts and finalizes the GIC init explicitly. 114b5790302SAndre Przywara */ 115bed2bd9eSMarc Zyngier static int gic__init_gic(struct kvm *kvm) 116bed2bd9eSMarc Zyngier { 117b5790302SAndre Przywara int ret; 118b5790302SAndre Przywara 119bed2bd9eSMarc Zyngier int lines = irq__get_nr_allocated_lines(); 120bed2bd9eSMarc Zyngier u32 nr_irqs = ALIGN(lines, 32) + GIC_SPI_IRQ_BASE; 121bed2bd9eSMarc Zyngier struct kvm_device_attr nr_irqs_attr = { 122bed2bd9eSMarc Zyngier .group = KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 123bed2bd9eSMarc Zyngier .addr = (u64)(unsigned long)&nr_irqs, 124bed2bd9eSMarc Zyngier }; 125b5790302SAndre Przywara struct kvm_device_attr vgic_init_attr = { 126b5790302SAndre Przywara .group = KVM_DEV_ARM_VGIC_GRP_CTRL, 127b5790302SAndre Przywara .attr = KVM_DEV_ARM_VGIC_CTRL_INIT, 128b5790302SAndre Przywara }; 129bed2bd9eSMarc Zyngier 130bed2bd9eSMarc Zyngier /* 131bed2bd9eSMarc Zyngier * If we didn't use the KVM_CREATE_DEVICE method, KVM will 132b5790302SAndre Przywara * give us some default number of interrupts. The GIC initialization 133b5790302SAndre Przywara * will be done automatically in this case. 134bed2bd9eSMarc Zyngier */ 135bed2bd9eSMarc Zyngier if (gic_fd < 0) 136bed2bd9eSMarc Zyngier return 0; 137bed2bd9eSMarc Zyngier 138b5790302SAndre Przywara if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, &nr_irqs_attr)) { 139b5790302SAndre Przywara ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &nr_irqs_attr); 140b5790302SAndre Przywara if (ret) 141b5790302SAndre Przywara return ret; 142b5790302SAndre Przywara } 143b5790302SAndre Przywara 144b5790302SAndre Przywara if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, &vgic_init_attr)) { 145b5790302SAndre Przywara ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &vgic_init_attr); 146b5790302SAndre Przywara if (ret) 147b5790302SAndre Przywara return ret; 148b5790302SAndre Przywara } 149bed2bd9eSMarc Zyngier 150bed2bd9eSMarc Zyngier return 0; 151bed2bd9eSMarc Zyngier } 152bed2bd9eSMarc Zyngier late_init(gic__init_gic) 153bed2bd9eSMarc Zyngier 154*02017c1dSAndre Przywara void gic__generate_fdt_nodes(void *fdt, u32 phandle, enum irqchip_type type) 1557c0e8b0cSWill Deacon { 156*02017c1dSAndre Przywara const char *compatible; 1577c0e8b0cSWill Deacon u64 reg_prop[] = { 1587c0e8b0cSWill Deacon cpu_to_fdt64(ARM_GIC_DIST_BASE), cpu_to_fdt64(ARM_GIC_DIST_SIZE), 1597c0e8b0cSWill Deacon cpu_to_fdt64(ARM_GIC_CPUI_BASE), cpu_to_fdt64(ARM_GIC_CPUI_SIZE), 1607c0e8b0cSWill Deacon }; 1617c0e8b0cSWill Deacon 162*02017c1dSAndre Przywara switch (type) { 163*02017c1dSAndre Przywara case IRQCHIP_GICV2: 164*02017c1dSAndre Przywara compatible = "arm,cortex-a15-gic"; 165*02017c1dSAndre Przywara break; 166*02017c1dSAndre Przywara default: 167*02017c1dSAndre Przywara return; 168*02017c1dSAndre Przywara } 169*02017c1dSAndre Przywara 1707c0e8b0cSWill Deacon _FDT(fdt_begin_node(fdt, "intc")); 171*02017c1dSAndre Przywara _FDT(fdt_property_string(fdt, "compatible", compatible)); 1727c0e8b0cSWill Deacon _FDT(fdt_property_cell(fdt, "#interrupt-cells", GIC_FDT_IRQ_NUM_CELLS)); 1737c0e8b0cSWill Deacon _FDT(fdt_property(fdt, "interrupt-controller", NULL, 0)); 1747c0e8b0cSWill Deacon _FDT(fdt_property(fdt, "reg", reg_prop, sizeof(reg_prop))); 1757c0e8b0cSWill Deacon _FDT(fdt_property_cell(fdt, "phandle", phandle)); 1767c0e8b0cSWill Deacon _FDT(fdt_end_node(fdt)); 1777c0e8b0cSWill Deacon } 1787c0e8b0cSWill Deacon 1797c0e8b0cSWill Deacon #define KVM_IRQCHIP_IRQ(x) (KVM_ARM_IRQ_TYPE_SPI << KVM_ARM_IRQ_TYPE_SHIFT) |\ 1807c0e8b0cSWill Deacon ((x) & KVM_ARM_IRQ_NUM_MASK) 1817c0e8b0cSWill Deacon 1827c0e8b0cSWill Deacon void kvm__irq_line(struct kvm *kvm, int irq, int level) 1837c0e8b0cSWill Deacon { 1847c0e8b0cSWill Deacon struct kvm_irq_level irq_level = { 1857c0e8b0cSWill Deacon .irq = KVM_IRQCHIP_IRQ(irq), 1867c0e8b0cSWill Deacon .level = !!level, 1877c0e8b0cSWill Deacon }; 1887c0e8b0cSWill Deacon 1897c0e8b0cSWill Deacon if (irq < GIC_SPI_IRQ_BASE || irq > GIC_MAX_IRQ) 1907c0e8b0cSWill Deacon pr_warning("Ignoring invalid GIC IRQ %d", irq); 1917c0e8b0cSWill Deacon else if (ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level) < 0) 1927c0e8b0cSWill Deacon pr_warning("Could not KVM_IRQ_LINE for irq %d", irq); 1937c0e8b0cSWill Deacon } 1947c0e8b0cSWill Deacon 1957c0e8b0cSWill Deacon void kvm__irq_trigger(struct kvm *kvm, int irq) 1967c0e8b0cSWill Deacon { 1977c0e8b0cSWill Deacon kvm__irq_line(kvm, irq, VIRTIO_IRQ_HIGH); 1987c0e8b0cSWill Deacon kvm__irq_line(kvm, irq, VIRTIO_IRQ_LOW); 1997c0e8b0cSWill Deacon } 200