Commit b0a11f44 authored by Joerg Roedel's avatar Joerg Roedel

Merge branches 'iommu/api' and 'iommu/amd' into for-linus

parents 7398ca79 0e93dd88
...@@ -586,6 +586,16 @@ config AMD_IOMMU ...@@ -586,6 +586,16 @@ config AMD_IOMMU
your BIOS for an option to enable it or if you have an IVRS ACPI your BIOS for an option to enable it or if you have an IVRS ACPI
table. table.
config AMD_IOMMU_STATS
bool "Export AMD IOMMU statistics to debugfs"
depends on AMD_IOMMU
select DEBUG_FS
help
This option enables code in the AMD IOMMU driver to collect various
statistics about whats happening in the driver and exports that
information to userspace via debugfs.
If unsure, say N.
# need this always selected by IOMMU for the VIA workaround # need this always selected by IOMMU for the VIA workaround
config SWIOTLB config SWIOTLB
def_bool y if X86_64 def_bool y if X86_64
......
...@@ -190,16 +190,23 @@ ...@@ -190,16 +190,23 @@
/* FIXME: move this macro to <linux/pci.h> */ /* FIXME: move this macro to <linux/pci.h> */
#define PCI_BUS(x) (((x) >> 8) & 0xff) #define PCI_BUS(x) (((x) >> 8) & 0xff)
/* Protection domain flags */
#define PD_DMA_OPS_MASK (1UL << 0) /* domain used for dma_ops */
#define PD_DEFAULT_MASK (1UL << 1) /* domain is a default dma_ops
domain for an IOMMU */
/* /*
* This structure contains generic data for IOMMU protection domains * This structure contains generic data for IOMMU protection domains
* independent of their use. * independent of their use.
*/ */
struct protection_domain { struct protection_domain {
spinlock_t lock; /* mostly used to lock the page table*/ spinlock_t lock; /* mostly used to lock the page table*/
u16 id; /* the domain id written to the device table */ u16 id; /* the domain id written to the device table */
int mode; /* paging mode (0-6 levels) */ int mode; /* paging mode (0-6 levels) */
u64 *pt_root; /* page table root pointer */ u64 *pt_root; /* page table root pointer */
void *priv; /* private data */ unsigned long flags; /* flags to find out type of domain */
unsigned dev_cnt; /* devices assigned to this domain */
void *priv; /* private data */
}; };
/* /*
...@@ -295,7 +302,7 @@ struct amd_iommu { ...@@ -295,7 +302,7 @@ struct amd_iommu {
bool int_enabled; bool int_enabled;
/* if one, we need to send a completion wait command */ /* if one, we need to send a completion wait command */
int need_sync; bool need_sync;
/* default dma_ops domain for that IOMMU */ /* default dma_ops domain for that IOMMU */
struct dma_ops_domain *default_dom; struct dma_ops_domain *default_dom;
...@@ -374,7 +381,7 @@ extern struct protection_domain **amd_iommu_pd_table; ...@@ -374,7 +381,7 @@ extern struct protection_domain **amd_iommu_pd_table;
extern unsigned long *amd_iommu_pd_alloc_bitmap; extern unsigned long *amd_iommu_pd_alloc_bitmap;
/* will be 1 if device isolation is enabled */ /* will be 1 if device isolation is enabled */
extern int amd_iommu_isolate; extern bool amd_iommu_isolate;
/* /*
* If true, the addresses will be flushed on unmap time, not when * If true, the addresses will be flushed on unmap time, not when
...@@ -382,18 +389,6 @@ extern int amd_iommu_isolate; ...@@ -382,18 +389,6 @@ extern int amd_iommu_isolate;
*/ */
extern bool amd_iommu_unmap_flush; extern bool amd_iommu_unmap_flush;
/* takes a PCI device id and prints it out in a readable form */
static inline void print_devid(u16 devid, int nl)
{
int bus = devid >> 8;
int dev = devid >> 3 & 0x1f;
int fn = devid & 0x07;
printk("%02x:%02x.%x", bus, dev, fn);
if (nl)
printk("\n");
}
/* takes bus and device/function and returns the device id /* takes bus and device/function and returns the device id
* FIXME: should that be in generic PCI code? */ * FIXME: should that be in generic PCI code? */
static inline u16 calc_devid(u8 bus, u8 devfn) static inline u16 calc_devid(u8 bus, u8 devfn)
...@@ -401,4 +396,32 @@ static inline u16 calc_devid(u8 bus, u8 devfn) ...@@ -401,4 +396,32 @@ static inline u16 calc_devid(u8 bus, u8 devfn)
return (((u16)bus) << 8) | devfn; return (((u16)bus) << 8) | devfn;
} }
#ifdef CONFIG_AMD_IOMMU_STATS
struct __iommu_counter {
char *name;
struct dentry *dent;
u64 value;
};
#define DECLARE_STATS_COUNTER(nm) \
static struct __iommu_counter nm = { \
.name = #nm, \
}
#define INC_STATS_COUNTER(name) name.value += 1
#define ADD_STATS_COUNTER(name, x) name.value += (x)
#define SUB_STATS_COUNTER(name, x) name.value -= (x)
#else /* CONFIG_AMD_IOMMU_STATS */
#define DECLARE_STATS_COUNTER(name)
#define INC_STATS_COUNTER(name)
#define ADD_STATS_COUNTER(name, x)
#define SUB_STATS_COUNTER(name, x)
static inline void amd_iommu_stats_init(void) { }
#endif /* CONFIG_AMD_IOMMU_STATS */
#endif /* _ASM_X86_AMD_IOMMU_TYPES_H */ #endif /* _ASM_X86_AMD_IOMMU_TYPES_H */
This diff is collapsed.
...@@ -122,7 +122,8 @@ u16 amd_iommu_last_bdf; /* largest PCI device id we have ...@@ -122,7 +122,8 @@ u16 amd_iommu_last_bdf; /* largest PCI device id we have
LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings
we find in ACPI */ we find in ACPI */
unsigned amd_iommu_aperture_order = 26; /* size of aperture in power of 2 */ unsigned amd_iommu_aperture_order = 26; /* size of aperture in power of 2 */
int amd_iommu_isolate = 1; /* if 1, device isolation is enabled */ bool amd_iommu_isolate = true; /* if true, device isolation is
enabled */
bool amd_iommu_unmap_flush; /* if true, flush on every unmap */ bool amd_iommu_unmap_flush; /* if true, flush on every unmap */
LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the
...@@ -245,12 +246,8 @@ static void __init iommu_feature_disable(struct amd_iommu *iommu, u8 bit) ...@@ -245,12 +246,8 @@ static void __init iommu_feature_disable(struct amd_iommu *iommu, u8 bit)
/* Function to enable the hardware */ /* Function to enable the hardware */
void __init iommu_enable(struct amd_iommu *iommu) void __init iommu_enable(struct amd_iommu *iommu)
{ {
printk(KERN_INFO "AMD IOMMU: Enabling IOMMU " printk(KERN_INFO "AMD IOMMU: Enabling IOMMU at %s cap 0x%hx\n",
"at %02x:%02x.%x cap 0x%hx\n", dev_name(&iommu->dev->dev), iommu->cap_ptr);
iommu->dev->bus->number,
PCI_SLOT(iommu->dev->devfn),
PCI_FUNC(iommu->dev->devfn),
iommu->cap_ptr);
iommu_feature_enable(iommu, CONTROL_IOMMU_EN); iommu_feature_enable(iommu, CONTROL_IOMMU_EN);
} }
...@@ -1218,9 +1215,9 @@ static int __init parse_amd_iommu_options(char *str) ...@@ -1218,9 +1215,9 @@ static int __init parse_amd_iommu_options(char *str)
{ {
for (; *str; ++str) { for (; *str; ++str) {
if (strncmp(str, "isolate", 7) == 0) if (strncmp(str, "isolate", 7) == 0)
amd_iommu_isolate = 1; amd_iommu_isolate = true;
if (strncmp(str, "share", 5) == 0) if (strncmp(str, "share", 5) == 0)
amd_iommu_isolate = 0; amd_iommu_isolate = false;
if (strncmp(str, "fullflush", 9) == 0) if (strncmp(str, "fullflush", 9) == 0)
amd_iommu_unmap_flush = true; amd_iommu_unmap_flush = true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment