All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V3 0/3] Add debugfs support to show scalable mode DMAR table
@ 2019-05-24 23:40 Sai Praneeth Prakhya
  2019-05-24 23:40 ` [PATCH V3 1/3] iommu/vt-d: Modify the format of intel DMAR tables dump Sai Praneeth Prakhya
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Sai Praneeth Prakhya @ 2019-05-24 23:40 UTC (permalink / raw)
  To: iommu; +Cc: Ashok Raj, Andy Shevchenko, David Woodhouse

Presently, "/sys/kernel/debug/iommu/intel/dmar_translation_struct" file dumps
only legacy DMAR table which consists of root table and context table. Scalable
mode DMAR table adds PASID directory and PASID table. Hence, add support to dump
these tables as well.

Directly extending the present dumping format for PASID tables will make the
output look clumsy. Hence, the first patch modifies the present format to a
tabular format. The second patch introduces macros that are used during PASID
table walk and the third patch actually adds support to dump scalable mode DMAR
table.

Changes from V1 to V2:
----------------------
1. Make my name consistent in "From" and "Signed-off-by"
2. Fix comment regarding scalable mode context entries
3. Add reviewed by tags

Changes from V2 to V3:
----------------------
Presently, for V2 patches if kernel command line argument "iommu=pt" is passed,
dumping DMAR table seg faults. This happens because in pass through mode (for
non-scalable DMAR's) 3rd bit of context entry is set and it is misinterpreted as
PASID enabled by debugfs code and hence tries to dereference PASID directory
pointer which leads to seg fault (PASID directory pointer is undefined for
non-scalable DMAR's). To fix this, dereference PASID directory pointer only when
1. PASID is supported and
2. PASID is enabled.

This patch is tested on
1. Non-scalable DMAR with and without iommu=pt
2. Scalable DMAR with and without iommu=pt

Sai Praneeth Prakhya (3):
  iommu/vt-d: Modify the format of intel DMAR tables dump
  iommu/vt-d: Introduce macros useful for dumping DMAR table
  iommu/vt-d: Add debugfs support to show scalable mode DMAR table
    internals

 drivers/iommu/intel-iommu-debugfs.c | 137 +++++++++++++++++++++++++++++-------
 drivers/iommu/intel-iommu.c         |   6 +-
 drivers/iommu/intel-pasid.c         |  17 -----
 drivers/iommu/intel-pasid.h         |  26 +++++++
 include/linux/intel-iommu.h         |   6 ++
 5 files changed, 146 insertions(+), 46 deletions(-)

Cc: Joerg Roedel <joro@8bytes.org>
Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Lu Baolu <baolu.lu@linux.intel.com>
Cc: Sohil Mehta <sohil.mehta@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Jacob Pan <jacob.jun.pan@linux.intel.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>

-- 
2.7.4

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH V3 1/3] iommu/vt-d: Modify the format of intel DMAR tables dump
  2019-05-24 23:40 [PATCH V3 0/3] Add debugfs support to show scalable mode DMAR table Sai Praneeth Prakhya
@ 2019-05-24 23:40 ` Sai Praneeth Prakhya
  2019-05-24 23:40 ` [PATCH V3 2/3] iommu/vt-d: Introduce macros useful for dumping DMAR table Sai Praneeth Prakhya
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Sai Praneeth Prakhya @ 2019-05-24 23:40 UTC (permalink / raw)
  To: iommu; +Cc: Ashok Raj, Andy Shevchenko, David Woodhouse

Presently, "/sys/kernel/debug/iommu/intel/dmar_translation_struct" file
dumps DMAR tables in the below format

IOMMU dmar2: Root Table Address:4362cc000
Root Table Entries:
 Bus: 0 H: 0 L: 4362f0001
 Context Table Entries for Bus: 0
  Entry	B:D.F	High	Low
  160   00:14.0	102     4362ef001
  184   00:17.0	302     435ec4001
  248   00:1f.0	202     436300001

This format has few short comings like
1. When extended for dumping scalable mode DMAR table it will quickly be
   very clumsy, making it unreadable.
2. It has information like the Bus number and Entry which are basically
   part of B:D.F, hence are a repetition and are not so useful.

So, change it to a new format which could be easily extended to dump
scalable mode DMAR table. The new format looks as below:

IOMMU dmar2: Root Table Address: 0x436f7d000
B.D.F	Root_entry				Context_entry
00:14.0	0x0000000000000000:0x0000000436fbd001	0x0000000000000102:0x0000000436fbc001
00:17.0	0x0000000000000000:0x0000000436fbd001	0x0000000000000302:0x0000000436af4001
00:1f.0	0x0000000000000000:0x0000000436fbd001	0x0000000000000202:0x0000000436fcd001

Cc: Joerg Roedel <joro@8bytes.org>
Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Lu Baolu <baolu.lu@linux.intel.com>
Cc: Sohil Mehta <sohil.mehta@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Jacob Pan <jacob.jun.pan@linux.intel.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>
---
 drivers/iommu/intel-iommu-debugfs.c | 65 +++++++++++++++++++++++--------------
 1 file changed, 41 insertions(+), 24 deletions(-)

diff --git a/drivers/iommu/intel-iommu-debugfs.c b/drivers/iommu/intel-iommu-debugfs.c
index 7fabf9b1c2dc..3f5399b5e6c0 100644
--- a/drivers/iommu/intel-iommu-debugfs.c
+++ b/drivers/iommu/intel-iommu-debugfs.c
@@ -14,6 +14,13 @@
 
 #include <asm/irq_remapping.h>
 
+struct tbl_walk {
+	u16 bus;
+	u16 devfn;
+	struct root_entry *rt_entry;
+	struct context_entry *ctx_entry;
+};
+
 struct iommu_regset {
 	int offset;
 	const char *regs;
@@ -131,16 +138,25 @@ static int iommu_regset_show(struct seq_file *m, void *unused)
 }
 DEFINE_SHOW_ATTRIBUTE(iommu_regset);
 
-static void ctx_tbl_entry_show(struct seq_file *m, struct intel_iommu *iommu,
-			       int bus)
+static inline void print_tbl_walk(struct seq_file *m)
 {
-	struct context_entry *context;
-	int devfn;
+	struct tbl_walk *tbl_wlk = m->private;
 
-	seq_printf(m, " Context Table Entries for Bus: %d\n", bus);
-	seq_puts(m, "  Entry\tB:D.F\tHigh\tLow\n");
+	seq_printf(m, "%02x:%02x.%x\t0x%016llx:0x%016llx\t0x%016llx:0x%016llx\n",
+		   tbl_wlk->bus, PCI_SLOT(tbl_wlk->devfn),
+		   PCI_FUNC(tbl_wlk->devfn), tbl_wlk->rt_entry->hi,
+		   tbl_wlk->rt_entry->lo, tbl_wlk->ctx_entry->hi,
+		   tbl_wlk->ctx_entry->lo);
+}
+
+static void ctx_tbl_walk(struct seq_file *m, struct intel_iommu *iommu, u16 bus)
+{
+	struct context_entry *context;
+	u16 devfn;
 
 	for (devfn = 0; devfn < 256; devfn++) {
+		struct tbl_walk tbl_wlk = {0};
+
 		context = iommu_context_addr(iommu, bus, devfn, 0);
 		if (!context)
 			return;
@@ -148,33 +164,34 @@ static void ctx_tbl_entry_show(struct seq_file *m, struct intel_iommu *iommu,
 		if (!context_present(context))
 			continue;
 
-		seq_printf(m, "  %-5d\t%02x:%02x.%x\t%-6llx\t%llx\n", devfn,
-			   bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-			   context[0].hi, context[0].lo);
+		tbl_wlk.bus = bus;
+		tbl_wlk.devfn = devfn;
+		tbl_wlk.rt_entry = &iommu->root_entry[bus];
+		tbl_wlk.ctx_entry = context;
+		m->private = &tbl_wlk;
+
+		print_tbl_walk(m);
 	}
 }
 
-static void root_tbl_entry_show(struct seq_file *m, struct intel_iommu *iommu)
+static void root_tbl_walk(struct seq_file *m, struct intel_iommu *iommu)
 {
 	unsigned long flags;
-	int bus;
+	u16 bus;
 
 	spin_lock_irqsave(&iommu->lock, flags);
-	seq_printf(m, "IOMMU %s: Root Table Address:%llx\n", iommu->name,
+	seq_printf(m, "IOMMU %s: Root Table Address: 0x%llx\n", iommu->name,
 		   (u64)virt_to_phys(iommu->root_entry));
-	seq_puts(m, "Root Table Entries:\n");
-
-	for (bus = 0; bus < 256; bus++) {
-		if (!(iommu->root_entry[bus].lo & 1))
-			continue;
+	seq_puts(m, "B.D.F\tRoot_entry\t\t\t\tContext_entry\n");
 
-		seq_printf(m, " Bus: %d H: %llx L: %llx\n", bus,
-			   iommu->root_entry[bus].hi,
-			   iommu->root_entry[bus].lo);
+	/*
+	 * No need to check if the root entry is present or not because
+	 * iommu_context_addr() performs the same check before returning
+	 * context entry.
+	 */
+	for (bus = 0; bus < 256; bus++)
+		ctx_tbl_walk(m, iommu, bus);
 
-		ctx_tbl_entry_show(m, iommu, bus);
-		seq_putc(m, '\n');
-	}
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
@@ -185,7 +202,7 @@ static int dmar_translation_struct_show(struct seq_file *m, void *unused)
 
 	rcu_read_lock();
 	for_each_active_iommu(iommu, drhd) {
-		root_tbl_entry_show(m, iommu);
+		root_tbl_walk(m, iommu);
 		seq_putc(m, '\n');
 	}
 	rcu_read_unlock();
-- 
2.7.4

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH V3 2/3] iommu/vt-d: Introduce macros useful for dumping DMAR table
  2019-05-24 23:40 [PATCH V3 0/3] Add debugfs support to show scalable mode DMAR table Sai Praneeth Prakhya
  2019-05-24 23:40 ` [PATCH V3 1/3] iommu/vt-d: Modify the format of intel DMAR tables dump Sai Praneeth Prakhya
