Skip to content

Commit cb10525

Browse files
rhvgoyaltorvalds
authored andcommitted
kexec: implementation of new syscall kexec_file_load
Previous patch provided the interface definition and this patch prvides implementation of new syscall. Previously segment list was prepared in user space. Now user space just passes kernel fd, initrd fd and command line and kernel will create a segment list internally. This patch contains generic part of the code. Actual segment preparation and loading is done by arch and image specific loader. Which comes in next patch. [[email protected]: coding-style fixes] Signed-off-by: Vivek Goyal <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Michael Kerrisk <[email protected]> Cc: Yinghai Lu <[email protected]> Cc: Eric Biederman <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Matthew Garrett <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Cc: Dave Young <[email protected]> Cc: WANG Chao <[email protected]> Cc: Baoquan He <[email protected]> Cc: Andy Lutomirski <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent f089568 commit cb10525

File tree

4 files changed

+587
-5
lines changed

4 files changed

+587
-5
lines changed

arch/x86/kernel/machine_kexec_64.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
#include <asm/mmu_context.h>
2323
#include <asm/debugreg.h>
2424

25+
static struct kexec_file_ops *kexec_file_loaders[] = {
26+
NULL,
27+
};
28+
2529
static void free_transition_pgtable(struct kimage *image)
2630
{
2731
free_page((unsigned long)image->arch.pud);
@@ -283,3 +287,44 @@ void arch_crash_save_vmcoreinfo(void)
283287
(unsigned long)&_text - __START_KERNEL);
284288
}
285289

290+
/* arch-dependent functionality related to kexec file-based syscall */
291+
292+
int arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
293+
unsigned long buf_len)
294+
{
295+
int i, ret = -ENOEXEC;
296+
struct kexec_file_ops *fops;
297+
298+
for (i = 0; i < ARRAY_SIZE(kexec_file_loaders); i++) {
299+
fops = kexec_file_loaders[i];
300+
if (!fops || !fops->probe)
301+
continue;
302+
303+
ret = fops->probe(buf, buf_len);
304+
if (!ret) {
305+
image->fops = fops;
306+
return ret;
307+
}
308+
}
309+
310+
return ret;
311+
}
312+
313+
void *arch_kexec_kernel_image_load(struct kimage *image)
314+
{
315+
if (!image->fops || !image->fops->load)
316+
return ERR_PTR(-ENOEXEC);
317+
318+
return image->fops->load(image, image->kernel_buf,
319+
image->kernel_buf_len, image->initrd_buf,
320+
image->initrd_buf_len, image->cmdline_buf,
321+
image->cmdline_buf_len);
322+
}
323+
324+
int arch_kimage_file_post_load_cleanup(struct kimage *image)
325+
{
326+
if (!image->fops || !image->fops->cleanup)
327+
return 0;
328+
329+
return image->fops->cleanup(image);
330+
}

include/linux/kexec.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,57 @@ struct kimage {
121121
#define KEXEC_TYPE_DEFAULT 0
122122
#define KEXEC_TYPE_CRASH 1
123123
unsigned int preserve_context : 1;
124+
/* If set, we are using file mode kexec syscall */
125+
unsigned int file_mode:1;
124126

125127
#ifdef ARCH_HAS_KIMAGE_ARCH
126128
struct kimage_arch arch;
127129
#endif
130+
131+
/* Additional fields for file based kexec syscall */
132+
void *kernel_buf;
133+
unsigned long kernel_buf_len;
134+
135+
void *initrd_buf;
136+
unsigned long initrd_buf_len;
137+
138+
char *cmdline_buf;
139+
unsigned long cmdline_buf_len;
140+
141+
/* File operations provided by image loader */
142+
struct kexec_file_ops *fops;
143+
144+
/* Image loader handling the kernel can store a pointer here */
145+
void *image_loader_data;
128146
};
129147

148+
/*
149+
* Keeps track of buffer parameters as provided by caller for requesting
150+
* memory placement of buffer.
151+
*/
152+
struct kexec_buf {
153+
struct kimage *image;
154+
char *buffer;
155+
unsigned long bufsz;
156+
unsigned long memsz;
157+
unsigned long buf_align;
158+
unsigned long buf_min;
159+
unsigned long buf_max;
160+
bool top_down; /* allocate from top of memory hole */
161+
};
130162

163+
typedef int (kexec_probe_t)(const char *kernel_buf, unsigned long kernel_size);
164+
typedef void *(kexec_load_t)(struct kimage *image, char *kernel_buf,
165+
unsigned long kernel_len, char *initrd,
166+
unsigned long initrd_len, char *cmdline,
167+
unsigned long cmdline_len);
168+
typedef int (kexec_cleanup_t)(struct kimage *image);
169+
170+
struct kexec_file_ops {
171+
kexec_probe_t *probe;
172+
kexec_load_t *load;
173+
kexec_cleanup_t *cleanup;
174+
};
131175

132176
/* kexec interface functions */
133177
extern void machine_kexec(struct kimage *image);
@@ -138,6 +182,11 @@ extern asmlinkage long sys_kexec_load(unsigned long entry,
138182
struct kexec_segment __user *segments,
139183
unsigned long flags);
140184
extern int kernel_kexec(void);
185+
extern int kexec_add_buffer(struct kimage *image, char *buffer,
186+
unsigned long bufsz, unsigned long memsz,
187+
unsigned long buf_align, unsigned long buf_min,
188+
unsigned long buf_max, bool top_down,
189+
unsigned long *load_addr);
141190
extern struct page *kimage_alloc_control_pages(struct kimage *image,
142191
unsigned int order);
143192
extern void crash_kexec(struct pt_regs *);
@@ -188,6 +237,10 @@ extern int kexec_load_disabled;
188237
#define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_PRESERVE_CONTEXT)
189238
#endif
190239

240+
/* List of defined/legal kexec file flags */
241+
#define KEXEC_FILE_FLAGS (KEXEC_FILE_UNLOAD | KEXEC_FILE_ON_CRASH | \
242+
KEXEC_FILE_NO_INITRAMFS)
243+
191244
#define VMCOREINFO_BYTES (4096)
192245
#define VMCOREINFO_NOTE_NAME "VMCOREINFO"
193246
#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)

include/uapi/linux/kexec.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@
1313
#define KEXEC_PRESERVE_CONTEXT 0x00000002
1414
#define KEXEC_ARCH_MASK 0xffff0000
1515

16+
/*
17+
* Kexec file load interface flags.
18+
* KEXEC_FILE_UNLOAD : Unload already loaded kexec/kdump image.
19+
* KEXEC_FILE_ON_CRASH : Load/unload operation belongs to kdump image.
20+
* KEXEC_FILE_NO_INITRAMFS : No initramfs is being loaded. Ignore the initrd
21+
* fd field.
22+
*/
23+
#define KEXEC_FILE_UNLOAD 0x00000001
24+
#define KEXEC_FILE_ON_CRASH 0x00000002
25+
#define KEXEC_FILE_NO_INITRAMFS 0x00000004
26+
1627
/* These values match the ELF architecture values.
1728
* Unless there is a good reason that should continue to be the case.
1829
*/

0 commit comments

Comments
 (0)