} 
static int do_kimage_alloc(struct kimage **rimage, unsigned long entry,	unsigned long nr_segments, struct kexec_segment __user *segments){	size_t segment_bytes;	struct kimage *image;	unsigned long i;	int result;	/* Allocate a controlling structure */	result = -ENOMEM;	image = kmalloc(sizeof(*image), GFP_KERNEL);	if (!image) {		goto out;	}	memset(image, 0, sizeof(*image));	image->head = 0;	image->entry = &image->head;	image->last_entry = &image->head;	image->control_page = ~0; /* By default this does not apply */	image->start = entry;	image->type = KEXEC_TYPE_DEFAULT;	/* Initialize the list of control pages */	INIT_LIST_HEAD(&image->control_pages);	/* Initialize the list of destination pages */	INIT_LIST_HEAD(&image->dest_pages);	/* Initialize the list of unuseable pages */	INIT_LIST_HEAD(&image->unuseable_pages);	/* Read in the segments */	image->nr_segments = nr_segments;	segment_bytes = nr_segments * sizeof(*segments);	result = copy_from_user(image->segment, segments, segment_bytes);	if (result)		goto out;	/*	 * Verify we have good destination addresses.  The caller is	 * responsible for making certain we don't attempt to load	 * the new image into invalid or reserved areas of RAM.  This	 * just verifies it is an address we can use.	 *	 * Since the kernel does everything in page size chunks ensure	 * the destination addreses are page aligned.  Too many	 * special cases crop of when we don't do this.  The most	 * insidious is getting overlapping destination addresses	 * simply because addresses are changed to page size	 * granularity.	 */	result = -EADDRNOTAVAIL;	for (i = 0; i < nr_segments; i++) {		unsigned long mstart, mend;		mstart = image->segment[i].mem;		mend   = mstart + image->segment[i].memsz;		if ((mstart & ~PAGE_MASK) || (mend & ~PAGE_MASK))			goto out;		if (mend >= KEXEC_DESTINATION_MEMORY_LIMIT)			goto out;	}	/* Verify our destination addresses do not overlap.	 * If we alloed overlapping destination addresses	 * through very weird things can happen with no	 * easy explanation as one segment stops on another.	 */	result = -EINVAL;	for(i = 0; i < nr_segments; i++) {		unsigned long mstart, mend;		unsigned long j;		mstart = image->segment[i].mem;		mend   = mstart + image->segment[i].memsz;		for(j = 0; j < i; j++) {			unsigned long pstart, pend;			pstart = image->segment[j].mem;			pend   = pstart + image->segment[j].memsz;			/* Do the segments overlap ? */			if ((mend > pstart) && (mstart < pend))				goto out;		}	}	/* Ensure our buffer sizes are strictly less than	 * our memory sizes.  This should always be the case,	 * and it is easier to check up front than to be surprised	 * later on.	 */	result = -EINVAL;	for(i = 0; i < nr_segments; i++) {		if (image->segment[i].bufsz > image->segment[i].memsz)			goto out;	}	result = 0; out:	if (result == 0) {		*rimage = image;	} else {		kfree(image);	}	return result;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/72414d3f1d22fc3e311b162fca95c430048d38ce/kexec.c/clean/kernel/kexec.c