xref: /kvmtool/arm/gic.c (revision 69ae77c5567a2504deda1a4fc3b1fab4f89b5afb)
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 
13*69ae77c5SAndre Przywara #define IRQCHIP_GIC 0
14*69ae77c5SAndre 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;
2943d2781cSAndre Przywara 	} else {
3043d2781cSAndre Przywara 		pr_err("irqchip: unknown type \"%s\"\n", arg);
3143d2781cSAndre Przywara 		return -1;
3243d2781cSAndre Przywara 	}
3343d2781cSAndre Przywara 
3443d2781cSAndre Przywara 	return 0;
3543d2781cSAndre Przywara }
3643d2781cSAndre Przywara 
37*69ae77c5SAndre Przywara static int irq__routing_init(struct kvm *kvm)
38*69ae77c5SAndre Przywara {
39*69ae77c5SAndre Przywara 	int r;
40*69ae77c5SAndre Przywara 	int irqlines = ALIGN(irq__get_nr_allocated_lines(), 32);
41*69ae77c5SAndre Przywara 
42*69ae77c5SAndre Przywara 	/*
43*69ae77c5SAndre Przywara 	 * This describes the default routing that the kernel uses without
44*69ae77c5SAndre Przywara 	 * any routing explicitly set up via KVM_SET_GSI_ROUTING. So we
45*69ae77c5SAndre Przywara 	 * don't need to commit these setting right now. The first actual
46*69ae77c5SAndre Przywara 	 * user (MSI routing) will engage these mappings then.
47*69ae77c5SAndre Przywara 	 */
48*69ae77c5SAndre Przywara 	for (next_gsi = 0; next_gsi < irqlines; next_gsi++) {
49*69ae77c5SAndre Przywara 		r = irq__allocate_routing_entry();
50*69ae77c5SAndre Przywara 		if (r)
51*69ae77c5SAndre Przywara 			return r;
52*69ae77c5SAndre Przywara 
53*69ae77c5SAndre Przywara 		irq_routing->entries[irq_routing->nr++] =
54*69ae77c5SAndre Przywara 			(struct kvm_irq_routing_entry) {
55*69ae77c5SAndre Przywara 				.gsi = next_gsi,
56*69ae77c5SAndre Przywara 				.type = KVM_IRQ_ROUTING_IRQCHIP,
57*69ae77c5SAndre Przywara 				.u.irqchip.irqchip = IRQCHIP_GIC,
58*69ae77c5SAndre Przywara 				.u.irqchip.pin = next_gsi,
59*69ae77c5SAndre Przywara 		};
60*69ae77c5SAndre Przywara 	}
61*69ae77c5SAndre Przywara 
62*69ae77c5SAndre Przywara 	return 0;
63*69ae77c5SAndre Przywara }
64*69ae77c5SAndre Przywara 
6512ca1401SAndre Przywara static int gic__create_its_frame(struct kvm *kvm, u64 its_frame_addr)
6612ca1401SAndre Przywara {
6712ca1401SAndre Przywara 	struct kvm_create_device its_device = {
6812ca1401SAndre Przywara 		.type = KVM_DEV_TYPE_ARM_VGIC_ITS,
6912ca1401SAndre Przywara 		.flags	= 0,
7012ca1401SAndre Przywara 	};
7112ca1401SAndre Przywara 	struct kvm_device_attr its_attr = {
7212ca1401SAndre Przywara 		.group	= KVM_DEV_ARM_VGIC_GRP_ADDR,
7312ca1401SAndre Przywara 		.attr	= KVM_VGIC_ITS_ADDR_TYPE,
7412ca1401SAndre Przywara 		.addr	= (u64)(unsigned long)&its_frame_addr,
7512ca1401SAndre Przywara 	};
7612ca1401SAndre Przywara 	struct kvm_device_attr its_init_attr = {
7712ca1401SAndre Przywara 		.group	= KVM_DEV_ARM_VGIC_GRP_CTRL,
7812ca1401SAndre Przywara 		.attr	= KVM_DEV_ARM_VGIC_CTRL_INIT,
7912ca1401SAndre Przywara 	};
8012ca1401SAndre Przywara 	int err;
8112ca1401SAndre Przywara 
8212ca1401SAndre Przywara 	err = ioctl(kvm->vm_fd, KVM_CREATE_DEVICE, &its_device);
8312ca1401SAndre Przywara 	if (err) {
8412ca1401SAndre Przywara 		fprintf(stderr,
8512ca1401SAndre Przywara 			"GICv3 ITS requested, but kernel does not support it.\n");
8612ca1401SAndre Przywara 		fprintf(stderr, "Try --irqchip=gicv3 instead\n");
8712ca1401SAndre Przywara 		return err;
8812ca1401SAndre Przywara 	}
8912ca1401SAndre Przywara 
9012ca1401SAndre Przywara 	err = ioctl(its_device.fd, KVM_HAS_DEVICE_ATTR, &its_attr);
9112ca1401SAndre Przywara 	if (err) {
9212ca1401SAndre Przywara 		close(its_device.fd);
9312ca1401SAndre Przywara 		its_device.fd = -1;
9412ca1401SAndre Przywara 		return err;
9512ca1401SAndre Przywara 	}
9612ca1401SAndre Przywara 
9712ca1401SAndre Przywara 	err = ioctl(its_device.fd, KVM_SET_DEVICE_ATTR, &its_attr);
9812ca1401SAndre Przywara 	if (err)
9912ca1401SAndre Przywara 		return err;
10012ca1401SAndre Przywara 
10112ca1401SAndre Przywara 	return ioctl(its_device.fd, KVM_SET_DEVICE_ATTR, &its_init_attr);
10212ca1401SAndre Przywara }
10312ca1401SAndre Przywara 
10412ca1401SAndre Przywara static int gic__create_msi_frame(struct kvm *kvm, enum irqchip_type type,
10512ca1401SAndre Przywara 				 u64 msi_frame_addr)
10612ca1401SAndre Przywara {
10712ca1401SAndre Przywara 	switch (type) {
10812ca1401SAndre Przywara 	case IRQCHIP_GICV3_ITS:
10912ca1401SAndre Przywara 		return gic__create_its_frame(kvm, msi_frame_addr);
11012ca1401SAndre Przywara 	default:	/* No MSI frame needed */
11112ca1401SAndre Przywara 		return 0;
11212ca1401SAndre Przywara 	}
11312ca1401SAndre Przywara }
11412ca1401SAndre Przywara 
11502017c1dSAndre Przywara static int gic__create_device(struct kvm *kvm, enum irqchip_type type)
11669b9a17aSMarc Zyngier {
11769b9a17aSMarc Zyngier 	int err;
11869b9a17aSMarc Zyngier 	u64 cpu_if_addr = ARM_GIC_CPUI_BASE;
11969b9a17aSMarc Zyngier 	u64 dist_addr = ARM_GIC_DIST_BASE;
12069b9a17aSMarc Zyngier 	struct kvm_create_device gic_device = {
12102017c1dSAndre Przywara 		.flags	= 0,
12269b9a17aSMarc Zyngier 	};
12369b9a17aSMarc Zyngier 	struct kvm_device_attr cpu_if_attr = {
12469b9a17aSMarc Zyngier 		.group	= KVM_DEV_ARM_VGIC_GRP_ADDR,
12569b9a17aSMarc Zyngier 		.attr	= KVM_VGIC_V2_ADDR_TYPE_CPU,
12669b9a17aSMarc Zyngier 		.addr	= (u64)(unsigned long)&cpu_if_addr,
12769b9a17aSMarc Zyngier 	};
12869b9a17aSMarc Zyngier 	struct kvm_device_attr dist_attr = {
12969b9a17aSMarc Zyngier 		.group	= KVM_DEV_ARM_VGIC_GRP_ADDR,
13069b9a17aSMarc Zyngier 		.addr	= (u64)(unsigned long)&dist_addr,
13169b9a17aSMarc Zyngier 	};
132bfb2c703SAndre Przywara 	struct kvm_device_attr redist_attr = {
133bfb2c703SAndre Przywara 		.group	= KVM_DEV_ARM_VGIC_GRP_ADDR,
134bfb2c703SAndre Przywara 		.attr	= KVM_VGIC_V3_ADDR_TYPE_REDIST,
135bfb2c703SAndre Przywara 		.addr	= (u64)(unsigned long)&gic_redists_base,
136bfb2c703SAndre Przywara 	};
13769b9a17aSMarc Zyngier 
13802017c1dSAndre Przywara 	switch (type) {
13902017c1dSAndre Przywara 	case IRQCHIP_GICV2:
14002017c1dSAndre Przywara 		gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V2;
14102017c1dSAndre Przywara 		dist_attr.attr  = KVM_VGIC_V2_ADDR_TYPE_DIST;
14202017c1dSAndre Przywara 		break;
143bfb2c703SAndre Przywara 	case IRQCHIP_GICV3:
14412ca1401SAndre Przywara 	case IRQCHIP_GICV3_ITS:
145bfb2c703SAndre Przywara 		gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V3;
146bfb2c703SAndre Przywara 		dist_attr.attr  = KVM_VGIC_V3_ADDR_TYPE_DIST;
147bfb2c703SAndre Przywara 		break;
14802017c1dSAndre Przywara 	}
14902017c1dSAndre Przywara 
15069b9a17aSMarc Zyngier 	err = ioctl(kvm->vm_fd, KVM_CREATE_DEVICE, &gic_device);
15169b9a17aSMarc Zyngier 	if (err)
15269b9a17aSMarc Zyngier 		return err;
15369b9a17aSMarc Zyngier 
15469b9a17aSMarc Zyngier 	gic_fd = gic_device.fd;
15569b9a17aSMarc Zyngier 
15602017c1dSAndre Przywara 	switch (type) {
15702017c1dSAndre Przywara 	case IRQCHIP_GICV2:
15869b9a17aSMarc Zyngier 		err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &cpu_if_attr);
15902017c1dSAndre Przywara 		break;
16012ca1401SAndre Przywara 	case IRQCHIP_GICV3_ITS:
161bfb2c703SAndre Przywara 	case IRQCHIP_GICV3:
162bfb2c703SAndre Przywara 		err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &redist_attr);
163bfb2c703SAndre Przywara 		break;
16402017c1dSAndre Przywara 	}
16569b9a17aSMarc Zyngier 	if (err)
16669b9a17aSMarc Zyngier 		goto out_err;
16769b9a17aSMarc Zyngier 
16869b9a17aSMarc Zyngier 	err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &dist_attr);
16969b9a17aSMarc Zyngier 	if (err)
17069b9a17aSMarc Zyngier 		goto out_err;
17169b9a17aSMarc Zyngier 
17212ca1401SAndre Przywara 	err = gic__create_msi_frame(kvm, type, gic_msi_base);
17312ca1401SAndre Przywara 	if (err)
17412ca1401SAndre Przywara 		goto out_err;
17512ca1401SAndre Przywara 
17669b9a17aSMarc Zyngier 	return 0;
17769b9a17aSMarc Zyngier 
17869b9a17aSMarc Zyngier out_err:
17969b9a17aSMarc Zyngier 	close(gic_fd);
18069b9a17aSMarc Zyngier 	gic_fd = -1;
18169b9a17aSMarc Zyngier 	return err;
18269b9a17aSMarc Zyngier }
18369b9a17aSMarc Zyngier 
18469b9a17aSMarc Zyngier static int gic__create_irqchip(struct kvm *kvm)
1857c0e8b0cSWill Deacon {
1867c0e8b0cSWill Deacon 	int err;
187aa7a0e79SWill Deacon 	struct kvm_arm_device_addr gic_addr[] = {
1887c0e8b0cSWill Deacon 		[0] = {
189aa7a0e79SWill Deacon 			.id = KVM_VGIC_V2_ADDR_TYPE_DIST |
190aa7a0e79SWill Deacon 			(KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT),
1917c0e8b0cSWill Deacon 			.addr = ARM_GIC_DIST_BASE,
1927c0e8b0cSWill Deacon 		},
1937c0e8b0cSWill Deacon 		[1] = {
194aa7a0e79SWill Deacon 			.id = KVM_VGIC_V2_ADDR_TYPE_CPU |
195aa7a0e79SWill Deacon 			(KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT),
1967c0e8b0cSWill Deacon 			.addr = ARM_GIC_CPUI_BASE,
1977c0e8b0cSWill Deacon 		}
1987c0e8b0cSWill Deacon 	};
1997c0e8b0cSWill Deacon 
2007c0e8b0cSWill Deacon 	err = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP);
2017c0e8b0cSWill Deacon 	if (err)
2027c0e8b0cSWill Deacon 		return err;
2037c0e8b0cSWill Deacon 
204aa7a0e79SWill Deacon 	err = ioctl(kvm->vm_fd, KVM_ARM_SET_DEVICE_ADDR, &gic_addr[0]);
2057c0e8b0cSWill Deacon 	if (err)
2067c0e8b0cSWill Deacon 		return err;
2077c0e8b0cSWill Deacon 
208aa7a0e79SWill Deacon 	err = ioctl(kvm->vm_fd, KVM_ARM_SET_DEVICE_ADDR, &gic_addr[1]);
2097c0e8b0cSWill Deacon 	return err;
2107c0e8b0cSWill Deacon }
2117c0e8b0cSWill Deacon 
21202017c1dSAndre Przywara int gic__create(struct kvm *kvm, enum irqchip_type type)
21369b9a17aSMarc Zyngier {
21469b9a17aSMarc Zyngier 	int err;
21569b9a17aSMarc Zyngier 
21602017c1dSAndre Przywara 	switch (type) {
21702017c1dSAndre Przywara 	case IRQCHIP_GICV2:
21802017c1dSAndre Przywara 		break;
21912ca1401SAndre Przywara 	case IRQCHIP_GICV3_ITS:
22012ca1401SAndre Przywara 		/* We reserve the 64K page with the doorbell as well. */
22112ca1401SAndre Przywara 		gic_msi_size = KVM_VGIC_V3_ITS_SIZE + SZ_64K;
22212ca1401SAndre Przywara 		/* fall through */
223bfb2c703SAndre Przywara 	case IRQCHIP_GICV3:
224bfb2c703SAndre Przywara 		gic_redists_size = kvm->cfg.nrcpus * ARM_GIC_REDIST_SIZE;
225bfb2c703SAndre Przywara 		gic_redists_base = ARM_GIC_DIST_BASE - gic_redists_size;
22612ca1401SAndre Przywara 		gic_msi_base = gic_redists_base - gic_msi_size;
227bfb2c703SAndre Przywara 		break;
22802017c1dSAndre Przywara 	default:
22902017c1dSAndre Przywara 		return -ENODEV;
23002017c1dSAndre Przywara 	}
23102017c1dSAndre Przywara 
23269b9a17aSMarc Zyngier 	/* Try the new way first, and fallback on legacy method otherwise */
23302017c1dSAndre Przywara 	err = gic__create_device(kvm, type);
23402017c1dSAndre Przywara 	if (err && type == IRQCHIP_GICV2)
23569b9a17aSMarc Zyngier 		err = gic__create_irqchip(kvm);
23669b9a17aSMarc Zyngier 
23769b9a17aSMarc Zyngier 	return err;
23869b9a17aSMarc Zyngier }
23969b9a17aSMarc Zyngier 
240b5790302SAndre Przywara /*
241b5790302SAndre Przywara  * Sets the number of used interrupts and finalizes the GIC init explicitly.
242b5790302SAndre Przywara  */
243bed2bd9eSMarc Zyngier static int gic__init_gic(struct kvm *kvm)
244bed2bd9eSMarc Zyngier {
245b5790302SAndre Przywara 	int ret;
246b5790302SAndre Przywara 
247bed2bd9eSMarc Zyngier 	int lines = irq__get_nr_allocated_lines();
248bed2bd9eSMarc Zyngier 	u32 nr_irqs = ALIGN(lines, 32) + GIC_SPI_IRQ_BASE;
249bed2bd9eSMarc Zyngier 	struct kvm_device_attr nr_irqs_attr = {
250bed2bd9eSMarc Zyngier 		.group	= KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
251bed2bd9eSMarc Zyngier 		.addr	= (u64)(unsigned long)&nr_irqs,
252bed2bd9eSMarc Zyngier 	};
253b5790302SAndre Przywara 	struct kvm_device_attr vgic_init_attr = {
254b5790302SAndre Przywara 		.group	= KVM_DEV_ARM_VGIC_GRP_CTRL,
255b5790302SAndre Przywara 		.attr	= KVM_DEV_ARM_VGIC_CTRL_INIT,
256b5790302SAndre Przywara 	};
257bed2bd9eSMarc Zyngier 
258bed2bd9eSMarc Zyngier 	/*
259bed2bd9eSMarc Zyngier 	 * If we didn't use the KVM_CREATE_DEVICE method, KVM will
260b5790302SAndre Przywara 	 * give us some default number of interrupts. The GIC initialization
261b5790302SAndre Przywara 	 * will be done automatically in this case.
262bed2bd9eSMarc Zyngier 	 */
263bed2bd9eSMarc Zyngier 	if (gic_fd < 0)
264bed2bd9eSMarc Zyngier 		return 0;
265bed2bd9eSMarc Zyngier 
266b5790302SAndre Przywara 	if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, &nr_irqs_attr)) {
267b5790302SAndre Przywara 		ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &nr_irqs_attr);
268b5790302SAndre Przywara 		if (ret)
269b5790302SAndre Przywara 			return ret;
270b5790302SAndre Przywara 	}
271b5790302SAndre Przywara 
272*69ae77c5SAndre Przywara 	irq__routing_init(kvm);
273*69ae77c5SAndre Przywara 
274b5790302SAndre Przywara 	if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, &vgic_init_attr)) {
275b5790302SAndre Przywara 		ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &vgic_init_attr);
276b5790302SAndre Przywara 		if (ret)
277b5790302SAndre Przywara 			return ret;
278b5790302SAndre Przywara 	}
279bed2bd9eSMarc Zyngier 
280714ab9e6SAndre Przywara 	kvm->msix_needs_devid = kvm__supports_vm_extension(kvm,
281714ab9e6SAndre Przywara 							   KVM_CAP_MSI_DEVID);
282714ab9e6SAndre Przywara 
283bed2bd9eSMarc Zyngier 	return 0;
284bed2bd9eSMarc Zyngier }
285bed2bd9eSMarc Zyngier late_init(gic__init_gic)
286bed2bd9eSMarc Zyngier 
2870063d50cSAndre Przywara void gic__generate_fdt_nodes(void *fdt, enum irqchip_type type)
2887c0e8b0cSWill Deacon {
28914421de9SAndre Przywara 	const char *compatible, *msi_compatible = NULL;
29014421de9SAndre Przywara 	u64 msi_prop[2];
2917c0e8b0cSWill Deacon 	u64 reg_prop[] = {
2927c0e8b0cSWill Deacon 		cpu_to_fdt64(ARM_GIC_DIST_BASE), cpu_to_fdt64(ARM_GIC_DIST_SIZE),
293bfb2c703SAndre Przywara 		0, 0,				/* to be filled */
2947c0e8b0cSWill Deacon 	};
2957c0e8b0cSWill Deacon 
29602017c1dSAndre Przywara 	switch (type) {
29702017c1dSAndre Przywara 	case IRQCHIP_GICV2:
29802017c1dSAndre Przywara 		compatible = "arm,cortex-a15-gic";
299bfb2c703SAndre Przywara 		reg_prop[2] = cpu_to_fdt64(ARM_GIC_CPUI_BASE);
300bfb2c703SAndre Przywara 		reg_prop[3] = cpu_to_fdt64(ARM_GIC_CPUI_SIZE);
301bfb2c703SAndre Przywara 		break;
30214421de9SAndre Przywara 	case IRQCHIP_GICV3_ITS:
30314421de9SAndre Przywara 		msi_compatible = "arm,gic-v3-its";
30414421de9SAndre Przywara 		/* fall-through */
305bfb2c703SAndre Przywara 	case IRQCHIP_GICV3:
306bfb2c703SAndre Przywara 		compatible = "arm,gic-v3";
307bfb2c703SAndre Przywara 		reg_prop[2] = cpu_to_fdt64(gic_redists_base);
308bfb2c703SAndre Przywara 		reg_prop[3] = cpu_to_fdt64(gic_redists_size);
30902017c1dSAndre Przywara 		break;
31002017c1dSAndre Przywara 	default:
31102017c1dSAndre Przywara 		return;
31202017c1dSAndre Przywara 	}
31302017c1dSAndre Przywara 
3147c0e8b0cSWill Deacon 	_FDT(fdt_begin_node(fdt, "intc"));
31502017c1dSAndre Przywara 	_FDT(fdt_property_string(fdt, "compatible", compatible));
3167c0e8b0cSWill Deacon 	_FDT(fdt_property_cell(fdt, "#interrupt-cells", GIC_FDT_IRQ_NUM_CELLS));
3177c0e8b0cSWill Deacon 	_FDT(fdt_property(fdt, "interrupt-controller", NULL, 0));
3187c0e8b0cSWill Deacon 	_FDT(fdt_property(fdt, "reg", reg_prop, sizeof(reg_prop)));
3190063d50cSAndre Przywara 	_FDT(fdt_property_cell(fdt, "phandle", PHANDLE_GIC));
32014421de9SAndre Przywara 	_FDT(fdt_property_cell(fdt, "#address-cells", 2));
32114421de9SAndre Przywara 	_FDT(fdt_property_cell(fdt, "#size-cells", 2));
32214421de9SAndre Przywara 
32314421de9SAndre Przywara 	if (msi_compatible) {
32414421de9SAndre Przywara 		_FDT(fdt_property(fdt, "ranges", NULL, 0));
32514421de9SAndre Przywara 
32614421de9SAndre Przywara 		_FDT(fdt_begin_node(fdt, "msic"));
32714421de9SAndre Przywara 		_FDT(fdt_property_string(fdt, "compatible", msi_compatible));
32814421de9SAndre Przywara 		_FDT(fdt_property(fdt, "msi-controller", NULL, 0));
32914421de9SAndre Przywara 		_FDT(fdt_property_cell(fdt, "phandle", PHANDLE_MSI));
33014421de9SAndre Przywara 		msi_prop[0] = cpu_to_fdt64(gic_msi_base);
33114421de9SAndre Przywara 		msi_prop[1] = cpu_to_fdt64(gic_msi_size);
33214421de9SAndre Przywara 		_FDT(fdt_property(fdt, "reg", msi_prop, sizeof(msi_prop)));
33314421de9SAndre Przywara 		_FDT(fdt_end_node(fdt));
33414421de9SAndre Przywara 	}
33514421de9SAndre Przywara 
3367c0e8b0cSWill Deacon 	_FDT(fdt_end_node(fdt));
3377c0e8b0cSWill Deacon }
3387c0e8b0cSWill Deacon 
3397c0e8b0cSWill Deacon #define KVM_IRQCHIP_IRQ(x) (KVM_ARM_IRQ_TYPE_SPI << KVM_ARM_IRQ_TYPE_SHIFT) |\
3407c0e8b0cSWill Deacon 			   ((x) & KVM_ARM_IRQ_NUM_MASK)
3417c0e8b0cSWill Deacon 
3427c0e8b0cSWill Deacon void kvm__irq_line(struct kvm *kvm, int irq, int level)
3437c0e8b0cSWill Deacon {
3447c0e8b0cSWill Deacon 	struct kvm_irq_level irq_level = {
3457c0e8b0cSWill Deacon 		.irq	= KVM_IRQCHIP_IRQ(irq),
3467c0e8b0cSWill Deacon 		.level	= !!level,
3477c0e8b0cSWill Deacon 	};
3487c0e8b0cSWill Deacon 
3497c0e8b0cSWill Deacon 	if (irq < GIC_SPI_IRQ_BASE || irq > GIC_MAX_IRQ)
3507c0e8b0cSWill Deacon 		pr_warning("Ignoring invalid GIC IRQ %d", irq);
3517c0e8b0cSWill Deacon 	else if (ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level) < 0)
3527c0e8b0cSWill Deacon 		pr_warning("Could not KVM_IRQ_LINE for irq %d", irq);
3537c0e8b0cSWill Deacon }
3547c0e8b0cSWill Deacon 
3557c0e8b0cSWill Deacon void kvm__irq_trigger(struct kvm *kvm, int irq)
3567c0e8b0cSWill Deacon {
3577c0e8b0cSWill Deacon 	kvm__irq_line(kvm, irq, VIRTIO_IRQ_HIGH);
3587c0e8b0cSWill Deacon 	kvm__irq_line(kvm, irq, VIRTIO_IRQ_LOW);
3597c0e8b0cSWill Deacon }
360