summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2008-12-10 19:33:26 +0100
committerJoerg Roedel <joerg.roedel@amd.com>2009-01-03 14:11:56 +0100
commit1ac4cbbc5eb56de96d264d10f464ba5222815b1b (patch)
tree1d98c0382683b4c7ec40602273fed14aabf222c7
parente2dc14a2a6c9a83baaafc51f06b7e73cec2167be (diff)
downloadlinux-1ac4cbbc5eb56de96d264d10f464ba5222815b1b.tar.gz
AMD IOMMU: allocate a new protection for hotplugged devices
Impact: also hotplug devices benefit from device isolation

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
-rw-r--r--arch/x86/kernel/amd_iommu.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index f2956546423b..f2260609eadc 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -923,6 +923,8 @@ static int device_change_notifier(struct notifier_block *nb,
 	struct protection_domain *domain;
 	struct dma_ops_domain *dma_domain;
 	struct amd_iommu *iommu;
+	int order = amd_iommu_aperture_order;
+	unsigned long flags;
 
 	if (devid > amd_iommu_last_bdf)
 		goto out;
@@ -955,6 +957,21 @@ static int device_change_notifier(struct notifier_block *nb,
 			goto out;
 		detach_device(domain, devid);
 		break;
+	case BUS_NOTIFY_ADD_DEVICE:
+		/* allocate a protection domain if a device is added */
+		dma_domain = find_protection_domain(devid);
+		if (dma_domain)
+			goto out;
+		dma_domain = dma_ops_domain_alloc(iommu, order);
+		if (!dma_domain)
+			goto out;
+		dma_domain->target_dev = devid;
+
+		spin_lock_irqsave(&iommu_pd_list_lock, flags);
+		list_add_tail(&dma_domain->list, &iommu_pd_list);
+		spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
+
+		break;
 	default:
 		goto out;
 	}