Fri Aug 18 15:02:11 2017 UTC ()
Pull up following revision(s) (requested by mrg in ticket #1475):
	sys/dev/ic/i82596.c: revision 1.37
Null out sc_rx_mbuf[i] after m_freem to avoid double-free later.
From Ilja Van Sprundel.
Also null out sc_tx_mbuf[i] after m_freem, out of paranoia.
XXX Not entirely clear to how tx mbufs are freed, but no way to test
this since it's ews4800mips- and hp700-only, so not keen to make any
more elaborate changes...


(snj)
diff -r1.29 -r1.29.20.1 src/sys/dev/ic/i82596.c

cvs diff -r1.29 -r1.29.20.1 src/sys/dev/ic/i82596.c (expand / switch to unified diff)

--- src/sys/dev/ic/i82596.c 2010/04/05 07:19:35 1.29
+++ src/sys/dev/ic/i82596.c 2017/08/18 15:02:11 1.29.20.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: i82596.c,v 1.29 2010/04/05 07:19:35 joerg Exp $ */ 1/* $NetBSD: i82596.c,v 1.29.20.1 2017/08/18 15:02:11 snj Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2003 Jochen Kunz. 4 * Copyright (c) 2003 Jochen Kunz.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -33,27 +33,27 @@ @@ -33,27 +33,27 @@
33 * Driver for the Intel i82596CA and i82596DX/SX 10MBit/s Ethernet chips. 33 * Driver for the Intel i82596CA and i82596DX/SX 10MBit/s Ethernet chips.
34 * 34 *
35 * It operates the i82596 in 32-Bit Linear Mode, opposed to the old i82586 35 * It operates the i82596 in 32-Bit Linear Mode, opposed to the old i82586
36 * ie(4) driver (src/sys/dev/ic/i82586.c), that degrades the i82596 to 36 * ie(4) driver (src/sys/dev/ic/i82586.c), that degrades the i82596 to
37 * i82586 compatibility mode. 37 * i82586 compatibility mode.
38 * 38 *
39 * Documentation about these chips can be found at 39 * Documentation about these chips can be found at
40 * 40 *
41 * http://developer.intel.com/design/network/datashts/290218.htm 41 * http://developer.intel.com/design/network/datashts/290218.htm
42 * http://developer.intel.com/design/network/datashts/290219.htm 42 * http://developer.intel.com/design/network/datashts/290219.htm
43 */ 43 */
44 44
45#include <sys/cdefs.h> 45#include <sys/cdefs.h>
46__KERNEL_RCSID(0, "$NetBSD: i82596.c,v 1.29 2010/04/05 07:19:35 joerg Exp $"); 46__KERNEL_RCSID(0, "$NetBSD: i82596.c,v 1.29.20.1 2017/08/18 15:02:11 snj Exp $");
47 47
48/* autoconfig and device stuff */ 48/* autoconfig and device stuff */
49#include <sys/param.h> 49#include <sys/param.h>
50#include <sys/device.h> 50#include <sys/device.h>
51#include <sys/conf.h> 51#include <sys/conf.h>
52#include "locators.h" 52#include "locators.h"
53#include "ioconf.h" 53#include "ioconf.h"
54 54
55/* bus_space / bus_dma etc. */ 55/* bus_space / bus_dma etc. */
56#include <sys/bus.h> 56#include <sys/bus.h>
57#include <sys/intr.h> 57#include <sys/intr.h>
58 58
59/* general system data and functions */ 59/* general system data and functions */
@@ -744,50 +744,53 @@ iee_start(struct ifnet *ifp) @@ -744,50 +744,53 @@ iee_start(struct ifnet *ifp)
744 if (bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_tx_map[t], 744 if (bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_tx_map[t],
745 sc->sc_tx_mbuf[t], BUS_DMA_WRITE | BUS_DMA_NOWAIT) != 0) { 745 sc->sc_tx_mbuf[t], BUS_DMA_WRITE | BUS_DMA_NOWAIT) != 0) {
746 /* 746 /*
747 * The packet needs more TBD then we support. 747 * The packet needs more TBD then we support.
748 * Copy the packet into a mbuf cluster to get it out. 748 * Copy the packet into a mbuf cluster to get it out.
749 */ 749 */
750 printf("%s: iee_start: failed to load DMA map\n", 750 printf("%s: iee_start: failed to load DMA map\n",
751 device_xname(sc->sc_dev)); 751 device_xname(sc->sc_dev));
752 MGETHDR(m, M_DONTWAIT, MT_DATA); 752 MGETHDR(m, M_DONTWAIT, MT_DATA);
753 if (m == NULL) { 753 if (m == NULL) {
754 printf("%s: iee_start: can't allocate mbuf\n", 754 printf("%s: iee_start: can't allocate mbuf\n",
755 device_xname(sc->sc_dev)); 755 device_xname(sc->sc_dev));
756 m_freem(sc->sc_tx_mbuf[t]); 756 m_freem(sc->sc_tx_mbuf[t]);
 757 sc->sc_tx_mbuf[t] = NULL;
757 t--; 758 t--;
758 continue; 759 continue;
759 } 760 }
760 MCLAIM(m, &sc->sc_ethercom.ec_rx_mowner); 761 MCLAIM(m, &sc->sc_ethercom.ec_rx_mowner);
761 MCLGET(m, M_DONTWAIT); 762 MCLGET(m, M_DONTWAIT);
762 if ((m->m_flags & M_EXT) == 0) { 763 if ((m->m_flags & M_EXT) == 0) {
763 printf("%s: iee_start: can't allocate mbuf " 764 printf("%s: iee_start: can't allocate mbuf "
764 "cluster\n", device_xname(sc->sc_dev)); 765 "cluster\n", device_xname(sc->sc_dev));
765 m_freem(sc->sc_tx_mbuf[t]); 766 m_freem(sc->sc_tx_mbuf[t]);
 767 sc->sc_tx_mbuf[t] = NULL;
766 m_freem(m); 768 m_freem(m);
767 t--; 769 t--;
768 continue; 770 continue;
769 } 771 }
770 m_copydata(sc->sc_tx_mbuf[t], 0, 772 m_copydata(sc->sc_tx_mbuf[t], 0,
771 sc->sc_tx_mbuf[t]->m_pkthdr.len, mtod(m, void *)); 773 sc->sc_tx_mbuf[t]->m_pkthdr.len, mtod(m, void *));
772 m->m_pkthdr.len = sc->sc_tx_mbuf[t]->m_pkthdr.len; 774 m->m_pkthdr.len = sc->sc_tx_mbuf[t]->m_pkthdr.len;
773 m->m_len = sc->sc_tx_mbuf[t]->m_pkthdr.len; 775 m->m_len = sc->sc_tx_mbuf[t]->m_pkthdr.len;
774 m_freem(sc->sc_tx_mbuf[t]); 776 m_freem(sc->sc_tx_mbuf[t]);
775 sc->sc_tx_mbuf[t] = m; 777 sc->sc_tx_mbuf[t] = m;
776 if (bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_tx_map[t], 778 if (bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_tx_map[t],
777 m, BUS_DMA_WRITE | BUS_DMA_NOWAIT) != 0) { 779 m, BUS_DMA_WRITE | BUS_DMA_NOWAIT) != 0) {
778 printf("%s: iee_start: can't load TX DMA map\n", 780 printf("%s: iee_start: can't load TX DMA map\n",
779 device_xname(sc->sc_dev)); 781 device_xname(sc->sc_dev));
780 m_freem(sc->sc_tx_mbuf[t]); 782 m_freem(sc->sc_tx_mbuf[t]);
 783 sc->sc_tx_mbuf[t] = NULL;
781 t--; 784 t--;
782 continue; 785 continue;
783 } 786 }
784 } 787 }
785 for (n = 0 ; n < sc->sc_tx_map[t]->dm_nsegs ; n++) { 788 for (n = 0 ; n < sc->sc_tx_map[t]->dm_nsegs ; n++) {
786 tbd = SC_TBD(sc, sc->sc_next_tbd + n); 789 tbd = SC_TBD(sc, sc->sc_next_tbd + n);
787 tbd->tbd_tb_addr = 790 tbd->tbd_tb_addr =
788 IEE_SWAPA32(sc->sc_tx_map[t]->dm_segs[n].ds_addr); 791 IEE_SWAPA32(sc->sc_tx_map[t]->dm_segs[n].ds_addr);
789 tbd->tbd_size = 792 tbd->tbd_size =
790 sc->sc_tx_map[t]->dm_segs[n].ds_len; 793 sc->sc_tx_map[t]->dm_segs[n].ds_len;
791 tbd->tbd_link_addr = 794 tbd->tbd_link_addr =
792 IEE_SWAPA32(IEE_PHYS_SHMEM(sc->sc_tbd_off + 795 IEE_SWAPA32(IEE_PHYS_SHMEM(sc->sc_tbd_off +
793 sc->sc_tbd_sz * (sc->sc_next_tbd + n + 1))); 796 sc->sc_tbd_sz * (sc->sc_next_tbd + n + 1)));
@@ -917,48 +920,51 @@ iee_init(struct ifnet *ifp) @@ -917,48 +920,51 @@ iee_init(struct ifnet *ifp)
917 MGETHDR(sc->sc_rx_mbuf[r], M_DONTWAIT, MT_DATA); 920 MGETHDR(sc->sc_rx_mbuf[r], M_DONTWAIT, MT_DATA);
918 if (sc->sc_rx_mbuf[r] == NULL) { 921 if (sc->sc_rx_mbuf[r] == NULL) {
919 printf("%s: iee_init: can't allocate mbuf\n", 922 printf("%s: iee_init: can't allocate mbuf\n",
920 device_xname(sc->sc_dev)); 923 device_xname(sc->sc_dev));
921 err = 1; 924 err = 1;
922 break; 925 break;
923 } 926 }
924 MCLAIM(sc->sc_rx_mbuf[r],&sc->sc_ethercom.ec_rx_mowner); 927 MCLAIM(sc->sc_rx_mbuf[r],&sc->sc_ethercom.ec_rx_mowner);
925 MCLGET(sc->sc_rx_mbuf[r], M_DONTWAIT); 928 MCLGET(sc->sc_rx_mbuf[r], M_DONTWAIT);
926 if ((sc->sc_rx_mbuf[r]->m_flags & M_EXT) == 0) { 929 if ((sc->sc_rx_mbuf[r]->m_flags & M_EXT) == 0) {
927 printf("%s: iee_init: can't allocate mbuf" 930 printf("%s: iee_init: can't allocate mbuf"
928 " cluster\n", device_xname(sc->sc_dev)); 931 " cluster\n", device_xname(sc->sc_dev));
929 m_freem(sc->sc_rx_mbuf[r]); 932 m_freem(sc->sc_rx_mbuf[r]);
 933 sc->sc_rx_mbuf[r] = NULL;
930 err = 1; 934 err = 1;
931 break; 935 break;
932 } 936 }
933 sc->sc_rx_mbuf[r]->m_len = 937 sc->sc_rx_mbuf[r]->m_len =
934 sc->sc_rx_mbuf[r]->m_pkthdr.len = MCLBYTES - 2; 938 sc->sc_rx_mbuf[r]->m_pkthdr.len = MCLBYTES - 2;
935 sc->sc_rx_mbuf[r]->m_data += 2; 939 sc->sc_rx_mbuf[r]->m_data += 2;
936 } 940 }
937 if (sc->sc_rx_map[r] == NULL && bus_dmamap_create(sc->sc_dmat, 941 if (sc->sc_rx_map[r] == NULL && bus_dmamap_create(sc->sc_dmat,
938 MCLBYTES, 1, MCLBYTES , 0, BUS_DMA_NOWAIT, 942 MCLBYTES, 1, MCLBYTES , 0, BUS_DMA_NOWAIT,
939 &sc->sc_rx_map[r]) != 0) { 943 &sc->sc_rx_map[r]) != 0) {
940 printf("%s: iee_init: can't create RX " 944 printf("%s: iee_init: can't create RX "
941 "DMA map\n", device_xname(sc->sc_dev)); 945 "DMA map\n", device_xname(sc->sc_dev));
942 m_freem(sc->sc_rx_mbuf[r]); 946 m_freem(sc->sc_rx_mbuf[r]);
 947 sc->sc_rx_mbuf[r] = NULL;
943 err = 1; 948 err = 1;
944 break; 949 break;
945 } 950 }
946 if (bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_rx_map[r], 951 if (bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_rx_map[r],
947 sc->sc_rx_mbuf[r], BUS_DMA_READ | BUS_DMA_NOWAIT) != 0) { 952 sc->sc_rx_mbuf[r], BUS_DMA_READ | BUS_DMA_NOWAIT) != 0) {
948 printf("%s: iee_init: can't load RX DMA map\n", 953 printf("%s: iee_init: can't load RX DMA map\n",
949 device_xname(sc->sc_dev)); 954 device_xname(sc->sc_dev));
950 bus_dmamap_destroy(sc->sc_dmat, sc->sc_rx_map[r]); 955 bus_dmamap_destroy(sc->sc_dmat, sc->sc_rx_map[r]);
951 m_freem(sc->sc_rx_mbuf[r]); 956 m_freem(sc->sc_rx_mbuf[r]);
 957 sc->sc_rx_mbuf[r] = NULL;
952 err = 1; 958 err = 1;
953 break; 959 break;
954 } 960 }
955 bus_dmamap_sync(sc->sc_dmat, sc->sc_rx_map[r], 0, 961 bus_dmamap_sync(sc->sc_dmat, sc->sc_rx_map[r], 0,
956 sc->sc_rx_map[r]->dm_mapsize, BUS_DMASYNC_PREREAD); 962 sc->sc_rx_map[r]->dm_mapsize, BUS_DMASYNC_PREREAD);
957 SC_RBD(sc, r)->rbd_size = sc->sc_rx_map[r]->dm_segs[0].ds_len; 963 SC_RBD(sc, r)->rbd_size = sc->sc_rx_map[r]->dm_segs[0].ds_len;
958 SC_RBD(sc, r)->rbd_rb_addr = 964 SC_RBD(sc, r)->rbd_rb_addr =
959 IEE_SWAPA32(sc->sc_rx_map[r]->dm_segs[0].ds_addr); 965 IEE_SWAPA32(sc->sc_rx_map[r]->dm_segs[0].ds_addr);
960 } 966 }
961 SC_RFD(sc, 0)->rfd_rbd_addr = 967 SC_RFD(sc, 0)->rfd_rbd_addr =
962 IEE_SWAPA32(IEE_PHYS_SHMEM(sc->sc_rbd_off)); 968 IEE_SWAPA32(IEE_PHYS_SHMEM(sc->sc_rbd_off));
963 if (err != 0) { 969 if (err != 0) {
964 for (n = 0 ; n < r; n++) { 970 for (n = 0 ; n < r; n++) {