diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2005-06-25 17:57:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-25 19:24:48 -0400 |
commit | dc009d92435f99498cbc579ce76bf28e837e2c14 (patch) | |
tree | 2ba8732b28225593d996b8faa079dc6ab4bbc9bc /include | |
parent | d0537508a9921efced238b20967e50e519ac34af (diff) |
[PATCH] kexec: add kexec syscalls
This patch introduces the architecture independent implementation the
sys_kexec_load, the compat_sys_kexec_load system calls.
Kexec on panic support has been integrated into the core patch and is
relatively clean.
In addition the hopefully architecture independent option
crashkernel=size@location has been docuemented. It's purpose is to reserve
space for the panic kernel to live, and where no DMA transfer will ever be
setup to access.
Signed-off-by: Eric Biederman <ebiederm@xmission.com>
Signed-off-by: Alexander Nyberg <alexn@telia.com>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Vivek Goyal <vgoyal@in.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/kexec.h | 127 | ||||
-rw-r--r-- | include/linux/reboot.h | 3 | ||||
-rw-r--r-- | include/linux/syscalls.h | 5 |
3 files changed, 133 insertions, 2 deletions
diff --git a/include/linux/kexec.h b/include/linux/kexec.h new file mode 100644 index 000000000000..e3fc35f4e35f --- /dev/null +++ b/include/linux/kexec.h | |||
@@ -0,0 +1,127 @@ | |||
1 | #ifndef LINUX_KEXEC_H | ||
2 | #define LINUX_KEXEC_H | ||
3 | |||
4 | #ifdef CONFIG_KEXEC | ||
5 | #include <linux/types.h> | ||
6 | #include <linux/list.h> | ||
7 | #include <linux/linkage.h> | ||
8 | #include <linux/compat.h> | ||
9 | #include <asm/kexec.h> | ||
10 | |||
11 | /* Verify architecture specific macros are defined */ | ||
12 | |||
13 | #ifndef KEXEC_SOURCE_MEMORY_LIMIT | ||
14 | #error KEXEC_SOURCE_MEMORY_LIMIT not defined | ||
15 | #endif | ||
16 | |||
17 | #ifndef KEXEC_DESTINATION_MEMORY_LIMIT | ||
18 | #error KEXEC_DESTINATION_MEMORY_LIMIT not defined | ||
19 | #endif | ||
20 | |||
21 | #ifndef KEXEC_CONTROL_MEMORY_LIMIT | ||
22 | #error KEXEC_CONTROL_MEMORY_LIMIT not defined | ||
23 | #endif | ||
24 | |||
25 | #ifndef KEXEC_CONTROL_CODE_SIZE | ||
26 | #error KEXEC_CONTROL_CODE_SIZE not defined | ||
27 | #endif | ||
28 | |||
29 | #ifndef KEXEC_ARCH | ||
30 | #error KEXEC_ARCH not defined | ||
31 | #endif | ||
32 | |||
33 | /* | ||
34 | * This structure is used to hold the arguments that are used when loading | ||
35 | * kernel binaries. | ||
36 | */ | ||
37 | |||
38 | typedef unsigned long kimage_entry_t; | ||
39 | #define IND_DESTINATION 0x1 | ||
40 | #define IND_INDIRECTION 0x2 | ||
41 | #define IND_DONE 0x4 | ||
42 | #define IND_SOURCE 0x8 | ||
43 | |||
44 | #define KEXEC_SEGMENT_MAX 8 | ||
45 | struct kexec_segment { | ||
46 | void __user *buf; | ||
47 | size_t bufsz; | ||
48 | unsigned long mem; /* User space sees this as a (void *) ... */ | ||
49 | size_t memsz; | ||
50 | }; | ||
51 | |||
52 | #ifdef CONFIG_COMPAT | ||
53 | struct compat_kexec_segment { | ||
54 | compat_uptr_t buf; | ||
55 | compat_size_t bufsz; | ||
56 | compat_ulong_t mem; /* User space sees this as a (void *) ... */ | ||
57 | compat_size_t memsz; | ||
58 | }; | ||
59 | #endif | ||
60 | |||
61 | struct kimage { | ||
62 | kimage_entry_t head; | ||
63 | kimage_entry_t *entry; | ||
64 | kimage_entry_t *last_entry; | ||
65 | |||
66 | unsigned long destination; | ||
67 | |||
68 | unsigned long start; | ||
69 | struct page *control_code_page; | ||
70 | |||
71 | unsigned long nr_segments; | ||
72 | struct kexec_segment segment[KEXEC_SEGMENT_MAX]; | ||
73 | |||
74 | struct list_head control_pages; | ||
75 | struct list_head dest_pages; | ||
76 | struct list_head unuseable_pages; | ||
77 | |||
78 | /* Address of next control page to allocate for crash kernels. */ | ||
79 | unsigned long control_page; | ||
80 | |||
81 | /* Flags to indicate special processing */ | ||
82 | unsigned int type : 1; | ||
83 | #define KEXEC_TYPE_DEFAULT 0 | ||
84 | #define KEXEC_TYPE_CRASH 1 | ||
85 | }; | ||
86 | |||
87 | |||
88 | |||
89 | /* kexec interface functions */ | ||
90 | extern NORET_TYPE void machine_kexec(struct kimage *image) ATTRIB_NORET; | ||
91 | extern int machine_kexec_prepare(struct kimage *image); | ||
92 | extern void machine_kexec_cleanup(struct kimage *image); | ||
93 | extern asmlinkage long sys_kexec_load(unsigned long entry, | ||
94 | unsigned long nr_segments, struct kexec_segment __user *segments, | ||
95 | unsigned long flags); | ||
96 | #ifdef CONFIG_COMPAT | ||
97 | extern asmlinkage long compat_sys_kexec_load(unsigned long entry, | ||
98 | unsigned long nr_segments, struct compat_kexec_segment __user *segments, | ||
99 | unsigned long flags); | ||
100 | #endif | ||
101 | extern struct page *kimage_alloc_control_pages(struct kimage *image, unsigned int order); | ||
102 | extern void crash_kexec(void); | ||
103 | extern struct kimage *kexec_image; | ||
104 | |||
105 | #define KEXEC_ON_CRASH 0x00000001 | ||
106 | #define KEXEC_ARCH_MASK 0xffff0000 | ||
107 | |||
108 | /* These values match the ELF architecture values. | ||
109 | * Unless there is a good reason that should continue to be the case. | ||
110 | */ | ||
111 | #define KEXEC_ARCH_DEFAULT ( 0 << 16) | ||
112 | #define KEXEC_ARCH_386 ( 3 << 16) | ||
113 | #define KEXEC_ARCH_X86_64 (62 << 16) | ||
114 | #define KEXEC_ARCH_PPC (20 << 16) | ||
115 | #define KEXEC_ARCH_PPC64 (21 << 16) | ||
116 | #define KEXEC_ARCH_IA_64 (50 << 16) | ||
117 | |||
118 | #define KEXEC_FLAGS (KEXEC_ON_CRASH) /* List of defined/legal kexec flags */ | ||
119 | |||
120 | /* Location of a reserved region to hold the crash kernel. | ||
121 | */ | ||
122 | extern struct resource crashk_res; | ||
123 | |||
124 | #else /* !CONFIG_KEXEC */ | ||
125 | static inline void crash_kexec(void) { } | ||
126 | #endif /* CONFIG_KEXEC */ | ||
127 | #endif /* LINUX_KEXEC_H */ | ||
diff --git a/include/linux/reboot.h b/include/linux/reboot.h index d60fafc8bdc5..c5a05e16edb2 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h | |||
@@ -51,6 +51,9 @@ extern void machine_restart(char *cmd); | |||
51 | extern void machine_halt(void); | 51 | extern void machine_halt(void); |
52 | extern void machine_power_off(void); | 52 | extern void machine_power_off(void); |
53 | 53 | ||
54 | extern void machine_shutdown(void); | ||
55 | extern void machine_crash_shutdown(void); | ||
56 | |||
54 | #endif | 57 | #endif |
55 | 58 | ||
56 | #endif /* _LINUX_REBOOT_H */ | 59 | #endif /* _LINUX_REBOOT_H */ |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index c39f6f72cbbc..7ba8f8f747aa 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -159,8 +159,9 @@ asmlinkage long sys_shutdown(int, int); | |||
159 | asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, | 159 | asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, |
160 | void __user *arg); | 160 | void __user *arg); |
161 | asmlinkage long sys_restart_syscall(void); | 161 | asmlinkage long sys_restart_syscall(void); |
162 | asmlinkage long sys_kexec_load(void *entry, unsigned long nr_segments, | 162 | asmlinkage long sys_kexec_load(unsigned long entry, |
163 | struct kexec_segment *segments, unsigned long flags); | 163 | unsigned long nr_segments, struct kexec_segment __user *segments, |
164 | unsigned long flags); | ||
164 | 165 | ||
165 | asmlinkage long sys_exit(int error_code); | 166 | asmlinkage long sys_exit(int error_code); |
166 | asmlinkage void sys_exit_group(int error_code); | 167 | asmlinkage void sys_exit_group(int error_code); |