changeset 3735:74d8d0dc0268

6419785 memory leak in pcicfg_unconfigure()
author prasad
date Wed, 28 Feb 2007 18:20:16 -0800
parents cc8896fe34a1
children aa9dbf463acb
files usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c
diffstat 1 files changed, 41 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c	Wed Feb 28 17:06:58 2007 -0800
+++ b/usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c	Wed Feb 28 18:20:16 2007 -0800
@@ -849,6 +849,7 @@
 			NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS) != NDI_SUCCESS) {
 			DEBUG0("Failed to free a bus number\n");
 			rc = PCICFG_FAILURE;
+			kmem_free(bus, k);
 			return (rc);
 		}
 
@@ -863,6 +864,7 @@
 		entry->memory_len = 0;
 		entry->pf_memory_len = 0;
 		entry->io_len = 0;
+		kmem_free(bus, k);
 		/* the following will free hole data. */
 		(void) pcicfg_destroy_phdl(new_device);
 	}
@@ -1627,6 +1629,7 @@
 				"bus-range", bus_range, 2) != DDI_SUCCESS) {
 			DEBUG0("Failed to set bus-range property");
 			entry->error = PCICFG_FAILURE;
+			(void) pcicfg_config_teardown(&handle);
 			return (DDI_WALK_TERMINATE);
 		}
 
@@ -1666,6 +1669,7 @@
 			if (pcicfg_update_ranges_prop(dip, &range[0])) {
 				DEBUG0("Failed to update ranges (i/o)\n");
 				entry->error = PCICFG_FAILURE;
+				(void) pcicfg_config_teardown(&handle);
 				return (DDI_WALK_TERMINATE);
 			}
 		}
@@ -1675,6 +1679,7 @@
 			if (pcicfg_update_ranges_prop(dip, &range[1])) {
 				DEBUG0("Failed to update ranges (memory)\n");
 				entry->error = PCICFG_FAILURE;
+				(void) pcicfg_config_teardown(&handle);
 				return (DDI_WALK_TERMINATE);
 			}
 		}
@@ -1684,6 +1689,7 @@
 			if (pcicfg_update_ranges_prop(dip, &range[2])) {
 				DEBUG0("Failed to update ranges (PF memory)\n");
 				entry->error = PCICFG_FAILURE;
+				(void) pcicfg_config_teardown(&handle);
 				return (DDI_WALK_TERMINATE);
 			}
 		}
@@ -1692,6 +1698,8 @@
 
 		PCICFG_DUMP_BRIDGE_CONFIG(handle);
 
+		(void) pcicfg_config_teardown(&handle);
+
 		return (DDI_WALK_PRUNECHILD);
 	}
 
@@ -1713,6 +1721,7 @@
 		&length) != DDI_PROP_SUCCESS) {
 		DEBUG0("Failed to read reg property\n");
 		entry->error = PCICFG_FAILURE;
+		(void) pcicfg_config_teardown(&handle);
 		return (DDI_WALK_TERMINATE);
 	}
 
@@ -1849,6 +1858,7 @@
 
 	if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
 		DEBUG0("Failed to map config space!\n");
+		kmem_free(reg, length);
 		return (PCICFG_FAILURE);
 	}
 
@@ -2205,6 +2215,7 @@
 			entry->io_len = 0;
 			entry->pf_memory_len = 0;
 			entry->error = PCICFG_FAILURE;
