diff mbox series

[kvm-unit-tests,RESEND] x86/intel-iommu: check if DMA translation is enabled before testing it

Message ID B5561618-963A-4750-A20C-03B937BE1CD6@amazon.de (mailing list archive)
State New, archived
Headers show
Series [kvm-unit-tests,RESEND] x86/intel-iommu: check if DMA translation is enabled before testing it | expand

Commit Message

Barzen, Benjamin Nov. 18, 2021, 9:51 a.m. UTC
From 74eaede66f7587bfb52a929bc553404a9a476392 Mon Sep 17 00:00:00 2001
From: Benjamin Barzen <bbarzen@amazon.de>
Date: Wed, 17 Nov 2021 11:40:58 +0000
Subject: [PATCH RESEND] x86/intel-iommu: check if DMA translation is enabled before testing it
 
Commit [1] to the Linux kernel allows for units where only interrupt
remapping is implemented. To signal this to the guest system, all SAGAW
bits of the DMAR capability register are set to 0. This commit checks that
at least one SAGAW bit is set before running DMA translation tests.
 
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c40aaaac10 
 
Signed-off-by: Benjamin Barzen <bbarzen@amazon.de>
---
lib/x86/intel-iommu.c |  7 +++++--
lib/x86/intel-iommu.h |  3 ++-
x86/intel-iommu.c     | 22 ++++++++++++++++------
3 files changed, 23 insertions(+), 9 deletions(-)
 
                pci_dev_print(&edu_dev.pci_dev);
-               vtd_test_dmar();
+               if (vtd_readq(DMAR_CAP_REG) & VTD_CAP_SAGAW) {
+                       vtd_test_dmar();
+               } else {
+                       report_skip(VTD_TEST_DMAR_4B);
+               }
                vtd_test_ir();
        }
-- 
2.32.0





Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879
diff mbox series

Patch

diff --git a/lib/x86/intel-iommu.c b/lib/x86/intel-iommu.c
index c811ba5..f6f5634 100644
--- a/lib/x86/intel-iommu.c
+++ b/lib/x86/intel-iommu.c
@@ -358,8 +358,11 @@  void vtd_init(void)
        vtd_dump_init_info();
        vtd_gcmd_or(VTD_GCMD_QI); /* Enable QI */
-       vtd_setup_root_table();
        vtd_setup_ir_table();
-       vtd_gcmd_or(VTD_GCMD_DMAR); /* Enable DMAR */
        vtd_gcmd_or(VTD_GCMD_IR);   /* Enable IR */
+
+       if(vtd_readq(DMAR_CAP_REG) & VTD_CAP_SAGAW){
+               vtd_setup_root_table();
+               vtd_gcmd_or(VTD_GCMD_DMAR); /* Enable DMAR */
+       }
}
diff --git a/lib/x86/intel-iommu.h b/lib/x86/intel-iommu.h
index e14f825..193d866 100644
--- a/lib/x86/intel-iommu.h
+++ b/lib/x86/intel-iommu.h
@@ -100,7 +100,8 @@ 
#define VTD_CAP_SAGAW_39bit         (0x2ULL << VTD_CAP_SAGAW_SHIFT)
/* 48-bit AGAW, 4-level page-table */
#define VTD_CAP_SAGAW_48bit         (0x4ULL << VTD_CAP_SAGAW_SHIFT)
-#define VTD_CAP_SAGAW               VTD_CAP_SAGAW_39bit
+/* All SAGAW bits */
+#define VTD_CAP_SAGAW               (0x1FULL << VTD_CAP_SAGAW_SHIFT)
 /* Both 1G/2M huge pages */
#define VTD_CAP_SLLPS               ((1ULL << 34) | (1ULL << 35))
diff --git a/x86/intel-iommu.c b/x86/intel-iommu.c
index 4442fe1..52f252e 100644
--- a/x86/intel-iommu.c
+++ b/x86/intel-iommu.c
@@ -140,14 +140,20 @@  int main(int argc, char *argv[])
        report(vtd_readl(DMAR_FSTS_REG) == 0, "fault status check");
        report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_QI, "QI enablement");
-       report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_ROOT, "DMAR table setup");
        report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_IR_TABLE, "IR table setup");
-       report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_DMAR, "DMAR enablement");
        report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_IR, "IR enablement");
-       report(vtd_readq(DMAR_CAP_REG) & VTD_CAP_SAGAW,
+
+       if (vtd_readq(DMAR_CAP_REG) & VTD_CAP_SAGAW) {
+               report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_ROOT, "DMAR table setup");
+               report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_DMAR, "DMAR enablement");
+               report(vtd_readq(DMAR_CAP_REG) & VTD_CAP_SAGAW_39bit,
               "DMAR support 39 bits address width");
-       report(vtd_readq(DMAR_CAP_REG) & VTD_CAP_SLLPS,
-              "DMAR support huge pages");
+               report(vtd_readq(DMAR_CAP_REG) & VTD_CAP_SLLPS,
+                       "DMAR support huge pages");
+       } else {
+               printf("DMAR marked as not implemented by machine,"
+                               " skipping DMAR setup and tests.\n");
+       }
        report_prefix_pop();
@@ -160,7 +166,11 @@  int main(int argc, char *argv[])
        } else {
                printf("Found EDU device:\n");