[PATCH 01/23] AMD IOMMU: check for invalid device pointers

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Joerg Roedel
Date: Wednesday, September 17, 2008 - 9:52 am

Currently AMD IOMMU code triggers a BUG_ON if NULL is passed as the
device. This is inconsistent with other IOMMU implementations. This
patch fixes it.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/kernel/amd_iommu.c |   43 +++++++++++++++++++++++++++++++++++--------
 1 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 01c68c3..695e0fc 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -646,6 +646,18 @@ static void set_device_domain(struct amd_iommu *iommu,
  *****************************************************************************/
 
 /*
+ * This function checks if the driver got a valid device from the caller to
+ * avoid dereferencing invalid pointers.
+ */
+static bool check_device(struct device *dev)
+{
+	if (!dev || !dev->dma_mask)
+		return false;
+
+	return true;
+}
+
+/*
  * In the dma_ops path we only have the struct device. This function
  * finds the corresponding IOMMU, the protection domain and the
  * requestor id for a given device.
@@ -661,18 +673,19 @@ static int get_device_resources(struct device *dev,
 	struct pci_dev *pcidev;
 	u16 _bdf;
 
-	BUG_ON(!dev || dev->bus != &pci_bus_type || !dev->dma_mask);
+	*iommu = NULL;
+	*domain = NULL;
+	*bdf = 0xffff;
+
+	if (dev->bus != &pci_bus_type)
+		return 0;
 
 	pcidev = to_pci_dev(dev);
 	_bdf = calc_devid(pcidev->bus->number, pcidev->devfn);
 
 	/* device not translated by any IOMMU in the system? */
-	if (_bdf > amd_iommu_last_bdf) {
-		*iommu = NULL;
-		*domain = NULL;
-		*bdf = 0xffff;
+	if (_bdf > amd_iommu_last_bdf)
 		return 0;
-	}
 
 	*bdf = amd_iommu_alias_table[_bdf];
 
@@ -826,6 +839,9 @@ static dma_addr_t map_single(struct device *dev, phys_addr_t paddr,
 	u16 devid;
 	dma_addr_t addr;
 
+	if (!check_device(dev))
+		return bad_dma_address;
+
 	get_device_resources(dev, &iommu, &domain, &devid);
 
 	if (iommu == NULL || domain == NULL)
@@ -860,7 +876,8 @@ static void unmap_single(struct device *dev, dma_addr_t dma_addr,
 	struct protection_domain *domain;
 	u16 devid;
 
-	if (!get_device_resources(dev, &iommu, &domain, &devid))
+	if (!check_device(dev) ||
+	    !get_device_resources(dev, &iommu, &domain, &devid))
 		/* device not handled by any AMD IOMMU */
 		return;
 
@@ -910,6 +927,9 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
 	phys_addr_t paddr;
 	int mapped_elems = 0;
 
+	if (!check_device(dev))
+		return 0;
+
 	get_device_resources(dev, &iommu, &domain, &devid);
 
 	if (!iommu || !domain)
@@ -967,7 +987,8 @@ static void unmap_sg(struct device *dev, struct scatterlist *sglist,
 	u16 devid;
 	int i;
 
-	if (!get_device_resources(dev, &iommu, &domain, &devid))
+	if (!check_device(dev) ||
+	    !get_device_resources(dev, &iommu, &domain, &devid))
 		return;
 
 	spin_lock_irqsave(&domain->lock, flags);
@@ -999,6 +1020,9 @@ static void *alloc_coherent(struct device *dev, size_t size,
 	u16 devid;
 	phys_addr_t paddr;
 
+	if (!check_device(dev))
+		return NULL;
+
 	virt_addr = (void *)__get_free_pages(flag, get_order(size));
 	if (!virt_addr)
 		return 0;
@@ -1047,6 +1071,9 @@ static void free_coherent(struct device *dev, size_t size,
 	struct protection_domain *domain;
 	u16 devid;
 
+	if (!check_device(dev))
+		return;
+
 	get_device_resources(dev, &iommu, &domain, &devid);
 
 	if (!iommu || !domain)
-- 
1.5.6.4


--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH 0/23] AMD IOMMU 2.6.28 updates for review, Joerg Roedel, (Wed Sep 17, 9:52 am)
[PATCH 01/23] AMD IOMMU: check for invalid device pointers, Joerg Roedel, (Wed Sep 17, 9:52 am)
[PATCH 03/23] AMD IOMMU: implement lazy IO/TLB flushing, Joerg Roedel, (Wed Sep 17, 9:52 am)
[PATCH 06/23] AMD IOMMU: add event buffer allocation, Joerg Roedel, (Wed Sep 17, 9:52 am)
[PATCH 08/23] AMD IOMMU: save pci_dev instead of devid, Joerg Roedel, (Wed Sep 17, 9:52 am)
[PATCH 09/23] AMD IOMMU: add MSI interrupt support, Joerg Roedel, (Wed Sep 17, 9:52 am)
[PATCH 10/23] AMD IOMMU: add event handling code, Joerg Roedel, (Wed Sep 17, 9:52 am)
[PATCH 11/23] AMD IOMMU: enable event logging, Joerg Roedel, (Wed Sep 17, 9:52 am)
[PATCH 13/23] AMD IOMMU: add dma_supported callback, Joerg Roedel, (Wed Sep 17, 9:52 am)
[PATCH 18/23] AMD IOMMU: simplify dma_mask_to_pages, Joerg Roedel, (Wed Sep 17, 9:52 am)
[PATCH 23/23] add AMD IOMMU tree to MAINTAINERS file, Joerg Roedel, (Wed Sep 17, 9:52 am)
Re: [PATCH 03/23] AMD IOMMU: implement lazy IO/TLB flushing, FUJITA Tomonori, (Wed Sep 17, 12:20 pm)
Re: [PATCH 18/23] AMD IOMMU: simplify dma_mask_to_pages, FUJITA Tomonori, (Wed Sep 17, 12:20 pm)
Re: [PATCH 03/23] AMD IOMMU: implement lazy IO/TLB flushing, FUJITA Tomonori, (Wed Sep 17, 6:29 pm)
Re: [PATCH 18/23] AMD IOMMU: simplify dma_mask_to_pages, Joerg Roedel, (Thu Sep 18, 12:32 am)
Re: [PATCH 18/23] AMD IOMMU: simplify dma_mask_to_pages, FUJITA Tomonori, (Thu Sep 18, 8:57 am)
Re: [PATCH 18/23] AMD IOMMU: simplify dma_mask_to_pages, Joerg Roedel, (Thu Sep 18, 9:39 am)
Re: [PATCH 03/23] AMD IOMMU: implement lazy IO/TLB flushing, FUJITA Tomonori, (Thu Sep 18, 4:10 pm)
Re: [PATCH 03/23] AMD IOMMU: implement lazy IO/TLB flushing, FUJITA Tomonori, (Fri Sep 19, 3:21 am)
Re: [PATCH 03/23] AMD IOMMU: implement lazy IO/TLB flushing, FUJITA Tomonori, (Fri Sep 19, 11:40 am)
RE: [PATCH 03/23] AMD IOMMU: implement lazy IO/TLB flushing, Keshavamurthy, Anil S, (Fri Sep 19, 11:47 am)
Re: [PATCH 03/23] AMD IOMMU: implement lazy IO/TLB flushing, Muli Ben-Yehuda, (Sat Sep 20, 10:27 pm)