+			(void) pcicfg_config_teardown(&handle);
 			return (DDI_WALK_TERMINATE);
 		}
 		/*
@@ -2288,7 +2299,7 @@
 	ppb_ranges_t		*ranges;
 	uint_t			*bus;
 	int			k;
-	int			length;
+	int			length = 0;
 	int			i;
 
 
@@ -2387,8 +2398,11 @@
 		(uint64_t)bus[0], (uint64_t)(bus[1] - bus[0] + 1),
 		NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS) != NDI_SUCCESS) {
 		DEBUG0("Failed to free a bus number\n");
+		kmem_free(bus, k);
 		return (PCICFG_FAILURE);
 	}
+
+	kmem_free(bus, k);
 	return (PCICFG_SUCCESS);
 }
 
@@ -2441,12 +2455,13 @@
 					mem_type = NDI_RA_TYPE_MEM;
 
 				if (ndi_ra_free(ddi_get_parent(dip),
-				(uint64_t)assigned[i].pci_phys_low,
-				(uint64_t)assigned[i].pci_size_low,
-				mem_type, NDI_RA_PASS) != NDI_SUCCESS) {
-				DEBUG0("Trouble freeing "
-				"PCI memory space\n");
-				return (PCICFG_FAILURE);
+				    (uint64_t)assigned[i].pci_phys_low,
+				    (uint64_t)assigned[i].pci_size_low,
+				    mem_type, NDI_RA_PASS) != NDI_SUCCESS) {
+					DEBUG0("Trouble freeing "
+					"PCI memory space\n");
+					kmem_free(assigned, length);
+					return (PCICFG_FAILURE);
 				}
 
 				DEBUG4("Returned 0x%x of 32 bit %s space"
@@ -2464,13 +2479,14 @@
 					mem_type = NDI_RA_TYPE_MEM;
 
 				if (ndi_ra_free(ddi_get_parent(dip),
-				PCICFG_LADDR(assigned[i].pci_phys_low,
-				assigned[i].pci_phys_mid),
-				(uint64_t)assigned[i].pci_size_low,
-				mem_type, NDI_RA_PASS) != NDI_SUCCESS) {
-				DEBUG0("Trouble freeing "
-				"PCI memory space\n");
-				return (PCICFG_FAILURE);
+				    PCICFG_LADDR(assigned[i].pci_phys_low,
+				    assigned[i].pci_phys_mid),
+				    (uint64_t)assigned[i].pci_size_low,
+				    mem_type, NDI_RA_PASS) != NDI_SUCCESS) {
+					DEBUG0("Trouble freeing "
+					"PCI memory space\n");
+					kmem_free(assigned, length);
+					return (PCICFG_FAILURE);
 				}
 
 				DEBUG5("Returned 0x%x of 64 bit %s space"
@@ -2484,12 +2500,14 @@
 			break;
 			case PCI_REG_ADDR_G(PCI_ADDR_IO):
 				if (ndi_ra_free(ddi_get_parent(dip),
-				(uint64_t)assigned[i].pci_phys_low,
-				(uint64_t)assigned[i].pci_size_low,
-				NDI_RA_TYPE_IO, NDI_RA_PASS) != NDI_SUCCESS) {
-				DEBUG0("Trouble freeing "
-				"PCI IO space\n");
-				return (PCICFG_FAILURE);
+				    (uint64_t)assigned[i].pci_phys_low,
+				    (uint64_t)assigned[i].pci_size_low,
+				    NDI_RA_TYPE_IO, NDI_RA_PASS) !=
+				    NDI_SUCCESS) {
+					DEBUG0("Trouble freeing "
+					"PCI IO space\n");
+					kmem_free(assigned, length);
+					return (PCICFG_FAILURE);
 				}
 				DEBUG3("Returned 0x%x of IO space @ 0x%x"
 				" from register 0x%x\n",
@@ -3165,16 +3183,14 @@
 
 	} while (pcicfg_do_legacy_props);
 
-	if ((ret = ndi_prop_update_string_array(DDI_DEV_T_NONE, dip,
-		"compatible", (char **)compat, n)) != DDI_SUCCESS) {
-		return (ret);
-	}
+	ret = ndi_prop_update_string_array(DDI_DEV_T_NONE, dip,
+		"compatible", (char **)compat, n);
 
 	for (i = 0; i < n; i++) {
 		kmem_free(compat[i], strlen(compat[i]) + 1);
 	}
 
-	return (PCICFG_SUCCESS);
+	return (ret);
 }
 
 /*