Skip to content

Commit d54d972

Browse files
Minfei HuangAlex Shi
authored andcommitted
kexec: do a cleanup for function kexec_load
There are a lof of work to be done in function kexec_load, not only for allocating structs and loading initram, but also for some misc. To make it more clear, wrap a new function do_kexec_load which is used to allocate structs and load initram. And the pre-work will be done in kexec_load. Signed-off-by: Minfei Huang <mnfhuang@gmail.com> Cc: Vivek Goyal <vgoyal@redhat.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Xunlei Pang <xlpang@redhat.com> Cc: Baoquan He <bhe@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> (cherry picked from commit 0eea08678ebe9f7d8ef98fed974a5bf1a0dd2dd2) Signed-off-by: Alex Shi <alex.shi@linaro.org>
1 parent b67152e commit d54d972

1 file changed

Lines changed: 69 additions & 56 deletions

File tree

kernel/kexec.c

Lines changed: 69 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,74 @@ static int kimage_alloc_init(struct kimage **rimage, unsigned long entry,
103103
return ret;
104104
}
105105

106+
static int do_kexec_load(unsigned long entry, unsigned long nr_segments,
107+
struct kexec_segment __user *segments, unsigned long flags)
108+
{
109+
struct kimage **dest_image, *image;
110+
unsigned long i;
111+
int ret;
112+
113+
if (flags & KEXEC_ON_CRASH) {
114+
dest_image = &kexec_crash_image;
115+
if (kexec_crash_image)
116+
arch_kexec_unprotect_crashkres();
117+
} else {
118+
dest_image = &kexec_image;
119+
}
120+
121+
if (nr_segments == 0) {
122+
/* Uninstall image */
123+
kimage_free(xchg(dest_image, NULL));
124+
return 0;
125+
}
126+
if (flags & KEXEC_ON_CRASH) {
127+
/*
128+
* Loading another kernel to switch to if this one
129+
* crashes. Free any current crash dump kernel before
130+
* we corrupt it.
131+
*/
132+
kimage_free(xchg(&kexec_crash_image, NULL));
133+
}
134+
135+
ret = kimage_alloc_init(&image, entry, nr_segments, segments, flags);
136+
if (ret)
137+
return ret;
138+
139+
if (flags & KEXEC_ON_CRASH)
140+
crash_map_reserved_pages();
141+
142+
if (flags & KEXEC_PRESERVE_CONTEXT)
143+
image->preserve_context = 1;
144+
145+
ret = machine_kexec_prepare(image);
146+
if (ret)
147+
goto out;
148+
149+
for (i = 0; i < nr_segments; i++) {
150+
ret = kimage_load_segment(image, &image->segment[i]);
151+
if (ret)
152+
goto out;
153+
}
154+
155+
kimage_terminate(image);
156+
157+
/* Install the new kernel and uninstall the old */
158+
image = xchg(dest_image, image);
159+
160+
out:
161+
if ((flags & KEXEC_ON_CRASH) && kexec_crash_image)
162+
arch_kexec_protect_crashkres();
163+
164+
/*
165+
* Once the reserved memory is mapped, we should unmap this memory
166+
* before returning
167+
*/
168+
if (flags & KEXEC_ON_CRASH)
169+
crash_unmap_reserved_pages();
170+
kimage_free(image);
171+
return ret;
172+
}
173+
106174
/*
107175
* Exec Kernel system call: for obvious reasons only root may call it.
108176
*
@@ -127,7 +195,6 @@ static int kimage_alloc_init(struct kimage **rimage, unsigned long entry,
127195
SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
128196
struct kexec_segment __user *, segments, unsigned long, flags)
129197
{
130-
struct kimage **dest_image, *image;
131198
int result;
132199

133200
/* We only trust the superuser with rebooting the system. */
@@ -152,9 +219,6 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
152219
if (nr_segments > KEXEC_SEGMENT_MAX)
153220
return -EINVAL;
154221

155-
image = NULL;
156-
result = 0;
157-
158222
/* Because we write directly to the reserved memory
159223
* region when loading crash kernels we need a mutex here to
160224
* prevent multiple crash kernels from attempting to load
@@ -166,63 +230,12 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
166230
if (!mutex_trylock(&kexec_mutex))
167231
return -EBUSY;
168232

169-
dest_image = &kexec_image;
170-
if (flags & KEXEC_ON_CRASH) {
171-
dest_image = &kexec_crash_image;
172-
if (kexec_crash_image)
173-
arch_kexec_unprotect_crashkres();
174-
}
175-
176-
if (nr_segments > 0) {
177-
unsigned long i;
178-
179-
if (flags & KEXEC_ON_CRASH) {
180-
/*
181-
* Loading another kernel to switch to if this one
182-
* crashes. Free any current crash dump kernel before
183-
* we corrupt it.
184-
*/
185-
186-
kimage_free(xchg(&kexec_crash_image, NULL));
187-
result = kimage_alloc_init(&image, entry, nr_segments,
188-
segments, flags);
189-
crash_map_reserved_pages();
190-
} else {
191-
/* Loading another kernel to reboot into. */
192-
193-
result = kimage_alloc_init(&image, entry, nr_segments,
194-
segments, flags);
195-
}
196-
if (result)
197-
goto unmap_page;
198-
199-
if (flags & KEXEC_PRESERVE_CONTEXT)
200-
image->preserve_context = 1;
201-
result = machine_kexec_prepare(image);
202-
if (result)
203-
goto unmap_page;
204-
205-
for (i = 0; i < nr_segments; i++) {
206-
result = kimage_load_segment(image, &image->segment[i]);
207-
if (result)
208-
goto unmap_page;
209-
}
210-
kimage_terminate(image);
211-
unmap_page:
212-
if (flags & KEXEC_ON_CRASH)
213-
crash_unmap_reserved_pages();
214-
if (result)
215-
goto out;
216-
}
217-
/* Install the new kernel, and Uninstall the old */
218-
image = xchg(dest_image, image);
233+
result = do_kexec_load(entry, nr_segments, segments, flags);
219234

220-
out:
221235
if ((flags & KEXEC_ON_CRASH) && kexec_crash_image)
222236
arch_kexec_protect_crashkres();
223237

224238
mutex_unlock(&kexec_mutex);
225-
kimage_free(image);
226239

227240
return result;
228241
}

0 commit comments

Comments
 (0)