diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2012-06-15 16:53:51 +0200 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2012-09-28 17:30:03 +0200 |
commit | 05152a0494449f60031da683e6d4cd60d0882214 (patch) | |
tree | 610e4df7df61da02c2cc3ccc24aeb38896f7509e | |
parent | 6efed63bec36e260204a50cfe6878cd36b710ade (diff) |
iommu/amd: Add slab-cache for irq remapping tables
The irq remapping tables for the AMD IOMMU need to be
aligned on a 128 byte boundary. Create a seperate slab-cache
to guarantee this alignment.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
-rw-r--r-- | drivers/iommu/amd_iommu.c | 2 | ||||
-rw-r--r-- | drivers/iommu/amd_iommu_init.c | 23 | ||||
-rw-r--r-- | drivers/iommu/amd_iommu_types.h | 9 | ||||
-rw-r--r-- | drivers/iommu/irq_remapping.h | 5 |
4 files changed, 39 insertions, 0 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 6f514831af1..b6a8079ff7b 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -95,6 +95,8 @@ struct iommu_cmd { u32 data[4]; }; +struct kmem_cache *amd_iommu_irq_cache; + static void update_domain(struct protection_domain *domain); static int __init alloc_passthrough_domain(void); diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 61798596119..073ed5d1e05 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -36,6 +36,7 @@ #include "amd_iommu_proto.h" #include "amd_iommu_types.h" +#include "irq_remapping.h" /* * definitions for the ACPI scanning code @@ -127,6 +128,7 @@ struct ivmd_header { } __attribute__((packed)); bool amd_iommu_dump; +bool amd_iommu_irq_remap __read_mostly; static bool amd_iommu_detected; static bool __initdata amd_iommu_disabled; @@ -1530,6 +1532,11 @@ static struct syscore_ops amd_iommu_syscore_ops = { static void __init free_on_init_error(void) { + if (amd_iommu_irq_cache) { + kmem_cache_destroy(amd_iommu_irq_cache); + amd_iommu_irq_cache = NULL; + } + amd_iommu_uninit_devices(); free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, @@ -1669,6 +1676,19 @@ static int __init early_amd_iommu_init(void) if (ret) goto out; + if (amd_iommu_irq_remap) { + /* + * Interrupt remapping enabled, create kmem_cache for the + * remapping tables. + */ + amd_iommu_irq_cache = kmem_cache_create("irq_remap_cache", + MAX_IRQS_PER_TABLE * sizeof(u32), + IRQ_TABLE_ALIGNMENT, + 0, NULL); + if (!amd_iommu_irq_cache) + goto out; + } + ret = init_memory_definitions(ivrs_base); if (ret) goto out; @@ -1716,6 +1736,9 @@ static bool detect_ivrs(void) /* Make sure ACS will be enabled during PCI probe */ pci_request_acs(); + if (!disable_irq_remap) + amd_iommu_irq_remap = true; + return true; } diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 4495b78b129..953cea80daa 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -334,6 +334,15 @@ extern bool amd_iommu_np_cache; /* Only true if all IOMMUs support device IOTLBs */ extern bool amd_iommu_iotlb_sup; +#define MAX_IRQS_PER_TABLE 256 +#define IRQ_TABLE_ALIGNMENT 128 + +/* Interrupt remapping feature used? */ +extern bool amd_iommu_irq_remap; + +/* kmem_cache to get tables with 128 byte alignement */ +extern struct kmem_cache *amd_iommu_irq_cache; + /* * Make iterating over all IOMMUs easier */ diff --git a/drivers/iommu/irq_remapping.h b/drivers/iommu/irq_remapping.h index b12974cc1df..624d360d9be 100644 --- a/drivers/iommu/irq_remapping.h +++ b/drivers/iommu/irq_remapping.h @@ -83,6 +83,11 @@ struct irq_remap_ops { extern struct irq_remap_ops intel_irq_remap_ops; +#else /* CONFIG_IRQ_REMAP */ + +#define irq_remapping_enabled 0 +#define disable_irq_remap 1 + #endif /* CONFIG_IRQ_REMAP */ #endif /* __IRQ_REMAPPING_H */ |