2 * drivers/xen/core/machine_kexec.c
3 * handle transition of Linux booting another kernel
6 #include <linux/kexec.h>
7 #include <linux/slab.h>
8 #include <xen/interface/kexec.h>
9 #include <xen/interface/platform.h>
10 #include <linux/reboot.h>
12 #include <linux/bootmem.h>
15 extern void machine_kexec_setup_load_arg(xen_kexec_image_t *xki,
16 struct kimage *image);
17 extern int machine_kexec_setup_resources(struct resource *hypervisor,
18 struct resource *phys_cpus,
20 extern int machine_kexec_setup_resource(struct resource *hypervisor,
21 struct resource *phys_cpu);
22 extern void machine_kexec_register_resources(struct resource *res);
24 static unsigned int xen_nr_phys_cpus, xen_max_nr_phys_cpus;
25 static struct resource xen_hypervisor_res;
26 static struct resource *xen_phys_cpus;
27 static struct xen_phys_cpu_entry {
28 struct xen_phys_cpu_entry *next;
32 size_t vmcoreinfo_size_xen;
33 unsigned long paddr_vmcoreinfo_xen;
35 static int fill_crash_res(struct resource *res, unsigned int cpu)
37 xen_kexec_range_t range = {
38 .range = KEXEC_RANGE_MA_CPU,
41 int rc = HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range);
43 if (!rc && !range.size)
46 res->name = "Crash note";
47 res->start = range.start;
48 res->end = range.start + range.size - 1;
49 res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
55 static struct resource *find_crash_res(const struct resource *r,
59 struct xen_phys_cpu_entry *ent;
61 for (i = 0; i < xen_max_nr_phys_cpus; ++i) {
62 struct resource *res = xen_phys_cpus + i;
64 if (res->parent && res->start == r->start
65 && res->end == r->end) {
72 for (ent = xen_phys_cpu_list; ent; ent = ent->next, ++i)
73 if (ent->res.parent && ent->res.start == r->start
74 && ent->res.end == r->end) {
83 static int kexec_cpu_callback(struct notifier_block *nfb,
84 unsigned long action, void *hcpu)
86 unsigned int i, cpu = (unsigned long)hcpu;
87 struct xen_phys_cpu_entry *ent;
88 struct resource *res = NULL, r;
90 if (xen_nr_phys_cpus < xen_max_nr_phys_cpus)
91 xen_nr_phys_cpus = xen_max_nr_phys_cpus;
94 for (i = 0; i < xen_max_nr_phys_cpus; ++i)
95 if (!xen_phys_cpus[i].parent) {
96 res = xen_phys_cpus + i;
100 for (ent = xen_phys_cpu_list; ent; ent = ent->next)
101 if (!ent->res.parent) {
106 ent = kmalloc(sizeof(*ent), GFP_KERNEL);
107 res = ent ? &ent->res : NULL;
110 if (res && !fill_crash_res(res, cpu)
111 && !machine_kexec_setup_resource(&xen_hypervisor_res,
114 ent->next = xen_phys_cpu_list;
115 xen_phys_cpu_list = ent;
119 pr_warn("Could not set up crash note for pCPU#%u\n",
126 if (!fill_crash_res(&r, cpu))
127 res = find_crash_res(&r, NULL);
130 xen_platform_op_t op;
132 map = kcalloc(BITS_TO_LONGS(xen_nr_phys_cpus),
133 sizeof(long), GFP_KERNEL);
137 op.cmd = XENPF_get_cpuinfo;
138 op.u.pcpu_info.xen_cpuid = 0;
139 if (HYPERVISOR_platform_op(&op) == 0)
140 i = op.u.pcpu_info.max_present + 1;
142 i = xen_nr_phys_cpus;
144 for (cpu = 0; cpu < i; ++cpu) {
147 if (fill_crash_res(&r, cpu))
149 if (find_crash_res(&r, &idx)) {
150 BUG_ON(idx >= xen_nr_phys_cpus);
155 for (i = 0; i < xen_max_nr_phys_cpus; ++i)
156 if (xen_phys_cpus[i].parent && !test_bit(i, map)) {
157 res = xen_phys_cpus + i;
160 for (ent = xen_phys_cpu_list; !res && ent;
161 ent = ent->next, ++i)
162 if (ent->res.parent && !test_bit(i, map))
167 release_resource(res);
174 static struct notifier_block kexec_cpu_notifier = {
175 .notifier_call = kexec_cpu_callback
178 void __init xen_machine_kexec_setup_resources(void)
180 xen_kexec_range_t range;
181 xen_platform_op_t op;
182 unsigned int k = 0, nr = 0;
185 if (strstr(boot_command_line, "crashkernel="))
186 pr_warning("Ignoring crashkernel command line, "
187 "parameter will be supplied by xen\n");
189 if (!is_initial_xendomain())
192 /* fill in crashk_res if range is reserved by hypervisor */
193 memset(&range, 0, sizeof(range));
194 range.range = KEXEC_RANGE_MA_CRASH;
196 if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range)
200 crashk_res.start = range.start;
201 crashk_res.end = range.start + range.size - 1;
203 /* determine maximum number of physical cpus */
204 op.cmd = XENPF_get_cpuinfo;
205 op.u.pcpu_info.xen_cpuid = 0;
206 if (HYPERVISOR_platform_op(&op) == 0)
207 k = op.u.pcpu_info.max_present + 1;
208 #if CONFIG_XEN_COMPAT < 0x040000
210 memset(&range, 0, sizeof(range));
211 range.range = KEXEC_RANGE_MA_CPU;
214 if(HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
224 xen_max_nr_phys_cpus = k;
226 /* allocate xen_phys_cpus */
228 xen_phys_cpus = alloc_bootmem(k * sizeof(struct resource));
230 /* fill in xen_phys_cpus with per-cpu crash note information */
232 for (k = 0; k < xen_max_nr_phys_cpus; k++)
233 if (!fill_crash_res(xen_phys_cpus + nr, k))
239 /* fill in xen_hypervisor_res with hypervisor machine address range */
241 memset(&range, 0, sizeof(range));
242 range.range = KEXEC_RANGE_MA_XEN;
244 if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
247 xen_hypervisor_res.name = "Hypervisor code and data";
248 xen_hypervisor_res.start = range.start;
249 xen_hypervisor_res.end = range.start + range.size - 1;
250 xen_hypervisor_res.flags = IORESOURCE_BUSY | IORESOURCE_MEM;
252 /* get physical address of vmcoreinfo */
253 memset(&range, 0, sizeof(range));
254 range.range = KEXEC_RANGE_MA_VMCOREINFO;
256 rc = HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range);
259 /* Hypercall succeeded */
260 vmcoreinfo_size_xen = range.size;
261 paddr_vmcoreinfo_xen = range.start;
265 * Indicate not to create sysfs file by resetting globals
267 vmcoreinfo_size_xen = 0;
268 paddr_vmcoreinfo_xen = 0;
270 #if CONFIG_XEN_COMPAT < 0x030300
271 /* The KEXEC_CMD_kexec_get_range hypercall did not implement
272 * KEXEC_RANGE_MA_VMCOREINFO until Xen 3.3.
273 * Do not bail out if it fails for this reason.
280 if (machine_kexec_setup_resources(&xen_hypervisor_res, xen_phys_cpus,
283 * It's too cumbersome to properly free xen_phys_cpus here.
284 * Failure at this stage is unexpected and the amount of
285 * memory is small therefore we tolerate the potential leak.
290 xen_nr_phys_cpus = nr;
291 rc = register_pcpu_notifier(&kexec_cpu_notifier);
293 pr_warn("kexec: pCPU notifier registration failed (%d)\n", rc);
298 free_bootmem(__pa(xen_phys_cpus),
299 xen_max_nr_phys_cpus * sizeof(*xen_phys_cpus));
301 xen_nr_phys_cpus = 0;
305 void __init xen_machine_kexec_register_resources(struct resource *res)
310 request_resource(res, &xen_hypervisor_res);
311 for (k = 0; k < xen_nr_phys_cpus; k++) {
312 r = xen_phys_cpus + k;
313 if (r->parent == NULL) /* out of xen_hypervisor_res range */
314 request_resource(res, r);
316 machine_kexec_register_resources(res);
320 static void setup_load_arg(xen_kexec_image_t *xki, struct kimage *image)
322 machine_kexec_setup_load_arg(xki, image);
324 xki->indirection_page = image->head;
325 xki->start_address = image->start;
329 * Load the image into xen so xen can kdump itself
330 * This might have been done in prepare, but prepare
331 * is currently called too early. It might make sense
332 * to move prepare, but for now, just add an extra hook.
334 int xen_machine_kexec_load(struct kimage *image)
336 xen_kexec_load_t xkl;
338 memset(&xkl, 0, sizeof(xkl));
339 xkl.type = image->type;
340 setup_load_arg(&xkl.image, image);
341 return HYPERVISOR_kexec_op(KEXEC_CMD_kexec_load, &xkl);
345 * Unload the image that was stored by machine_kexec_load()
346 * This might have been done in machine_kexec_cleanup() but it
347 * is called too late, and its possible xen could try and kdump
348 * using resources that have been freed.
350 void xen_machine_kexec_unload(struct kimage *image)
352 xen_kexec_load_t xkl;
354 memset(&xkl, 0, sizeof(xkl));
355 xkl.type = image->type;
356 WARN_ON(HYPERVISOR_kexec_op(KEXEC_CMD_kexec_unload, &xkl));
360 * Do not allocate memory (or fail in any way) in machine_kexec().
361 * We are past the point of no return, committed to rebooting now.
363 * This has the hypervisor move to the prefered reboot CPU,
364 * stop all CPUs and kexec. That is it combines machine_shutdown()
365 * and machine_kexec() in Linux kexec terms.
367 void __noreturn machine_kexec(struct kimage *image)
369 xen_kexec_exec_t xke;
371 memset(&xke, 0, sizeof(xke));
372 xke.type = image->type;
373 VOID(HYPERVISOR_kexec_op(KEXEC_CMD_kexec, &xke));
374 panic("KEXEC_CMD_kexec hypercall should not return\n");
378 unsigned long paddr_vmcoreinfo_note(void)
380 return virt_to_machine(&vmcoreinfo_note);
384 void machine_shutdown(void)
389 void machine_crash_shutdown(struct pt_regs *regs)
391 /* The kernel is broken so disable interrupts */
397 * c-file-style: "linux"
398 * indent-tabs-mode: t