Re: [PATCH] agpgart oops & chipset support, patch against 2.4.0-test6-pre2

From: Jeff Hartmann (jhartmann@valinux.com)
Date: Fri Aug 04 2000 - 11:53:11 EST


Jeff Hartmann wrote:
>
> Byron Stanoszek wrote:
> >
> > Hi guys. I have compiled in AGP + VIA chipset support into the kernel (not as
> > a module). Well, it seems like a nasty oops appears if the agp backend code
> > does not detect your card from its default list of chipsets.
> >
> > I have the output of the Oops in the following text, and I can determine the
> > cause is most likely the variable agp_bridge.current_size is NULL on line 306
> > of agpgart_be.c. However, I believe the problem is more than a quick one-liner
> > fix; rather the code should not go beyond the point of detecting the card and
> > returning anything significant for AGP support if the card is not valid.
> >
> > Of course, there's another possibility too: Default the Via chipset to the
> > generic card if it can't find it, and take out the module parameter. Anyways,
> > I'll leave that up to the agpgart developer(s) to decide.
> >
> > However, please apply the attached patch to the latest kernel that allows
> > support for my Via chipset (86C686 / 8371). You'll find this in any Epox
> > EP-7KXA motherboard (rev. 0.4).
> >
> > ---ksymoops report follows:---
> >
> > Unable to handle kernel NULL pointer dereference at virtual address 00000000
> > c01ade02
> > *pde = 00000000
> > Oops: 0000
> > CPU: 0
> > EIP: 0010:[<c01ade02>]
> > Using defaults from ksymoops -t elf32-i386 -a i386
> > EFLAGS: 00010297
> > eax: 00000000 ebx: c12bb400 ecx: 00000000 edx: 00000000
> > esi: c028ae80 edi: c12bb420 ebp: c12bb400 esp: c1259f9c
> > ds: 0018 es: 0018 ss: 0018
> > Stack: c01ade5e c028ae3c c12bb43c c01b6cfb c12bb400 00000000 c028a800 c02e0388
> > c02dfc60 00000001 c0faff35 c02c7788 c0295fd8 00000000 0008e000 c0296bfa
> > 00000f00 c0296c3a c0107007 00000f00 c0295fd8 c0108aa8 00000000 00000078
> > Call Trace: [<c01ade5e>] [<c01b6efb>] [<c01aff35>] [<c0107007>] [<c0108aa8>]
> > Code: 8b 00 c3 31 c0 c3 90 8d b4 26 00 00 00 00 57 53 8b 5c 24 0c
> >
> > >>EIP; c01ade02 <agp_return_size+12/20> <=====
> > Trace; c01ade5e <agp_copy_info+4e/70>
> > Trace; c01b6efb <drm_agp_init+bb/1f0>
> > Trace; c01aff35 <mga_init+115/1f0>
> > Trace; c0107007 <init+7/110>
> > Trace; c0108aa8 <kernel_thread+28/40>
> > Code; c01ade02 <agp_return_size+12/20>
> > 00000000 <_EIP>:
> > Code; c01ade02 <agp_return_size+12/20> <=====
> > 0: 8b 00 mov (%eax),%eax <=====
> > Code; c01ade04 <agp_return_size+14/20>
> > 2: c3 ret
> > Code; c01ade05 <agp_return_size+15/20>
> > 3: 31 c0 xor %eax,%eax
> > Code; c01ade07 <agp_return_size+17/20>
> > 5: c3 ret
> > Code; c01ade08 <agp_return_size+18/20>
> > 6: 90 nop
> > Code; c01ade09 <agp_return_size+19/20>
> > 7: 8d b4 26 00 00 00 00 lea 0x0(%esi,1),%esi
> > Code; c01ade10 <agp_copy_info+0/70>
> > e: 57 push %edi
> > Code; c01ade11 <agp_copy_info+1/70>
> > f: 53 push %ebx
> > Code; c01ade12 <agp_copy_info+2/70>
> > 10: 8b 5c 24 0c mov 0xc(%esp,1),%ebx
> >
> > Kernel panic: Attempted to kill init!
> >
> > --
> > Byron Stanoszek Ph: (330) 644-3059
> > Systems Programmer Fax: (330) 644-8110
> > Commercial Timesharing Inc. Email: bstanoszek@comtime.com
> >
> > ------------------------------------------------------------------------
> > Name: agp-via.patch
> > agp-via.patch Type: Plain Text (TEXT/PLAIN)
> > Encoding: BASE64
>
> I'll look at this, it looks like we need to setup a check for null in
> agp_copy_info when built into the kernel.
>
> -Jeff

