Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1343177 > unrolled thread
| Started by | Minfei Huang <mhuang@redhat.com> |
|---|---|
| First post | 2016-02-25 15:00 +0100 |
| Last post | 2016-02-29 12:10 +0100 |
| Articles | 3 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH] kexec: Make a pair of map/unmap reserved pages in error path Minfei Huang <mhuang@redhat.com> - 2016-02-25 15:00 +0100
Re: [PATCH] kexec: Make a pair of map/unmap reserved pages in error path Andrew Morton <akpm@linux-foundation.org> - 2016-02-27 02:00 +0100
Re: [PATCH] kexec: Make a pair of map/unmap reserved pages in error path Minfei Huang <mhuang@redhat.com> - 2016-02-29 12:10 +0100
| From | Minfei Huang <mhuang@redhat.com> |
|---|---|
| Date | 2016-02-25 15:00 +0100 |
| Subject | [PATCH] kexec: Make a pair of map/unmap reserved pages in error path |
| Message-ID | <r64Cv-4Cd-11@gated-at.bofh.it> |
From: Minfei Huang <mnfhuang@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.
Signed-off-by: Minfei Huang <mnfhuang@gmail.com>
---
kernel/kexec.c | 112 ++++++++++++++++++++++++++++++++-------------------------
1 file changed, 63 insertions(+), 49 deletions(-)
diff --git a/kernel/kexec.c b/kernel/kexec.c
index ee70aef..48cf69c 100644
--- 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;
+
+ 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;
+}
+
/*
* Exec Kernel system call: for obvious reasons only root may call it.
*
@@ -127,7 +189,6 @@ out_free_image:
SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
struct kexec_segment __user *, segments, unsigned long, flags)
{
- struct kimage **dest_image, *image;
int result;
/* We only trust the superuser with rebooting the system. */
@@ -152,9 +213,6 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
if (nr_segments > KEXEC_SEGMENT_MAX)
return -EINVAL;
- image = NULL;
- result = 0;
-
/* Because we write directly to the reserved memory
* region when loading crash kernels we need a mutex here to
* prevent multiple crash kernels from attempting to load
@@ -166,53 +224,9 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
if (!mutex_trylock(&kexec_mutex))
return -EBUSY;
- dest_image = &kexec_image;
- if (flags & KEXEC_ON_CRASH)
- dest_image = &kexec_crash_image;
- if (nr_segments > 0) {
- unsigned long i;
-
- 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));
- result = kimage_alloc_init(&image, entry, nr_segments,
- segments, flags);
- crash_map_reserved_pages();
- } else {
- /* Loading another kernel to reboot into. */
-
- result = kimage_alloc_init(&image, entry, nr_segments,
- segments, flags);
- }
- if (result)
- goto out;
-
- if (flags & KEXEC_PRESERVE_CONTEXT)
- image->preserve_context = 1;
- result = machine_kexec_prepare(image);
- if (result)
- goto out;
-
- for (i = 0; i < nr_segments; i++) {
- result = kimage_load_segment(image, &image->segment[i]);
- if (result)
- goto out;
- }
- kimage_terminate(image);
- if (flags & KEXEC_ON_CRASH)
- crash_unmap_reserved_pages();
- }
- /* Install the new kernel, and Uninstall the old */
- image = xchg(dest_image, image);
+ result = do_kexec_load(entry, nr_segments, segments, flags);
-out:
mutex_unlock(&kexec_mutex);
- kimage_free(image);
return result;
}
--
2.1.0
[toc] | [next] | [standalone]
| From | Andrew Morton <akpm@linux-foundation.org> |
|---|---|
| Date | 2016-02-27 02:00 +0100 |
| Subject | Re: [PATCH] kexec: Make a pair of map/unmap reserved pages in error path |
| Message-ID | <r6BoK-3aU-5@gated-at.bofh.it> |
| In reply to | #1343177 |
On Thu, 25 Feb 2016 22:02:40 +0800 Minfei Huang <mhuang@redhat.com> wrote:
> From: Minfei Huang <mnfhuang@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;
> +}
> +
>
> ...
>
[toc] | [prev] | [next] | [standalone]
| From | Minfei Huang <mhuang@redhat.com> |
|---|---|
| Date | 2016-02-29 12:10 +0100 |
| Subject | Re: [PATCH] kexec: Make a pair of map/unmap reserved pages in error path |
| Message-ID | <r7tSb-2et-41@gated-at.bofh.it> |
| In reply to | #1344875 |
On 02/26/16 at 04:56pm, Andrew Morton wrote:
> On Thu, 25 Feb 2016 22:02:40 +0800 Minfei Huang <mhuang@redhat.com> wrote:
>
> > From: Minfei Huang <mnfhuang@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.
I will bisect this patch to make it more simple to be reviewed.
>
> > --- 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().
The variable image is NULL, if kimage_alloc_init returns with error. And
kimage_alloc_init will do the cleanup before returning. So it's fine
without calling kimage_free.
Thanks
Minfei
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web