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>
This commit is contained in:
Joerg Roedel 2012-06-15 16:53:51 +02:00
parent 6efed63bec
commit 05152a0494
4 changed files with 39 additions and 0 deletions

View file

@ -95,6 +95,8 @@ struct iommu_cmd {
u32 data[4]; u32 data[4];
}; };
struct kmem_cache *amd_iommu_irq_cache;
static void update_domain(struct protection_domain *domain); static void update_domain(struct protection_domain *domain);
static int __init alloc_passthrough_domain(void); static int __init alloc_passthrough_domain(void);

View file

@ -36,6 +36,7 @@
#include "amd_iommu_proto.h" #include "amd_iommu_proto.h"
#include "amd_iommu_types.h" #include "amd_iommu_types.h"
#include "irq_remapping.h"
/* /*
* definitions for the ACPI scanning code * definitions for the ACPI scanning code
@ -127,6 +128,7 @@ struct ivmd_header {
} __attribute__((packed)); } __attribute__((packed));
bool amd_iommu_dump; bool amd_iommu_dump;
bool amd_iommu_irq_remap __read_mostly;
static bool amd_iommu_detected; static bool amd_iommu_detected;
static bool __initdata amd_iommu_disabled; 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) 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(); amd_iommu_uninit_devices();
free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, free_pages((unsigned long)amd_iommu_pd_alloc_bitmap,
@ -1669,6 +1676,19 @@ static int __init early_amd_iommu_init(void)
if (ret) if (ret)
goto out; 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); ret = init_memory_definitions(ivrs_base);
if (ret) if (ret)
goto out; goto out;
@ -1716,6 +1736,9 @@ static bool detect_ivrs(void)
/* Make sure ACS will be enabled during PCI probe */ /* Make sure ACS will be enabled during PCI probe */
pci_request_acs(); pci_request_acs();
if (!disable_irq_remap)
amd_iommu_irq_remap = true;
return true; return true;
} }

View file

@ -334,6 +334,15 @@ extern bool amd_iommu_np_cache;
/* Only true if all IOMMUs support device IOTLBs */ /* Only true if all IOMMUs support device IOTLBs */
extern bool amd_iommu_iotlb_sup; 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 * Make iterating over all IOMMUs easier
*/ */

View file

@ -83,6 +83,11 @@ struct irq_remap_ops {
extern struct irq_remap_ops intel_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 /* CONFIG_IRQ_REMAP */
#endif /* __IRQ_REMAPPING_H */ #endif /* __IRQ_REMAPPING_H */