Skip to content

Commit

Permalink
Merge git://git.infradead.org/users/dwmw2/iommu-2.6.32
Browse files Browse the repository at this point in the history
* git://git.infradead.org/users/dwmw2/iommu-2.6.32:
  intel-iommu: Support PCIe hot-plug
  intel-iommu: Obey coherent_dma_mask for alloc_coherent on passthrough
  intel-iommu: Check for 'DMAR at zero' BIOS error earlier.
  • Loading branch information
Linus Torvalds committed Nov 14, 2009
2 parents 24dfb2b + 99dcade commit a9366e6
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 11 deletions.
49 changes: 39 additions & 10 deletions drivers/pci/dmar.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,15 +175,6 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header)
int ret = 0;

drhd = (struct acpi_dmar_hardware_unit *)header;
if (!drhd->address) {
/* Promote an attitude of violence to a BIOS engineer today */
WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n"
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
dmi_get_system_info(DMI_BIOS_VENDOR),
dmi_get_system_info(DMI_BIOS_VERSION),
dmi_get_system_info(DMI_PRODUCT_VERSION));
return -ENODEV;
}
dmaru = kzalloc(sizeof(*dmaru), GFP_KERNEL);
if (!dmaru)
return -ENOMEM;
Expand Down Expand Up @@ -591,12 +582,50 @@ int __init dmar_table_init(void)
return 0;
}

int __init check_zero_address(void)
{
struct acpi_table_dmar *dmar;
struct acpi_dmar_header *entry_header;
struct acpi_dmar_hardware_unit *drhd;

dmar = (struct acpi_table_dmar *)dmar_tbl;
entry_header = (struct acpi_dmar_header *)(dmar + 1);

while (((unsigned long)entry_header) <
(((unsigned long)dmar) + dmar_tbl->length)) {
/* Avoid looping forever on bad ACPI tables */
if (entry_header->length == 0) {
printk(KERN_WARNING PREFIX
"Invalid 0-length structure\n");
return 0;
}

if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) {
drhd = (void *)entry_header;
if (!drhd->address) {
/* Promote an attitude of violence to a BIOS engineer today */
WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n"
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
dmi_get_system_info(DMI_BIOS_VENDOR),
dmi_get_system_info(DMI_BIOS_VERSION),
dmi_get_system_info(DMI_PRODUCT_VERSION));
return 0;
}
break;
}

entry_header = ((void *)entry_header + entry_header->length);
}
return 1;
}

void __init detect_intel_iommu(void)
{
int ret;

ret = dmar_table_detect();

if (ret)
ret = check_zero_address();
{
#ifdef CONFIG_INTR_REMAP
struct acpi_table_dmar *dmar;
Expand Down
39 changes: 38 additions & 1 deletion drivers/pci/intel-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2767,7 +2767,15 @@ static void *intel_alloc_coherent(struct device *hwdev, size_t size,

size = PAGE_ALIGN(size);
order = get_order(size);
flags &= ~(GFP_DMA | GFP_DMA32);

if (!iommu_no_mapping(hwdev))
flags &= ~(GFP_DMA | GFP_DMA32);
else if (hwdev->coherent_dma_mask < dma_get_required_mask(hwdev)) {
if (hwdev->coherent_dma_mask < DMA_BIT_MASK(32))
flags |= GFP_DMA;
else
flags |= GFP_DMA32;
}

vaddr = (void *)__get_free_pages(flags, order);
if (!vaddr)
Expand Down Expand Up @@ -3207,6 +3215,33 @@ static int __init init_iommu_sysfs(void)
}
#endif /* CONFIG_PM */

/*
* Here we only respond to action of unbound device from driver.
*
* Added device is not attached to its DMAR domain here yet. That will happen
* when mapping the device to iova.
*/
static int device_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
struct device *dev = data;
struct pci_dev *pdev = to_pci_dev(dev);
struct dmar_domain *domain;

domain = find_domain(pdev);
if (!domain)
return 0;

if (action == BUS_NOTIFY_UNBOUND_DRIVER && !iommu_pass_through)
domain_remove_one_dev_info(domain, pdev);

return 0;
}

static struct notifier_block device_nb = {
.notifier_call = device_notifier,
};

int __init intel_iommu_init(void)
{
int ret = 0;
Expand Down Expand Up @@ -3259,6 +3294,8 @@ int __init intel_iommu_init(void)

register_iommu(&intel_iommu_ops);

bus_register_notifier(&pci_bus_type, &device_nb);

return 0;
}

Expand Down

0 comments on commit a9366e6

Please sign in to comment.