On Fri, 5 Jan 2024, Jiqian Chen wrote:
> In PVH dom0, it uses the linux local interrupt mechanism,
> when it allocs irq for a gsi, it is dynamic, and follow
> the principle of applying first, distributing first. And
> the irq number is alloced from small to large, but the
> applying gsi number is not, may gsi 38 comes before gsi
> 28, that causes the irq number is not equal with the gsi
> number. And when passthrough a device, qemu wants to use
> gsi to map pirq, xen_pt_realize->xc_physdev_map_pirq, but
> the gsi number is got from file
> /sys/bus/pci/devices//irq in current code, so it
> will fail when mapping.
>
> Add gsi into XenHostPCIDevice and use gsi number that
> read from gsi sysfs if it exists.
>
> Co-developed-by: Huang Rui
> Signed-off-by: Jiqian Chen
Reviewed-by: Stefano Stabellini
> ---
> hw/xen/xen-host-pci-device.c | 7 +++
> hw/xen/xen-host-pci-device.h | 1 +
> hw/xen/xen_pt.c | 6 +-
> 3 files changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/hw/xen/xen-host-pci-device.c b/hw/xen/xen-host-pci-device.c
> index 8c6e9a1716a2..5be3279aa25b 100644
> --- a/hw/xen/xen-host-pci-device.c
> +++ b/hw/xen/xen-host-pci-device.c
> @@ -370,6 +370,13 @@ void xen_host_pci_device_get(XenHostPCIDevice *d,
> uint16_t domain,
> }
> d->irq = v;
>
> +xen_host_pci_get_dec_value(d, "gsi", , errp);
> +if (*errp) {
> +d->gsi = -1;
> +} else {
> +d->gsi = v;
> +}
> +
> xen_host_pci_get_hex_value(d, "class", , errp);
> if (*errp) {
> goto error;
> diff --git a/hw/xen/xen-host-pci-device.h b/hw/xen/xen-host-pci-device.h
> index 4d8d34ecb024..74c552bb5548 100644
> --- a/hw/xen/xen-host-pci-device.h
> +++ b/hw/xen/xen-host-pci-device.h
> @@ -27,6 +27,7 @@ typedef struct XenHostPCIDevice {
> uint16_t device_id;
> uint32_t class_code;
> int irq;
> +int gsi;
>
> XenHostPCIIORegion io_regions[PCI_NUM_REGIONS - 1];
> XenHostPCIIORegion rom;
> diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
> index 36e6f93c372f..d448f3a17306 100644
> --- a/hw/xen/xen_pt.c
> +++ b/hw/xen/xen_pt.c
> @@ -839,7 +839,11 @@ static void xen_pt_realize(PCIDevice *d, Error **errp)
> goto out;
> }
>
> -machine_irq = s->real_device.irq;
> +if (s->real_device.gsi < 0) {
> +machine_irq = s->real_device.irq;
> +} else {
> +machine_irq = s->real_device.gsi;
> +}
> if (machine_irq == 0) {
> XEN_PT_LOG(d, "machine irq is 0\n");
> cmd |= PCI_COMMAND_INTX_DISABLE;
> --
> 2.34.1
>