Kernel crash on Asus A7N8X-X

Frédéric PRACA frederic.praca at freebsd-fr.org
Thu Mar 6 20:38:34 UTC 2008


Selon John Baldwin <jhb at freebsd.org>:

> On Thursday 06 March 2008 08:31:26 am John Baldwin wrote:
> > The Linux AGP driver has the same code.  It appears to be forcing a read of
> > the TLB registers to force prior writes to clear the TLB entries to flush
> > perhaps?  I'm not sure why you are getting a panic.  What kind of fault did
> > you get?  (The original kernel panic messages would be needed.)
>
> Actually, it looks like you have a 64MB aperture and with either a 32MB or
> 64MB aperture this loop runs off the end of the GATT (GATT has 16384 entries
> * 4 bytes == 64k == 16 pages on x86) so if it dies before it starts the next
> loop that might explain it.  The patch below makes it walk the full GATT
> reading the first word from each page to force a flush w/o walking off the
> end of the GATT.
>
> Actually, this is what appears to have happened:
>
> (gdb) set $start = 0xd4d05000  (ag_virtual)
> (gdb) set $fva = 3570491392    (eva in trap_pfault() frame)
> (gdb) p ($fva - $start) / 4
> $2 = 17408
>
> That's well over your current ag_entries of 16384.  Try this patch (note
> Linux's in-kernel agp driver has the same bug):
>
> Index: agp_nvidia.c
> ===================================================================
> RCS file: /host/cvs/usr/cvs/src/sys/dev/agp/agp_nvidia.c,v
> retrieving revision 1.13
> diff -u -r1.13 agp_nvidia.c
> --- agp_nvidia.c	12 Nov 2007 21:51:37 -0000	1.13
> +++ agp_nvidia.c	6 Mar 2008 13:37:43 -0000
> @@ -347,7 +347,7 @@
>  	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 @@
>  	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);
>
> --
> John Baldwin

Thanks a lot John, this code works. I have been able to launch X w/o crashing
the kernel.

Fred


More information about the freebsd-hackers mailing list