[PATCH] kexec: Make a pair of map/unmap reserved pages in error path

Andrew Morton akpm at linux-foundation.org
Fri Feb 26 16:56:05 PST 2016


On Thu, 25 Feb 2016 22:02:40 +0800 Minfei Huang <mhuang at redhat.com> wrote:

> From: Minfei Huang <mnfhuang at gmail.com>
> 
> For some arch, kexec shall map the reserved pages, then use them, when
> we try to start the kdump service.
> 
> kexec may return directly, without unmaping the reserved pages, if it
> fails during starting service. To fix it, we make a pair of map/unmap
> reserved pages both in generic path and error path.

This patch both refactors the code AND fixes the bug.  It is a
decent-looking refactoring, but mixing the two together makes it *much*
harder to review the bugfix.  These two steps should be separated
please, with the bugfix patch coming first.

> --- a/kernel/kexec.c
> +++ b/kernel/kexec.c
> @@ -103,6 +103,68 @@ out_free_image:
>  	return ret;
>  }
>  
> +static int do_kexec_load(unsigned long entry, unsigned long nr_segments,
> +		struct kexec_segment __user *segments, unsigned long flags)
> +{
> +	struct kimage **dest_image, *image;
> +	unsigned long i;
> +	int ret;
> +
> +	if (flags & KEXEC_ON_CRASH)
> +		dest_image = &kexec_crash_image;
> +	else
> +		dest_image = &kexec_image;
> +
> +	if (nr_segments == 0) {
> +		/* Uninstall image */
> +		kimage_free(xchg(dest_image, NULL));
> +		return 0;
> +	}
> +	if (flags & KEXEC_ON_CRASH) {
> +		/*
> +		 * Loading another kernel to switch to if this one
> +		 * crashes.  Free any current crash dump kernel before
> +		 * we corrupt it.
> +		 */
> +		kimage_free(xchg(&kexec_crash_image, NULL));
> +	}
> +
> +	ret = kimage_alloc_init(&image, entry, nr_segments, segments, flags);
> +	if (ret)
> +		return ret;

This is a bug, isn't it?  Missed kimage_free().

> +	if (flags & KEXEC_ON_CRASH)
> +		crash_map_reserved_pages();
> +
> +	if (flags & KEXEC_PRESERVE_CONTEXT)
> +		image->preserve_context = 1;
> +
> +	ret = machine_kexec_prepare(image);
> +	if (ret)
> +		goto out;
> +
> +	for (i = 0; i < nr_segments; i++) {
> +		ret = kimage_load_segment(image, &image->segment[i]);
> +		if (ret)
> +			goto out;
> +	}
> +
> +	kimage_terminate(image);
> +
> +	/* Install the new kernel and uninstall the old */
> +	image = xchg(dest_image, image);
> +
> +out:
> +	/*
> +	 * Once the reserved memory is mapped, we should unmap this memory
> +	 * before returning
> +	 */
> +	if (flags & KEXEC_ON_CRASH)
> +		crash_unmap_reserved_pages();
> +	kimage_free(image);
> +	return ret;
> +}
> +
>
> ...
>



More information about the kexec mailing list