Qing He
2009-Apr-15 13:41 UTC
[Xen-devel] [PATCH 0/2] passthrough: guest MSI reconfiguration
This patchset enables guest MSI reconfiugration. It includes the following two patches. [PATCH 1/2] passthrough: allow pt_bind_irq for msi update [PATCH 2/2] ioemu: guest MSI config on disable The first one enables msi update in pt_bind_irq and the second one adds MSI update when MSI is disabled. It fixes MSI failure for some guest drivers, e.g. e1000e, who sets an msi test irqhandler using an alternative vector. Thanks, Qing _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Qing He
2009-Apr-15 13:41 UTC
[Xen-devel] [PATCH 1/2] passthrough: allow pt_bind_irq for msi update
This patch extends pt_bind_irq to handle the update of msi guest vector and flag. Unbind and rebind using separate hypercalls may not be viable sometime. For example, the guest may update MSI address/data on fly without disabling it first (e.g. change delivery/destination), implement these updates in such a way may result in interrupt loss. Signed-off-by: Qing He <qing.he@intel.com> --- diff -r accf139b2eb9 xen/drivers/passthrough/io.c --- a/xen/drivers/passthrough/io.c Mon Apr 06 21:12:33 2009 +0100 +++ b/xen/drivers/passthrough/io.c Wed Apr 15 17:22:11 2009 +0800 @@ -148,12 +148,23 @@ return rc; } } - else if (hvm_irq_dpci->mirq[pirq].gmsi.gvec != pt_irq_bind->u.msi.gvec - ||hvm_irq_dpci->msi_gvec_pirq[pt_irq_bind->u.msi.gvec] != pirq) + else + { + uint32_t mask = HVM_IRQ_DPCI_MACH_MSI | HVM_IRQ_DPCI_GUEST_MSI; + uint32_t old_gvec; - { - spin_unlock(&d->event_lock); - return -EBUSY; + if ( (hvm_irq_dpci->mirq[pirq].flags & mask) != mask) + { + spin_unlock(&d->event_lock); + return -EBUSY; + } + + /* if pirq is already mapped as vmsi, update the guest data/addr */ + old_gvec = hvm_irq_dpci->mirq[pirq].gmsi.gvec; + hvm_irq_dpci->msi_gvec_pirq[old_gvec] = 0; + hvm_irq_dpci->mirq[pirq].gmsi.gvec = pt_irq_bind->u.msi.gvec; + hvm_irq_dpci->mirq[pirq].gmsi.gflags = pt_irq_bind->u.msi.gflags; + hvm_irq_dpci->msi_gvec_pirq[pt_irq_bind->u.msi.gvec] = pirq; } } else _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
It''s possible for a guest to change the MSI vector or flags when MSI is disabled, after it''s first initialized. This patch handles the address and data update when it''s disabled. Signed-off-by: Qing He <qing.he@intel.com> --- diff --git a/hw/pass-through.c b/hw/pass-through.c index 95b4a47..030102d 100644 --- a/hw/pass-through.c +++ b/hw/pass-through.c @@ -3354,7 +3354,7 @@ static int pt_msgaddr32_reg_write(struct pt_dev *ptdev, /* update MSI */ if (cfg_entry->data != old_addr) { - if (ptdev->msi->flags & PCI_MSI_FLAGS_ENABLE) + if (ptdev->msi->flags & PT_MSI_MAPPED) pt_msi_update(ptdev); } @@ -3392,7 +3392,7 @@ static int pt_msgaddr64_reg_write(struct pt_dev *ptdev, /* update MSI */ if (cfg_entry->data != old_addr) { - if (ptdev->msi->flags & PCI_MSI_FLAGS_ENABLE) + if (ptdev->msi->flags & PT_MSI_MAPPED) pt_msi_update(ptdev); } @@ -3434,7 +3434,7 @@ static int pt_msgdata_reg_write(struct pt_dev *ptdev, /* update MSI */ if (cfg_entry->data != old_data) { - if (flags & PCI_MSI_FLAGS_ENABLE) + if (flags & PT_MSI_MAPPED) pt_msi_update(ptdev); } diff --git a/hw/pt-msi.c b/hw/pt-msi.c index d28038a..118f3c5 100644 --- a/hw/pt-msi.c +++ b/hw/pt-msi.c @@ -110,10 +110,6 @@ uint32_t __get_msi_gflags(uint32_t data, uint64_t addr) return result; } -/* - * Update msi mapping, usually called when MSI enabled, - * except the first time - */ int pt_msi_update(struct pt_dev *d) { uint8_t gvec = 0; @@ -125,7 +121,8 @@ int pt_msi_update(struct pt_dev *d) addr = (uint64_t)d->msi->addr_hi << 32 | d->msi->addr_lo; gflags = __get_msi_gflags(d->msi->data, addr); - PT_LOG("Update msi with pirq %x gvec %x\n", d->msi->pirq, gvec); + PT_LOG("Update msi with pirq %x gvec %x, gflag %x\n", + d->msi->pirq, gvec, gflags); return xc_domain_update_msi_irq(xc_handle, domid, gvec, d->msi->pirq, gflags, 0); } _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Qing He
2009-Apr-16 09:18 UTC
[Xen-devel] [PATCH 2/2][RESEND] ioemu: guest MSI config on disable
On Wed, 2009-04-15 at 21:41 +0800, Qing He wrote:> It''s possible for a guest to change the MSI vector or flags > when MSI is disabled, after it''s first initialized. This patch > handles the address and data update when it''s disabled. > > Signed-off-by: Qing He <qing.he@intel.com> > ---Just realized that I was not based on the latest code, here is the update patch, please ignore the previous one. --- diff --git a/hw/pass-through.c b/hw/pass-through.c index 11382fd..710acbf 100644 --- a/hw/pass-through.c +++ b/hw/pass-through.c @@ -3436,7 +3436,7 @@ static int pt_msgaddr32_reg_write(struct pt_dev *ptdev, /* update MSI */ if (cfg_entry->data != old_addr) { - if (ptdev->msi->flags & PCI_MSI_FLAGS_ENABLE) + if (ptdev->msi->flags & PT_MSI_MAPPED) pt_msi_update(ptdev); } @@ -3474,7 +3474,7 @@ static int pt_msgaddr64_reg_write(struct pt_dev *ptdev, /* update MSI */ if (cfg_entry->data != old_addr) { - if (ptdev->msi->flags & PCI_MSI_FLAGS_ENABLE) + if (ptdev->msi->flags & PT_MSI_MAPPED) pt_msi_update(ptdev); } @@ -3516,7 +3516,7 @@ static int pt_msgdata_reg_write(struct pt_dev *ptdev, /* update MSI */ if (cfg_entry->data != old_data) { - if (flags & PCI_MSI_FLAGS_ENABLE) + if (flags & PT_MSI_MAPPED) pt_msi_update(ptdev); } diff --git a/hw/pt-msi.c b/hw/pt-msi.c index 4a54ba3..9f4a3b3 100644 --- a/hw/pt-msi.c +++ b/hw/pt-msi.c @@ -110,10 +110,6 @@ uint32_t __get_msi_gflags(uint32_t data, uint64_t addr) return result; } -/* - * Update msi mapping, usually called when MSI enabled, - * except the first time - */ int pt_msi_update(struct pt_dev *d) { uint8_t gvec = 0; @@ -126,7 +122,8 @@ int pt_msi_update(struct pt_dev *d) addr = (uint64_t)d->msi->addr_hi << 32 | d->msi->addr_lo; gflags = __get_msi_gflags(d->msi->data, addr); - PT_LOG("Update msi with pirq %x gvec %x\n", d->msi->pirq, gvec); + PT_LOG("Update msi with pirq %x gvec %x gflags %x\n", + d->msi->pirq, gvec, gflags); ret = xc_domain_update_msi_irq(xc_handle, domid, gvec, d->msi->pirq, gflags, 0); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel