NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/39382: uvm_fault in recognizing codec ALC662-GR at boot



>Number:         39382
>Category:       kern
>Synopsis:       uvm_fault in recognizing codec ALC662-GR at boot
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Aug 19 21:50:01 +0000 2008
>Originator:     Takahiro Hayashi
>Release:        current 4.99.72
>Organization:
>Environment:
NetBSD peer 4.99.72 NetBSD 4.99.72 (PEER) #13: Tue Aug 19 14:30:54 JST 2008  
root@peer:/usr/obj/sys/arch/i386/compile/PEER i386
>Description:
On Intel D945GCLF mother board GENERIC kernel may uvm_fault
at recognizing codec ALC662-GR.

azalia0: codec[2]: Realtek ALC662-GR (rev. 1.1), HDA rev. 1.0
uvm_fault(0xc0adfb00, 0xc3184000, 1) -> 0xe
fatal page fault in supervisor mode
trap type 6 code 0 eip c07b2964 cs 8 eflags 10202 cr2 c3184004 ilevel 0
kernel: supervisor trap page fault, code=0
Stopped in pid 0.23 (system) at netbsd:memcpy+0x14:     repe movsl      (%esi),%
es:(%edi)
db{0}> trace
memcpy(cce5f02c,d,cce6019c,26,fa,0,0,cce5f02c,0,0) at netbsd:memcpy+0x14
azalia_attach_intr(cccb2dc4,0,cc395520,c046c180,cc395520,cc395520,0,c01002e1,cc3
95520,0) at netbsd:azalia_attach_intr+0xec9
config_interrupts_thread(cc395520,0,c01002cd,0,c01002cd,0,0,0,0,0) at netbsd:con
fig_interrupts_thread+0x27
db{0}>

This occurs in second memcpy() in function
sys/dev/pci/azalia_codec.c:generic_mixer_create_virtual().
The problem is referencing pointers which point realloc()'ed
area calculated before realloc().
realloc() may move the area so pointers need recalculation.

>How-To-Repeat:
boot GENERIC kernel on D945GCLF board
>Fix:
The variables pointing this->mixers should be recalculated
after generic_mixer_ensure_capacity() which uses realloc()
like this (sorry for tab-space confusion):

Index: sys/dev/pci/azalia_codec.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/azalia_codec.c,v
retrieving revision 1.70
diff -u -r1.70 azalia_codec.c
--- sys/dev/pci/azalia_codec.c  15 Aug 2008 13:47:25 -0000      1.70
+++ sys/dev/pci/azalia_codec.c  19 Aug 2008 05:43:53 -0000
@@ -1320,7 +1320,7 @@
        mixer_devinfo_t *d;
        convgroup_t *cgdac = &this->dacs.groups[0];
        convgroup_t *cgadc = &this->adcs.groups[0];
-       int i, err;
+       int i, imdac, imadc, err;

        /* Clear mixer indexes, to make generic_mixer_fix_index happy */
        for (i = 0; i < this->nmixers; i++) {
@@ -1328,18 +1328,23 @@
                d->index = d->prev = d->next = 0;
        }

+       imdac = imadc = 0;
        for (i = 0; i < this->nmixers; i++) {
                if (this->mixers[i].devinfo.type != AUDIO_MIXER_VALUE)
                        continue;
                if (mdac == NULL && this->dacs.ngroups > 0 &&
                    cgdac->nconv > 0) {
-                       if (this->mixers[i].nid == cgdac->conv[0])
-                               mdac = mmaster = &this->mixers[i];
+                       if (this->mixers[i].nid == cgdac->conv[0]) {
+                               imdac = i;
+                               mdac = mmaster = &this->mixers[imdac];
+                       }
                }
                if (madc == NULL && this->adcs.ngroups > 0 &&
                    cgadc->nconv > 0) {
-                       if (this->mixers[i].nid == cgadc->conv[0])
-                               madc = &this->mixers[i];
+                       if (this->mixers[i].nid == cgadc->conv[0]) {
+                               imadc = i;
+                               madc = &this->mixers[imadc];
+                       }
                }
        }

@@ -1349,6 +1354,7 @@
                        return err;
                m = &this->mixers[this->nmixers];
                d = &m->devinfo;
+               mdac = mmaster = &this->mixers[imdac];
                memcpy(m, mmaster, sizeof(*m));
                d->mixer_class = AZ_CLASS_OUTPUT;
                snprintf(d->label.name, sizeof(d->label.name), AudioNmaster);
@@ -1359,6 +1365,7 @@
                        return err;
                m = &this->mixers[this->nmixers];
                d = &m->devinfo;
+               mdac = mmaster = &this->mixers[imdac];
                memcpy(m, mdac, sizeof(*m));
                d->mixer_class = AZ_CLASS_INPUT;
                snprintf(d->label.name, sizeof(d->label.name), AudioNdac);
@@ -1371,6 +1378,7 @@
                        return err;
                m = &this->mixers[this->nmixers];
                d = &m->devinfo;
+               madc = &this->mixers[imadc];
                memcpy(m, madc, sizeof(*m));
                d->mixer_class = AZ_CLASS_RECORD;
                snprintf(d->label.name,sizeof(d->label.name), AudioNvolume);



Home | Main Index | Thread Index | Old Index