|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [RFC PATCH v7 09/14] iommu: Provide 'X' debug key to dump IOMMU context infos
It is often useful to know the state of all contexts and what devices
are in it. It can also be used to know what device belong to which domains.
Signed-off-by: Teddy Astie <teddy.astie@xxxxxxxxxx>
---
v7: introduced
xen/drivers/passthrough/amd/iommu_init.c | 46 ++++++++++++++++++++++++
xen/drivers/passthrough/vtd/iommu.c | 45 ++++++++++++++++++++++-
2 files changed, 90 insertions(+), 1 deletion(-)
diff --git a/xen/drivers/passthrough/amd/iommu_init.c
b/xen/drivers/passthrough/amd/iommu_init.c
index bf32b6c718..1c38ac0369 100644
--- a/xen/drivers/passthrough/amd/iommu_init.c
+++ b/xen/drivers/passthrough/amd/iommu_init.c
@@ -1332,6 +1332,51 @@ static int __init cf_check amd_iommu_setup_device_table(
return 0;
}
+static void cf_check amd_dump_domain_iommu_contexts(struct domain *d)
+{
+ unsigned int i, iommu_no;
+ struct domain_iommu *hd = dom_iommu(d);
+ struct iommu_context *ctx;
+ struct pci_dev *pdev;
+
+ if (d == dom_io)
+ printk("d[IO] contexts\n");
+ else
+ printk("d%hu contexts\n", d->domain_id);
+
+ for (i = 0; i < (1 + hd->other_contexts.count); ++i)
+ {
+ if ( (ctx = iommu_get_context(d, i)) )
+ {
+ printk(" Context %d (%"PRI_mfn")\n", i,
+ mfn_x(page_to_mfn(ctx->arch.amd.root_table)));
+
+ for (iommu_no = 0; iommu_no < nr_amd_iommus; iommu_no++)
+ printk(" IOMMU %u (used=%lu; did=%hu)\n", iommu_no,
+ ctx->arch.amd.iommu_dev_cnt[iommu_no],
+ ctx->arch.amd.didmap[iommu_no]);
+
+ list_for_each_entry(pdev, &ctx->devices, context_list)
+ {
+ printk(" - %pp\n", &pdev->sbdf);
+ }
+
+ iommu_put_context(ctx);
+ }
+ }
+}
+
+static void cf_check amd_dump_iommu_contexts(unsigned char key)
+{
+ struct domain *d;
+
+ for_each_domain(d)
+ if (is_iommu_enabled(d))
+ amd_dump_domain_iommu_contexts(d);
+
+ amd_dump_domain_iommu_contexts(dom_io);
+}
+
/* Check whether SP5100 SATA Combined mode is on */
static bool __init amd_sp5100_erratum28(void)
{
@@ -1486,6 +1531,7 @@ int __init amd_iommu_init(bool xt)
register_keyhandler('V', &amd_iommu_dump_intremap_tables,
"dump IOMMU intremap tables", 0);
+ register_keyhandler('X', amd_dump_iommu_contexts, "dump iommu contexts",
1);
return 0;
error_out:
diff --git a/xen/drivers/passthrough/vtd/iommu.c
b/xen/drivers/passthrough/vtd/iommu.c
index 3319903297..a602edd755 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -1954,6 +1954,49 @@ static int __must_check init_vtd_hw(bool resume)
return iommu_flush_all();
}
+static void cf_check vtd_dump_domain_contexts(struct domain *d)
+{
+ unsigned int i, iommu_no;
+ struct pci_dev *pdev;
+ struct iommu_context *ctx;
+ struct domain_iommu *hd = dom_iommu(d);
+
+ if (d == dom_io)
+ printk("d[IO] contexts\n");
+ else
+ printk("d%hu contexts\n", d->domain_id);
+
+ for (i = 0; i < (1 + hd->other_contexts.count); ++i)
+ {
+ if ( (ctx = iommu_get_context(d, i)) )
+ {
+ printk(" Context %d (%"PRIx64")\n", i, ctx->arch.vtd.pgd_maddr);
+
+ for (iommu_no = 0; iommu_no < nr_iommus; iommu_no++)
+ printk(" IOMMU %u (used=%lu; did=%hu)\n", iommu_no,
+ ctx->arch.vtd.iommu_dev_cnt[iommu_no],
+ ctx->arch.vtd.didmap[iommu_no]);
+
+ list_for_each_entry(pdev, &ctx->devices, context_list)
+ {
+ printk(" - %pp\n", &pdev->sbdf);
+ }
+
+ iommu_put_context(ctx);
+ }
+ }
+}
+
+static void cf_check vtd_dump_contexts(unsigned char key)
+{
+ struct domain *d;
+
+ for_each_domain(d)
+ if (is_iommu_enabled(d))
+ vtd_dump_domain_contexts(d);
+
+ vtd_dump_domain_contexts(dom_io);
+}
static struct iommu_state {
uint32_t fectl;
@@ -2088,7 +2131,7 @@ static int __init cf_check vtd_setup(void)
iommu_ops.page_sizes |= large_sizes;
register_keyhandler('V', vtd_dump_iommu_info, "dump iommu info", 1);
-
+ register_keyhandler('X', vtd_dump_contexts, "dump iommu contexts", 1);
return 0;
error:
--
2.51.2
--
Teddy Astie | Vates XCP-ng Developer
XCP-ng & Xen Orchestra - Vates solutions
web: https://vates.tech
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |