aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2008-03-07 13:36:38 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2008-03-07 13:36:38 +0000
commitce6d690203aa1d4b7e7d6d608d3905d49c388e1b (patch)
treec1311f8cd9f24b9dbcc849f73902d4158fd7d6c6 /sys
parent233f8184ecfa5df4a666a64792a97db0ecdc9d66 (diff)
downloadsrc-ce6d690203aa1d4b7e7d6d608d3905d49c388e1b.tar.gz
src-ce6d690203aa1d4b7e7d6d608d3905d49c388e1b.zip
Calculate the number of pages the GATT spans when reading from each page
to flush the TLB instead of hardcoding a size of 33 pages. Apertures of 32MB and 64MB only use a 16 page GATT and an aperture of 128MB only uses a 32 page GATT, so without this the code could walk off the end of the pointer and cause a page fault if the next page was unmapped. Also, for aperture sizes > 128MB, not all of the pages would be read. The Linux driver has the same bug. MFC after: 1 week Tested by: Frédéric PRACA frederic.praca of freebsd-fr.org
Notes
Notes: svn path=/head/; revision=176896
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/agp/agp_nvidia.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/sys/dev/agp/agp_nvidia.c b/sys/dev/agp/agp_nvidia.c
index 72cd4b883ea0..9aa082c5a90f 100644
--- a/sys/dev/agp/agp_nvidia.c
+++ b/sys/dev/agp/agp_nvidia.c
@@ -347,7 +347,7 @@ agp_nvidia_flush_tlb (device_t dev, int offset)
struct agp_nvidia_softc *sc;
u_int32_t wbc_reg, temp;
volatile u_int32_t *ag_virtual;
- int i;
+ int i, pages;
sc = (struct agp_nvidia_softc *)device_get_softc(dev);
@@ -373,9 +373,10 @@ agp_nvidia_flush_tlb (device_t dev, int offset)
ag_virtual = (volatile u_int32_t *)sc->gatt->ag_virtual;
/* Flush TLB entries. */
- for(i = 0; i < 32 + 1; i++)
+ pages = sc->gatt->ag_entries * sizeof(u_int32_t) / PAGE_SIZE;
+ for(i = 0; i < pages; i++)
temp = ag_virtual[i * PAGE_SIZE / sizeof(u_int32_t)];
- for(i = 0; i < 32 + 1; i++)
+ for(i = 0; i < pages; i++)
temp = ag_virtual[i * PAGE_SIZE / sizeof(u_int32_t)];
return (0);