+ if (size < MAX_SIZE_ZDLUT)
+ z = get_zone_dlut(size);
+ else if (size < kalloc_max_prerounded)
+ z = get_zone_search(size, k_zindex_start);
+ else {
+ /* if size was too large for a zone, then use kmem_free */
+
+ vm_map_t alloc_map = kernel_map;
+
+ if ((((vm_offset_t) data) >= kalloc_map_min) && (((vm_offset_t) data) <= kalloc_map_max))
+ alloc_map = kalloc_map;
+ if (size > kalloc_largest_allocated) {
+ /*
+ * work around double FREEs of small MALLOCs
+ * this used to end up being a nop
+ * since the pointer being freed from an
+ * alloc backed by the zalloc world could
+ * never show up in the kalloc_map... however,
+ * the kernel_map is a different issue... since it
+ * was released back into the zalloc pool, a pointer
+ * would have gotten written over the 'size' that
+ * the MALLOC was retaining in the first 4 bytes of
+ * the underlying allocation... that pointer ends up
+ * looking like a really big size on the 2nd FREE and
+ * pushes the kfree into the kernel_map... we
+ * end up removing a ton of virtual space before we panic
+ * this check causes us to ignore the kfree for a size
+ * that must be 'bogus'... note that it might not be due
+ * to the above scenario, but it would still be wrong and
+ * cause serious damage.
+ */
+
+ OSAddAtomic(1, &kfree_nop_count);
+ return;
+ }
+ kmem_free(alloc_map, (vm_offset_t)data, size);
+ kalloc_spin_lock();