On Thu, Aug 17, 2017 at 07:36:20PM +0200, Andreas Kinzler wrote:
> On Tue, 15 Aug 2017 11:55:10 +0200, Roger Pau Monné <roger....@citrix.com>
> wrote:
> > Could you please try the patch below and paste the output you get on
> > the Xen console?
> 
> Output is in attached file. Does it help?

Yes, thanks. I'm quite sure the problem is that MSIX table entries are
being unmasked before MSIX is enabled, and so Xen is not able to snoop
those writes.

Just to confirm, can you try the following two debug patches? One is
for the hypervisor, the other is for QEMU.

Thanks, Roger.
diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c
index a36692c313..87caef300a 100644
--- a/xen/arch/x86/hvm/vmsi.c
+++ b/xen/arch/x86/hvm/vmsi.c
@@ -329,6 +329,8 @@ static int msixtbl_write(struct vcpu *v, unsigned long 
address,
 
     ASSERT(msi_desc == desc->msi_desc);
    
+    printk("%smasking entry %#x\n",
+           (val & PCI_MSIX_VECTOR_BITMASK) ? "" : "un", nr_entry);
     guest_mask_msi_irq(desc, !!(val & PCI_MSIX_VECTOR_BITMASK));
 
 unlock:
@@ -430,6 +432,9 @@ static void add_msixtbl_entry(struct domain *d,
     entry->gtable = (unsigned long) gtable;
 
     list_add_rcu(&entry->list, &d->arch.hvm_domain.msixtbl_list);
+
+    printk("%04x:%02x:%02x.%u added to msixtbl list\n", pdev->seg, pdev->bus,
+            PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
 }
 
 static void free_msixtbl_entry(struct rcu_head *rcu)
@@ -510,8 +515,12 @@ out:
                  (gtable + msi_desc->msi_attrib.entry_nr *
                            PCI_MSIX_ENTRY_SIZE +
                   PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET) )
+            {
+                printk("msixtbl_pt_register: detected attempt to write to 
vector ctrl (entry %#x)\n",
+                       msi_desc->msi_attrib.entry_nr);
                 v->arch.hvm_vcpu.hvm_io.msix_unmask_address =
                     v->arch.hvm_vcpu.hvm_io.msix_snoop_address;
+            }
         }
     }
 
@@ -619,6 +628,7 @@ void msix_write_completion(struct vcpu *v)
         return;
 
     v->arch.hvm_vcpu.hvm_io.msix_unmask_address = 0;
+    printk("Detected MSI-X unmask in write completion\n");
     if ( msixtbl_write(v, ctrl_address, 4, 0) != X86EMUL_OKAY )
         gdprintk(XENLOG_WARNING, "MSI-X write completion failure\n");
 }
diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
index 77998f4fb3..0ca31c22e2 100644
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -980,6 +980,8 @@ static int msix_capability_init(struct pci_dev *dev,
 
         list_add_tail(&entry->list, &dev->msi_list);
         *desc = entry;
+        printk("%04x:%02x:%02x.%u added entry %#x to msi_list\n",
+               seg, bus, slot, func, msi->entry_nr);
     }
 
     if ( !msix->used_entries )
@@ -1297,6 +1299,18 @@ int pci_msi_conf_write_intercept(struct pci_dev *pdev, 
unsigned int reg,
             if ( reg != msix_control_reg(pos) || size != 2 )
                 return -EACCES;
 
+                printk("MSIX ctrl write. Enabled: %d Maskall: %d. "
+                       "Configured entries:\n",
+                       !!(*data & PCI_MSIX_FLAGS_ENABLE),
+                       !!(*data & PCI_MSIX_FLAGS_MASKALL));
+                list_for_each_entry( entry, &pdev->msi_list, list )
+                {
+                    printk("%#x host_masked: %d guest_masked: %d\n",
+                           entry->msi_attrib.entry_nr,
+                           entry->msi_attrib.host_masked,
+                           entry->msi_attrib.guest_masked);
+                }
+
             pdev->msix->guest_maskall = !!(*data & PCI_MSIX_FLAGS_MASKALL);
             if ( pdev->msix->host_maskall )
                 *data |= PCI_MSIX_FLAGS_MASKALL;
diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index 191d9caea1..c296cf682c 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -10,6 +10,7 @@ void xen_pt_log(const PCIDevice *d, const char *f, ...) 
GCC_FMT_ATTR(2, 3);
 
 #define XEN_PT_ERR(d, _f, _a...) xen_pt_log(d, "%s: Error: "_f, __func__, ##_a)
 
+#define XEN_PT_LOGGING_ENABLED 1
 #ifdef XEN_PT_LOGGING_ENABLED
 #  define XEN_PT_LOG(d, _f, _a...)  xen_pt_log(d, "%s: " _f, __func__, ##_a)
 #  define XEN_PT_WARN(d, _f, _a...) \
diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
index 1f04ec5eec..893ac06a80 100644
--- a/hw/xen/xen_pt_config_init.c
+++ b/hw/xen/xen_pt_config_init.c
@@ -1482,6 +1482,7 @@ static int 
xen_pt_msixctrl_reg_write(XenPCIPassthroughState *s,
     /* update MSI-X */
     if ((*val & PCI_MSIX_FLAGS_ENABLE)
         && !(*val & PCI_MSIX_FLAGS_MASKALL)) {
+        XEN_PT_LOG(&s->dev, "Enabling MSIX, setting up entries\n");
         xen_pt_msix_update(s);
     } else if (!(*val & PCI_MSIX_FLAGS_ENABLE) && s->msix->enabled) {
         xen_pt_msix_disable(s);
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
index dfb8d64654..2662eb1940 100644
--- a/hw/xen/xen_pt_msi.c
+++ b/hw/xen/xen_pt_msi.c
@@ -132,8 +132,9 @@ static int msi_msix_setup(XenPCIPassthroughState *s,
 
         if (is_msix) {
             table_base = s->msix->table_base;
+            XEN_PT_LOG(&s->dev, "Mapping PIRQ for MSIX entry %d\n",
+                       msix_entry);
         }
-
         rc = xc_physdev_map_pirq_msi(xen_xc, xen_domid, XEN_PT_AUTO_ASSIGN,
                                      ppirq, PCI_DEVFN(s->real_device.dev,
                                                       s->real_device.func),
@@ -345,6 +346,9 @@ static int xen_pt_msix_update_one(XenPCIPassthroughState 
*s, int entry_nr,
         entry->data = entry->latch(DATA);
     }
 
+    XEN_PT_LOG(&s->dev, "Setting up MSIX vector %d PIRQ: %d Masked: %d\n",
+               entry_nr, entry->pirq, vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT);
+
     rc = msi_msix_setup(s, entry->addr, entry->data, &pirq, true, entry_nr,
                         entry->pirq == XEN_PT_UNASSIGNED_PIRQ);
     if (rc) {
@@ -468,6 +472,10 @@ static void pci_msix_write(void *opaque, hwaddr addr,
         xen_pt_msix_update_one(s, entry_nr, *vec_ctrl);
     }
 
+    if (offset == PCI_MSIX_ENTRY_VECTOR_CTRL)
+        XEN_PT_LOG(&s->dev, "Write to MSIX table entry %u CTRL, masked: %d\n",
+                   entry_nr, !!(val & PCI_MSIX_ENTRY_CTRL_MASKBIT));
+
     set_entry_value(entry, offset, val);
 }
 
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

Reply via email to