@ 2019-05-24 23:40 ` Sai Praneeth Prakhya
  2019-05-24 23:40 ` [PATCH V3 3/3] iommu/vt-d: Add debugfs support to show scalable mode DMAR table internals Sai Praneeth Prakhya
  2019-05-27 14:16 ` [PATCH V3 0/3] Add debugfs support to show scalable mode DMAR table Joerg Roedel
  3 siblings, 0 replies; 6+ messages in thread
From: Sai Praneeth Prakhya @ 2019-05-24 23:40 UTC (permalink / raw)
  To: iommu; +Cc: Ashok Raj, Andy Shevchenko, David Woodhouse

A scalable mode DMAR table walk would involve looking at bits in each stage
of walk, like,
1. Is PASID enabled in the context entry?
2. What's the size of PASID directory?
3. Is the PASID directory entry present?
4. Is the PASID table entry present?
5. Number of PASID table entries?

Hence, add these macros that will later be used during this walk.
Apart from adding new macros, move existing macros (like
pasid_pde_is_present(), get_pasid_table_from_pde() and pasid_supported())
to appropriate header files so that they could be reused.

Cc: Joerg Roedel <joro@8bytes.org>
Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Lu Baolu <baolu.lu@linux.intel.com>
Cc: Sohil Mehta <sohil.mehta@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Jacob Pan <jacob.jun.pan@linux.intel.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>
---
 drivers/iommu/intel-iommu.c |  6 +-----
 drivers/iommu/intel-pasid.c | 17 -----------------
 drivers/iommu/intel-pasid.h | 26 ++++++++++++++++++++++++++
 include/linux/intel-iommu.h |  6 ++++++
 4 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index a209199f3af6..f284732fe62b 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -357,6 +357,7 @@ int dmar_disabled = 0;
 int dmar_disabled = 1;
 #endif /*CONFIG_INTEL_IOMMU_DEFAULT_ON*/
 
+int intel_iommu_sm;
 int intel_iommu_enabled = 0;
 EXPORT_SYMBOL_GPL(intel_iommu_enabled);
 
@@ -364,17 +365,12 @@ static int dmar_map_gfx = 1;
 static int dmar_forcedac;
 static int intel_iommu_strict;
 static int intel_iommu_superpage = 1;
-static int intel_iommu_sm;
 static int iommu_identity_mapping;
 
 #define IDENTMAP_ALL		1
 #define IDENTMAP_GFX		2
 #define IDENTMAP_AZALIA		4
 
-#define sm_supported(iommu)	(intel_iommu_sm && ecap_smts((iommu)->ecap))
-#define pasid_supported(iommu)	(sm_supported(iommu) &&			\
-				 ecap_pasid((iommu)->ecap))
-
 int intel_iommu_gfx_mapped;
 EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
 
diff --git a/drivers/iommu/intel-pasid.c b/drivers/iommu/intel-pasid.c
index 2fefeafda437..6895a23b2157 100644
--- a/drivers/iommu/intel-pasid.c
+++ b/drivers/iommu/intel-pasid.c
@@ -169,23 +169,6 @@ int intel_pasid_alloc_table(struct device *dev)
 	return 0;
 }
 
-/* Get PRESENT bit of a PASID directory entry. */
-static inline bool
-pasid_pde_is_present(struct pasid_dir_entry *pde)
-{
-	return READ_ONCE(pde->val) & PASID_PTE_PRESENT;
-}
-
-/* Get PASID table from a PASID directory entry. */
-static inline struct pasid_entry *
-get_pasid_table_from_pde(struct pasid_dir_entry *pde)
-{
-	if (!pasid_pde_is_present(pde))
-		return NULL;
-
-	return phys_to_virt(READ_ONCE(pde->val) & PDE_PFN_MASK);
-}
-
 void intel_pasid_free_table(struct device *dev)
 {
 	struct device_domain_info *info;
diff --git a/drivers/iommu/intel-pasid.h b/drivers/iommu/intel-pasid.h
index 23537b3f34e3..fc8cd8f17de1 100644
--- a/drivers/iommu/intel-pasid.h
+++ b/drivers/iommu/intel-pasid.h
@@ -18,6 +18,10 @@
 #define PDE_PFN_MASK			PAGE_MASK
 #define PASID_PDE_SHIFT			6
 #define MAX_NR_PASID_BITS		20
+#define PASID_TBL_ENTRIES		BIT(PASID_PDE_SHIFT)
+
+#define is_pasid_enabled(entry)		(((entry)->lo >> 3) & 0x1)
+#define get_pasid_dir_size(entry)	(1 << ((((entry)->lo >> 9) & 0x7) + 7))
 
 /*
  * Domain ID reserved for pasid entries programmed for first-level
@@ -49,6 +53,28 @@ struct pasid_table {
 	struct list_head	dev;		/* device list */
 };
 
+/* Get PRESENT bit of a PASID directory entry. */
+static inline bool pasid_pde_is_present(struct pasid_dir_entry *pde)
+{
+	return READ_ONCE(pde->val) & PASID_PTE_PRESENT;
+}
+
+/* Get PASID table from a PASID directory entry. */
+static inline struct pasid_entry *
+get_pasid_table_from_pde(struct pasid_dir_entry *pde)
+{
+	if (!pasid_pde_is_present(pde))
+		return NULL;
+
+	return phys_to_virt(READ_ONCE(pde->val) & PDE_PFN_MASK);
+}
+
+/* Get PRESENT bit of a PASID table entry. */
+static inline bool pasid_pte_is_present(struct pasid_entry *pte)
+{
+	return READ_ONCE(pte->val[0]) & PASID_PTE_PRESENT;
+}
+
 extern u32 intel_pasid_max_id;
 int intel_pasid_alloc_id(void *ptr, int start, int end, gfp_t gfp);
 void intel_pasid_free_id(int pasid);
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 6925a18a5ca3..4140726867a9 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -447,6 +447,12 @@ enum {
 #define VTD_FLAG_TRANS_PRE_ENABLED	(1 << 0)
 #define VTD_FLAG_IRQ_REMAP_PRE_ENABLED	(1 << 1)
 
+extern int intel_iommu_sm;
+
+#define sm_supported(iommu)	(intel_iommu_sm && ecap_smts((iommu)->ecap))
+#define pasid_supported(iommu)	(sm_supported(iommu) &&			\
+				 ecap_pasid((iommu)->ecap))
+
 struct pasid_entry;
 struct pasid_state_entry;
 struct page_req_dsc;
-- 
2.7.4

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH V3 3/3] iommu/vt-d: Add debugfs support to show scalable mode DMAR table internals
  2019-05-24 23:40 [PATCH V3 0/3] Add debugfs support to show scalable mode DMAR table Sai Praneeth Prakhya
  2019-05-24 23:40 ` [PATCH V3 1/3] iommu/vt-d: Modify the format of intel DMAR tables dump Sai Praneeth Prakhya
  2019-05-24 23:40 ` [PATCH V3 2/3] iommu/vt-d: Introduce macros useful for dumping DMAR table Sai Praneeth Prakhya
@ 2019-05-24 23:40 ` Sai Praneeth Prakhya
  2019-05-27 14:16 ` [PATCH V3 0/3] Add debugfs support to show scalable mode DMAR table Joerg Roedel
  3 siblings, 0 replies; 6+ messages in thread
From: Sai Praneeth Prakhya @ 2019-05-24 23:40 UTC (permalink / raw)
  To: iommu; +Cc: Ashok Raj, Andy Shevchenko, David Woodhouse

A DMAR table walk would typically follow the below process.
1. Bus number is used to index into root table which points to a context
   table.
2. Device number and Function number are used together to index into
   context table which then points to a pasid directory.
3. PASID[19:6] is used to index into PASID directory which points to a
   PASID table.
4. PASID[5:0] is used to index into PASID table which points to all levels
   of page tables.

Whenever a user opens the file
"/sys/kernel/debug/iommu/intel/dmar_translation_struct", the above
described DMAR table walk is performed and the contents of the table are
dumped into the file. The dump could be handy while dealing with devices
that use PASID.

Example of such dump:
cat /sys/kernel/debug/iommu/intel/dmar_translation_struct

(Please note that because of 80 char limit, entries that should have been
in the same line are broken into different lines)

IOMMU dmar0: Root Table Address: 0x436f7c000
B.D.F	Root_entry				Context_entry
PASID	PASID_table_entry
00:0a.0	0x0000000000000000:0x000000044dd3f001	0x0000000000100000:0x0000000435460e1d
0	0x000000044d6e1089:0x0000000000000003:0x0000000000000001
00:0a.0	0x0000000000000000:0x000000044dd3f001	0x0000000000100000:0x0000000435460e1d
1	0x0000000000000049:0x0000000000000001:0x0000000003c0e001

Note that the above format is followed even for legacy DMAR table dump
which doesn't support PASID and hence in such cases PASID is defaulted to
-1 indicating that PASID and it's related fields are invalid.

Cc: Joerg Roedel <joro@8bytes.org>
Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Lu Baolu <baolu.lu@linux.intel.com>
Cc: Sohil Mehta <sohil.mehta@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Jacob Pan <jacob.jun.pan@linux.intel.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>
---
 drivers/iommu/intel-iommu-debugfs.c | 78 +++++++++++++++++++++++++++++++++++--
 1 file changed, 75 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/intel-iommu-debugfs.c b/drivers/iommu/intel-iommu-debugfs.c
index 3f5399b5e6c0..73a552914455 100644
--- a/drivers/iommu/intel-iommu-debugfs.c
+++ b/drivers/iommu/intel-iommu-debugfs.c
@@ -14,11 +14,15 @@
 
 #include <asm/irq_remapping.h>
 
+#include "intel-pasid.h"
+
 struct tbl_walk {
 	u16 bus;
 	u16 devfn;
+	u32 pasid;
 	struct root_entry *rt_entry;
 	struct context_entry *ctx_entry;
+	struct pasid_entry *pasid_tbl_entry;
 };
 
 struct iommu_regset {
@@ -142,21 +146,82 @@ static inline void print_tbl_walk(struct seq_file *m)
 {
 	struct tbl_walk *tbl_wlk = m->private;
 
-	seq_printf(m, "%02x:%02x.%x\t0x%016llx:0x%016llx\t0x%016llx:0x%016llx\n",
+	seq_printf(m, "%02x:%02x.%x\t0x%016llx:0x%016llx\t0x%016llx:0x%016llx\t",
 		   tbl_wlk->bus, PCI_SLOT(tbl_wlk->devfn),
 		   PCI_FUNC(tbl_wlk->devfn), tbl_wlk->rt_entry->hi,
 		   tbl_wlk->rt_entry->lo, tbl_wlk->ctx_entry->hi,
 		   tbl_wlk->ctx_entry->lo);
+
+	/*
+	 * A legacy mode DMAR doesn't support PASID, hence default it to -1
+	 * indicating that it's invalid. Also, default all PASID related fields
+	 * to 0.
+	 */
+	if (!tbl_wlk->pasid_tbl_entry)
+		seq_printf(m, "%-6d\t0x%016llx:0x%016llx:0x%016llx\n", -1,
+			   (u64)0, (u64)0, (u64)0);
+	else
+		seq_printf(m, "%-6d\t0x%016llx:0x%016llx:0x%016llx\n",
+			   tbl_wlk->pasid, tbl_wlk->pasid_tbl_entry->val[0],
+			   tbl_wlk->pasid_tbl_entry->val[1],
+			   tbl_wlk->pasid_tbl_entry->val[2]);
+}
+
+static void pasid_tbl_walk(struct seq_file *m, struct pasid_entry *tbl_entry,
+			   u16 dir_idx)
+{
+	struct tbl_walk *tbl_wlk = m->private;
+	u8 tbl_idx;
+
+	for (tbl_idx = 0; tbl_idx < PASID_TBL_ENTRIES; tbl_idx++) {
+		if (pasid_pte_is_present(tbl_entry)) {
+			tbl_wlk->pasid_tbl_entry = tbl_entry;
+			tbl_wlk->pasid = (dir_idx << PASID_PDE_SHIFT) + tbl_idx;
+			print_tbl_walk(m);
+		}
+
+		tbl_entry++;
+	}
+}
+
+static void pasid_dir_walk(struct seq_file *m, u64 pasid_dir_ptr,
+			   u16 pasid_dir_size)
+{
+	struct pasid_dir_entry *dir_entry = phys_to_virt(pasid_dir_ptr);
+	struct pasid_entry *pasid_tbl;
+	u16 dir_idx;
+
+	for (dir_idx = 0; dir_idx < pasid_dir_size; dir_idx++) {
+		pasid_tbl = get_pasid_table_from_pde(dir_entry);
+		if (pasid_tbl)
+			pasid_tbl_walk(m, pasid_tbl, dir_idx);
+
+		dir_entry++;
+	}
 }
 
 static void ctx_tbl_walk(struct seq_file *m, struct intel_iommu *iommu, u16 bus)
 {
 	struct context_entry *context;
-	u16 devfn;
+	u16 devfn, pasid_dir_size;
+	u64 pasid_dir_ptr;
 
 	for (devfn = 0; devfn < 256; devfn++) {
 		struct tbl_walk tbl_wlk = {0};
 
+		/*
+		 * Scalable mode root entry points to upper scalable mode
+		 * context table and lower scalable mode context table. Each
+		 * scalable mode context table has 128 context entries where as
+		 * legacy mode context table has 256 context entries. So in
+		 * scalable mode, the context entries for former 128 devices are
+		 * in the lower scalable mode context table, while the latter
+		 * 128 devices are in the upper scalable mode context table.
+		 * In scalable mode, when devfn > 127, iommu_context_addr()
+		 * automatically refers to upper scalable mode context table and
+		 * hence the caller doesn't have to worry about differences
+		 * between scalable mode and non scalable mode.
+		 */
 		context = iommu_context_addr(iommu, bus, devfn, 0);
 		if (!context)
 			return;
@@ -170,6 +235,13 @@ static void ctx_tbl_walk(struct seq_file *m, struct intel_iommu *iommu, u16 bus)
 		tbl_wlk.ctx_entry = context;
 		m->private = &tbl_wlk;
 
+		if (pasid_supported(iommu) && is_pasid_enabled(context)) {
+			pasid_dir_ptr = context->lo & VTD_PAGE_MASK;
+			pasid_dir_size = get_pasid_dir_size(context);
+			pasid_dir_walk(m, pasid_dir_ptr, pasid_dir_size);
+			continue;
+		}
+
 		print_tbl_walk(m);
 	}
 }
@@ -182,7 +254,7 @@ static void root_tbl_walk(struct seq_file *m, struct intel_iommu *iommu)
 	spin_lock_irqsave(&iommu->lock, flags);
 	seq_printf(m, "IOMMU %s: Root Table Address: 0x%llx\n", iommu->name,
 		   (u64)virt_to_phys(iommu->root_entry));
-	seq_puts(m, "B.D.F\tRoot_entry\t\t\t\tContext_entry\n");
+	seq_puts(m, "B.D.F\tRoot_entry\t\t\t\tContext_entry\t\t\t\tPASID\tPASID_table_entry\n");
 
 	/*
 	 * No need to check if the root entry is present or not because
-- 
2.7.4

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH V3 0/3] Add debugfs support to show scalable mode DMAR table
  2019-05-24 23:40 [PATCH V3 0/3] Add debugfs support to show scalable mode DMAR table Sai Praneeth Prakhya
                   ` (2 preceding siblings ...)
  2019-05-24 23:40 ` [PATCH V3 3/3] iommu/vt-d: Add debugfs support to show scalable mode DMAR table internals Sai Praneeth Prakhya
@ 2019-05-27 14:16 ` Joerg Roedel
  2019-05-29 16:19   ` Prakhya, Sai Praneeth
  3 siblings, 1 reply; 6+ messages in thread
From: Joerg Roedel @ 2019-05-27 14:16 UTC (permalink / raw)
  To: Sai Praneeth Prakhya; +Cc: Ashok Raj, iommu, Andy Shevchenko, David Woodhouse

On Fri, May 24, 2019 at 04:40:14PM -0700, Sai Praneeth Prakhya wrote:
> Changes from V2 to V3:
> ----------------------
> Presently, for V2 patches if kernel command line argument "iommu=pt" is passed,
> dumping DMAR table seg faults. This happens because in pass through mode (for
> non-scalable DMAR's) 3rd bit of context entry is set and it is misinterpreted as
> PASID enabled by debugfs code and hence tries to dereference PASID directory
> pointer which leads to seg fault (PASID directory pointer is undefined for
> non-scalable DMAR's). To fix this, dereference PASID directory pointer only when
> 1. PASID is supported and
> 2. PASID is enabled.
> 
> This patch is tested on
> 1. Non-scalable DMAR with and without iommu=pt
> 2. Scalable DMAR with and without iommu=pt

Sorry, missed this patch-set. Applied this one instead of V2.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [PATCH V3 0/3] Add debugfs support to show scalable mode DMAR table
  2019-05-27 14:16 ` [PATCH V3 0/3] Add debugfs support to show scalable mode DMAR table Joerg Roedel
