--- 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);