ia64/xen-unstable

view linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c @ 12707:c7e33053f59b

[LINUX] Only initialise kexec in domain0.

Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
author Ian Campbell <ian.campbell@xensource.com>
date Thu Nov 30 17:53:59 2006 +0000 (2006-11-30)
parents c988f781817d
children d7f71de58c4b
line source
1 /*
2 * drivers/xen/core/machine_kexec.c
3 * handle transition of Linux booting another kernel
4 */
6 #include <linux/kexec.h>
7 #include <xen/interface/kexec.h>
8 #include <linux/mm.h>
9 #include <linux/bootmem.h>
10 #include <asm/hypercall.h>
12 extern void machine_kexec_setup_load_arg(xen_kexec_image_t *xki,
13 struct kimage *image);
15 int xen_max_nr_phys_cpus;
16 struct resource xen_hypervisor_res;
17 struct resource *xen_phys_cpus;
19 void xen_machine_kexec_setup_resources(void)
20 {
21 xen_kexec_range_t range;
22 struct resource *res;
23 int k = 0;
25 if (!is_initial_xendomain())
26 return;
28 /* determine maximum number of physical cpus */
30 while (1) {
31 memset(&range, 0, sizeof(range));
32 range.range = KEXEC_RANGE_MA_CPU;
33 range.nr = k;
35 if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
36 break;
38 k++;
39 }
41 xen_max_nr_phys_cpus = k;
43 /* allocate xen_phys_cpus */
45 xen_phys_cpus = alloc_bootmem_low(k * sizeof(struct resource));
46 BUG_ON(!xen_phys_cpus);
48 /* fill in xen_phys_cpus with per-cpu crash note information */
50 for (k = 0; k < xen_max_nr_phys_cpus; k++) {
51 memset(&range, 0, sizeof(range));
52 range.range = KEXEC_RANGE_MA_CPU;
53 range.nr = k;
55 BUG_ON(HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range));
57 res = xen_phys_cpus + k;
59 memset(res, 0, sizeof(*res));
60 res->name = "Crash note";
61 res->start = range.start;
62 res->end = range.start + range.size - 1;
63 res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
64 }
66 /* fill in xen_hypervisor_res with hypervisor machine address range */
68 memset(&range, 0, sizeof(range));
69 range.range = KEXEC_RANGE_MA_XEN;
71 BUG_ON(HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range));
73 xen_hypervisor_res.name = "Hypervisor code and data";
74 xen_hypervisor_res.start = range.start;
75 xen_hypervisor_res.end = range.start + range.size - 1;
76 xen_hypervisor_res.flags = IORESOURCE_BUSY | IORESOURCE_MEM;
78 /* fill in crashk_res if range is reserved by hypervisor */
80 memset(&range, 0, sizeof(range));
81 range.range = KEXEC_RANGE_MA_CRASH;
83 BUG_ON(HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range));
85 if (range.size) {
86 crashk_res.start = range.start;
87 crashk_res.end = range.start + range.size - 1;
88 }
89 }
91 void xen_machine_kexec_register_resources(struct resource *res)
92 {
93 int k;
95 request_resource(res, &xen_hypervisor_res);
97 for (k = 0; k < xen_max_nr_phys_cpus; k++)
98 request_resource(res, xen_phys_cpus + k);
100 }
102 static void setup_load_arg(xen_kexec_image_t *xki, struct kimage *image)
103 {
104 machine_kexec_setup_load_arg(xki, image);
106 xki->indirection_page = image->head;
107 xki->start_address = image->start;
108 }
110 /*
111 * Load the image into xen so xen can kdump itself
112 * This might have been done in prepare, but prepare
113 * is currently called too early. It might make sense
114 * to move prepare, but for now, just add an extra hook.
115 */
116 int xen_machine_kexec_load(struct kimage *image)
117 {
118 xen_kexec_load_t xkl;
120 memset(&xkl, 0, sizeof(xkl));
121 xkl.type = image->type;
122 setup_load_arg(&xkl.image, image);
123 return HYPERVISOR_kexec_op(KEXEC_CMD_kexec_load, &xkl);
124 }
126 /*
127 * Unload the image that was stored by machine_kexec_load()
128 * This might have been done in machine_kexec_cleanup() but it
129 * is called too late, and its possible xen could try and kdump
130 * using resources that have been freed.
131 */
132 void xen_machine_kexec_unload(struct kimage *image)
133 {
134 xen_kexec_load_t xkl;
136 memset(&xkl, 0, sizeof(xkl));
137 xkl.type = image->type;
138 HYPERVISOR_kexec_op(KEXEC_CMD_kexec_unload, &xkl);
139 }
141 /*
142 * Do not allocate memory (or fail in any way) in machine_kexec().
143 * We are past the point of no return, committed to rebooting now.
144 *
145 * This has the hypervisor move to the prefered reboot CPU,
146 * stop all CPUs and kexec. That is it combines machine_shutdown()
147 * and machine_kexec() in Linux kexec terms.
148 */
149 NORET_TYPE void xen_machine_kexec(struct kimage *image)
150 {
151 xen_kexec_exec_t xke;
153 memset(&xke, 0, sizeof(xke));
154 xke.type = image->type;
155 HYPERVISOR_kexec_op(KEXEC_CMD_kexec, &xke);
156 panic("KEXEC_CMD_kexec hypercall should not return\n");
157 }
159 void machine_shutdown(void)
160 {
161 /* do nothing */
162 }
165 /*
166 * Local variables:
167 * c-file-style: "linux"
168 * indent-tabs-mode: t
169 * c-indent-level: 8
170 * c-basic-offset: 8
171 * tab-width: 8
172 * End:
173 */