All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] agp/intel: Correctly initialise the IFP resource for allocation
@ 2010-09-04 13:19 Chris Wilson
  2010-09-04 13:54 ` Chris Wilson
  2010-09-04 14:03 ` [PATCH] agp/intel: Promote warning about failure to setup flush to error Chris Wilson
  0 siblings, 2 replies; 3+ messages in thread
From: Chris Wilson @ 2010-09-04 13:19 UTC (permalink / raw)
  To: intel-gfx

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@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

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-09-04 14:02 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-04 13:19 [PATCH] agp/intel: Correctly initialise the IFP resource for allocation Chris Wilson
2010-09-04 13:54 ` Chris Wilson
2010-09-04 14:03 ` [PATCH] agp/intel: Promote warning about failure to setup flush to error Chris Wilson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.