This one is a bit tricky.  In the indirect case, config_make_softc()
allocates a chunk corresponding to a given `cf->cf_attach->ca_devsize'.

ok?

Index: kern/subr_autoconf.c
===================================================================
RCS file: /cvs/src/sys/kern/subr_autoconf.c,v
retrieving revision 1.92
diff -u -p -r1.92 subr_autoconf.c
--- kern/subr_autoconf.c        14 Mar 2016 23:08:06 -0000      1.92
+++ kern/subr_autoconf.c        18 Nov 2018 16:07:04 -0000
@@ -154,13 +154,15 @@ mapply(struct matchinfo *m, struct cfdat
                    pri);
 
        if (pri > m->pri) {
-               if (m->indirect && m->match)
-                       free(m->match, M_DEVBUF, 0);
+               if (m->indirect && m->match) {
+                       cf = ((struct device *)m->match)->dv_cfdata;
+                       free(m->match, M_DEVBUF, cf->cf_attach->ca_devsize);
+               }
                m->match = match;
                m->pri = pri;
        } else {
                if (m->indirect)
-                       free(match, M_DEVBUF, 0);
+                       free(match, M_DEVBUF, cf->cf_attach->ca_devsize);
        }
 }
 
@@ -471,7 +473,7 @@ config_make_softc(struct device *parent,
                            old != 0 ? "expand" : "creat");
                if (old != 0) {
                        bcopy(cd->cd_devs, nsp, old * sizeof(void *));
-                       free(cd->cd_devs, M_DEVBUF, 0);
+                       free(cd->cd_devs, M_DEVBUF, old * sizeof(void *));
                }
                cd->cd_devs = nsp;
        }
@@ -613,7 +615,7 @@ config_detach(struct device *dev, int fl
                if (cd->cd_devs[i] != NULL)
                        break;
        if (i == cd->cd_ndevs) {                /* nothing found; deallocate */
-               free(cd->cd_devs, M_DEVBUF, 0);
+               free(cd->cd_devs, M_DEVBUF, i * sizeof(void *));
                cd->cd_devs = NULL;
                cd->cd_ndevs = 0;
                cf->cf_unit = 0;

Reply via email to