ia64/xen-unstable

view xen/common/kexec.c @ 12835:58284e749407

Remove unused KEXEC_RANGE_VA_XEN.

KEXEC_RANGE_VA_XEN is currently unused and there is no point in exporting it.

Signed-Off-By: Magnus Damm <magnus@valinux.co.jp>
---

Applies to xen-unstable-12756

xen/common/kexec.c | 13 +++----------
xen/include/public/kexec.h | 3 +--
2 files changed, 4 insertions(+), 12 deletions(-)
author Ian Campbell <ian.campbell@xensource.com>
date Thu Dec 07 11:43:19 2006 +0000 (2006-12-07)
parents b08b870770f9
children de69059a1f0e
line source
1 /******************************************************************************
2 * kexec.c - Achitecture independent kexec code for Xen
3 *
4 * Xen port written by:
5 * - Simon 'Horms' Horman <horms@verge.net.au>
6 * - Magnus Damm <magnus@valinux.co.jp>
7 */
9 #include <asm/kexec.h>
10 #include <xen/lib.h>
11 #include <xen/ctype.h>
12 #include <xen/errno.h>
13 #include <xen/guest_access.h>
14 #include <xen/sched.h>
15 #include <xen/types.h>
16 #include <xen/kexec.h>
17 #include <xen/keyhandler.h>
18 #include <public/kexec.h>
19 #include <xen/cpumask.h>
20 #include <asm/atomic.h>
21 #include <xen/spinlock.h>
22 #include <xen/version.h>
23 #include <public/elfnote.h>
25 DEFINE_PER_CPU (crash_note_t, crash_notes);
26 cpumask_t crash_saved_cpus;
27 int crashing_cpu;
29 xen_kexec_image_t kexec_image[KEXEC_IMAGE_NR];
31 #define KEXEC_FLAG_DEFAULT_POS (KEXEC_IMAGE_NR + 0)
32 #define KEXEC_FLAG_CRASH_POS (KEXEC_IMAGE_NR + 1)
33 #define KEXEC_FLAG_IN_PROGRESS (KEXEC_IMAGE_NR + 2)
35 unsigned long kexec_flags = 0; /* the lowest bits are for KEXEC_IMAGE... */
37 spinlock_t kexec_lock = SPIN_LOCK_UNLOCKED;
39 xen_kexec_reserve_t kexec_crash_area;
41 static void __init parse_crashkernel(char *str)
42 {
43 unsigned long start, size;
45 size = parse_size_and_unit(str, &str);
46 if ( *str == '@' )
47 start = parse_size_and_unit(str+1, NULL);
48 else
49 start = 0;
51 if ( start && size )
52 {
53 kexec_crash_area.start = start;
54 kexec_crash_area.size = size;
55 }
56 }
57 custom_param("crashkernel", parse_crashkernel);
59 static void one_cpu_only(void)
60 {
61 /* Only allow the first cpu to continue - force other cpus to spin */
62 if ( test_and_set_bit(KEXEC_FLAG_IN_PROGRESS, &kexec_flags) )
63 {
64 while (1);
65 }
66 }
68 /* Save the registers in the per-cpu crash note buffer */
70 void machine_crash_save_cpu(void)
71 {
72 int cpu = smp_processor_id();
73 crash_note_t *cntp;
75 if ( !cpu_test_and_set(cpu, crash_saved_cpus) )
76 {
77 cntp = &per_cpu(crash_notes, cpu);
78 elf_core_save_regs(&cntp->core.desc.desc.pr_reg,
79 &cntp->xen_regs.desc.desc);
81 /* setup crash "CORE" note */
82 setup_crash_note(cntp, core, CORE_STR, CORE_STR_LEN, NT_PRSTATUS);
84 /* setup crash note "Xen", XEN_ELFNOTE_CRASH_REGS */
85 setup_crash_note(cntp, xen_regs, XEN_STR, XEN_STR_LEN,
86 XEN_ELFNOTE_CRASH_REGS);
87 }
88 }
90 /* Setup the single Xen specific info crash note */
92 crash_xen_info_t *machine_crash_save_info(void)
93 {
94 int cpu = smp_processor_id();
95 crash_note_t *cntp;
96 crash_xen_info_t *info;
98 BUG_ON(!cpu_test_and_set(cpu, crash_saved_cpus));
100 cntp = &per_cpu(crash_notes, cpu);
102 /* setup crash note "Xen", XEN_ELFNOTE_CRASH_INFO */
103 setup_crash_note(cntp, xen_info, XEN_STR, XEN_STR_LEN,
104 XEN_ELFNOTE_CRASH_INFO);
106 info = &cntp->xen_info.desc.desc;
108 info->xen_major_version = xen_major_version();
109 info->xen_minor_version = xen_minor_version();
110 info->xen_extra_version = __pa(xen_extra_version());
111 info->xen_changeset = __pa(xen_changeset());
112 info->xen_compiler = __pa(xen_compiler());
113 info->xen_compile_date = __pa(xen_compile_date());
114 info->xen_compile_time = __pa(xen_compile_time());
115 info->tainted = tainted;
117 return info;
118 }
120 void machine_crash_kexec(void)
121 {
122 int pos;
123 xen_kexec_image_t *image;
125 one_cpu_only();
127 machine_crash_save_cpu();
128 crashing_cpu = smp_processor_id();
130 machine_crash_shutdown();
132 pos = (test_bit(KEXEC_FLAG_CRASH_POS, &kexec_flags) != 0);
134 if ( test_bit(KEXEC_IMAGE_CRASH_BASE + pos, &kexec_flags) )
135 {
136 image = &kexec_image[KEXEC_IMAGE_CRASH_BASE + pos];
137 machine_kexec(image); /* Does not return */
138 }
139 }
141 static void do_crashdump_trigger(unsigned char key)
142 {
143 printk("triggering crashdump\n");
144 machine_crash_kexec();
145 }
147 static __init int register_crashdump_trigger(void)
148 {
149 register_keyhandler('c', do_crashdump_trigger, "trigger a crashdump");
150 return 0;
151 }
152 __initcall(register_crashdump_trigger);
154 static int kexec_get_reserve(xen_kexec_range_t *range)
155 {
156 range->start = kexec_crash_area.start;
157 range->size = kexec_crash_area.size;
158 return 0;
159 }
161 extern unsigned long _text;
163 static int kexec_get_xen(xen_kexec_range_t *range)
164 {
165 range->start = virt_to_maddr(&_text);
166 range->size = (unsigned long)&_end - (unsigned long)&_text;
167 return 0;
168 }
170 static int kexec_get_cpu(xen_kexec_range_t *range)
171 {
172 if ( range->nr < 0 || range->nr >= num_present_cpus() )
173 return -EINVAL;
175 range->start = __pa((unsigned long)&per_cpu(crash_notes, range->nr));
176 range->size = sizeof(crash_note_t);
177 return 0;
178 }
180 static int kexec_get_range(XEN_GUEST_HANDLE(void) uarg)
181 {
182 xen_kexec_range_t range;
183 int ret = -EINVAL;
185 if ( unlikely(copy_from_guest(&range, uarg, 1)) )
186 return -EFAULT;
188 switch ( range.range )
189 {
190 case KEXEC_RANGE_MA_CRASH:
191 ret = kexec_get_reserve(&range);
192 break;
193 case KEXEC_RANGE_MA_XEN:
194 ret = kexec_get_xen(&range);
195 break;
196 case KEXEC_RANGE_MA_CPU:
197 ret = kexec_get_cpu(&range);
198 break;
199 }
201 if ( ret == 0 && unlikely(copy_to_guest(uarg, &range, 1)) )
202 return -EFAULT;
204 return ret;
205 }
207 static int kexec_load_get_bits(int type, int *base, int *bit)
208 {
209 switch ( type )
210 {
211 case KEXEC_TYPE_DEFAULT:
212 *base = KEXEC_IMAGE_DEFAULT_BASE;
213 *bit = KEXEC_FLAG_DEFAULT_POS;
214 break;
215 case KEXEC_TYPE_CRASH:
216 *base = KEXEC_IMAGE_CRASH_BASE;
217 *bit = KEXEC_FLAG_CRASH_POS;
218 break;
219 default:
220 return -1;
221 }
222 return 0;
223 }
225 static int kexec_load_unload(unsigned long op, XEN_GUEST_HANDLE(void) uarg)
226 {
227 xen_kexec_load_t load;
228 xen_kexec_image_t *image;
229 int base, bit, pos;
230 int ret = 0;
232 if ( unlikely(copy_from_guest(&load, uarg, 1)) )
233 return -EFAULT;
235 if ( kexec_load_get_bits(load.type, &base, &bit) )
236 return -EINVAL;
238 pos = (test_bit(bit, &kexec_flags) != 0);
240 /* Load the user data into an unused image */
241 if ( op == KEXEC_CMD_kexec_load )
242 {
243 image = &kexec_image[base + !pos];
245 BUG_ON(test_bit((base + !pos), &kexec_flags)); /* must be free */
247 memcpy(image, &load.image, sizeof(*image));
249 if ( !(ret = machine_kexec_load(load.type, base + !pos, image)) )
250 {
251 /* Set image present bit */
252 set_bit((base + !pos), &kexec_flags);
254 /* Make new image the active one */
255 change_bit(bit, &kexec_flags);
256 }
257 }
259 /* Unload the old image if present and load successful */
260 if ( ret == 0 && !test_bit(KEXEC_FLAG_IN_PROGRESS, &kexec_flags) )
261 {
262 if ( test_and_clear_bit((base + pos), &kexec_flags) )
263 {
264 image = &kexec_image[base + pos];
265 machine_kexec_unload(load.type, base + pos, image);
266 }
267 }
269 return ret;
270 }
272 static int kexec_exec(XEN_GUEST_HANDLE(void) uarg)
273 {
274 xen_kexec_exec_t exec;
275 xen_kexec_image_t *image;
276 int base, bit, pos;
278 if ( unlikely(copy_from_guest(&exec, uarg, 1)) )
279 return -EFAULT;
281 if ( kexec_load_get_bits(exec.type, &base, &bit) )
282 return -EINVAL;
284 pos = (test_bit(bit, &kexec_flags) != 0);
286 /* Only allow kexec/kdump into loaded images */
287 if ( !test_bit(base + pos, &kexec_flags) )
288 return -ENOENT;
290 switch (exec.type)
291 {
292 case KEXEC_TYPE_DEFAULT:
293 image = &kexec_image[base + pos];
294 one_cpu_only();
295 machine_reboot_kexec(image); /* Does not return */
296 break;
297 case KEXEC_TYPE_CRASH:
298 machine_crash_kexec(); /* Does not return */
299 break;
300 }
302 return -EINVAL; /* never reached */
303 }
305 long do_kexec_op(unsigned long op, XEN_GUEST_HANDLE(void) uarg)
306 {
307 unsigned long flags;
308 int ret = -EINVAL;
310 if ( !IS_PRIV(current->domain) )
311 return -EPERM;
313 switch ( op )
314 {
315 case KEXEC_CMD_kexec_get_range:
316 ret = kexec_get_range(uarg);
317 break;
318 case KEXEC_CMD_kexec_load:
319 case KEXEC_CMD_kexec_unload:
320 spin_lock_irqsave(&kexec_lock, flags);
321 if (!test_bit(KEXEC_FLAG_IN_PROGRESS, &kexec_flags))
322 {
323 ret = kexec_load_unload(op, uarg);
324 }
325 spin_unlock_irqrestore(&kexec_lock, flags);
326 break;
327 case KEXEC_CMD_kexec:
328 ret = kexec_exec(uarg);
329 break;
330 }
332 return ret;
333 }
335 /*
336 * Local variables:
337 * mode: C
338 * c-set-style: "BSD"
339 * c-basic-offset: 4
340 * tab-width: 4
341 * indent-tabs-mode: nil
342 * End:
343 */