xref: /kvmtool/arm/gic.c (revision 76392d29aeeafe2a26c2ec06156a43e11b6cadd6)
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;
2743d2781cSAndre Przywara 	} else if (!strcmp(arg, "gicv3")) {
2843d2781cSAndre Przywara 		*type = IRQCHIP_GICV3;
29*76392d29SAndre Przywara 	} else if (!strcmp(arg, "gicv3-its")) {
30*76392d29SAndre Przywara 		*type = IRQCHIP_GICV3_ITS;
3143d2781cSAndre Przywara 	} else {
3243d2781cSAndre Przywara 		pr_err("irqchip: unknown type \"%s\"\n", arg);
3343d2781cSAndre Przywara 		return -1;
3443d2781cSAndre Przywara 	}
3543d2781cSAndre Przywara 
3643d2781cSAndre Przywara 	return 0;
3743d2781cSAndre Przywara }
3843d2781cSAndre Przywara 
3969ae77c5SAndre Przywara static int irq__routing_init(struct kvm *kvm)
4069ae77c5SAndre Przywara {
4169ae77c5SAndre Przywara 	int r;
4269ae77c5SAndre Przywara 	int irqlines = ALIGN(irq__get_nr_allocated_lines(), 32);
4369ae77c5SAndre Przywara 
4469ae77c5SAndre Przywara 	/*
4569ae77c5SAndre Przywara 	 * This describes the default routing that the kernel uses without
4669ae77c5SAndre Przywara 	 * any routing explicitly set up via KVM_SET_GSI_ROUTING. So we
4769ae77c5SAndre Przywara 	 * don't need to commit these setting right now. The first actual
4869ae77c5SAndre Przywara 	 * user (MSI routing) will engage these mappings then.
4969ae77c5SAndre Przywara 	 */
5069ae77c5SAndre Przywara 	for (next_gsi = 0; next_gsi < irqlines; next_gsi++) {
5169ae77c5SAndre Przywara 		r = irq__allocate_routing_entry();
5269ae77c5SAndre Przywara 		if (r)
5369ae77c5SAndre Przywara 			return r;
5469ae77c5SAndre Przywara 
5569ae77c5SAndre Przywara 		irq_routing->entries[irq_routing->nr++] =
5669ae77c5SAndre Przywara 			(struct kvm_irq_routing_entry) {
5769ae77c5SAndre Przywara 				.gsi = next_gsi,
5869ae77c5SAndre Przywara 				.type = KVM_IRQ_ROUTING_IRQCHIP,
5969ae77c5SAndre Przywara 				.u.irqchip.irqchip = IRQCHIP_GIC,
6069ae77c5SAndre Przywara 				.u.irqchip.pin = next_gsi,
6169ae77c5SAndre Przywara 		};
6269ae77c5SAndre Przywara 	}
6369ae77c5SAndre Przywara 
6469ae77c5SAndre Przywara 	return 0;
6569ae77c5SAndre Przywara }
6669ae77c5SAndre Przywara 
6712ca1401SAndre Przywara static int gic__create_its_frame(struct kvm *kvm, u64 its_frame_addr)
6812ca1401SAndre Przywara {
6912ca1401SAndre Przywara 	struct kvm_create_device its_device = {
7012ca1401SAndre Przywara 		.type = KVM_DEV_TYPE_ARM_VGIC_ITS,
7112ca1401SAndre Przywara 		.flags	= 0,
7212ca1401SAndre Przywara 	};
7312ca1401SAndre Przywara 	struct kvm_device_attr its_attr = {
7412ca1401SAndre Przywara 		.group	= KVM_DEV_ARM_VGIC_GRP_ADDR,
7512ca1401SAndre Przywara 		.attr	= KVM_VGIC_ITS_ADDR_TYPE,
7612ca1401SAndre Przywara 		.addr	= (u64)(unsigned long)&its_frame_addr,
7712ca1401SAndre Przywara 	};
7812ca1401SAndre Przywara 	struct kvm_device_attr its_init_attr = {
7912ca1401SAndre Przywara 		.group	= KVM_DEV_ARM_VGIC_GRP_CTRL,
8012ca1401SAndre Przywara 		.attr	= KVM_DEV_ARM_VGIC_CTRL_INIT,
8112ca1401SAndre Przywara 	};
8212ca1401SAndre Przywara 	int err;
8312ca1401SAndre Przywara 
8412ca1401SAndre Przywara 	err = ioctl(kvm->vm_fd, KVM_CREATE_DEVICE, &its_device);
8512ca1401SAndre Przywara 	if (err) {
8612ca1401SAndre Przywara 		fprintf(stderr,
8712ca1401SAndre Przywara 			"GICv3 ITS requested, but kernel does not support it.\n");
8812ca1401SAndre Przywara 		fprintf(stderr, "Try --irqchip=gicv3 instead\n");
8912ca1401SAndre Przywara 		return err;
9012ca1401SAndre Przywara 	}
9112ca1401SAndre Przywara 
9212ca1401SAndre Przywara 	err = ioctl(its_device.fd, KVM_HAS_DEVICE_ATTR, &its_attr);
9312ca1401SAndre Przywara 	if (err) {
9412ca1401SAndre Przywara 		close(its_device.fd);
9512ca1401SAndre Przywara 		its_device.fd = -1;
9612ca1401SAndre Przywara 		return err;
9712ca1401SAndre Przywara 	}
9812ca1401SAndre Przywara 
9912ca1401SAndre Przywara 	err = ioctl(its_device.fd, KVM_SET_DEVICE_ATTR, &its_attr);
10012ca1401SAndre Przywara 	if (err)
10112ca1401SAndre Przywara 		return err;
10212ca1401SAndre Przywara 
10312ca1401SAndre Przywara 	return ioctl(its_device.fd, KVM_SET_DEVICE_ATTR, &its_init_attr);
10412ca1401SAndre Przywara }
10512ca1401SAndre Przywara 
10612ca1401SAndre Przywara static int gic__create_msi_frame(struct kvm *kvm, enum irqchip_type type,
10712ca1401SAndre Przywara 				 u64 msi_frame_addr)
10812ca1401SAndre Przywara {
10912ca1401SAndre Przywara 	switch (type) {
11012ca1401SAndre Przywara 	case IRQCHIP_GICV3_ITS:
11112ca1401SAndre Przywara 		return gic__create_its_frame(kvm, msi_frame_addr);
11212ca1401SAndre Przywara 	default:	/* No MSI frame needed */
11312ca1401SAndre Przywara 		return 0;
11412ca1401SAndre Przywara 	}
11512ca1401SAndre Przywara }
11612ca1401SAndre Przywara 
11702017c1dSAndre Przywara static int gic__create_device(struct kvm *kvm, enum irqchip_type type)
11869b9a17aSMarc Zyngier {
11969b9a17aSMarc Zyngier 	int err;
12069b9a17aSMarc Zyngier 	u64 cpu_if_addr = ARM_GIC_CPUI_BASE;
12169b9a17aSMarc Zyngier 	u64 dist_addr = ARM_GIC_DIST_BASE;
12269b9a17aSMarc Zyngier 	struct kvm_create_device gic_device = {
12302017c1dSAndre Przywara 		.flags	= 0,
12469b9a17aSMarc Zyngier 	};
12569b9a17aSMarc Zyngier 	struct kvm_device_attr cpu_if_attr = {
12669b9a17aSMarc Zyngier 		.group	= KVM_DEV_ARM_VGIC_GRP_ADDR,
12769b9a17aSMarc Zyngier 		.attr	= KVM_VGIC_V2_ADDR_TYPE_CPU,
12869b9a17aSMarc Zyngier 		.addr	= (u64)(unsigned long)&cpu_if_addr,
12969b9a17aSMarc Zyngier 	};
13069b9a17aSMarc Zyngier 	struct kvm_device_attr dist_attr = {
13169b9a17aSMarc Zyngier 		.group	= KVM_DEV_ARM_VGIC_GRP_ADDR,
13269b9a17aSMarc Zyngier 		.addr	= (u64)(unsigned long)&dist_addr,
13369b9a17aSMarc Zyngier 	};
134bfb2c703SAndre Przywara 	struct kvm_device_attr redist_attr = {
135bfb2c703SAndre Przywara 		.group	= KVM_DEV_ARM_VGIC_GRP_ADDR,
136bfb2c703SAndre Przywara 		.attr	= KVM_VGIC_V3_ADDR_TYPE_REDIST,
137bfb2c703SAndre Przywara 		.addr	= (u64)(unsigned long)&gic_redists_base,
138bfb2c703SAndre Przywara 	};
13969b9a17aSMarc Zyngier 
14002017c1dSAndre Przywara 	switch (type) {
14102017c1dSAndre Przywara 	case IRQCHIP_GICV2:
14202017c1dSAndre Przywara 		gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V2;
14302017c1dSAndre Przywara 		dist_attr.attr  = KVM_VGIC_V2_ADDR_TYPE_DIST;
14402017c1dSAndre Przywara 		break;
145bfb2c703SAndre Przywara 	case IRQCHIP_GICV3:
14612ca1401SAndre Przywara 	case IRQCHIP_GICV3_ITS:
147bfb2c703SAndre Przywara 		gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V3;
148bfb2c703SAndre Przywara 		dist_attr.attr  = KVM_VGIC_V3_ADDR_TYPE_DIST;
149bfb2c703SAndre Przywara 		break;
15002017c1dSAndre Przywara 	}
15102017c1dSAndre Przywara 
15269b9a17aSMarc Zyngier 	err = ioctl(kvm->vm_fd, KVM_CREATE_DEVICE, &gic_device);
15369b9a17aSMarc Zyngier 	if (err)
15469b9a17aSMarc Zyngier 		return err;
15569b9a17aSMarc Zyngier 
15669b9a17aSMarc Zyngier 	gic_fd = gic_device.fd;
15769b9a17aSMarc Zyngier 
15802017c1dSAndre Przywara 	switch (type) {
15902017c1dSAndre Przywara 	case IRQCHIP_GICV2:
16069b9a17aSMarc Zyngier 		err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &cpu_if_attr);
16102017c1dSAndre Przywara 		break;
16212ca1401SAndre Przywara 	case IRQCHIP_GICV3_ITS:
163bfb2c703SAndre Przywara 	case IRQCHIP_GICV3:
164bfb2c703SAndre Przywara 		err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &redist_attr);
165bfb2c703SAndre Przywara 		break;
16602017c1dSAndre Przywara 	}
16769b9a17aSMarc Zyngier 	if (err)
16869b9a17aSMarc Zyngier 		goto out_err;
16969b9a17aSMarc Zyngier 
17069b9a17aSMarc Zyngier 	err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &dist_attr);
17169b9a17aSMarc Zyngier 	if (err)
17269b9a17aSMarc Zyngier 		goto out_err;
17369b9a17aSMarc Zyngier 
17412ca1401SAndre Przywara 	err = gic__create_msi_frame(kvm, type, gic_msi_base);
17512ca1401SAndre Przywara 	if (err)
17612ca1401SAndre Przywara 		goto out_err;
17712ca1401SAndre Przywara 
17869b9a17aSMarc Zyngier 	return 0;
17969b9a17aSMarc Zyngier 
18069b9a17aSMarc Zyngier out_err:
18169b9a17aSMarc Zyngier 	close(gic_fd);
18269b9a17aSMarc Zyngier 	gic_fd = -1;
18369b9a17aSMarc Zyngier 	return err;
18469b9a17aSMarc Zyngier }
18569b9a17aSMarc Zyngier 
18669b9a17aSMarc Zyngier static int gic__create_irqchip(struct kvm *kvm)
1877c0e8b0cSWill Deacon {
1887c0e8b0cSWill Deacon 	int err;
189aa7a0e79SWill Deacon 	struct kvm_arm_device_addr gic_addr[] = {
1907c0e8b0cSWill Deacon 		[0] = {
191aa7a0e79SWill Deacon 			.id = KVM_VGIC_V2_ADDR_TYPE_DIST |
192aa7a0e79SWill Deacon 			(KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT),
1937c0e8b0cSWill Deacon 			.addr = ARM_GIC_DIST_BASE,
1947c0e8b0cSWill Deacon 		},
1957c0e8b0cSWill Deacon 		[1] = {
196aa7a0e79SWill Deacon 			.id = KVM_VGIC_V2_ADDR_TYPE_CPU |
197aa7a0e79SWill Deacon 			(KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT),
1987c0e8b0cSWill Deacon 			.addr = ARM_GIC_CPUI_BASE,
1997c0e8b0cSWill Deacon 		}
2007c0e8b0cSWill Deacon 	};
2017c0e8b0cSWill Deacon 
2027c0e8b0cSWill Deacon 	err = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP);
2037c0e8b0cSWill Deacon 	if (err)
2047c0e8b0cSWill Deacon 		return err;
2057c0e8b0cSWill Deacon 
206aa7a0e79SWill Deacon 	err = ioctl(kvm->vm_fd, KVM_ARM_SET_DEVICE_ADDR, &gic_addr[0]);
2077c0e8b0cSWill Deacon 	if (err)
2087c0e8b0cSWill Deacon 		return err;
2097c0e8b0cSWill Deacon 
210aa7a0e79SWill Deacon 	err = ioctl(kvm->vm_fd, KVM_ARM_SET_DEVICE_ADDR, &gic_addr[1]);
2117c0e8b0cSWill Deacon 	return err;
2127c0e8b0cSWill Deacon }
2137c0e8b0cSWill Deacon 
21402017c1dSAndre Przywara int gic__create(struct kvm *kvm, enum irqchip_type type)
21569b9a17aSMarc Zyngier {
21669b9a17aSMarc Zyngier 	int err;
21769b9a17aSMarc Zyngier 
21802017c1dSAndre Przywara 	switch (type) {
21902017c1dSAndre Przywara 	case IRQCHIP_GICV2:
22002017c1dSAndre Przywara 		break;
22112ca1401SAndre Przywara 	case IRQCHIP_GICV3_ITS:
22212ca1401SAndre Przywara 		/* We reserve the 64K page with the doorbell as well. */
22312ca1401SAndre Przywara 		gic_msi_size = KVM_VGIC_V3_ITS_SIZE + SZ_64K;
22412ca1401SAndre Przywara 		/* fall through */
225bfb2c703SAndre Przywara 	case IRQCHIP_GICV3:
226bfb2c703SAndre Przywara 		gic_redists_size = kvm->cfg.nrcpus * ARM_GIC_REDIST_SIZE;
227bfb2c703SAndre Przywara 		gic_redists_base = ARM_GIC_DIST_BASE - gic_redists_size;
22812ca1401SAndre Przywara 		gic_msi_base = gic_redists_base - gic_msi_size;
229bfb2c703SAndre Przywara 		break;
23002017c1dSAndre Przywara 	default:
23102017c1dSAndre Przywara 		return -ENODEV;
23202017c1dSAndre Przywara 	}
23302017c1dSAndre Przywara 
23469b9a17aSMarc Zyngier 	/* Try the new way first, and fallback on legacy method otherwise */
23502017c1dSAndre Przywara 	err = gic__create_device(kvm, type);
23602017c1dSAndre Przywara 	if (err && type == IRQCHIP_GICV2)
23769b9a17aSMarc Zyngier 		err = gic__create_irqchip(kvm);
23869b9a17aSMarc Zyngier 
23969b9a17aSMarc Zyngier 	return err;
24069b9a17aSMarc Zyngier }
24169b9a17aSMarc Zyngier 
242b5790302SAndre Przywara /*
243b5790302SAndre Przywara  * Sets the number of used interrupts and finalizes the GIC init explicitly.
244b5790302SAndre Przywara  */
245bed2bd9eSMarc Zyngier static int gic__init_gic(struct kvm *kvm)
246bed2bd9eSMarc Zyngier {
247b5790302SAndre Przywara 	int ret;
248b5790302SAndre Przywara 
249bed2bd9eSMarc Zyngier 	int lines = irq__get_nr_allocated_lines();
250bed2bd9eSMarc Zyngier 	u32 nr_irqs = ALIGN(lines, 32) + GIC_SPI_IRQ_BASE;
251bed2bd9eSMarc Zyngier 	struct kvm_device_attr nr_irqs_attr = {
252bed2bd9eSMarc Zyngier 		.group	= KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
253bed2bd9eSMarc Zyngier 		.addr	= (u64)(unsigned long)&nr_irqs,
254bed2bd9eSMarc Zyngier 	};
255b5790302SAndre Przywara 	struct kvm_device_attr vgic_init_attr = {
256b5790302SAndre Przywara 		.group	= KVM_DEV_ARM_VGIC_GRP_CTRL,
257b5790302SAndre Przywara 		.attr	= KVM_DEV_ARM_VGIC_CTRL_INIT,
258b5790302SAndre Przywara 	};
259bed2bd9eSMarc Zyngier 
260bed2bd9eSMarc Zyngier 	/*
261bed2bd9eSMarc Zyngier 	 * If we didn't use the KVM_CREATE_DEVICE method, KVM will
262b5790302SAndre Przywara 	 * give us some default number of interrupts. The GIC initialization
263b5790302SAndre Przywara 	 * will be done automatically in this case.
264bed2bd9eSMarc Zyngier 	 */
265bed2bd9eSMarc Zyngier 	if (gic_fd < 0)
266bed2bd9eSMarc Zyngier 		return 0;
267bed2bd9eSMarc Zyngier 
268b5790302SAndre Przywara 	if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, &nr_irqs_attr)) {
269b5790302SAndre Przywara 		ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &nr_irqs_attr);
270b5790302SAndre Przywara 		if (ret)
271b5790302SAndre Przywara 			return ret;
272b5790302SAndre Przywara 	}
273b5790302SAndre Przywara 
27469ae77c5SAndre Przywara 	irq__routing_init(kvm);
27569ae77c5SAndre Przywara 
276b5790302SAndre Przywara 	if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, &vgic_init_attr)) {
277b5790302SAndre Przywara 		ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &vgic_init_attr);
278b5790302SAndre Przywara 		if (ret)
279b5790302SAndre Przywara 			return ret;
280b5790302SAndre Przywara 	}
281bed2bd9eSMarc Zyngier 
282714ab9e6SAndre Przywara 	kvm->msix_needs_devid = kvm__supports_vm_extension(kvm,
283714ab9e6SAndre Przywara 							   KVM_CAP_MSI_DEVID);
284714ab9e6SAndre Przywara 
285bed2bd9eSMarc Zyngier 	return 0;
286bed2bd9eSMarc Zyngier }
287bed2bd9eSMarc Zyngier late_init(gic__init_gic)
288bed2bd9eSMarc Zyngier 
2890063d50cSAndre Przywara void gic__generate_fdt_nodes(void *fdt, enum irqchip_type type)
2907c0e8b0cSWill Deacon {
29114421de9SAndre Przywara 	const char *compatible, *msi_compatible = NULL;
29214421de9SAndre Przywara 	u64 msi_prop[2];
2937c0e8b0cSWill Deacon 	u64 reg_prop[] = {
2947c0e8b0cSWill Deacon 		cpu_to_fdt64(ARM_GIC_DIST_BASE), cpu_to_fdt64(ARM_GIC_DIST_SIZE),
295bfb2c703SAndre Przywara 		0, 0,				/* to be filled */
2967c0e8b0cSWill Deacon 	};
2977c0e8b0cSWill Deacon 
29802017c1dSAndre Przywara 	switch (type) {
29902017c1dSAndre Przywara 	case IRQCHIP_GICV2:
30002017c1dSAndre Przywara 		compatible = "arm,cortex-a15-gic";
301bfb2c703SAndre Przywara 		reg_prop[2] = cpu_to_fdt64(ARM_GIC_CPUI_BASE);
302bfb2c703SAndre Przywara 		reg_prop[3] = cpu_to_fdt64(ARM_GIC_CPUI_SIZE);
303bfb2c703SAndre Przywara 		break;
30414421de9SAndre Przywara 	case IRQCHIP_GICV3_ITS:
30514421de9SAndre Przywara 		msi_compatible = "arm,gic-v3-its";
30614421de9SAndre Przywara 		/* fall-through */
307bfb2c703SAndre Przywara 	case IRQCHIP_GICV3:
308bfb2c703SAndre Przywara 		compatible = "arm,gic-v3";
309bfb2c703SAndre Przywara 		reg_prop[2] = cpu_to_fdt64(gic_redists_base);
310bfb2c703SAndre Przywara 		reg_prop[3] = cpu_to_fdt64(gic_redists_size);
31102017c1dSAndre Przywara 		break;
31202017c1dSAndre Przywara 	default:
31302017c1dSAndre Przywara 		return;
31402017c1dSAndre Przywara 	}
31502017c1dSAndre Przywara 
3167c0e8b0cSWill Deacon 	_FDT(fdt_begin_node(fdt, "intc"));
31702017c1dSAndre Przywara 	_FDT(fdt_property_string(fdt, "compatible", compatible));
3187c0e8b0cSWill Deacon 	_FDT(fdt_property_cell(fdt, "#interrupt-cells", GIC_FDT_IRQ_NUM_CELLS));
3197c0e8b0cSWill Deacon 	_FDT(fdt_property(fdt, "interrupt-controller", NULL, 0));
3207c0e8b0cSWill Deacon 	_FDT(fdt_property(fdt, "reg", reg_prop, sizeof(reg_prop)));
3210063d50cSAndre Przywara 	_FDT(fdt_property_cell(fdt, "phandle", PHANDLE_GIC));
32214421de9SAndre Przywara 	_FDT(fdt_property_cell(fdt, "#address-cells", 2));
32314421de9SAndre Przywara 	_FDT(fdt_property_cell(fdt, "#size-cells", 2));
32414421de9SAndre Przywara 
32514421de9SAndre Przywara 	if (msi_compatible) {
32614421de9SAndre Przywara 		_FDT(fdt_property(fdt, "ranges", NULL, 0));
32714421de9SAndre Przywara 
32814421de9SAndre Przywara 		_FDT(fdt_begin_node(fdt, "msic"));
32914421de9SAndre Przywara 		_FDT(fdt_property_string(fdt, "compatible", msi_compatible));
33014421de9SAndre Przywara 		_FDT(fdt_property(fdt, "msi-controller", NULL, 0));
33114421de9SAndre Przywara 		_FDT(fdt_property_cell(fdt, "phandle", PHANDLE_MSI));
33214421de9SAndre Przywara 		msi_prop[0] = cpu_to_fdt64(gic_msi_base);
33314421de9SAndre Przywara 		msi_prop[1] = cpu_to_fdt64(gic_msi_size);
33414421de9SAndre Przywara 		_FDT(fdt_property(fdt, "reg", msi_prop, sizeof(msi_prop)));
33514421de9SAndre Przywara 		_FDT(fdt_end_node(fdt));
33614421de9SAndre Przywara 	}
33714421de9SAndre Przywara 
3387c0e8b0cSWill Deacon 	_FDT(fdt_end_node(fdt));
3397c0e8b0cSWill Deacon }
3407c0e8b0cSWill Deacon 
3417c0e8b0cSWill Deacon #define KVM_IRQCHIP_IRQ(x) (KVM_ARM_IRQ_TYPE_SPI << KVM_ARM_IRQ_TYPE_SHIFT) |\
3427c0e8b0cSWill Deacon 			   ((x) & KVM_ARM_IRQ_NUM_MASK)
3437c0e8b0cSWill Deacon 
3447c0e8b0cSWill Deacon void kvm__irq_line(struct kvm *kvm, int irq, int level)
3457c0e8b0cSWill Deacon {
3467c0e8b0cSWill Deacon 	struct kvm_irq_level irq_level = {
3477c0e8b0cSWill Deacon 		.irq	= KVM_IRQCHIP_IRQ(irq),
3487c0e8b0cSWill Deacon 		.level	= !!level,
3497c0e8b0cSWill Deacon 	};
3507c0e8b0cSWill Deacon 
3517c0e8b0cSWill Deacon 	if (irq < GIC_SPI_IRQ_BASE || irq > GIC_MAX_IRQ)
3527c0e8b0cSWill Deacon 		pr_warning("Ignoring invalid GIC IRQ %d", irq);
3537c0e8b0cSWill Deacon 	else if (ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level) < 0)
3547c0e8b0cSWill Deacon 		pr_warning("Could not KVM_IRQ_LINE for irq %d", irq);
3557c0e8b0cSWill Deacon }
3567c0e8b0cSWill Deacon 
3577c0e8b0cSWill Deacon void kvm__irq_trigger(struct kvm *kvm, int irq)
3587c0e8b0cSWill Deacon {
3597c0e8b0cSWill Deacon 	kvm__irq_line(kvm, irq, VIRTIO_IRQ_HIGH);
3607c0e8b0cSWill Deacon 	kvm__irq_line(kvm, irq, VIRTIO_IRQ_LOW);
3617c0e8b0cSWill Deacon }
362