I modified agpgart_be.c so that it always checks for an unsupported
chipset before it does anything. This change does require some
modifications to the drm so that it will function properly (some
additional checks in agpsupport.c), I've done these modifications to a
local copy of our Xfree drm kernel directory. I'll do some integration
and testing this weekend and get a patch out against the latest
pre-patch kernel. However, here is a patch to agpgart_be.c against
2.4.0-pre5 which does the checking in each exported function. It is a
completely logical change, and doesn't require any additional interfaces
to fix this problem.

-Jeff

diff -ur linux-2.4.0-test5-orig/Makefile linux/Makefile
--- linux-2.4.0-test5-orig/Makefile Thu Jul 27 14:39:16 2000
+++ linux/Makefile Fri Aug 4 09:06:03 2000
@@ -128,8 +128,8 @@
 DRIVERS-m :=
 DRIVERS- :=
 
-DRIVERS-$(CONFIG_DRM) += drivers/char/drm/drm.o
 DRIVERS-$(CONFIG_AGP) += drivers/char/agp/agp.o
+DRIVERS-$(CONFIG_DRM) += drivers/char/drm/drm.o
 DRIVERS-$(CONFIG_NUBUS) += drivers/nubus/nubus.a
 DRIVERS-$(CONFIG_ISDN) += drivers/isdn/isdn.a
 DRIVERS-$(CONFIG_NET_FC) += drivers/net/fc/fc.a
diff -ur linux-2.4.0-test5-orig/drivers/char/agp/agpgart_be.c linux/drivers/char/agp/agpgart_be.c
--- linux-2.4.0-test5-orig/drivers/char/agp/agpgart_be.c Mon Jun 19 18:59:42 2000
+++ linux/drivers/char/agp/agpgart_be.c Fri Aug 4 08:05:34 2000
@@ -108,6 +108,9 @@
 
 int agp_backend_acquire(void)
 {
+ if (agp_bridge.type == NOT_SUPPORTED) {
+ return -EINVAL;
+ }
         atomic_inc(&agp_bridge.agp_in_use);
 
         if (atomic_read(&agp_bridge.agp_in_use) != 1) {
@@ -120,6 +123,9 @@
 
 void agp_backend_release(void)
 {
+ if (agp_bridge.type == NOT_SUPPORTED) {
+ return -EINVAL;
+ }
         atomic_dec(&agp_bridge.agp_in_use);
         MOD_DEC_USE_COUNT;
 }
@@ -197,6 +203,10 @@
 {
         agp_memory *new;
 
+ if (agp_bridge.type == NOT_SUPPORTED) {
+ return NULL;
+ }
+
         new = kmalloc(sizeof(agp_memory), GFP_KERNEL);
 
         if (new == NULL) {
@@ -224,6 +234,9 @@
 {
         int i;
 
+ if (agp_bridge.type == NOT_SUPPORTED) {
+ return;
+ }
         if (curr == NULL) {
                 return;
         }
@@ -255,6 +268,9 @@
         agp_memory *new;
         int i;
 
+ if (agp_bridge.type == NOT_SUPPORTED) {
+ return NULL;
+ }
         if ((atomic_read(&agp_bridge.current_memory_agp) + page_count) >
             agp_bridge.max_memory_agp) {
                 return NULL;
@@ -334,6 +350,10 @@
 void agp_copy_info(agp_kern_info * info)
 {
         memset(info, 0, sizeof(agp_kern_info));
+ if (agp_bridge.type == NOT_SUPPORTED) {
+ info->chipset = agp_bridge.type;
+ return;
+ }
         info->version.major = agp_bridge.version->major;
         info->version.minor = agp_bridge.version->minor;
         info->device = agp_bridge.dev;
@@ -357,7 +377,8 @@
 {
         int ret_val;
 
- if ((curr == NULL) || (curr->is_bound == TRUE)) {
+ if ((agp_bridge.type == NOT_SUPPORTED) ||
+ (curr == NULL) || (curr->is_bound == TRUE)) {
                 return -EINVAL;
         }
         if (curr->is_flushed == FALSE) {
@@ -378,7 +399,7 @@
 {
         int ret_val;
 
- if (curr == NULL) {
+ if ((agp_bridge.type == NOT_SUPPORTED) || (curr == NULL)) {
                 return -EINVAL;
         }
         if (curr->is_bound != TRUE) {
@@ -791,6 +812,7 @@
 
 void agp_enable(u32 mode)
 {
+ if (agp_bridge.type == NOT_SUPPORTED) return;
         agp_bridge.agp_enable(mode);
 }
 
@@ -2451,11 +2473,14 @@
                AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR);
 
         ret_val = agp_backend_initialize();
- if (ret_val)
+ if (ret_val) {
+ agp_bridge.type = NOT_SUPPORTED;
                 return ret_val;
+ }
 
         ret_val = agp_frontend_initialize();
         if (ret_val) {
+ agp_bridge.type = NOT_SUPPORTED;
                 agp_backend_cleanup();
                 return ret_val;
         }

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Aug 07 2000 - 21:00:13 EST