mirror of
https://github.com/qemu/qemu.git
synced 2025-08-04 08:23:09 +00:00
xen/passthrough: use gsi to map pirq when dom0 is PVH
In PVH dom0, when passthrough a device to domU, QEMU code xen_pt_realize->xc_physdev_map_pirq wants to use gsi, but in current codes the gsi number is got from file /sys/bus/pci/devices/<sbdf>/irq, that is wrong, because irq is not equal with gsi, they are in different spaces, so pirq mapping fails. To solve above problem, use new interface of Xen, xc_pcidev_get_gsi to get gsi and use xc_physdev_map_pirq_gsi to map pirq when dom0 is PVH. Signed-off-by: Jiqian Chen <Jiqian.Chen@amd.com> Signed-off-by: Huang Rui <ray.huang@amd.com> Signed-off-by: Jiqian Chen <Jiqian.Chen@amd.com> Acked-by: Anthony PERARD <anthony@xenproject.org> Reviewed-by: Stewart Hildebrand <stewart.hildebrand@amd.com> Message-Id: <20241106061418.3655304-1-Jiqian.Chen@amd.com> Signed-off-by: Anthony PERARD <anthony.perard@vates.tech>
This commit is contained in:
parent
5136598e26
commit
cfcacbab38
@ -766,6 +766,57 @@ static void xen_pt_destroy(PCIDevice *d) {
|
|||||||
}
|
}
|
||||||
/* init */
|
/* init */
|
||||||
|
|
||||||
|
#if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 42000
|
||||||
|
static bool xen_pt_need_gsi(void)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int len;
|
||||||
|
/*
|
||||||
|
* The max length of guest_type is "PVH"+'\n'+'\0', it is 5,
|
||||||
|
* so here set the length of type to be twice.
|
||||||
|
*/
|
||||||
|
char type[10];
|
||||||
|
const char *guest_type = "/sys/hypervisor/guest_type";
|
||||||
|
|
||||||
|
fp = fopen(guest_type, "r");
|
||||||
|
if (!fp) {
|
||||||
|
error_report("Cannot open %s: %s", guest_type, strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fgets(type, sizeof(type), fp)) {
|
||||||
|
len = strlen(type);
|
||||||
|
if (len) {
|
||||||
|
type[len - 1] = '\0';
|
||||||
|
if (!strcmp(type, "PVH")) {
|
||||||
|
fclose(fp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xen_pt_map_pirq_for_gsi(PCIDevice *d, int *pirq)
|
||||||
|
{
|
||||||
|
int gsi;
|
||||||
|
XenPCIPassthroughState *s = XEN_PT_DEVICE(d);
|
||||||
|
|
||||||
|
gsi = xc_pcidev_get_gsi(xen_xc,
|
||||||
|
PCI_SBDF(s->real_device.domain,
|
||||||
|
s->real_device.bus,
|
||||||
|
s->real_device.dev,
|
||||||
|
s->real_device.func));
|
||||||
|
if (gsi >= 0) {
|
||||||
|
return xc_physdev_map_pirq_gsi(xen_xc, xen_domid, gsi, pirq);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gsi;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void xen_pt_realize(PCIDevice *d, Error **errp)
|
static void xen_pt_realize(PCIDevice *d, Error **errp)
|
||||||
{
|
{
|
||||||
ERRP_GUARD();
|
ERRP_GUARD();
|
||||||
@ -847,7 +898,16 @@ static void xen_pt_realize(PCIDevice *d, Error **errp)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 42000
|
||||||
|
if (xen_pt_need_gsi()) {
|
||||||
|
rc = xen_pt_map_pirq_for_gsi(d, &pirq);
|
||||||
|
} else {
|
||||||
rc = xc_physdev_map_pirq(xen_xc, xen_domid, machine_irq, &pirq);
|
rc = xc_physdev_map_pirq(xen_xc, xen_domid, machine_irq, &pirq);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
rc = xc_physdev_map_pirq(xen_xc, xen_domid, machine_irq, &pirq);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
XEN_PT_ERR(d, "Mapping machine irq %u to pirq %i failed, (err: %d)\n",
|
XEN_PT_ERR(d, "Mapping machine irq %u to pirq %i failed, (err: %d)\n",
|
||||||
machine_irq, pirq, errno);
|
machine_irq, pirq, errno);
|
||||||
|
@ -23,6 +23,10 @@ extern bool pci_available;
|
|||||||
#define PCI_SLOT_MAX 32
|
#define PCI_SLOT_MAX 32
|
||||||
#define PCI_FUNC_MAX 8
|
#define PCI_FUNC_MAX 8
|
||||||
|
|
||||||
|
#define PCI_SBDF(seg, bus, dev, func) \
|
||||||
|
((((uint32_t)(seg)) << 16) | \
|
||||||
|
(PCI_BUILD_BDF(bus, PCI_DEVFN(dev, func))))
|
||||||
|
|
||||||
/* Class, Vendor and Device IDs from Linux's pci_ids.h */
|
/* Class, Vendor and Device IDs from Linux's pci_ids.h */
|
||||||
#include "hw/pci/pci_ids.h"
|
#include "hw/pci/pci_ids.h"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user