>>> On 17.01.17 at 16:08, <firemet...@users.sourceforge.net> wrote:
> But fortunately commenting out that line could still reproduce the IOMMU
> fault.
> I was lucky to capture the full log before it fills up my 100MB ring buffer
> (in less than 2 seconds).

So here's a first take at a debugging patch. I've tried to limit existing
output, so that you'd have better chance of again capturing all
interesting messages.

Jan

--- unstable.orig/xen/drivers/passthrough/vtd/iommu.c   2017-01-03 
10:55:55.000000000 +0100
+++ unstable/xen/drivers/passthrough/vtd/iommu.c        2017-01-19 
17:26:48.000000000 +0100
@@ -897,8 +897,23 @@ static int iommu_page_fault_do_one(struc
            kind, fault_reason, reason);
 
     if ( iommu_verbose && fault_type == DMA_REMAP )
+{//temp
+ static domid_t last;
+ static unsigned long cnt, thr;
+ const struct pci_dev*pdev;
+ pcidevs_lock();
+ pdev = pci_get_real_pdev(seg, PCI_BUS(source_id), PCI_DEVFN2(source_id));
+ if(pdev && pdev->domain && pdev->domain->domain_id > last) {
+  thr = cnt = 0;
+  last = pdev->domain->domain_id;
+ }
+ pcidevs_unlock();
+ if(++cnt > thr) {
+  thr |= cnt;
         print_vtd_entries(iommu, PCI_BUS(source_id), PCI_DEVFN2(source_id),
                           addr >> PAGE_SHIFT);
+ }
+}
 
     return 0;
 }
@@ -1890,6 +1905,7 @@ static void iommu_set_pgd(struct domain
 
 static int rmrr_identity_mapping(struct domain *d, bool_t map,
                                  const struct acpi_rmrr_unit *rmrr,
+u16 bdf,//temp
                                  u32 flag)
 {
     unsigned long base_pfn = rmrr->base_address >> PAGE_SHIFT_4K;
@@ -1914,6 +1930,7 @@ static int rmrr_identity_mapping(struct
             if ( map )
             {
                 ++mrmrr->count;
+printk(XENLOG_GUEST "d%d: RMRR [%lx,%lx] count %u\n", d->domain_id, base_pfn, 
end_pfn, mrmrr->count);//temp
                 return 0;
             }
 
@@ -1928,6 +1945,7 @@ static int rmrr_identity_mapping(struct
             }
 
             list_del(&mrmrr->list);
+printk(XENLOG_GUEST "d%d: RMRR [%lx,%lx] zapped (%d)\n", d->domain_id, 
mrmrr->base >> PAGE_SHIFT_4K, end_pfn, ret);//temp
             xfree(mrmrr);
             return ret;
         }
@@ -1941,11 +1959,30 @@ static int rmrr_identity_mapping(struct
         int err = set_identity_p2m_entry(d, base_pfn, p2m_access_rw, flag);
 
         if ( err )
+{//temp
+ printk(XENLOG_GUEST "d%d: RMRR [%lx,%lx] map error %d @ %lx\n", d->domain_id, 
rmrr->base_address >> PAGE_SHIFT_4K, end_pfn, err, base_pfn);
             return err;
+} else {
+ static domid_t last;
+ static unsigned long cnt, thr;
+ if(d->domain_id > last) {
+  thr = cnt = 0;
+  last = d->domain_id;
+ }
+ if(!(base_pfn & 0xff) && ++cnt > thr) {
+  const struct pci_dev*pdev = pci_get_pdev(rmrr->segment, PCI_BUS(bdf), 
PCI_DEVFN2(bdf));
+  const struct acpi_drhd_unit*drhd = pdev ? acpi_find_matched_drhd_unit(pdev) 
: NULL;
+  thr |= cnt;
+  printk(XENLOG_GUEST "d%d: RMRR [%lx,%lx] mapped %lx\n", d->domain_id, 
rmrr->base_address >> PAGE_SHIFT_4K, end_pfn, base_pfn);
+  if(drhd)
+   print_vtd_entries(drhd->iommu, PCI_BUS(bdf), PCI_DEVFN2(bdf), base_pfn);
+ }
+}
         base_pfn++;
     }
 
     mrmrr = xmalloc(struct mapped_rmrr);
+printk(XENLOG_GUEST "d%d: RMRR [%lx,%lx] alloc -> %p\n", d->domain_id, 
rmrr->base_address >> PAGE_SHIFT_4K, end_pfn, mrmrr);//temp
     if ( !mrmrr )
         return -ENOMEM;
     mrmrr->base = rmrr->base_address;
@@ -1987,7 +2024,7 @@ static int intel_iommu_add_device(u8 dev
              * Since RMRRs are always reserved in the e820 map for the hardware
              * domain, there shouldn't be a conflict.
              */
-            ret = rmrr_identity_mapping(pdev->domain, 1, rmrr, 0);
+            ret = rmrr_identity_mapping(pdev->domain, 1, rmrr, bdf, 0);
             if ( ret )
                 dprintk(XENLOG_ERR VTDPREFIX, "d%d: RMRR mapping failed\n",
                         pdev->domain->domain_id);
@@ -2032,7 +2069,7 @@ static int intel_iommu_remove_device(u8
          * Any flag is nothing to clear these mappings but here
          * its always safe and strict to set 0.
          */
-        rmrr_identity_mapping(pdev->domain, 0, rmrr, 0);
+        rmrr_identity_mapping(pdev->domain, 0, rmrr, bdf, 0);
     }
 
     return domain_context_unmap(pdev->domain, devfn, pdev);
@@ -2199,7 +2236,7 @@ static void __hwdom_init setup_hwdom_rmr
          * domain, there shouldn't be a conflict. So its always safe and
          * strict to set 0.
          */
-        ret = rmrr_identity_mapping(d, 1, rmrr, 0);
+        ret = rmrr_identity_mapping(d, 1, rmrr, bdf, 0);
         if ( ret )
             dprintk(XENLOG_ERR VTDPREFIX,
                      "IOMMU: mapping reserved region failed\n");
@@ -2356,7 +2393,7 @@ static int reassign_device_ownership(
                  * Any RMRR flag is always ignored when remove a device,
                  * but its always safe and strict to set 0.
                  */
-                ret = rmrr_identity_mapping(source, 0, rmrr, 0);
+                ret = rmrr_identity_mapping(source, 0, rmrr, bdf, 0);
                 if ( ret != -ENOENT )
                     return ret;
             }
@@ -2446,7 +2483,7 @@ static int intel_iommu_assign_device(
              PCI_BUS(bdf) == bus &&
              PCI_DEVFN2(bdf) == devfn )
         {
-            ret = rmrr_identity_mapping(d, 1, rmrr, flag);
+            ret = rmrr_identity_mapping(d, 1, rmrr, bdf, flag);
             if ( ret )
             {
                 reassign_device_ownership(d, hardware_domain, devfn, pdev);
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

Reply via email to