@ 2019-05-29 16:19   ` Prakhya, Sai Praneeth
  0 siblings, 0 replies; 6+ messages in thread
From: Prakhya, Sai Praneeth @ 2019-05-29 16:19 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Raj, Ashok, iommu, Andy Shevchenko, David Woodhouse

> > Changes from V2 to V3:
> > ----------------------
> > Presently, for V2 patches if kernel command line argument "iommu=pt"
> > is passed, dumping DMAR table seg faults. This happens because in pass
> > through mode (for non-scalable DMAR's) 3rd bit of context entry is set
> > and it is misinterpreted as PASID enabled by debugfs code and hence
> > tries to dereference PASID directory pointer which leads to seg fault
> > (PASID directory pointer is undefined for non-scalable DMAR's). To fix
> > this, dereference PASID directory pointer only when 1. PASID is
> > supported and 2. PASID is enabled.
> >
> > This patch is tested on
> > 1. Non-scalable DMAR with and without iommu=pt 2. Scalable DMAR with
> > and without iommu=pt
> 
> Sorry, missed this patch-set. Applied this one instead of V2.

Thanks! This is the right patch set. I have also checked IOMMU tree and it looks good :)

Regards,
Sai
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-05-29 16:24 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-24 23:40 [PATCH V3 0/3] Add debugfs support to show scalable mode DMAR table Sai Praneeth Prakhya
2019-05-24 23:40 ` [PATCH V3 1/3] iommu/vt-d: Modify the format of intel DMAR tables dump Sai Praneeth Prakhya
2019-05-24 23:40 ` [PATCH V3 2/3] iommu/vt-d: Introduce macros useful for dumping DMAR table Sai Praneeth Prakhya
2019-05-24 23:40 ` [PATCH V3 3/3] iommu/vt-d: Add debugfs support to show scalable mode DMAR table internals Sai Praneeth Prakhya
2019-05-27 14:16 ` [PATCH V3 0/3] Add debugfs support to show scalable mode DMAR table Joerg Roedel
2019-05-29 16:19   ` Prakhya, Sai Praneeth

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.