From ce6d690203aa1d4b7e7d6d608d3905d49c388e1b Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 7 Mar 2008 13:36:38 +0000 Subject: [PATCH] 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. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit MFC after: 1 week Tested by: Frédéric PRACA frederic.praca of freebsd-fr.org --- sys/dev/agp/agp_nvidia.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/dev/agp/agp_nvidia.c b/sys/dev/agp/agp_nvidia.c index 72cd4b883ea..9aa082c5a90 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); -- 2.45.2