[Intel-gfx] [PATCH] agp/intel: Correctly initialise the IFP resource for allocation

Chris Wilson chris at chris-wilson.co.uk
Sat Sep 4 15:19:17 CEST 2010


In order to allocate a resource we need to specify the resource type or
else the allocation will fail. In this case, the failure would lead to
silent memory corruption as the Global Write Buffer would not be flushed
prior to access by the GPU. This could result in invalid rendering or
worse.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/char/agp/intel-gtt.c |   82 ++++++++++++++++++++++++++---------------
 1 files changed, 52 insertions(+), 30 deletions(-)

diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index d22ffb8..8f27ebc 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -68,7 +68,9 @@ static struct _intel_private {
 	struct page *i8xx_page;
 	struct resource ifp_resource;
 	int resource_valid;
-} intel_private;
+} intel_private = {
+	.ifp_resource = { .name = "Isoch Flush Page", .flags = IORESOURCE_MEM }
+};
 
 #ifdef USE_PCI_DMA_API
 static int intel_agp_map_page(struct page *page, dma_addr_t *ret)
@@ -986,65 +988,85 @@ static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count, int type)
 static int intel_alloc_chipset_flush_resource(void)
 {
 	int ret;
-	ret = pci_bus_alloc_resource(agp_bridge->dev->bus, &intel_private.ifp_resource, PAGE_SIZE,
-				     PAGE_SIZE, PCIBIOS_MIN_MEM, 0,
-				     pcibios_align_resource, agp_bridge->dev);
+
+	ret = pci_bus_alloc_resource(agp_bridge->dev->bus,
+				     &intel_private.ifp_resource,
+				     PAGE_SIZE, PAGE_SIZE,
+				     PCIBIOS_MIN_MEM, 0,
+				     pcibios_align_resource,
+				     agp_bridge->dev);
+	if (ret) {
+		dev_err(&intel_private.pcidev->dev,
+			"Failed to allocate Isoch Flush Page: %d.",
+			ret);
+		intel_private.resource_valid = 0;
+	}
 
 	return ret;
 }
 
-static void intel_i915_setup_chipset_flush(void)
+static int intel_request_chipset_flush_resource(u64 addr)
 {
 	int ret;
+
+	intel_private.ifp_resource.start = addr;
+	intel_private.ifp_resource.end = addr + PAGE_SIZE;
+
+	ret = request_resource(&iomem_resource, &intel_private.ifp_resource);
+	/* some BIOSes reserve this area in a pnp some don't */
+	if (ret) {
+		dev_err(&intel_private.pcidev->dev,
+			"Failed to request Isoch Flush Page: %d.",
+			ret);
+		intel_private.resource_valid = 0;
+	}
+
+	return ret;
+}
+
+static void intel_i915_setup_chipset_flush(void)
+{
 	u32 temp;
 
 	pci_read_config_dword(agp_bridge->dev, I915_IFPADDR, &temp);
+
+	intel_private.resource_valid = 1;
 	if (!(temp & 0x1)) {
-		intel_alloc_chipset_flush_resource();
-		intel_private.resource_valid = 1;
-		pci_write_config_dword(agp_bridge->dev, I915_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1);
+		if (intel_alloc_chipset_flush_resource() == 0)
+			pci_write_config_dword(agp_bridge->dev,
+					       I915_IFPADDR,
+					       (intel_private.ifp_resource.start & 0xffffffff) | 0x1);
 	} else {
 		temp &= ~1;
+		intel_request_chipset_flush_resource(temp);
 
-		intel_private.resource_valid = 1;
-		intel_private.ifp_resource.start = temp;
-		intel_private.ifp_resource.end = temp + PAGE_SIZE;
-		ret = request_resource(&iomem_resource, &intel_private.ifp_resource);
-		/* some BIOSes reserve this area in a pnp some don't */
-		if (ret)
-			intel_private.resource_valid = 0;
 	}
 }
 
 static void intel_i965_g33_setup_chipset_flush(void)
 {
 	u32 temp_hi, temp_lo;
-	int ret;
 
 	pci_read_config_dword(agp_bridge->dev, I965_IFPADDR + 4, &temp_hi);
 	pci_read_config_dword(agp_bridge->dev, I965_IFPADDR, &temp_lo);
 
+	intel_private.resource_valid = 1;
 	if (!(temp_lo & 0x1)) {
-
-		intel_alloc_chipset_flush_resource();
-
-		intel_private.resource_valid = 1;
-		pci_write_config_dword(agp_bridge->dev, I965_IFPADDR + 4,
-			upper_32_bits(intel_private.ifp_resource.start));
-		pci_write_config_dword(agp_bridge->dev, I965_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1);
+		if (intel_alloc_chipset_flush_resource() == 0) {
+			pci_write_config_dword(agp_bridge->dev,
+					       I965_IFPADDR + 4,
+					       upper_32_bits(intel_private.ifp_resource.start));
+			pci_write_config_dword(agp_bridge->dev,
+					       I965_IFPADDR,
+					       (intel_private.ifp_resource.start & 0xffffffff) | 0x1);
+		}
 	} else {
 		u64 l64;
 
 		temp_lo &= ~0x1;
 		l64 = ((u64)temp_hi << 32) | temp_lo;
 
-		intel_private.resource_valid = 1;
-		intel_private.ifp_resource.start = l64;
-		intel_private.ifp_resource.end = l64 + PAGE_SIZE;
-		ret = request_resource(&iomem_resource, &intel_private.ifp_resource);
-		/* some BIOSes reserve this area in a pnp some don't */
-		if (ret)
-			intel_private.resource_valid = 0;
+		intel_request_chipset_flush_resource(l64);
 	}
 }
 
-- 
1.7.1




More information about the Intel-gfx mailing list