ia64/xen-unstable

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