1
0
Fork 0
alistair23-linux/drivers/iommu/intel-iommu-debugfs.c

423 lines
12 KiB
C
Raw Permalink Normal View History

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright © 2018 Intel Corporation.
*
* Authors: Gayatri Kammela <gayatri.kammela@intel.com>
* Sohil Mehta <sohil.mehta@intel.com>
* Jacob Pan <jacob.jun.pan@linux.intel.com>
*/
#include <linux/debugfs.h>
#include <linux/dmar.h>
#include <linux/intel-iommu.h>
#include <linux/pci.h>
#include <asm/irq_remapping.h>
iommu/vt-d: Add debugfs support to show scalable mode DMAR table internals 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:17 -06:00
#include "intel-pasid.h"
iommu/vt-d: Modify the format of intel DMAR tables dump 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:15 -06:00
struct tbl_walk {
u16 bus;
u16 devfn;
iommu/vt-d: Add debugfs support to show scalable mode DMAR table internals 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:17 -06:00
u32 pasid;
iommu/vt-d: Modify the format of intel DMAR tables dump 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:15 -06:00
struct root_entry *rt_entry;
struct context_entry *ctx_entry;
iommu/vt-d: Add debugfs support to show scalable mode DMAR table internals 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:17 -06:00
struct pasid_entry *pasid_tbl_entry;
iommu/vt-d: Modify the format of intel DMAR tables dump 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:15 -06:00
};
struct iommu_regset {
int offset;
const char *regs;
};
#define IOMMU_REGSET_ENTRY(_reg_) \
{ DMAR_##_reg_##_REG, __stringify(_reg_) }
static const struct iommu_regset iommu_regs_32[] = {
IOMMU_REGSET_ENTRY(VER),
IOMMU_REGSET_ENTRY(GCMD),
IOMMU_REGSET_ENTRY(GSTS),
IOMMU_REGSET_ENTRY(FSTS),
IOMMU_REGSET_ENTRY(FECTL),
IOMMU_REGSET_ENTRY(FEDATA),
IOMMU_REGSET_ENTRY(FEADDR),
IOMMU_REGSET_ENTRY(FEUADDR),
IOMMU_REGSET_ENTRY(PMEN),
IOMMU_REGSET_ENTRY(PLMBASE),
IOMMU_REGSET_ENTRY(PLMLIMIT),
IOMMU_REGSET_ENTRY(ICS),
IOMMU_REGSET_ENTRY(PRS),
IOMMU_REGSET_ENTRY(PECTL),
IOMMU_REGSET_ENTRY(PEDATA),
IOMMU_REGSET_ENTRY(PEADDR),
IOMMU_REGSET_ENTRY(PEUADDR),
};
static const struct iommu_regset iommu_regs_64[] = {
IOMMU_REGSET_ENTRY(CAP),
IOMMU_REGSET_ENTRY(ECAP),
IOMMU_REGSET_ENTRY(RTADDR),
IOMMU_REGSET_ENTRY(CCMD),
IOMMU_REGSET_ENTRY(AFLOG),
IOMMU_REGSET_ENTRY(PHMBASE),
IOMMU_REGSET_ENTRY(PHMLIMIT),
IOMMU_REGSET_ENTRY(IQH),
IOMMU_REGSET_ENTRY(IQT),
IOMMU_REGSET_ENTRY(IQA),
IOMMU_REGSET_ENTRY(IRTA),
IOMMU_REGSET_ENTRY(PQH),
IOMMU_REGSET_ENTRY(PQT),
IOMMU_REGSET_ENTRY(PQA),
IOMMU_REGSET_ENTRY(MTRRCAP),
IOMMU_REGSET_ENTRY(MTRRDEF),
IOMMU_REGSET_ENTRY(MTRR_FIX64K_00000),
IOMMU_REGSET_ENTRY(MTRR_FIX16K_80000),
IOMMU_REGSET_ENTRY(MTRR_FIX16K_A0000),
IOMMU_REGSET_ENTRY(MTRR_FIX4K_C0000),
IOMMU_REGSET_ENTRY(MTRR_FIX4K_C8000),
IOMMU_REGSET_ENTRY(MTRR_FIX4K_D0000),
IOMMU_REGSET_ENTRY(MTRR_FIX4K_D8000),
IOMMU_REGSET_ENTRY(MTRR_FIX4K_E0000),
IOMMU_REGSET_ENTRY(MTRR_FIX4K_E8000),
IOMMU_REGSET_ENTRY(MTRR_FIX4K_F0000),
IOMMU_REGSET_ENTRY(MTRR_FIX4K_F8000),
IOMMU_REGSET_ENTRY(MTRR_PHYSBASE0),
IOMMU_REGSET_ENTRY(MTRR_PHYSMASK0),
IOMMU_REGSET_ENTRY(MTRR_PHYSBASE1),
IOMMU_REGSET_ENTRY(MTRR_PHYSMASK1),
IOMMU_REGSET_ENTRY(MTRR_PHYSBASE2),
IOMMU_REGSET_ENTRY(MTRR_PHYSMASK2),
IOMMU_REGSET_ENTRY(MTRR_PHYSBASE3),
IOMMU_REGSET_ENTRY(MTRR_PHYSMASK3),
IOMMU_REGSET_ENTRY(MTRR_PHYSBASE4),
IOMMU_REGSET_ENTRY(MTRR_PHYSMASK4),
IOMMU_REGSET_ENTRY(MTRR_PHYSBASE5),
IOMMU_REGSET_ENTRY(MTRR_PHYSMASK5),
IOMMU_REGSET_ENTRY(MTRR_PHYSBASE6),
IOMMU_REGSET_ENTRY(MTRR_PHYSMASK6),
IOMMU_REGSET_ENTRY(MTRR_PHYSBASE7),
IOMMU_REGSET_ENTRY(MTRR_PHYSMASK7),
IOMMU_REGSET_ENTRY(MTRR_PHYSBASE8),
IOMMU_REGSET_ENTRY(MTRR_PHYSMASK8),
IOMMU_REGSET_ENTRY(MTRR_PHYSBASE9),
IOMMU_REGSET_ENTRY(MTRR_PHYSMASK9),
IOMMU_REGSET_ENTRY(VCCAP),
IOMMU_REGSET_ENTRY(VCMD),
IOMMU_REGSET_ENTRY(VCRSP),
};
static int iommu_regset_show(struct seq_file *m, void *unused)
{
struct dmar_drhd_unit *drhd;
struct intel_iommu *iommu;
unsigned long flag;
int i, ret = 0;
u64 value;
rcu_read_lock();
for_each_active_iommu(iommu, drhd) {
if (!drhd->reg_base_addr) {
seq_puts(m, "IOMMU: Invalid base address\n");
ret = -EINVAL;
goto out;
}
seq_printf(m, "IOMMU: %s Register Base Address: %llx\n",
iommu->name, drhd->reg_base_addr);
seq_puts(m, "Name\t\t\tOffset\t\tContents\n");
/*
* Publish the contents of the 64-bit hardware registers
* by adding the offset to the pointer (virtual address).
*/
raw_spin_lock_irqsave(&iommu->register_lock, flag);
for (i = 0 ; i < ARRAY_SIZE(iommu_regs_32); i++) {
value = dmar_readl(iommu->reg + iommu_regs_32[i].offset);
seq_printf(m, "%-16s\t0x%02x\t\t0x%016llx\n",
iommu_regs_32[i].regs, iommu_regs_32[i].offset,
value);
}
for (i = 0 ; i < ARRAY_SIZE(iommu_regs_64); i++) {
value = dmar_readq(iommu->reg + iommu_regs_64[i].offset);
seq_printf(m, "%-16s\t0x%02x\t\t0x%016llx\n",
iommu_regs_64[i].regs, iommu_regs_64[i].offset,
value);
}
raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
seq_putc(m, '\n');
}
out:
rcu_read_unlock();
return ret;
}
DEFINE_SHOW_ATTRIBUTE(iommu_regset);
iommu/vt-d: Modify the format of intel DMAR tables dump 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:15 -06:00
static inline void print_tbl_walk(struct seq_file *m)
{
iommu/vt-d: Modify the format of intel DMAR tables dump 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:15 -06:00
struct tbl_walk *tbl_wlk = m->private;
iommu/vt-d: Add debugfs support to show scalable mode DMAR table internals 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:17 -06:00
seq_printf(m, "%02x:%02x.%x\t0x%016llx:0x%016llx\t0x%016llx:0x%016llx\t",
iommu/vt-d: Modify the format of intel DMAR tables dump 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:15 -06:00
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);
iommu/vt-d: Add debugfs support to show scalable mode DMAR table internals 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:17 -06:00
/*
* 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[2],
iommu/vt-d: Add debugfs support to show scalable mode DMAR table internals 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:17 -06:00
tbl_wlk->pasid_tbl_entry->val[1],
tbl_wlk->pasid_tbl_entry->val[0]);
iommu/vt-d: Add debugfs support to show scalable mode DMAR table internals 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:17 -06:00
}
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++;
}
iommu/vt-d: Modify the format of intel DMAR tables dump 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:15 -06:00
}
static void ctx_tbl_walk(struct seq_file *m, struct intel_iommu *iommu, u16 bus)
{
struct context_entry *context;
iommu/vt-d: Add debugfs support to show scalable mode DMAR table internals 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:17 -06:00
u16 devfn, pasid_dir_size;
u64 pasid_dir_ptr;
for (devfn = 0; devfn < 256; devfn++) {
iommu/vt-d: Modify the format of intel DMAR tables dump 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:15 -06:00
struct tbl_walk tbl_wlk = {0};
iommu/vt-d: Add debugfs support to show scalable mode DMAR table internals 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:17 -06:00
/*
* 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;
if (!context_present(context))
continue;
iommu/vt-d: Modify the format of intel DMAR tables dump 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:15 -06:00
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;
if (dmar_readq(iommu->reg + DMAR_RTADDR_REG) & DMA_RTADDR_SMT) {
iommu/vt-d: Add debugfs support to show scalable mode DMAR table internals 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:17 -06:00
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;
}
iommu/vt-d: Modify the format of intel DMAR tables dump 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:15 -06:00
print_tbl_walk(m);
}
}
iommu/vt-d: Modify the format of intel DMAR tables dump 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:15 -06:00
static void root_tbl_walk(struct seq_file *m, struct intel_iommu *iommu)
{
unsigned long flags;
iommu/vt-d: Modify the format of intel DMAR tables dump 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:15 -06:00
u16 bus;
spin_lock_irqsave(&iommu->lock, flags);
iommu/vt-d: Modify the format of intel DMAR tables dump 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:15 -06:00
seq_printf(m, "IOMMU %s: Root Table Address: 0x%llx\n", iommu->name,
(u64)virt_to_phys(iommu->root_entry));
iommu/vt-d: Add debugfs support to show scalable mode DMAR table internals 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:17 -06:00
seq_puts(m, "B.D.F\tRoot_entry\t\t\t\tContext_entry\t\t\t\tPASID\tPASID_table_entry\n");
iommu/vt-d: Modify the format of intel DMAR tables dump 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:15 -06:00
/*
* 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);
spin_unlock_irqrestore(&iommu->lock, flags);
}
static int dmar_translation_struct_show(struct seq_file *m, void *unused)
{
struct dmar_drhd_unit *drhd;
struct intel_iommu *iommu;
u32 sts;
rcu_read_lock();
for_each_active_iommu(iommu, drhd) {
sts = dmar_readl(iommu->reg + DMAR_GSTS_REG);
if (!(sts & DMA_GSTS_TES)) {
seq_printf(m, "DMA Remapping is not enabled on %s\n",
iommu->name);
continue;
}
iommu/vt-d: Modify the format of intel DMAR tables dump 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> Signed-off-by: Joerg Roedel <jroedel@suse.de>
2019-05-24 17:40:15 -06:00
root_tbl_walk(m, iommu);
seq_putc(m, '\n');
}
rcu_read_unlock();
return 0;
}
DEFINE_SHOW_ATTRIBUTE(dmar_translation_struct);
#ifdef CONFIG_IRQ_REMAP
static void ir_tbl_remap_entry_show(struct seq_file *m,
struct intel_iommu *iommu)
{
struct irte *ri_entry;
unsigned long flags;
int idx;
seq_puts(m, " Entry SrcID DstID Vct IRTE_high\t\tIRTE_low\n");
raw_spin_lock_irqsave(&irq_2_ir_lock, flags);
for (idx = 0; idx < INTR_REMAP_TABLE_ENTRIES; idx++) {
ri_entry = &iommu->ir_table->base[idx];
if (!ri_entry->present || ri_entry->p_pst)
continue;
seq_printf(m, " %-5d %02x:%02x.%01x %08x %02x %016llx\t%016llx\n",
idx, PCI_BUS_NUM(ri_entry->sid),
PCI_SLOT(ri_entry->sid), PCI_FUNC(ri_entry->sid),
ri_entry->dest_id, ri_entry->vector,
ri_entry->high, ri_entry->low);
}
raw_spin_unlock_irqrestore(&irq_2_ir_lock, flags);
}
static void ir_tbl_posted_entry_show(struct seq_file *m,
struct intel_iommu *iommu)
{
struct irte *pi_entry;
unsigned long flags;
int idx;
seq_puts(m, " Entry SrcID PDA_high PDA_low Vct IRTE_high\t\tIRTE_low\n");
raw_spin_lock_irqsave(&irq_2_ir_lock, flags);
for (idx = 0; idx < INTR_REMAP_TABLE_ENTRIES; idx++) {
pi_entry = &iommu->ir_table->base[idx];
if (!pi_entry->present || !pi_entry->p_pst)
continue;
seq_printf(m, " %-5d %02x:%02x.%01x %08x %08x %02x %016llx\t%016llx\n",
idx, PCI_BUS_NUM(pi_entry->sid),
PCI_SLOT(pi_entry->sid), PCI_FUNC(pi_entry->sid),
pi_entry->pda_h, pi_entry->pda_l << 6,
pi_entry->vector, pi_entry->high,
pi_entry->low);
}
raw_spin_unlock_irqrestore(&irq_2_ir_lock, flags);
}
/*
* For active IOMMUs go through the Interrupt remapping
* table and print valid entries in a table format for
* Remapped and Posted Interrupts.
*/
static int ir_translation_struct_show(struct seq_file *m, void *unused)
{
struct dmar_drhd_unit *drhd;
struct intel_iommu *iommu;
u64 irta;
u32 sts;
rcu_read_lock();
for_each_active_iommu(iommu, drhd) {
if (!ecap_ir_support(iommu->ecap))
continue;
seq_printf(m, "Remapped Interrupt supported on IOMMU: %s\n",
iommu->name);
sts = dmar_readl(iommu->reg + DMAR_GSTS_REG);
if (iommu->ir_table && (sts & DMA_GSTS_IRES)) {
irta = virt_to_phys(iommu->ir_table->base);
seq_printf(m, " IR table address:%llx\n", irta);
ir_tbl_remap_entry_show(m, iommu);
} else {
seq_puts(m, "Interrupt Remapping is not enabled\n");
}
seq_putc(m, '\n');
}
seq_puts(m, "****\n\n");
for_each_active_iommu(iommu, drhd) {
if (!cap_pi_support(iommu->cap))
continue;
seq_printf(m, "Posted Interrupt supported on IOMMU: %s\n",
iommu->name);
if (iommu->ir_table) {
irta = virt_to_phys(iommu->ir_table->base);
seq_printf(m, " IR table address:%llx\n", irta);
ir_tbl_posted_entry_show(m, iommu);
} else {
seq_puts(m, "Interrupt Remapping is not enabled\n");
}
seq_putc(m, '\n');
}
rcu_read_unlock();
return 0;
}
DEFINE_SHOW_ATTRIBUTE(ir_translation_struct);
#endif
void __init intel_iommu_debugfs_init(void)
{
struct dentry *intel_iommu_debug = debugfs_create_dir("intel",
iommu_debugfs_dir);
debugfs_create_file("iommu_regset", 0444, intel_iommu_debug, NULL,
&iommu_regset_fops);
debugfs_create_file("dmar_translation_struct", 0444, intel_iommu_debug,
NULL, &dmar_translation_struct_fops);
#ifdef CONFIG_IRQ_REMAP
debugfs_create_file("ir_translation_struct", 0444, intel_iommu_debug,
NULL, &ir_translation_struct_fops);
#endif
}