Use the VFIO device property API to retrieve interrupt information (type and flags) during device node creation. Signed-off-by: Baptiste Reynal <b.reynal@xxxxxxxxxxxxxxxxxxxxxx> --- v1 -> v2: check irq_prop->data size add some comments --- hw/arm/sysbus-fdt.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c index 0c9d59a..c3b3d97 100644 --- a/hw/arm/sysbus-fdt.c +++ b/hw/arm/sysbus-fdt.c @@ -31,6 +31,7 @@ #include "hw/vfio/vfio-pl330.h" #include <libfdt.h> +#include <linux/vfio.h> /* * internal struct that contains the information to create dynamic @@ -64,9 +65,10 @@ typedef struct NodeCreationPair { * set_interrupts_fdt_node * * Helper function, generate interrupts property for a given node + * based on the host device tree */ static int set_interrupts_fdt_node(char *nodename, SysBusDevice *sbdev, - void *opaque, int type, int flags) + void *opaque) { PlatformBusFDTData *data = opaque; PlatformBusDevice *pbus = data->pbus; @@ -76,15 +78,23 @@ static int set_interrupts_fdt_node(char *nodename, SysBusDevice *sbdev, int i, ret; VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev); VFIODevice *vbasedev = &vdev->vbasedev; + struct vfio_dev_property *irq_prop; + + irq_prop = vfio_get_dev_property(vbasedev->fd, "interrupts", + VFIO_DEV_PROPERTY_TYPE_U32); + + if (irq_prop == NULL || irq_prop->length < vbasedev->num_irqs * 3) { + return -1; + } irq_attr = g_new(uint32_t, vbasedev->num_irqs*3); for (i = 0; i < vbasedev->num_irqs; i++) { irq_number = platform_bus_get_irqn(pbus, sbdev , i) - + data->irq_start; - irq_attr[3*i] = cpu_to_be32(type); + + data->irq_start; + irq_attr[3*i] = cpu_to_be32(((__u32 *) irq_prop->data)[3*i]); irq_attr[3*i+1] = cpu_to_be32(irq_number); - irq_attr[3*i+2] = cpu_to_be32(flags); + irq_attr[3*i+2] = cpu_to_be32(((__u32 *) irq_prop->data)[3*i+2]); } ret = qemu_fdt_setprop(fdt, nodename, "interrupts", @@ -94,6 +104,7 @@ static int set_interrupts_fdt_node(char *nodename, SysBusDevice *sbdev, error_report("could not set interrupts property of node %s", nodename); } g_free(irq_attr); + g_free(irq_prop); return ret; } @@ -173,7 +184,7 @@ static int add_calxeda_midway_xgmac_fdt_node(SysBusDevice *sbdev, void *opaque) goto fail; } - ret = set_interrupts_fdt_node(nodename, sbdev, opaque, 0, 0x4); + ret = set_interrupts_fdt_node(nodename, sbdev, opaque); if (ret < 0) { goto fail; @@ -253,7 +264,7 @@ static int add_arm_pl330_fdt_node(SysBusDevice *sbdev, void *opaque) goto fail; } - ret = set_interrupts_fdt_node(nodename, sbdev, opaque, 0, 0x4); + ret = set_interrupts_fdt_node(nodename, sbdev, opaque); if (ret < 0) { error_report("could not set interrupts property of node %s", -- 2.3.0 _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm