>>> On 17.01.17 at 16:08, <[email protected]> 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
[email protected]
https://lists.xen.org/xen-devel