Blame view
kernel/kexec.c
7.97 KB
40b0b3f8f treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
dc009d924 [PATCH] kexec: ad... |
2 |
/* |
2965faa5e kexec: split kexe... |
3 |
* kexec.c - kexec_load system call |
dc009d924 [PATCH] kexec: ad... |
4 |
* Copyright (C) 2002-2004 Eric Biederman <ebiederm@xmission.com> |
dc009d924 [PATCH] kexec: ad... |
5 |
*/ |
de90a6bca kexec: use file n... |
6 |
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
c59ede7b7 [PATCH] move capa... |
7 |
#include <linux/capability.h> |
dc009d924 [PATCH] kexec: ad... |
8 9 |
#include <linux/mm.h> #include <linux/file.h> |
a210fd32a kexec: add call t... |
10 |
#include <linux/security.h> |
dc009d924 [PATCH] kexec: ad... |
11 |
#include <linux/kexec.h> |
8c5a1cf0a kexec: use a mute... |
12 |
#include <linux/mutex.h> |
dc009d924 [PATCH] kexec: ad... |
13 |
#include <linux/list.h> |
dc009d924 [PATCH] kexec: ad... |
14 |
#include <linux/syscalls.h> |
a43cac0d9 kexec: split kexe... |
15 |
#include <linux/vmalloc.h> |
2965faa5e kexec: split kexe... |
16 |
#include <linux/slab.h> |
dc009d924 [PATCH] kexec: ad... |
17 |
|
a43cac0d9 kexec: split kexe... |
18 |
#include "kexec_internal.h" |
dabe78628 kexec: move segme... |
19 20 21 |
static int copy_user_segment_list(struct kimage *image, unsigned long nr_segments, struct kexec_segment __user *segments) |
dc009d924 [PATCH] kexec: ad... |
22 |
{ |
dabe78628 kexec: move segme... |
23 |
int ret; |
dc009d924 [PATCH] kexec: ad... |
24 |
size_t segment_bytes; |
dc009d924 [PATCH] kexec: ad... |
25 26 27 28 |
/* Read in the segments */ image->nr_segments = nr_segments; segment_bytes = nr_segments * sizeof(*segments); |
dabe78628 kexec: move segme... |
29 30 31 32 33 34 |
ret = copy_from_user(image->segment, segments, segment_bytes); if (ret) ret = -EFAULT; return ret; } |
255aedd90 kexec: use common... |
35 36 37 38 |
static int kimage_alloc_init(struct kimage **rimage, unsigned long entry, unsigned long nr_segments, struct kexec_segment __user *segments, unsigned long flags) |
dc009d924 [PATCH] kexec: ad... |
39 |
{ |
255aedd90 kexec: use common... |
40 |
int ret; |
dc009d924 [PATCH] kexec: ad... |
41 |
struct kimage *image; |
255aedd90 kexec: use common... |
42 43 44 45 |
bool kexec_on_panic = flags & KEXEC_ON_CRASH; if (kexec_on_panic) { /* Verify we have a valid entry point */ |
43546d866 kexec: allow arch... |
46 47 |
if ((entry < phys_to_boot_phys(crashk_res.start)) || (entry > phys_to_boot_phys(crashk_res.end))) |
255aedd90 kexec: use common... |
48 49 |
return -EADDRNOTAVAIL; } |
dc009d924 [PATCH] kexec: ad... |
50 51 |
/* Allocate and initialize a controlling structure */ |
dabe78628 kexec: move segme... |
52 53 54 55 56 |
image = do_kimage_alloc_init(); if (!image) return -ENOMEM; image->start = entry; |
255aedd90 kexec: use common... |
57 58 |
ret = copy_user_segment_list(image, nr_segments, segments); if (ret) |
dabe78628 kexec: move segme... |
59 |
goto out_free_image; |
255aedd90 kexec: use common... |
60 |
if (kexec_on_panic) { |
cdf4b3fa0 kexec: set KEXEC_... |
61 |
/* Enable special crash kernel control page alloc policy. */ |
255aedd90 kexec: use common... |
62 63 64 |
image->control_page = crashk_res.start; image->type = KEXEC_TYPE_CRASH; } |
cdf4b3fa0 kexec: set KEXEC_... |
65 66 67 |
ret = sanity_check_segment_list(image); if (ret) goto out_free_image; |
dc009d924 [PATCH] kexec: ad... |
68 69 70 71 72 |
/* * Find a location for the control code buffer, and add it * the vector of segments so that it's pages will also be * counted as destination pages. */ |
255aedd90 kexec: use common... |
73 |
ret = -ENOMEM; |
dc009d924 [PATCH] kexec: ad... |
74 |
image->control_code_page = kimage_alloc_control_pages(image, |
163f6876f kexec jump: renam... |
75 |
get_order(KEXEC_CONTROL_PAGE_SIZE)); |
dc009d924 [PATCH] kexec: ad... |
76 |
if (!image->control_code_page) { |
e1bebcf41 kernel/kexec.c: c... |
77 78 |
pr_err("Could not allocate control_code_buffer "); |
dabe78628 kexec: move segme... |
79 |
goto out_free_image; |
dc009d924 [PATCH] kexec: ad... |
80 |
} |
255aedd90 kexec: use common... |
81 82 83 84 85 86 87 |
if (!kexec_on_panic) { image->swap_page = kimage_alloc_control_pages(image, 0); if (!image->swap_page) { pr_err("Could not allocate swap buffer "); goto out_free_control_pages; } |
3ab835213 kexec jump |
88 |
} |
b92e7e0da kexec: fix memory... |
89 90 |
*rimage = image; return 0; |
dabe78628 kexec: move segme... |
91 |
out_free_control_pages: |
b92e7e0da kexec: fix memory... |
92 |
kimage_free_page_list(&image->control_pages); |
dabe78628 kexec: move segme... |
93 |
out_free_image: |
b92e7e0da kexec: fix memory... |
94 |
kfree(image); |
255aedd90 kexec: use common... |
95 |
return ret; |
dc009d924 [PATCH] kexec: ad... |
96 |
} |
0eea08678 kexec: do a clean... |
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
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; if (kexec_crash_image) arch_kexec_unprotect_crashkres(); } 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; |
0eea08678 kexec: do a clean... |
129 130 131 132 133 134 |
if (flags & KEXEC_PRESERVE_CONTEXT) image->preserve_context = 1; ret = machine_kexec_prepare(image); if (ret) goto out; |
1229384f5 kdump: protect vm... |
135 136 137 138 139 140 141 |
/* * Some architecture(like S390) may touch the crash memory before * machine_kexec_prepare(), we must copy vmcoreinfo data after it. */ ret = kimage_crash_copy_vmcoreinfo(image); if (ret) goto out; |
0eea08678 kexec: do a clean... |
142 143 144 145 146 147 148 |
for (i = 0; i < nr_segments; i++) { ret = kimage_load_segment(image, &image->segment[i]); if (ret) goto out; } kimage_terminate(image); |
de68e4dae kexec: add machin... |
149 150 151 |
ret = machine_kexec_post_load(image); if (ret) goto out; |
0eea08678 kexec: do a clean... |
152 153 154 155 156 157 |
/* Install the new kernel and uninstall the old */ image = xchg(dest_image, image); out: if ((flags & KEXEC_ON_CRASH) && kexec_crash_image) arch_kexec_protect_crashkres(); |
0eea08678 kexec: do a clean... |
158 159 160 |
kimage_free(image); return ret; } |
dc009d924 [PATCH] kexec: ad... |
161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
/* * Exec Kernel system call: for obvious reasons only root may call it. * * This call breaks up into three pieces. * - A generic part which loads the new kernel from the current * address space, and very carefully places the data in the * allocated pages. * * - A generic part that interacts with the kernel and tells all of * the devices to shut down. Preventing on-going dmas, and placing * the devices in a consistent state so a later kernel can * reinitialize them. * * - A machine specific part that includes the syscall number |
002ace782 kexec: Typo s/the... |
175 |
* and then copies the image to it's final destination. And |
dc009d924 [PATCH] kexec: ad... |
176 177 178 179 180 |
* jumps into the image at entry. * * kexec does not sync, or unmount filesystems so if you need * that to happen you need to do that yourself. */ |
8c5a1cf0a kexec: use a mute... |
181 |
|
6b27aef09 kexec: call do_ke... |
182 183 |
static inline int kexec_load_check(unsigned long nr_segments, unsigned long flags) |
dc009d924 [PATCH] kexec: ad... |
184 |
{ |
a210fd32a kexec: add call t... |
185 |
int result; |
dc009d924 [PATCH] kexec: ad... |
186 |
/* We only trust the superuser with rebooting the system. */ |
7984754b9 kexec: add sysctl... |
187 |
if (!capable(CAP_SYS_BOOT) || kexec_load_disabled) |
dc009d924 [PATCH] kexec: ad... |
188 |
return -EPERM; |
a210fd32a kexec: add call t... |
189 |
/* Permit LSMs and IMA to fail the kexec */ |
b64fcae74 LSM: Introduce ke... |
190 |
result = security_kernel_load_data(LOADING_KEXEC_IMAGE, false); |
a210fd32a kexec: add call t... |
191 192 |
if (result < 0) return result; |
dc009d924 [PATCH] kexec: ad... |
193 |
/* |
7d31f4602 kexec_load: Disab... |
194 195 196 197 198 199 200 201 |
* kexec can be used to circumvent module loading restrictions, so * prevent loading in that case */ result = security_locked_down(LOCKDOWN_KEXEC); if (result) return result; /* |
dc009d924 [PATCH] kexec: ad... |
202 203 204 205 206 |
* Verify we have a legal set of flags * This leaves us room for future extensions. */ if ((flags & KEXEC_FLAGS) != (flags & ~KEXEC_ARCH_MASK)) return -EINVAL; |
dc009d924 [PATCH] kexec: ad... |
207 208 209 210 211 |
/* Put an artificial cap on the number * of segments passed to kexec_load. */ if (nr_segments > KEXEC_SEGMENT_MAX) return -EINVAL; |
6b27aef09 kexec: call do_ke... |
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
return 0; } SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, struct kexec_segment __user *, segments, unsigned long, flags) { int result; result = kexec_load_check(nr_segments, flags); if (result) return result; /* Verify we are on the appropriate architecture */ if (((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH) && ((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH_DEFAULT)) return -EINVAL; |
dc009d924 [PATCH] kexec: ad... |
228 229 230 231 232 233 234 235 |
/* 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 * simultaneously, and to prevent a crash kernel from loading * over the top of a in use crash kernel. * * KISS: always take the mutex. */ |
8c5a1cf0a kexec: use a mute... |
236 |
if (!mutex_trylock(&kexec_mutex)) |
dc009d924 [PATCH] kexec: ad... |
237 |
return -EBUSY; |
72414d3f1 [PATCH] kexec cod... |
238 |
|
0eea08678 kexec: do a clean... |
239 |
result = do_kexec_load(entry, nr_segments, segments, flags); |
dc009d924 [PATCH] kexec: ad... |
240 |
|
8c5a1cf0a kexec: use a mute... |
241 |
mutex_unlock(&kexec_mutex); |
72414d3f1 [PATCH] kexec cod... |
242 |
|
dc009d924 [PATCH] kexec: ad... |
243 244 245 246 |
return result; } #ifdef CONFIG_COMPAT |
ca2c405ab kexec/compat: con... |
247 248 249 250 |
COMPAT_SYSCALL_DEFINE4(kexec_load, compat_ulong_t, entry, compat_ulong_t, nr_segments, struct compat_kexec_segment __user *, segments, compat_ulong_t, flags) |
dc009d924 [PATCH] kexec: ad... |
251 252 253 254 |
{ struct compat_kexec_segment in; struct kexec_segment out, __user *ksegments; unsigned long i, result; |
6b27aef09 kexec: call do_ke... |
255 256 257 |
result = kexec_load_check(nr_segments, flags); if (result) return result; |
dc009d924 [PATCH] kexec: ad... |
258 259 260 |
/* Don't allow clients that don't understand the native * architecture to do anything. */ |
72414d3f1 [PATCH] kexec cod... |
261 |
if ((flags & KEXEC_ARCH_MASK) == KEXEC_ARCH_DEFAULT) |
dc009d924 [PATCH] kexec: ad... |
262 |
return -EINVAL; |
dc009d924 [PATCH] kexec: ad... |
263 |
|
dc009d924 [PATCH] kexec: ad... |
264 |
ksegments = compat_alloc_user_space(nr_segments * sizeof(out)); |
e1bebcf41 kernel/kexec.c: c... |
265 |
for (i = 0; i < nr_segments; i++) { |
dc009d924 [PATCH] kexec: ad... |
266 |
result = copy_from_user(&in, &segments[i], sizeof(in)); |
72414d3f1 [PATCH] kexec cod... |
267 |
if (result) |
dc009d924 [PATCH] kexec: ad... |
268 |
return -EFAULT; |
dc009d924 [PATCH] kexec: ad... |
269 270 271 272 273 274 275 |
out.buf = compat_ptr(in.buf); out.bufsz = in.bufsz; out.mem = in.mem; out.memsz = in.memsz; result = copy_to_user(&ksegments[i], &out, sizeof(out)); |
72414d3f1 [PATCH] kexec cod... |
276 |
if (result) |
dc009d924 [PATCH] kexec: ad... |
277 |
return -EFAULT; |
dc009d924 [PATCH] kexec: ad... |
278 |
} |
6b27aef09 kexec: call do_ke... |
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
/* 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 * simultaneously, and to prevent a crash kernel from loading * over the top of a in use crash kernel. * * KISS: always take the mutex. */ if (!mutex_trylock(&kexec_mutex)) return -EBUSY; result = do_kexec_load(entry, nr_segments, ksegments, flags); mutex_unlock(&kexec_mutex); return result; |
dc009d924 [PATCH] kexec: ad... |
295 296 |
} #endif |