diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index dd1a6d4..d9eb422 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -981,6 +981,9 @@ and is between 256 and 4096 characters. It is defined in the file result in a hardware IOTLB flush operation as opposed to batching them for performance. + intel_iommu_drhd_mask=0xAAAAAAAA + Set a bit mask of DMAR hardware unit to be ignored + inttest= [IA64] iomem= Disable strict checking of access to MMIO memory diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 7b287cb..64954fe 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -167,7 +167,7 @@ static int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, * present in the platform */ static int __init -dmar_parse_one_drhd(struct acpi_dmar_header *header) +dmar_parse_one_drhd(struct acpi_dmar_header *header, int drhd_count) { struct acpi_dmar_hardware_unit *drhd; struct dmar_drhd_unit *dmaru; @@ -197,6 +197,8 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header) kfree(dmaru); return ret; } + if (intel_iommu_drhd_mask & (0x1 << drhd_count)) + dmaru->ignored = 1; dmar_register_drhd_unit(dmaru); return 0; } @@ -405,6 +407,7 @@ parse_dmar_table(void) { struct acpi_table_dmar *dmar; struct acpi_dmar_header *entry_header; + int drhd_count = 0; int ret = 0; /* @@ -440,7 +443,8 @@ parse_dmar_table(void) switch (entry_header->type) { case ACPI_DMAR_TYPE_HARDWARE_UNIT: - ret = dmar_parse_one_drhd(entry_header); + ret = dmar_parse_one_drhd(entry_header, drhd_count); + drhd_count++; break; case ACPI_DMAR_TYPE_RESERVED_MEMORY: #ifdef CONFIG_DMAR diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 2314ad7..03afd92 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -337,6 +337,7 @@ static DEFINE_SPINLOCK(device_domain_lock); static LIST_HEAD(device_domain_list); static struct iommu_ops intel_iommu_ops; +unsigned int intel_iommu_drhd_mask; static int __init intel_iommu_setup(char *str) { @@ -371,6 +372,15 @@ static int __init intel_iommu_setup(char *str) } __setup("intel_iommu=", intel_iommu_setup); +static int __init intel_iommu_drhd_mask_setup(char *str) +{ + if (!str) + return -EINVAL; + intel_iommu_drhd_mask = simple_strtoul(str, NULL, 0); + return 0; +} +__setup("intel_iommu_drhd_mask=", intel_iommu_drhd_mask_setup); + static struct kmem_cache *iommu_domain_cache; static struct kmem_cache *iommu_devinfo_cache; static struct kmem_cache *iommu_iova_cache; diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 482dc91..113c8e9 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -359,5 +359,6 @@ extern void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 qdep, u64 addr, unsigned mask); extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu); +extern unsigned int intel_iommu_drhd_mask; #endif