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 1369ae77c5SAndre Przywara #define IRQCHIP_GIC 0 1469ae77c5SAndre Przywara 1569b9a17aSMarc Zyngier static int gic_fd = -1; 16bfb2c703SAndre Przywara static u64 gic_redists_base; 17bfb2c703SAndre Przywara static u64 gic_redists_size; 1812ca1401SAndre Przywara static u64 gic_msi_base; 1912ca1401SAndre Przywara static u64 gic_msi_size = 0; 2069b9a17aSMarc Zyngier 2143d2781cSAndre Przywara int irqchip_parser(const struct option *opt, const char *arg, int unset) 2243d2781cSAndre Przywara { 2343d2781cSAndre Przywara enum irqchip_type *type = opt->value; 2443d2781cSAndre Przywara 2543d2781cSAndre Przywara if (!strcmp(arg, "gicv2")) { 2643d2781cSAndre Przywara *type = IRQCHIP_GICV2; 27f6108d72SJean-Philippe Brucker } else if (!strcmp(arg, "gicv2m")) { 28f6108d72SJean-Philippe Brucker *type = IRQCHIP_GICV2M; 2943d2781cSAndre Przywara } else if (!strcmp(arg, "gicv3")) { 3043d2781cSAndre Przywara *type = IRQCHIP_GICV3; 3176392d29SAndre Przywara } else if (!strcmp(arg, "gicv3-its")) { 3276392d29SAndre Przywara *type = IRQCHIP_GICV3_ITS; 3343d2781cSAndre Przywara } else { 3443d2781cSAndre Przywara pr_err("irqchip: unknown type \"%s\"\n", arg); 3543d2781cSAndre Przywara return -1; 3643d2781cSAndre Przywara } 3743d2781cSAndre Przywara 3843d2781cSAndre Przywara return 0; 3943d2781cSAndre Przywara } 4043d2781cSAndre Przywara 4169ae77c5SAndre Przywara static int irq__routing_init(struct kvm *kvm) 4269ae77c5SAndre Przywara { 4369ae77c5SAndre Przywara int r; 4469ae77c5SAndre Przywara int irqlines = ALIGN(irq__get_nr_allocated_lines(), 32); 4569ae77c5SAndre Przywara 4669ae77c5SAndre Przywara /* 4769ae77c5SAndre Przywara * This describes the default routing that the kernel uses without 4869ae77c5SAndre Przywara * any routing explicitly set up via KVM_SET_GSI_ROUTING. So we 4969ae77c5SAndre Przywara * don't need to commit these setting right now. The first actual 5069ae77c5SAndre Przywara * user (MSI routing) will engage these mappings then. 5169ae77c5SAndre Przywara */ 5269ae77c5SAndre Przywara for (next_gsi = 0; next_gsi < irqlines; next_gsi++) { 5369ae77c5SAndre Przywara r = irq__allocate_routing_entry(); 5469ae77c5SAndre Przywara if (r) 5569ae77c5SAndre Przywara return r; 5669ae77c5SAndre Przywara 5769ae77c5SAndre Przywara irq_routing->entries[irq_routing->nr++] = 5869ae77c5SAndre Przywara (struct kvm_irq_routing_entry) { 5969ae77c5SAndre Przywara .gsi = next_gsi, 6069ae77c5SAndre Przywara .type = KVM_IRQ_ROUTING_IRQCHIP, 6169ae77c5SAndre Przywara .u.irqchip.irqchip = IRQCHIP_GIC, 6269ae77c5SAndre Przywara .u.irqchip.pin = next_gsi, 6369ae77c5SAndre Przywara }; 6469ae77c5SAndre Przywara } 6569ae77c5SAndre Przywara 6669ae77c5SAndre Przywara return 0; 6769ae77c5SAndre Przywara } 6869ae77c5SAndre Przywara 6912ca1401SAndre Przywara static int gic__create_its_frame(struct kvm *kvm, u64 its_frame_addr) 7012ca1401SAndre Przywara { 7112ca1401SAndre Przywara struct kvm_create_device its_device = { 7212ca1401SAndre Przywara .type = KVM_DEV_TYPE_ARM_VGIC_ITS, 7312ca1401SAndre Przywara .flags = 0, 7412ca1401SAndre Przywara }; 7512ca1401SAndre Przywara struct kvm_device_attr its_attr = { 7612ca1401SAndre Przywara .group = KVM_DEV_ARM_VGIC_GRP_ADDR, 7712ca1401SAndre Przywara .attr = KVM_VGIC_ITS_ADDR_TYPE, 7812ca1401SAndre Przywara .addr = (u64)(unsigned long)&its_frame_addr, 7912ca1401SAndre Przywara }; 8012ca1401SAndre Przywara struct kvm_device_attr its_init_attr = { 8112ca1401SAndre Przywara .group = KVM_DEV_ARM_VGIC_GRP_CTRL, 8212ca1401SAndre Przywara .attr = KVM_DEV_ARM_VGIC_CTRL_INIT, 8312ca1401SAndre Przywara }; 8412ca1401SAndre Przywara int err; 8512ca1401SAndre Przywara 8612ca1401SAndre Przywara err = ioctl(kvm->vm_fd, KVM_CREATE_DEVICE, &its_device); 8712ca1401SAndre Przywara if (err) { 8812ca1401SAndre Przywara fprintf(stderr, 8912ca1401SAndre Przywara "GICv3 ITS requested, but kernel does not support it.\n"); 9012ca1401SAndre Przywara fprintf(stderr, "Try --irqchip=gicv3 instead\n"); 9112ca1401SAndre Przywara return err; 9212ca1401SAndre Przywara } 9312ca1401SAndre Przywara 9412ca1401SAndre Przywara err = ioctl(its_device.fd, KVM_HAS_DEVICE_ATTR, &its_attr); 9512ca1401SAndre Przywara if (err) { 9612ca1401SAndre Przywara close(its_device.fd); 9712ca1401SAndre Przywara its_device.fd = -1; 9812ca1401SAndre Przywara return err; 9912ca1401SAndre Przywara } 10012ca1401SAndre Przywara 10112ca1401SAndre Przywara err = ioctl(its_device.fd, KVM_SET_DEVICE_ATTR, &its_attr); 10212ca1401SAndre Przywara if (err) 10312ca1401SAndre Przywara return err; 10412ca1401SAndre Przywara 10512ca1401SAndre Przywara return ioctl(its_device.fd, KVM_SET_DEVICE_ATTR, &its_init_attr); 10612ca1401SAndre Przywara } 10712ca1401SAndre Przywara 10812ca1401SAndre Przywara static int gic__create_msi_frame(struct kvm *kvm, enum irqchip_type type, 10912ca1401SAndre Przywara u64 msi_frame_addr) 11012ca1401SAndre Przywara { 11112ca1401SAndre Przywara switch (type) { 112f6108d72SJean-Philippe Brucker case IRQCHIP_GICV2M: 113f6108d72SJean-Philippe Brucker return gic__create_gicv2m_frame(kvm, msi_frame_addr); 11412ca1401SAndre Przywara case IRQCHIP_GICV3_ITS: 11512ca1401SAndre Przywara return gic__create_its_frame(kvm, msi_frame_addr); 11612ca1401SAndre Przywara default: /* No MSI frame needed */ 11712ca1401SAndre Przywara return 0; 11812ca1401SAndre Przywara } 11912ca1401SAndre Przywara } 12012ca1401SAndre Przywara 12102017c1dSAndre Przywara static int gic__create_device(struct kvm *kvm, enum irqchip_type type) 12269b9a17aSMarc Zyngier { 12369b9a17aSMarc Zyngier int err; 12469b9a17aSMarc Zyngier u64 cpu_if_addr = ARM_GIC_CPUI_BASE; 12569b9a17aSMarc Zyngier u64 dist_addr = ARM_GIC_DIST_BASE; 12669b9a17aSMarc Zyngier struct kvm_create_device gic_device = { 12702017c1dSAndre Przywara .flags = 0, 12869b9a17aSMarc Zyngier }; 12969b9a17aSMarc Zyngier struct kvm_device_attr cpu_if_attr = { 13069b9a17aSMarc Zyngier .group = KVM_DEV_ARM_VGIC_GRP_ADDR, 13169b9a17aSMarc Zyngier .attr = KVM_VGIC_V2_ADDR_TYPE_CPU, 13269b9a17aSMarc Zyngier .addr = (u64)(unsigned long)&cpu_if_addr, 13369b9a17aSMarc Zyngier }; 13469b9a17aSMarc Zyngier struct kvm_device_attr dist_attr = { 13569b9a17aSMarc Zyngier .group = KVM_DEV_ARM_VGIC_GRP_ADDR, 13669b9a17aSMarc Zyngier .addr = (u64)(unsigned long)&dist_addr, 13769b9a17aSMarc Zyngier }; 138bfb2c703SAndre Przywara struct kvm_device_attr redist_attr = { 139bfb2c703SAndre Przywara .group = KVM_DEV_ARM_VGIC_GRP_ADDR, 140bfb2c703SAndre Przywara .attr = KVM_VGIC_V3_ADDR_TYPE_REDIST, 141bfb2c703SAndre Przywara .addr = (u64)(unsigned long)&gic_redists_base, 142bfb2c703SAndre Przywara }; 14369b9a17aSMarc Zyngier 14402017c1dSAndre Przywara switch (type) { 145f6108d72SJean-Philippe Brucker case IRQCHIP_GICV2M: 14602017c1dSAndre Przywara case IRQCHIP_GICV2: 14702017c1dSAndre Przywara gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V2; 14802017c1dSAndre Przywara dist_attr.attr = KVM_VGIC_V2_ADDR_TYPE_DIST; 14902017c1dSAndre Przywara break; 150bfb2c703SAndre Przywara case IRQCHIP_GICV3: 15112ca1401SAndre Przywara case IRQCHIP_GICV3_ITS: 152bfb2c703SAndre Przywara gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V3; 153bfb2c703SAndre Przywara dist_attr.attr = KVM_VGIC_V3_ADDR_TYPE_DIST; 154bfb2c703SAndre Przywara break; 15502017c1dSAndre Przywara } 15602017c1dSAndre Przywara 15769b9a17aSMarc Zyngier err = ioctl(kvm->vm_fd, KVM_CREATE_DEVICE, &gic_device); 15869b9a17aSMarc Zyngier if (err) 15969b9a17aSMarc Zyngier return err; 16069b9a17aSMarc Zyngier 16169b9a17aSMarc Zyngier gic_fd = gic_device.fd; 16269b9a17aSMarc Zyngier 16302017c1dSAndre Przywara switch (type) { 164f6108d72SJean-Philippe Brucker case IRQCHIP_GICV2M: 16502017c1dSAndre Przywara case IRQCHIP_GICV2: 16669b9a17aSMarc Zyngier err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &cpu_if_attr); 16702017c1dSAndre Przywara break; 16812ca1401SAndre Przywara case IRQCHIP_GICV3_ITS: 169bfb2c703SAndre Przywara case IRQCHIP_GICV3: 170bfb2c703SAndre Przywara err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &redist_attr); 171bfb2c703SAndre Przywara break; 17202017c1dSAndre Przywara } 17369b9a17aSMarc Zyngier if (err) 17469b9a17aSMarc Zyngier goto out_err; 17569b9a17aSMarc Zyngier 17669b9a17aSMarc Zyngier err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &dist_attr); 17769b9a17aSMarc Zyngier if (err) 17869b9a17aSMarc Zyngier goto out_err; 17969b9a17aSMarc Zyngier 18012ca1401SAndre Przywara err = gic__create_msi_frame(kvm, type, gic_msi_base); 18112ca1401SAndre Przywara if (err) 18212ca1401SAndre Przywara goto out_err; 18312ca1401SAndre Przywara 18469b9a17aSMarc Zyngier return 0; 18569b9a17aSMarc Zyngier 18669b9a17aSMarc Zyngier out_err: 18769b9a17aSMarc Zyngier close(gic_fd); 18869b9a17aSMarc Zyngier gic_fd = -1; 18969b9a17aSMarc Zyngier return err; 19069b9a17aSMarc Zyngier } 19169b9a17aSMarc Zyngier 19269b9a17aSMarc Zyngier static int gic__create_irqchip(struct kvm *kvm) 1937c0e8b0cSWill Deacon { 1947c0e8b0cSWill Deacon int err; 195aa7a0e79SWill Deacon struct kvm_arm_device_addr gic_addr[] = { 1967c0e8b0cSWill Deacon [0] = { 197aa7a0e79SWill Deacon .id = KVM_VGIC_V2_ADDR_TYPE_DIST | 198aa7a0e79SWill Deacon (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT), 1997c0e8b0cSWill Deacon .addr = ARM_GIC_DIST_BASE, 2007c0e8b0cSWill Deacon }, 2017c0e8b0cSWill Deacon [1] = { 202aa7a0e79SWill Deacon .id = KVM_VGIC_V2_ADDR_TYPE_CPU | 203aa7a0e79SWill Deacon (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT), 2047c0e8b0cSWill Deacon .addr = ARM_GIC_CPUI_BASE, 2057c0e8b0cSWill Deacon } 2067c0e8b0cSWill Deacon }; 2077c0e8b0cSWill Deacon 2087c0e8b0cSWill Deacon err = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP); 2097c0e8b0cSWill Deacon if (err) 2107c0e8b0cSWill Deacon return err; 2117c0e8b0cSWill Deacon 212aa7a0e79SWill Deacon err = ioctl(kvm->vm_fd, KVM_ARM_SET_DEVICE_ADDR, &gic_addr[0]); 2137c0e8b0cSWill Deacon if (err) 2147c0e8b0cSWill Deacon return err; 2157c0e8b0cSWill Deacon 216aa7a0e79SWill Deacon err = ioctl(kvm->vm_fd, KVM_ARM_SET_DEVICE_ADDR, &gic_addr[1]); 2177c0e8b0cSWill Deacon return err; 2187c0e8b0cSWill Deacon } 2197c0e8b0cSWill Deacon 22002017c1dSAndre Przywara int gic__create(struct kvm *kvm, enum irqchip_type type) 22169b9a17aSMarc Zyngier { 22269b9a17aSMarc Zyngier int err; 22369b9a17aSMarc Zyngier 22402017c1dSAndre Przywara switch (type) { 225f6108d72SJean-Philippe Brucker case IRQCHIP_GICV2M: 226f6108d72SJean-Philippe Brucker gic_msi_size = KVM_VGIC_V2M_SIZE; 227f6108d72SJean-Philippe Brucker gic_msi_base = ARM_GIC_DIST_BASE - gic_msi_size; 228f6108d72SJean-Philippe Brucker break; 22902017c1dSAndre Przywara case IRQCHIP_GICV2: 23002017c1dSAndre Przywara break; 23112ca1401SAndre Przywara case IRQCHIP_GICV3_ITS: 232*a5d36dd1SAndre Przywara /* The 64K page with the doorbell is included. */ 233*a5d36dd1SAndre Przywara gic_msi_size = KVM_VGIC_V3_ITS_SIZE; 23412ca1401SAndre Przywara /* fall through */ 235bfb2c703SAndre Przywara case IRQCHIP_GICV3: 236bfb2c703SAndre Przywara gic_redists_size = kvm->cfg.nrcpus * ARM_GIC_REDIST_SIZE; 237bfb2c703SAndre Przywara gic_redists_base = ARM_GIC_DIST_BASE - gic_redists_size; 23812ca1401SAndre Przywara gic_msi_base = gic_redists_base - gic_msi_size; 239bfb2c703SAndre Przywara break; 24002017c1dSAndre Przywara default: 24102017c1dSAndre Przywara return -ENODEV; 24202017c1dSAndre Przywara } 24302017c1dSAndre Przywara 24469b9a17aSMarc Zyngier /* Try the new way first, and fallback on legacy method otherwise */ 24502017c1dSAndre Przywara err = gic__create_device(kvm, type); 24602017c1dSAndre Przywara if (err && type == IRQCHIP_GICV2) 24769b9a17aSMarc Zyngier err = gic__create_irqchip(kvm); 24869b9a17aSMarc Zyngier 24969b9a17aSMarc Zyngier return err; 25069b9a17aSMarc Zyngier } 25169b9a17aSMarc Zyngier 252b5790302SAndre Przywara /* 253b5790302SAndre Przywara * Sets the number of used interrupts and finalizes the GIC init explicitly. 254b5790302SAndre Przywara */ 255bed2bd9eSMarc Zyngier static int gic__init_gic(struct kvm *kvm) 256bed2bd9eSMarc Zyngier { 257b5790302SAndre Przywara int ret; 258b5790302SAndre Przywara 259bed2bd9eSMarc Zyngier int lines = irq__get_nr_allocated_lines(); 260bed2bd9eSMarc Zyngier u32 nr_irqs = ALIGN(lines, 32) + GIC_SPI_IRQ_BASE; 261bed2bd9eSMarc Zyngier struct kvm_device_attr nr_irqs_attr = { 262bed2bd9eSMarc Zyngier .group = KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 263bed2bd9eSMarc Zyngier .addr = (u64)(unsigned long)&nr_irqs, 264bed2bd9eSMarc Zyngier }; 265b5790302SAndre Przywara struct kvm_device_attr vgic_init_attr = { 266b5790302SAndre Przywara .group = KVM_DEV_ARM_VGIC_GRP_CTRL, 267b5790302SAndre Przywara .attr = KVM_DEV_ARM_VGIC_CTRL_INIT, 268b5790302SAndre Przywara }; 269bed2bd9eSMarc Zyngier 270bed2bd9eSMarc Zyngier /* 271bed2bd9eSMarc Zyngier * If we didn't use the KVM_CREATE_DEVICE method, KVM will 272b5790302SAndre Przywara * give us some default number of interrupts. The GIC initialization 273b5790302SAndre Przywara * will be done automatically in this case. 274bed2bd9eSMarc Zyngier */ 275bed2bd9eSMarc Zyngier if (gic_fd < 0) 276bed2bd9eSMarc Zyngier return 0; 277bed2bd9eSMarc Zyngier 278b5790302SAndre Przywara if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, &nr_irqs_attr)) { 279b5790302SAndre Przywara ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &nr_irqs_attr); 280b5790302SAndre Przywara if (ret) 281b5790302SAndre Przywara return ret; 282b5790302SAndre Przywara } 283b5790302SAndre Przywara 28469ae77c5SAndre Przywara irq__routing_init(kvm); 28569ae77c5SAndre Przywara 286b5790302SAndre Przywara if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, &vgic_init_attr)) { 287b5790302SAndre Przywara ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &vgic_init_attr); 288b5790302SAndre Przywara if (ret) 289b5790302SAndre Przywara return ret; 290b5790302SAndre Przywara } 291bed2bd9eSMarc Zyngier 292714ab9e6SAndre Przywara kvm->msix_needs_devid = kvm__supports_vm_extension(kvm, 293714ab9e6SAndre Przywara KVM_CAP_MSI_DEVID); 294714ab9e6SAndre Przywara 295bed2bd9eSMarc Zyngier return 0; 296bed2bd9eSMarc Zyngier } 297bed2bd9eSMarc Zyngier late_init(gic__init_gic) 298bed2bd9eSMarc Zyngier 2990063d50cSAndre Przywara void gic__generate_fdt_nodes(void *fdt, enum irqchip_type type) 3007c0e8b0cSWill Deacon { 30114421de9SAndre Przywara const char *compatible, *msi_compatible = NULL; 30214421de9SAndre Przywara u64 msi_prop[2]; 3037c0e8b0cSWill Deacon u64 reg_prop[] = { 3047c0e8b0cSWill Deacon cpu_to_fdt64(ARM_GIC_DIST_BASE), cpu_to_fdt64(ARM_GIC_DIST_SIZE), 305bfb2c703SAndre Przywara 0, 0, /* to be filled */ 3067c0e8b0cSWill Deacon }; 3077c0e8b0cSWill Deacon 30802017c1dSAndre Przywara switch (type) { 309f6108d72SJean-Philippe Brucker case IRQCHIP_GICV2M: 310f6108d72SJean-Philippe Brucker msi_compatible = "arm,gic-v2m-frame"; 311f6108d72SJean-Philippe Brucker /* fall-through */ 31202017c1dSAndre Przywara case IRQCHIP_GICV2: 31302017c1dSAndre Przywara compatible = "arm,cortex-a15-gic"; 314bfb2c703SAndre Przywara reg_prop[2] = cpu_to_fdt64(ARM_GIC_CPUI_BASE); 315bfb2c703SAndre Przywara reg_prop[3] = cpu_to_fdt64(ARM_GIC_CPUI_SIZE); 316bfb2c703SAndre Przywara break; 31714421de9SAndre Przywara case IRQCHIP_GICV3_ITS: 31814421de9SAndre Przywara msi_compatible = "arm,gic-v3-its"; 31914421de9SAndre Przywara /* fall-through */ 320bfb2c703SAndre Przywara case IRQCHIP_GICV3: 321bfb2c703SAndre Przywara compatible = "arm,gic-v3"; 322bfb2c703SAndre Przywara reg_prop[2] = cpu_to_fdt64(gic_redists_base); 323bfb2c703SAndre Przywara reg_prop[3] = cpu_to_fdt64(gic_redists_size); 32402017c1dSAndre Przywara break; 32502017c1dSAndre Przywara default: 32602017c1dSAndre Przywara return; 32702017c1dSAndre Przywara } 32802017c1dSAndre Przywara 3297c0e8b0cSWill Deacon _FDT(fdt_begin_node(fdt, "intc")); 33002017c1dSAndre Przywara _FDT(fdt_property_string(fdt, "compatible", compatible)); 3317c0e8b0cSWill Deacon _FDT(fdt_property_cell(fdt, "#interrupt-cells", GIC_FDT_IRQ_NUM_CELLS)); 3327c0e8b0cSWill Deacon _FDT(fdt_property(fdt, "interrupt-controller", NULL, 0)); 3337c0e8b0cSWill Deacon _FDT(fdt_property(fdt, "reg", reg_prop, sizeof(reg_prop))); 3340063d50cSAndre Przywara _FDT(fdt_property_cell(fdt, "phandle", PHANDLE_GIC)); 33514421de9SAndre Przywara _FDT(fdt_property_cell(fdt, "#address-cells", 2)); 33614421de9SAndre Przywara _FDT(fdt_property_cell(fdt, "#size-cells", 2)); 33714421de9SAndre Przywara 33814421de9SAndre Przywara if (msi_compatible) { 33914421de9SAndre Przywara _FDT(fdt_property(fdt, "ranges", NULL, 0)); 34014421de9SAndre Przywara 34114421de9SAndre Przywara _FDT(fdt_begin_node(fdt, "msic")); 34214421de9SAndre Przywara _FDT(fdt_property_string(fdt, "compatible", msi_compatible)); 34314421de9SAndre Przywara _FDT(fdt_property(fdt, "msi-controller", NULL, 0)); 34414421de9SAndre Przywara _FDT(fdt_property_cell(fdt, "phandle", PHANDLE_MSI)); 34514421de9SAndre Przywara msi_prop[0] = cpu_to_fdt64(gic_msi_base); 34614421de9SAndre Przywara msi_prop[1] = cpu_to_fdt64(gic_msi_size); 34714421de9SAndre Przywara _FDT(fdt_property(fdt, "reg", msi_prop, sizeof(msi_prop))); 34814421de9SAndre Przywara _FDT(fdt_end_node(fdt)); 34914421de9SAndre Przywara } 35014421de9SAndre Przywara 3517c0e8b0cSWill Deacon _FDT(fdt_end_node(fdt)); 3527c0e8b0cSWill Deacon } 3537c0e8b0cSWill Deacon 3547c0e8b0cSWill Deacon #define KVM_IRQCHIP_IRQ(x) (KVM_ARM_IRQ_TYPE_SPI << KVM_ARM_IRQ_TYPE_SHIFT) |\ 3557c0e8b0cSWill Deacon ((x) & KVM_ARM_IRQ_NUM_MASK) 3567c0e8b0cSWill Deacon 3577c0e8b0cSWill Deacon void kvm__irq_line(struct kvm *kvm, int irq, int level) 3587c0e8b0cSWill Deacon { 3597c0e8b0cSWill Deacon struct kvm_irq_level irq_level = { 3607c0e8b0cSWill Deacon .irq = KVM_IRQCHIP_IRQ(irq), 3617c0e8b0cSWill Deacon .level = !!level, 3627c0e8b0cSWill Deacon }; 3637c0e8b0cSWill Deacon 3647c0e8b0cSWill Deacon if (irq < GIC_SPI_IRQ_BASE || irq > GIC_MAX_IRQ) 3657c0e8b0cSWill Deacon pr_warning("Ignoring invalid GIC IRQ %d", irq); 3667c0e8b0cSWill Deacon else if (ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level) < 0) 3677c0e8b0cSWill Deacon pr_warning("Could not KVM_IRQ_LINE for irq %d", irq); 3687c0e8b0cSWill Deacon } 3697c0e8b0cSWill Deacon 3707c0e8b0cSWill Deacon void kvm__irq_trigger(struct kvm *kvm, int irq) 3717c0e8b0cSWill Deacon { 3727c0e8b0cSWill Deacon kvm__irq_line(kvm, irq, VIRTIO_IRQ_HIGH); 3737c0e8b0cSWill Deacon kvm__irq_line(kvm, irq, VIRTIO_IRQ_LOW); 3747c0e8b0cSWill Deacon } 375