debuggers.hg
changeset 12661:c988f781817d
[XEN] Kexec / Kdump: Generic code
This patch implements the generic portion of the Kexec / Kdump port to Xen.
Signed-Off-By: Magnus Damm <magnus@valinux.co.jp>
Signed-Off-By: Simon Horman <horms@verge.net.au>
This patch implements the generic portion of the Kexec / Kdump port to Xen.
Signed-Off-By: Magnus Damm <magnus@valinux.co.jp>
Signed-Off-By: Simon Horman <horms@verge.net.au>
line diff
1.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/Makefile Wed Nov 29 23:40:40 2006 +0000 1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/Makefile Thu Nov 30 12:38:50 2006 +0000 1.3 @@ -11,3 +11,4 @@ obj-$(CONFIG_XEN_SYSFS) += xen_sysfs.o 1.4 obj-$(CONFIG_XEN_SKBUFF) += skbuff.o 1.5 obj-$(CONFIG_XEN_REBOOT) += reboot.o machine_reboot.o 1.6 obj-$(CONFIG_XEN_SMPBOOT) += smpboot.o 1.7 +obj-$(CONFIG_KEXEC) += machine_kexec.o
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c Thu Nov 30 12:38:50 2006 +0000 2.3 @@ -0,0 +1,170 @@ 2.4 +/* 2.5 + * drivers/xen/core/machine_kexec.c 2.6 + * handle transition of Linux booting another kernel 2.7 + */ 2.8 + 2.9 +#include <linux/kexec.h> 2.10 +#include <xen/interface/kexec.h> 2.11 +#include <linux/mm.h> 2.12 +#include <linux/bootmem.h> 2.13 +#include <asm/hypercall.h> 2.14 + 2.15 +extern void machine_kexec_setup_load_arg(xen_kexec_image_t *xki, 2.16 + struct kimage *image); 2.17 + 2.18 +int xen_max_nr_phys_cpus; 2.19 +struct resource xen_hypervisor_res; 2.20 +struct resource *xen_phys_cpus; 2.21 + 2.22 +void xen_machine_kexec_setup_resources(void) 2.23 +{ 2.24 + xen_kexec_range_t range; 2.25 + struct resource *res; 2.26 + int k = 0; 2.27 + 2.28 + /* determine maximum number of physical cpus */ 2.29 + 2.30 + while (1) { 2.31 + memset(&range, 0, sizeof(range)); 2.32 + range.range = KEXEC_RANGE_MA_CPU; 2.33 + range.nr = k; 2.34 + 2.35 + if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range)) 2.36 + break; 2.37 + 2.38 + k++; 2.39 + } 2.40 + 2.41 + xen_max_nr_phys_cpus = k; 2.42 + 2.43 + /* allocate xen_phys_cpus */ 2.44 + 2.45 + xen_phys_cpus = alloc_bootmem_low(k * sizeof(struct resource)); 2.46 + BUG_ON(!xen_phys_cpus); 2.47 + 2.48 + /* fill in xen_phys_cpus with per-cpu crash note information */ 2.49 + 2.50 + for (k = 0; k < xen_max_nr_phys_cpus; k++) { 2.51 + memset(&range, 0, sizeof(range)); 2.52 + range.range = KEXEC_RANGE_MA_CPU; 2.53 + range.nr = k; 2.54 + 2.55 + BUG_ON(HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range)); 2.56 + 2.57 + res = xen_phys_cpus + k; 2.58 + 2.59 + memset(res, 0, sizeof(*res)); 2.60 + res->name = "Crash note"; 2.61 + res->start = range.start; 2.62 + res->end = range.start + range.size - 1; 2.63 + res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; 2.64 + } 2.65 + 2.66 + /* fill in xen_hypervisor_res with hypervisor machine address range */ 2.67 + 2.68 + memset(&range, 0, sizeof(range)); 2.69 + range.range = KEXEC_RANGE_MA_XEN; 2.70 + 2.71 + BUG_ON(HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range)); 2.72 + 2.73 + xen_hypervisor_res.name = "Hypervisor code and data"; 2.74 + xen_hypervisor_res.start = range.start; 2.75 + xen_hypervisor_res.end = range.start + range.size - 1; 2.76 + xen_hypervisor_res.flags = IORESOURCE_BUSY | IORESOURCE_MEM; 2.77 + 2.78 + /* fill in crashk_res if range is reserved by hypervisor */ 2.79 + 2.80 + memset(&range, 0, sizeof(range)); 2.81 + range.range = KEXEC_RANGE_MA_CRASH; 2.82 + 2.83 + BUG_ON(HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range)); 2.84 + 2.85 + if (range.size) { 2.86 + crashk_res.start = range.start; 2.87 + crashk_res.end = range.start + range.size - 1; 2.88 + } 2.89 +} 2.90 + 2.91 +void xen_machine_kexec_register_resources(struct resource *res) 2.92 +{ 2.93 + int k; 2.94 + 2.95 + request_resource(res, &xen_hypervisor_res); 2.96 + 2.97 + for (k = 0; k < xen_max_nr_phys_cpus; k++) 2.98 + request_resource(res, xen_phys_cpus + k); 2.99 + 2.100 +} 2.101 + 2.102 +static void setup_load_arg(xen_kexec_image_t *xki, struct kimage *image) 2.103 +{ 2.104 + machine_kexec_setup_load_arg(xki, image); 2.105 + 2.106 + xki->indirection_page = image->head; 2.107 + xki->start_address = image->start; 2.108 +} 2.109 + 2.110 +/* 2.111 + * Load the image into xen so xen can kdump itself 2.112 + * This might have been done in prepare, but prepare 2.113 + * is currently called too early. It might make sense 2.114 + * to move prepare, but for now, just add an extra hook. 2.115 + */ 2.116 +int xen_machine_kexec_load(struct kimage *image) 2.117 +{ 2.118 + xen_kexec_load_t xkl; 2.119 + 2.120 + memset(&xkl, 0, sizeof(xkl)); 2.121 + xkl.type = image->type; 2.122 + setup_load_arg(&xkl.image, image); 2.123 + return HYPERVISOR_kexec_op(KEXEC_CMD_kexec_load, &xkl); 2.124 +} 2.125 + 2.126 +/* 2.127 + * Unload the image that was stored by machine_kexec_load() 2.128 + * This might have been done in machine_kexec_cleanup() but it 2.129 + * is called too late, and its possible xen could try and kdump 2.130 + * using resources that have been freed. 2.131 + */ 2.132 +void xen_machine_kexec_unload(struct kimage *image) 2.133 +{ 2.134 + xen_kexec_load_t xkl; 2.135 + 2.136 + memset(&xkl, 0, sizeof(xkl)); 2.137 + xkl.type = image->type; 2.138 + HYPERVISOR_kexec_op(KEXEC_CMD_kexec_unload, &xkl); 2.139 +} 2.140 + 2.141 +/* 2.142 + * Do not allocate memory (or fail in any way) in machine_kexec(). 2.143 + * We are past the point of no return, committed to rebooting now. 2.144 + * 2.145 + * This has the hypervisor move to the prefered reboot CPU, 2.146 + * stop all CPUs and kexec. That is it combines machine_shutdown() 2.147 + * and machine_kexec() in Linux kexec terms. 2.148 + */ 2.149 +NORET_TYPE void xen_machine_kexec(struct kimage *image) 2.150 +{ 2.151 + xen_kexec_exec_t xke; 2.152 + 2.153 + memset(&xke, 0, sizeof(xke)); 2.154 + xke.type = image->type; 2.155 + HYPERVISOR_kexec_op(KEXEC_CMD_kexec, &xke); 2.156 + panic("KEXEC_CMD_kexec hypercall should not return\n"); 2.157 +} 2.158 + 2.159 +void machine_shutdown(void) 2.160 +{ 2.161 + /* do nothing */ 2.162 +} 2.163 + 2.164 + 2.165 +/* 2.166 + * Local variables: 2.167 + * c-file-style: "linux" 2.168 + * indent-tabs-mode: t 2.169 + * c-indent-level: 8 2.170 + * c-basic-offset: 8 2.171 + * tab-width: 8 2.172 + * End: 2.173 + */
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/patches/linux-2.6.16.33/kexec-generic.patch Thu Nov 30 12:38:50 2006 +0000 3.3 @@ -0,0 +1,228 @@ 3.4 +--- 0001/include/linux/kexec.h 3.5 ++++ work/include/linux/kexec.h 3.6 +@@ -31,6 +31,13 @@ 3.7 + #error KEXEC_ARCH not defined 3.8 + #endif 3.9 + 3.10 ++#ifndef KEXEC_ARCH_HAS_PAGE_MACROS 3.11 ++#define kexec_page_to_pfn(page) page_to_pfn(page) 3.12 ++#define kexec_pfn_to_page(pfn) pfn_to_page(pfn) 3.13 ++#define kexec_virt_to_phys(addr) virt_to_phys(addr) 3.14 ++#define kexec_phys_to_virt(addr) phys_to_virt(addr) 3.15 ++#endif 3.16 ++ 3.17 + /* 3.18 + * This structure is used to hold the arguments that are used when loading 3.19 + * kernel binaries. 3.20 +@@ -91,6 +98,13 @@ struct kimage { 3.21 + extern NORET_TYPE void machine_kexec(struct kimage *image) ATTRIB_NORET; 3.22 + extern int machine_kexec_prepare(struct kimage *image); 3.23 + extern void machine_kexec_cleanup(struct kimage *image); 3.24 ++#ifdef CONFIG_XEN 3.25 ++extern int xen_machine_kexec_load(struct kimage *image); 3.26 ++extern void xen_machine_kexec_unload(struct kimage *image); 3.27 ++extern NORET_TYPE void xen_machine_kexec(struct kimage *image) ATTRIB_NORET; 3.28 ++extern void xen_machine_kexec_setup_resources(void); 3.29 ++extern void xen_machine_kexec_register_resources(struct resource *res); 3.30 ++#endif 3.31 + extern asmlinkage long sys_kexec_load(unsigned long entry, 3.32 + unsigned long nr_segments, 3.33 + struct kexec_segment __user *segments, 3.34 +--- 0001/kernel/kexec.c 3.35 ++++ work/kernel/kexec.c 3.36 +@@ -403,7 +403,7 @@ static struct page *kimage_alloc_normal_ 3.37 + pages = kimage_alloc_pages(GFP_KERNEL, order); 3.38 + if (!pages) 3.39 + break; 3.40 +- pfn = page_to_pfn(pages); 3.41 ++ pfn = kexec_page_to_pfn(pages); 3.42 + epfn = pfn + count; 3.43 + addr = pfn << PAGE_SHIFT; 3.44 + eaddr = epfn << PAGE_SHIFT; 3.45 +@@ -437,6 +437,7 @@ static struct page *kimage_alloc_normal_ 3.46 + return pages; 3.47 + } 3.48 + 3.49 ++#ifndef CONFIG_XEN 3.50 + static struct page *kimage_alloc_crash_control_pages(struct kimage *image, 3.51 + unsigned int order) 3.52 + { 3.53 +@@ -490,7 +491,7 @@ static struct page *kimage_alloc_crash_c 3.54 + } 3.55 + /* If I don't overlap any segments I have found my hole! */ 3.56 + if (i == image->nr_segments) { 3.57 +- pages = pfn_to_page(hole_start >> PAGE_SHIFT); 3.58 ++ pages = kexec_pfn_to_page(hole_start >> PAGE_SHIFT); 3.59 + break; 3.60 + } 3.61 + } 3.62 +@@ -517,6 +518,13 @@ struct page *kimage_alloc_control_pages( 3.63 + 3.64 + return pages; 3.65 + } 3.66 ++#else /* !CONFIG_XEN */ 3.67 ++struct page *kimage_alloc_control_pages(struct kimage *image, 3.68 ++ unsigned int order) 3.69 ++{ 3.70 ++ return kimage_alloc_normal_control_pages(image, order); 3.71 ++} 3.72 ++#endif 3.73 + 3.74 + static int kimage_add_entry(struct kimage *image, kimage_entry_t entry) 3.75 + { 3.76 +@@ -532,7 +540,7 @@ static int kimage_add_entry(struct kimag 3.77 + return -ENOMEM; 3.78 + 3.79 + ind_page = page_address(page); 3.80 +- *image->entry = virt_to_phys(ind_page) | IND_INDIRECTION; 3.81 ++ *image->entry = kexec_virt_to_phys(ind_page) | IND_INDIRECTION; 3.82 + image->entry = ind_page; 3.83 + image->last_entry = ind_page + 3.84 + ((PAGE_SIZE/sizeof(kimage_entry_t)) - 1); 3.85 +@@ -593,13 +601,13 @@ static int kimage_terminate(struct kimag 3.86 + #define for_each_kimage_entry(image, ptr, entry) \ 3.87 + for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE); \ 3.88 + ptr = (entry & IND_INDIRECTION)? \ 3.89 +- phys_to_virt((entry & PAGE_MASK)): ptr +1) 3.90 ++ kexec_phys_to_virt((entry & PAGE_MASK)): ptr +1) 3.91 + 3.92 + static void kimage_free_entry(kimage_entry_t entry) 3.93 + { 3.94 + struct page *page; 3.95 + 3.96 +- page = pfn_to_page(entry >> PAGE_SHIFT); 3.97 ++ page = kexec_pfn_to_page(entry >> PAGE_SHIFT); 3.98 + kimage_free_pages(page); 3.99 + } 3.100 + 3.101 +@@ -611,6 +619,10 @@ static void kimage_free(struct kimage *i 3.102 + if (!image) 3.103 + return; 3.104 + 3.105 ++#ifdef CONFIG_XEN 3.106 ++ xen_machine_kexec_unload(image); 3.107 ++#endif 3.108 ++ 3.109 + kimage_free_extra_pages(image); 3.110 + for_each_kimage_entry(image, ptr, entry) { 3.111 + if (entry & IND_INDIRECTION) { 3.112 +@@ -686,7 +698,7 @@ static struct page *kimage_alloc_page(st 3.113 + * have a match. 3.114 + */ 3.115 + list_for_each_entry(page, &image->dest_pages, lru) { 3.116 +- addr = page_to_pfn(page) << PAGE_SHIFT; 3.117 ++ addr = kexec_page_to_pfn(page) << PAGE_SHIFT; 3.118 + if (addr == destination) { 3.119 + list_del(&page->lru); 3.120 + return page; 3.121 +@@ -701,12 +713,12 @@ static struct page *kimage_alloc_page(st 3.122 + if (!page) 3.123 + return NULL; 3.124 + /* If the page cannot be used file it away */ 3.125 +- if (page_to_pfn(page) > 3.126 ++ if (kexec_page_to_pfn(page) > 3.127 + (KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) { 3.128 + list_add(&page->lru, &image->unuseable_pages); 3.129 + continue; 3.130 + } 3.131 +- addr = page_to_pfn(page) << PAGE_SHIFT; 3.132 ++ addr = kexec_page_to_pfn(page) << PAGE_SHIFT; 3.133 + 3.134 + /* If it is the destination page we want use it */ 3.135 + if (addr == destination) 3.136 +@@ -729,7 +741,7 @@ static struct page *kimage_alloc_page(st 3.137 + struct page *old_page; 3.138 + 3.139 + old_addr = *old & PAGE_MASK; 3.140 +- old_page = pfn_to_page(old_addr >> PAGE_SHIFT); 3.141 ++ old_page = kexec_pfn_to_page(old_addr >> PAGE_SHIFT); 3.142 + copy_highpage(page, old_page); 3.143 + *old = addr | (*old & ~PAGE_MASK); 3.144 + 3.145 +@@ -779,7 +791,7 @@ static int kimage_load_normal_segment(st 3.146 + result = -ENOMEM; 3.147 + goto out; 3.148 + } 3.149 +- result = kimage_add_page(image, page_to_pfn(page) 3.150 ++ result = kimage_add_page(image, kexec_page_to_pfn(page) 3.151 + << PAGE_SHIFT); 3.152 + if (result < 0) 3.153 + goto out; 3.154 +@@ -811,6 +823,7 @@ out: 3.155 + return result; 3.156 + } 3.157 + 3.158 ++#ifndef CONFIG_XEN 3.159 + static int kimage_load_crash_segment(struct kimage *image, 3.160 + struct kexec_segment *segment) 3.161 + { 3.162 +@@ -833,7 +846,7 @@ static int kimage_load_crash_segment(str 3.163 + char *ptr; 3.164 + size_t uchunk, mchunk; 3.165 + 3.166 +- page = pfn_to_page(maddr >> PAGE_SHIFT); 3.167 ++ page = kexec_pfn_to_page(maddr >> PAGE_SHIFT); 3.168 + if (page == 0) { 3.169 + result = -ENOMEM; 3.170 + goto out; 3.171 +@@ -881,6 +894,13 @@ static int kimage_load_segment(struct ki 3.172 + 3.173 + return result; 3.174 + } 3.175 ++#else /* CONFIG_XEN */ 3.176 ++static int kimage_load_segment(struct kimage *image, 3.177 ++ struct kexec_segment *segment) 3.178 ++{ 3.179 ++ return kimage_load_normal_segment(image, segment); 3.180 ++} 3.181 ++#endif 3.182 + 3.183 + /* 3.184 + * Exec Kernel system call: for obvious reasons only root may call it. 3.185 +@@ -991,6 +1011,11 @@ asmlinkage long sys_kexec_load(unsigned 3.186 + if (result) 3.187 + goto out; 3.188 + } 3.189 ++#ifdef CONFIG_XEN 3.190 ++ result = xen_machine_kexec_load(image); 3.191 ++ if (result) 3.192 ++ goto out; 3.193 ++#endif 3.194 + /* Install the new kernel, and Uninstall the old */ 3.195 + image = xchg(dest_image, image); 3.196 + 3.197 +@@ -1045,7 +1070,6 @@ void crash_kexec(struct pt_regs *regs) 3.198 + struct kimage *image; 3.199 + int locked; 3.200 + 3.201 +- 3.202 + /* Take the kexec_lock here to prevent sys_kexec_load 3.203 + * running on one cpu from replacing the crash kernel 3.204 + * we are using after a panic on a different cpu. 3.205 +@@ -1061,7 +1085,11 @@ void crash_kexec(struct pt_regs *regs) 3.206 + struct pt_regs fixed_regs; 3.207 + crash_setup_regs(&fixed_regs, regs); 3.208 + machine_crash_shutdown(&fixed_regs); 3.209 ++#ifdef CONFIG_XEN 3.210 ++ xen_machine_kexec(image); 3.211 ++#else 3.212 + machine_kexec(image); 3.213 ++#endif 3.214 + } 3.215 + xchg(&kexec_lock, 0); 3.216 + } 3.217 +--- 0002/kernel/sys.c 3.218 ++++ work/kernel/sys.c 3.219 +@@ -435,8 +435,12 @@ void kernel_kexec(void) 3.220 + kernel_restart_prepare(NULL); 3.221 + printk(KERN_EMERG "Starting new kernel\n"); 3.222 + machine_shutdown(); 3.223 ++#ifdef CONFIG_XEN 3.224 ++ xen_machine_kexec(image); 3.225 ++#else 3.226 + machine_kexec(image); 3.227 + #endif 3.228 ++#endif 3.229 + } 3.230 + EXPORT_SYMBOL_GPL(kernel_kexec); 3.231 +
4.1 --- a/patches/linux-2.6.16.33/series Wed Nov 29 23:40:40 2006 +0000 4.2 +++ b/patches/linux-2.6.16.33/series Thu Nov 30 12:38:50 2006 +0000 4.3 @@ -1,3 +1,4 @@ 4.4 +kexec-generic.patch 4.5 blktap-aio-16_03_06.patch 4.6 device_bind.patch 4.7 fix-hz-suspend.patch
5.1 --- a/xen/arch/ia64/xen/Makefile Wed Nov 29 23:40:40 2006 +0000 5.2 +++ b/xen/arch/ia64/xen/Makefile Thu Nov 30 12:38:50 2006 +0000 5.3 @@ -1,3 +1,5 @@ 5.4 +obj-y += machine_kexec.o 5.5 +obj-y += crash.o 5.6 obj-y += acpi.o 5.7 obj-y += dom0_ops.o 5.8 obj-y += domain.o
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/xen/arch/ia64/xen/crash.c Thu Nov 30 12:38:50 2006 +0000 6.3 @@ -0,0 +1,19 @@ 6.4 +#include <xen/lib.h> /* for printk() used in stub */ 6.5 +#include <xen/types.h> 6.6 +#include <public/kexec.h> 6.7 + 6.8 +void machine_crash_shutdown(void) 6.9 +{ 6.10 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 6.11 +} 6.12 + 6.13 +/* 6.14 + * Local variables: 6.15 + * mode: C 6.16 + * c-set-style: "BSD" 6.17 + * c-basic-offset: 4 6.18 + * tab-width: 4 6.19 + * indent-tabs-mode: nil 6.20 + * End: 6.21 + */ 6.22 +
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/xen/arch/ia64/xen/machine_kexec.c Thu Nov 30 12:38:50 2006 +0000 7.3 @@ -0,0 +1,34 @@ 7.4 +#include <xen/lib.h> /* for printk() used in stubs */ 7.5 +#include <xen/types.h> 7.6 +#include <public/kexec.h> 7.7 + 7.8 +int machine_kexec_load(int type, int slot, xen_kexec_image_t *image) 7.9 +{ 7.10 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 7.11 + return -1; 7.12 +} 7.13 + 7.14 +void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image) 7.15 +{ 7.16 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 7.17 +} 7.18 + 7.19 +void machine_kexec(xen_kexec_image_t *image) 7.20 +{ 7.21 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 7.22 +} 7.23 + 7.24 +void machine_shutdown(xen_kexec_image_t *image) 7.25 +{ 7.26 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 7.27 +} 7.28 + 7.29 +/* 7.30 + * Local variables: 7.31 + * mode: C 7.32 + * c-set-style: "BSD" 7.33 + * c-basic-offset: 4 7.34 + * tab-width: 4 7.35 + * indent-tabs-mode: nil 7.36 + * End: 7.37 + */
8.1 --- a/xen/arch/powerpc/Makefile Wed Nov 29 23:40:40 2006 +0000 8.2 +++ b/xen/arch/powerpc/Makefile Thu Nov 30 12:38:50 2006 +0000 8.3 @@ -40,6 +40,8 @@ obj-y += smp-tbsync.o 8.4 obj-y += sysctl.o 8.5 obj-y += time.o 8.6 obj-y += usercopy.o 8.7 +obj-y += machine_kexec.o 8.8 +obj-y += crash.o 8.9 8.10 obj-$(debug) += 0opt.o 8.11 obj-$(crash_debug) += gdbstub.o
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/xen/arch/powerpc/crash.c Thu Nov 30 12:38:50 2006 +0000 9.3 @@ -0,0 +1,19 @@ 9.4 +#include <xen/lib.h> /* for printk() used in stub */ 9.5 +#include <xen/types.h> 9.6 +#include <public/kexec.h> 9.7 + 9.8 +void machine_crash_shutdown(void) 9.9 +{ 9.10 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 9.11 +} 9.12 + 9.13 +/* 9.14 + * Local variables: 9.15 + * mode: C 9.16 + * c-set-style: "BSD" 9.17 + * c-basic-offset: 4 9.18 + * tab-width: 4 9.19 + * indent-tabs-mode: nil 9.20 + * End: 9.21 + */ 9.22 +
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/xen/arch/powerpc/machine_kexec.c Thu Nov 30 12:38:50 2006 +0000 10.3 @@ -0,0 +1,34 @@ 10.4 +#include <xen/lib.h> /* for printk() used in stubs */ 10.5 +#include <xen/types.h> 10.6 +#include <public/kexec.h> 10.7 + 10.8 +int machine_kexec_load(int type, int slot, xen_kexec_image_t *image) 10.9 +{ 10.10 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 10.11 + return -1; 10.12 +} 10.13 + 10.14 +void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image) 10.15 +{ 10.16 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 10.17 +} 10.18 + 10.19 +void machine_kexec(xen_kexec_image_t *image) 10.20 +{ 10.21 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 10.22 +} 10.23 + 10.24 +void machine_shutdown(xen_kexec_image_t *image) 10.25 +{ 10.26 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 10.27 +} 10.28 + 10.29 +/* 10.30 + * Local variables: 10.31 + * mode: C 10.32 + * c-set-style: "BSD" 10.33 + * c-basic-offset: 4 10.34 + * tab-width: 4 10.35 + * indent-tabs-mode: nil 10.36 + * End: 10.37 + */
11.1 --- a/xen/arch/x86/Makefile Wed Nov 29 23:40:40 2006 +0000 11.2 +++ b/xen/arch/x86/Makefile Thu Nov 30 12:38:50 2006 +0000 11.3 @@ -43,6 +43,8 @@ obj-y += trampoline.o 11.4 obj-y += traps.o 11.5 obj-y += usercopy.o 11.6 obj-y += x86_emulate.o 11.7 +obj-y += machine_kexec.o 11.8 +obj-y += crash.o 11.9 11.10 obj-$(crash_debug) += gdbstub.o 11.11
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/xen/arch/x86/crash.c Thu Nov 30 12:38:50 2006 +0000 12.3 @@ -0,0 +1,19 @@ 12.4 +#include <xen/lib.h> /* for printk() used in stub */ 12.5 +#include <xen/types.h> 12.6 +#include <public/kexec.h> 12.7 + 12.8 +void machine_crash_shutdown(void) 12.9 +{ 12.10 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 12.11 +} 12.12 + 12.13 +/* 12.14 + * Local variables: 12.15 + * mode: C 12.16 + * c-set-style: "BSD" 12.17 + * c-basic-offset: 4 12.18 + * tab-width: 4 12.19 + * indent-tabs-mode: nil 12.20 + * End: 12.21 + */ 12.22 +
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/xen/arch/x86/machine_kexec.c Thu Nov 30 12:38:50 2006 +0000 13.3 @@ -0,0 +1,34 @@ 13.4 +#include <xen/lib.h> /* for printk() used in stubs */ 13.5 +#include <xen/types.h> 13.6 +#include <public/kexec.h> 13.7 + 13.8 +int machine_kexec_load(int type, int slot, xen_kexec_image_t *image) 13.9 +{ 13.10 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 13.11 + return -1; 13.12 +} 13.13 + 13.14 +void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image) 13.15 +{ 13.16 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 13.17 +} 13.18 + 13.19 +void machine_kexec(xen_kexec_image_t *image) 13.20 +{ 13.21 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 13.22 +} 13.23 + 13.24 +void machine_shutdown(xen_kexec_image_t *image) 13.25 +{ 13.26 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 13.27 +} 13.28 + 13.29 +/* 13.30 + * Local variables: 13.31 + * mode: C 13.32 + * c-set-style: "BSD" 13.33 + * c-basic-offset: 4 13.34 + * tab-width: 4 13.35 + * indent-tabs-mode: nil 13.36 + * End: 13.37 + */
14.1 --- a/xen/common/Makefile Wed Nov 29 23:40:40 2006 +0000 14.2 +++ b/xen/common/Makefile Thu Nov 30 12:38:50 2006 +0000 14.3 @@ -7,6 +7,7 @@ obj-y += event_channel.o 14.4 obj-y += grant_table.o 14.5 obj-y += kernel.o 14.6 obj-y += keyhandler.o 14.7 +obj-y += kexec.o 14.8 obj-y += lib.o 14.9 obj-y += memory.o 14.10 obj-y += multicall.o
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/xen/common/kexec.c Thu Nov 30 12:38:50 2006 +0000 15.3 @@ -0,0 +1,370 @@ 15.4 +/****************************************************************************** 15.5 + * kexec.c - Achitecture independent kexec code for Xen 15.6 + * 15.7 + * Xen port written by: 15.8 + * - Simon 'Horms' Horman <horms@verge.net.au> 15.9 + * - Magnus Damm <magnus@valinux.co.jp> 15.10 + */ 15.11 + 15.12 +#include <asm/kexec.h> 15.13 +#include <xen/lib.h> 15.14 +#include <xen/ctype.h> 15.15 +#include <xen/errno.h> 15.16 +#include <xen/guest_access.h> 15.17 +#include <xen/sched.h> 15.18 +#include <xen/types.h> 15.19 +#include <xen/kexec.h> 15.20 +#include <xen/keyhandler.h> 15.21 +#include <public/kexec.h> 15.22 +#include <xen/cpumask.h> 15.23 +#include <asm/atomic.h> 15.24 +#include <xen/spinlock.h> 15.25 +#include <xen/version.h> 15.26 +#include <public/elfnote.h> 15.27 + 15.28 +static char opt_crashkernel[32] = ""; 15.29 +string_param("crashkernel", opt_crashkernel); 15.30 + 15.31 +DEFINE_PER_CPU (crash_note_t, crash_notes); 15.32 +cpumask_t crash_saved_cpus; 15.33 +int crashing_cpu; 15.34 + 15.35 +xen_kexec_image_t kexec_image[KEXEC_IMAGE_NR]; 15.36 + 15.37 +#define KEXEC_FLAG_DEFAULT_POS (KEXEC_IMAGE_NR + 0) 15.38 +#define KEXEC_FLAG_CRASH_POS (KEXEC_IMAGE_NR + 1) 15.39 +#define KEXEC_FLAG_IN_PROGRESS (KEXEC_IMAGE_NR + 2) 15.40 + 15.41 +unsigned long kexec_flags = 0; /* the lowest bits are for KEXEC_IMAGE... */ 15.42 + 15.43 +spinlock_t kexec_lock = SPIN_LOCK_UNLOCKED; 15.44 + 15.45 +static void one_cpu_only(void) 15.46 +{ 15.47 + /* Only allow the first cpu to continue - force other cpus to spin */ 15.48 + if (test_and_set_bit(KEXEC_FLAG_IN_PROGRESS, &kexec_flags)) 15.49 + { 15.50 + while (1); 15.51 + } 15.52 +} 15.53 + 15.54 +/* Save the registers in the per-cpu crash note buffer */ 15.55 + 15.56 +void machine_crash_save_cpu(void) 15.57 +{ 15.58 + int cpu = smp_processor_id(); 15.59 + crash_note_t *cntp; 15.60 + 15.61 + if (!cpu_test_and_set(cpu, crash_saved_cpus)) 15.62 + { 15.63 + cntp = &per_cpu(crash_notes, cpu); 15.64 + elf_core_save_regs(&cntp->core.desc.desc.pr_reg, 15.65 + &cntp->xen_regs.desc.desc); 15.66 + 15.67 + /* setup crash "CORE" note */ 15.68 + setup_crash_note(cntp, core, CORE_STR, CORE_STR_LEN, NT_PRSTATUS); 15.69 + 15.70 + /* setup crash note "Xen", XEN_ELFNOTE_CRASH_REGS */ 15.71 + setup_crash_note(cntp, xen_regs, XEN_STR, XEN_STR_LEN, 15.72 + XEN_ELFNOTE_CRASH_REGS); 15.73 + } 15.74 +} 15.75 + 15.76 +/* Setup the single Xen specific info crash note */ 15.77 + 15.78 +crash_xen_info_t *machine_crash_save_info(void) 15.79 +{ 15.80 + int cpu = smp_processor_id(); 15.81 + crash_note_t *cntp; 15.82 + crash_xen_info_t *info; 15.83 + 15.84 + BUG_ON(!cpu_test_and_set(cpu, crash_saved_cpus)); 15.85 + 15.86 + cntp = &per_cpu(crash_notes, cpu); 15.87 + 15.88 + /* setup crash note "Xen", XEN_ELFNOTE_CRASH_INFO */ 15.89 + setup_crash_note(cntp, xen_info, XEN_STR, XEN_STR_LEN, 15.90 + XEN_ELFNOTE_CRASH_INFO); 15.91 + 15.92 + info = &cntp->xen_info.desc.desc; 15.93 + 15.94 + info->xen_major_version = xen_major_version(); 15.95 + info->xen_minor_version = xen_minor_version(); 15.96 + info->xen_extra_version = __pa(xen_extra_version()); 15.97 + info->xen_changeset = __pa(xen_changeset()); 15.98 + info->xen_compiler = __pa(xen_compiler()); 15.99 + info->xen_compile_date = __pa(xen_compile_date()); 15.100 + info->xen_compile_time = __pa(xen_compile_time()); 15.101 + info->tainted = tainted; 15.102 + 15.103 + return info; 15.104 +} 15.105 + 15.106 +void machine_crash_kexec(void) 15.107 +{ 15.108 + int pos; 15.109 + xen_kexec_image_t *image; 15.110 + 15.111 + one_cpu_only(); 15.112 + 15.113 + machine_crash_save_cpu(); 15.114 + crashing_cpu = smp_processor_id(); 15.115 + 15.116 + machine_crash_shutdown(); 15.117 + 15.118 + pos = (test_bit(KEXEC_FLAG_CRASH_POS, &kexec_flags) != 0); 15.119 + 15.120 + if (test_bit(KEXEC_IMAGE_CRASH_BASE + pos, &kexec_flags)) 15.121 + { 15.122 + image = &kexec_image[KEXEC_IMAGE_CRASH_BASE + pos]; 15.123 + machine_kexec(image); /* Does not return */ 15.124 + } 15.125 + 15.126 + while (1); /* No image available - just spin */ 15.127 +} 15.128 + 15.129 +static void do_crashdump_trigger(unsigned char key) 15.130 +{ 15.131 + printk("triggering crashdump\n"); 15.132 + machine_crash_kexec(); 15.133 +} 15.134 + 15.135 +static __init int register_crashdump_trigger(void) 15.136 +{ 15.137 + register_keyhandler('c', do_crashdump_trigger, "trigger a crashdump"); 15.138 + return 0; 15.139 +} 15.140 +__initcall(register_crashdump_trigger); 15.141 + 15.142 +void machine_kexec_reserved(xen_kexec_reserve_t *reservation) 15.143 +{ 15.144 + unsigned long val[2]; 15.145 + char *str = opt_crashkernel; 15.146 + int k = 0; 15.147 + 15.148 + memset(reservation, 0, sizeof(*reservation)); 15.149 + 15.150 + while (k < ARRAY_SIZE(val)) { 15.151 + if (*str == '\0') { 15.152 + break; 15.153 + } 15.154 + val[k] = simple_strtoul(str, &str, 0); 15.155 + switch (toupper(*str)) { 15.156 + case 'G': val[k] <<= 10; 15.157 + case 'M': val[k] <<= 10; 15.158 + case 'K': val[k] <<= 10; 15.159 + str++; 15.160 + } 15.161 + if (*str == '@') { 15.162 + str++; 15.163 + } 15.164 + k++; 15.165 + } 15.166 + 15.167 + if (k == ARRAY_SIZE(val)) { 15.168 + reservation->size = val[0]; 15.169 + reservation->start = val[1]; 15.170 + } 15.171 +} 15.172 + 15.173 +static int kexec_get_reserve(xen_kexec_range_t *range) 15.174 +{ 15.175 + xen_kexec_reserve_t reservation; 15.176 + 15.177 + machine_kexec_reserved(&reservation); 15.178 + 15.179 + range->start = reservation.start; 15.180 + range->size = reservation.size; 15.181 + return 0; 15.182 +} 15.183 + 15.184 +extern unsigned long _text, _end; 15.185 + 15.186 +static int kexec_get_xen(xen_kexec_range_t *range, int get_ma) 15.187 +{ 15.188 + if (get_ma) 15.189 + range->start = virt_to_maddr(&_text); 15.190 + else 15.191 + range->start = (unsigned long) &_text; 15.192 + 15.193 + range->size = &_end - &_text; 15.194 + return 0; 15.195 +} 15.196 + 15.197 +static int kexec_get_cpu(xen_kexec_range_t *range) 15.198 +{ 15.199 + if (range->nr < 0 || range->nr >= num_present_cpus()) 15.200 + return -EINVAL; 15.201 + 15.202 + range->start = __pa((unsigned long)&per_cpu(crash_notes, range->nr)); 15.203 + range->size = sizeof(crash_note_t); 15.204 + return 0; 15.205 +} 15.206 + 15.207 +static int kexec_get_range(XEN_GUEST_HANDLE(void) uarg) 15.208 +{ 15.209 + xen_kexec_range_t range; 15.210 + int ret = -EINVAL; 15.211 + 15.212 + if (unlikely(copy_from_guest(&range, uarg, 1))) 15.213 + return -EFAULT; 15.214 + 15.215 + switch (range.range) 15.216 + { 15.217 + case KEXEC_RANGE_MA_CRASH: 15.218 + ret = kexec_get_reserve(&range); 15.219 + break; 15.220 + case KEXEC_RANGE_MA_XEN: 15.221 + ret = kexec_get_xen(&range, 1); 15.222 + break; 15.223 + case KEXEC_RANGE_VA_XEN: 15.224 + ret = kexec_get_xen(&range, 0); 15.225 + break; 15.226 + case KEXEC_RANGE_MA_CPU: 15.227 + ret = kexec_get_cpu(&range); 15.228 + break; 15.229 + } 15.230 + 15.231 + if (ret == 0 && unlikely(copy_to_guest(uarg, &range, 1))) 15.232 + return -EFAULT; 15.233 + 15.234 + return ret; 15.235 +} 15.236 + 15.237 +static int kexec_load_get_bits(int type, int *base, int *bit) 15.238 +{ 15.239 + switch (type) 15.240 + { 15.241 + case KEXEC_TYPE_DEFAULT: 15.242 + *base = KEXEC_IMAGE_DEFAULT_BASE; 15.243 + *bit = KEXEC_FLAG_DEFAULT_POS; 15.244 + break; 15.245 + case KEXEC_TYPE_CRASH: 15.246 + *base = KEXEC_IMAGE_CRASH_BASE; 15.247 + *bit = KEXEC_FLAG_CRASH_POS; 15.248 + break; 15.249 + default: 15.250 + return -1; 15.251 + } 15.252 + return 0; 15.253 +} 15.254 + 15.255 +static int kexec_load_unload(unsigned long op, XEN_GUEST_HANDLE(void) uarg) 15.256 +{ 15.257 + xen_kexec_load_t load; 15.258 + xen_kexec_image_t *image; 15.259 + int base, bit, pos; 15.260 + int ret = 0; 15.261 + 15.262 + if (unlikely(copy_from_guest(&load, uarg, 1))) 15.263 + return -EFAULT; 15.264 + 15.265 + if (kexec_load_get_bits(load.type, &base, &bit)) 15.266 + return -EINVAL; 15.267 + 15.268 + pos = (test_bit(bit, &kexec_flags) != 0); 15.269 + 15.270 + /* Load the user data into an unused image */ 15.271 + if (op == KEXEC_CMD_kexec_load) 15.272 + { 15.273 + image = &kexec_image[base + !pos]; 15.274 + 15.275 + BUG_ON(test_bit((base + !pos), &kexec_flags)); /* must be free */ 15.276 + 15.277 + memcpy(image, &load.image, sizeof(*image)); 15.278 + 15.279 + if (!(ret = machine_kexec_load(load.type, base + !pos, image))) 15.280 + { 15.281 + /* Set image present bit */ 15.282 + set_bit((base + !pos), &kexec_flags); 15.283 + 15.284 + /* Make new image the active one */ 15.285 + change_bit(bit, &kexec_flags); 15.286 + } 15.287 + } 15.288 + 15.289 + /* Unload the old image if present and load successful */ 15.290 + if (ret == 0 && !test_bit(KEXEC_FLAG_IN_PROGRESS, &kexec_flags)) 15.291 + { 15.292 + if (test_and_clear_bit((base + pos), &kexec_flags)) 15.293 + { 15.294 + image = &kexec_image[base + pos]; 15.295 + machine_kexec_unload(load.type, base + pos, image); 15.296 + } 15.297 + } 15.298 + 15.299 + return ret; 15.300 +} 15.301 + 15.302 +static int kexec_exec(XEN_GUEST_HANDLE(void) uarg) 15.303 +{ 15.304 + xen_kexec_exec_t exec; 15.305 + xen_kexec_image_t *image; 15.306 + int base, bit, pos; 15.307 + 15.308 + if (unlikely(copy_from_guest(&exec, uarg, 1))) 15.309 + return -EFAULT; 15.310 + 15.311 + if (kexec_load_get_bits(exec.type, &base, &bit)) 15.312 + return -EINVAL; 15.313 + 15.314 + pos = (test_bit(bit, &kexec_flags) != 0); 15.315 + 15.316 + /* Only allow kexec/kdump into loaded images */ 15.317 + if (!test_bit(base + pos, &kexec_flags)) 15.318 + return -ENOENT; 15.319 + 15.320 + switch (exec.type) 15.321 + { 15.322 + case KEXEC_TYPE_DEFAULT: 15.323 + image = &kexec_image[base + pos]; 15.324 + one_cpu_only(); 15.325 + machine_shutdown(image); /* Does not return */ 15.326 + break; 15.327 + case KEXEC_TYPE_CRASH: 15.328 + machine_crash_kexec(); /* Does not return */ 15.329 + break; 15.330 + } 15.331 + 15.332 + return -EINVAL; /* never reached */ 15.333 +} 15.334 + 15.335 +long do_kexec_op(unsigned long op, XEN_GUEST_HANDLE(void) uarg) 15.336 +{ 15.337 + unsigned long flags; 15.338 + int ret = -EINVAL; 15.339 + 15.340 + if ( !IS_PRIV(current->domain) ) 15.341 + return -EPERM; 15.342 + 15.343 + switch (op) 15.344 + { 15.345 + case KEXEC_CMD_kexec_get_range: 15.346 + ret = kexec_get_range(uarg); 15.347 + break; 15.348 + case KEXEC_CMD_kexec_load: 15.349 + case KEXEC_CMD_kexec_unload: 15.350 + spin_lock_irqsave(&kexec_lock, flags); 15.351 + if (!test_bit(KEXEC_FLAG_IN_PROGRESS, &kexec_flags)) 15.352 + { 15.353 + ret = kexec_load_unload(op, uarg); 15.354 + } 15.355 + spin_unlock_irqrestore(&kexec_lock, flags); 15.356 + break; 15.357 + case KEXEC_CMD_kexec: 15.358 + ret = kexec_exec(uarg); 15.359 + break; 15.360 + } 15.361 + 15.362 + return ret; 15.363 +} 15.364 + 15.365 +/* 15.366 + * Local variables: 15.367 + * mode: C 15.368 + * c-set-style: "BSD" 15.369 + * c-basic-offset: 4 15.370 + * tab-width: 4 15.371 + * indent-tabs-mode: nil 15.372 + * End: 15.373 + */
16.1 --- a/xen/common/page_alloc.c Wed Nov 29 23:40:40 2006 +0000 16.2 +++ b/xen/common/page_alloc.c Thu Nov 30 12:38:50 2006 +0000 16.3 @@ -237,24 +237,35 @@ void init_boot_pages(paddr_t ps, paddr_t 16.4 } 16.5 } 16.6 16.7 +unsigned long alloc_boot_pages_at(unsigned long nr_pfns, unsigned long pfn_at) 16.8 +{ 16.9 + unsigned long i; 16.10 + 16.11 + for ( i = 0; i < nr_pfns; i++ ) 16.12 + if ( allocated_in_map(pfn_at + i) ) 16.13 + break; 16.14 + 16.15 + if ( i == nr_pfns ) 16.16 + { 16.17 + map_alloc(pfn_at, nr_pfns); 16.18 + return pfn_at; 16.19 + } 16.20 + 16.21 + return 0; 16.22 +} 16.23 + 16.24 unsigned long alloc_boot_pages(unsigned long nr_pfns, unsigned long pfn_align) 16.25 { 16.26 - unsigned long pg, i; 16.27 + unsigned long pg, i = 0; 16.28 16.29 for ( pg = 0; (pg + nr_pfns) < max_page; pg += pfn_align ) 16.30 { 16.31 - for ( i = 0; i < nr_pfns; i++ ) 16.32 - if ( allocated_in_map(pg + i) ) 16.33 - break; 16.34 - 16.35 - if ( i == nr_pfns ) 16.36 - { 16.37 - map_alloc(pg, nr_pfns); 16.38 - return pg; 16.39 - } 16.40 + i = alloc_boot_pages_at(nr_pfns, pg); 16.41 + if (i != 0) 16.42 + break; 16.43 } 16.44 16.45 - return 0; 16.46 + return i; 16.47 } 16.48 16.49
17.1 --- a/xen/drivers/char/console.c Wed Nov 29 23:40:40 2006 +0000 17.2 +++ b/xen/drivers/char/console.c Thu Nov 30 12:38:50 2006 +0000 17.3 @@ -27,6 +27,7 @@ 17.4 #include <xen/guest_access.h> 17.5 #include <xen/shutdown.h> 17.6 #include <xen/vga.h> 17.7 +#include <xen/kexec.h> 17.8 #include <asm/current.h> 17.9 #include <asm/debugger.h> 17.10 #include <asm/io.h> 17.11 @@ -865,6 +866,8 @@ void panic(const char *fmt, ...) 17.12 17.13 debugger_trap_immediate(); 17.14 17.15 + machine_crash_kexec(); 17.16 + 17.17 if ( opt_noreboot ) 17.18 { 17.19 machine_halt();
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/xen/include/asm-ia64/elf.h Thu Nov 30 12:38:50 2006 +0000 18.3 @@ -0,0 +1,30 @@ 18.4 +#ifndef __IA64_ELF_H__ 18.5 +#define __IA64_ELF_H__ 18.6 + 18.7 +#include <xen/lib.h> /* for printk() used in stub */ 18.8 + 18.9 +typedef struct { 18.10 + unsigned long dummy; 18.11 +} ELF_Gregset; 18.12 + 18.13 +typedef struct { 18.14 + unsigned long dummy; 18.15 +} crash_xen_core_t; 18.16 + 18.17 +extern inline void elf_core_save_regs(ELF_Gregset *core_regs, 18.18 + crash_xen_core_t *xen_core_regs) 18.19 +{ 18.20 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 18.21 +} 18.22 + 18.23 +#endif /* __IA64_ELF_H__ */ 18.24 + 18.25 +/* 18.26 + * Local variables: 18.27 + * mode: C 18.28 + * c-set-style: "BSD" 18.29 + * c-basic-offset: 4 18.30 + * tab-width: 4 18.31 + * indent-tabs-mode: nil 18.32 + * End: 18.33 + */
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/xen/include/asm-ia64/kexec.h Thu Nov 30 12:38:50 2006 +0000 19.3 @@ -0,0 +1,25 @@ 19.4 +#ifndef __IA64_KEXEC_H__ 19.5 +#define __IA64_KEXEC_H__ 19.6 + 19.7 +#include <xen/lib.h> /* for printk() used in stub */ 19.8 +#include <xen/types.h> 19.9 +#include <public/xen.h> 19.10 +#include <xen/kexec.h> 19.11 + 19.12 +static inline void machine_kexec(xen_kexec_image_t *image) 19.13 +{ 19.14 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 19.15 +} 19.16 + 19.17 +#endif /* __IA64_KEXEC_H__ */ 19.18 + 19.19 +/* 19.20 + * Local variables: 19.21 + * mode: C 19.22 + * c-set-style: "BSD" 19.23 + * c-basic-offset: 4 19.24 + * tab-width: 4 19.25 + * indent-tabs-mode: nil 19.26 + * End: 19.27 + */ 19.28 +
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/xen/include/asm-powerpc/elf.h Thu Nov 30 12:38:50 2006 +0000 20.3 @@ -0,0 +1,30 @@ 20.4 +#ifndef _ASM_ELF_H__ 20.5 +#define _ASM_ELF_H__ 20.6 + 20.7 +#include <xen/lib.h> /* for printk() used in stub */ 20.8 + 20.9 +typedef struct { 20.10 + unsigned long dummy; 20.11 +} ELF_Gregset; 20.12 + 20.13 +typedef struct { 20.14 + unsigned long dummy; 20.15 +} crash_xen_core_t; 20.16 + 20.17 +extern inline void elf_core_save_regs(ELF_Gregset *core_regs, 20.18 + crash_xen_core_t *xen_core_regs) 20.19 +{ 20.20 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 20.21 +} 20.22 + 20.23 +#endif /* _ASM_ELF_H__ */ 20.24 + 20.25 +/* 20.26 + * Local variables: 20.27 + * mode: C 20.28 + * c-set-style: "BSD" 20.29 + * c-basic-offset: 4 20.30 + * tab-width: 4 20.31 + * indent-tabs-mode: nil 20.32 + * End: 20.33 + */
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/xen/include/asm-powerpc/kexec.h Thu Nov 30 12:38:50 2006 +0000 21.3 @@ -0,0 +1,25 @@ 21.4 +#ifndef _ASM_KEXEC_H__ 21.5 +#define _ASM_KEXEC_H__ 21.6 + 21.7 +#include <xen/lib.h> /* for printk() used in stub */ 21.8 +#include <xen/types.h> 21.9 +#include <public/xen.h> 21.10 +#include <xen/kexec.h> 21.11 + 21.12 +static inline void machine_kexec(xen_kexec_image_t *image) 21.13 +{ 21.14 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 21.15 +} 21.16 + 21.17 +#endif /* _ASM_KEXEC_H__ */ 21.18 + 21.19 +/* 21.20 + * Local variables: 21.21 + * mode: C 21.22 + * c-set-style: "BSD" 21.23 + * c-basic-offset: 4 21.24 + * tab-width: 4 21.25 + * indent-tabs-mode: nil 21.26 + * End: 21.27 + */ 21.28 +
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/xen/include/asm-x86/elf.h Thu Nov 30 12:38:50 2006 +0000 22.3 @@ -0,0 +1,30 @@ 22.4 +#ifndef __X86_ELF_H__ 22.5 +#define __X86_ELF_H__ 22.6 + 22.7 +#include <xen/lib.h> /* for printk() used in stub */ 22.8 + 22.9 +typedef struct { 22.10 + unsigned long dummy; 22.11 +} ELF_Gregset; 22.12 + 22.13 +typedef struct { 22.14 + unsigned long dummy; 22.15 +} crash_xen_core_t; 22.16 + 22.17 +extern inline void elf_core_save_regs(ELF_Gregset *core_regs, 22.18 + crash_xen_core_t *xen_core_regs) 22.19 +{ 22.20 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 22.21 +} 22.22 + 22.23 +#endif /* __X86_ELF_H__ */ 22.24 + 22.25 +/* 22.26 + * Local variables: 22.27 + * mode: C 22.28 + * c-set-style: "BSD" 22.29 + * c-basic-offset: 4 22.30 + * tab-width: 4 22.31 + * indent-tabs-mode: nil 22.32 + * End: 22.33 + */
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/xen/include/asm-x86/kexec.h Thu Nov 30 12:38:50 2006 +0000 23.3 @@ -0,0 +1,24 @@ 23.4 +#ifndef __X86_KEXEC_H__ 23.5 +#define __X86_KEXEC_H__ 23.6 + 23.7 +#include <xen/lib.h> /* for printk() used in stub */ 23.8 +#include <xen/types.h> 23.9 +#include <public/xen.h> 23.10 +#include <xen/kexec.h> 23.11 + 23.12 +static inline void machine_kexec(xen_kexec_image_t *image) 23.13 +{ 23.14 + printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); 23.15 +} 23.16 + 23.17 +#endif /* __X86_KEXEC_H__ */ 23.18 + 23.19 +/* 23.20 + * Local variables: 23.21 + * mode: C 23.22 + * c-set-style: "BSD" 23.23 + * c-basic-offset: 4 23.24 + * tab-width: 4 23.25 + * indent-tabs-mode: nil 23.26 + * End: 23.27 + */
24.1 --- a/xen/include/public/elfnote.h Wed Nov 29 23:40:40 2006 +0000 24.2 +++ b/xen/include/public/elfnote.h Thu Nov 30 12:38:50 2006 +0000 24.3 @@ -147,6 +147,25 @@ 24.4 */ 24.5 #define XEN_ELFNOTE_HV_START_LOW 12 24.6 24.7 +/* 24.8 + * System information exported through crash notes. 24.9 + * 24.10 + * The kexec / kdump code will create one XEN_ELFNOTE_CRASH_INFO 24.11 + * note in case of a system crash. This note will contain various 24.12 + * information about the system, see xen/include/xen/elfcore.h. 24.13 + */ 24.14 +#define XEN_ELFNOTE_CRASH_INFO 0x1000001 24.15 + 24.16 +/* 24.17 + * System registers exported through crash notes. 24.18 + * 24.19 + * The kexec / kdump code will create one XEN_ELFNOTE_CRASH_REGS 24.20 + * note per cpu in case of a system crash. This note is architecture 24.21 + * specific and will contain registers not saved in the "CORE" note. 24.22 + * See xen/include/xen/elfcore.h for more information. 24.23 + */ 24.24 +#define XEN_ELFNOTE_CRASH_REGS 0x1000002 24.25 + 24.26 #endif /* __XEN_PUBLIC_ELFNOTE_H__ */ 24.27 24.28 /*
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/xen/include/public/kexec.h Thu Nov 30 12:38:50 2006 +0000 25.3 @@ -0,0 +1,131 @@ 25.4 +/****************************************************************************** 25.5 + * kexec.h - Public portion 25.6 + * 25.7 + * Xen port written by: 25.8 + * - Simon 'Horms' Horman <horms@verge.net.au> 25.9 + * - Magnus Damm <magnus@valinux.co.jp> 25.10 + */ 25.11 + 25.12 +#ifndef _XEN_PUBLIC_KEXEC_H 25.13 +#define _XEN_PUBLIC_KEXEC_H 25.14 + 25.15 + 25.16 +/* This file describes the Kexec / Kdump hypercall interface for Xen. 25.17 + * 25.18 + * Kexec under vanilla Linux allows a user to reboot the physical machine 25.19 + * into a new user-specified kernel. The Xen port extends this idea 25.20 + * to allow rebooting of the machine from dom0. When kexec for dom0 25.21 + * is used to reboot, both the hypervisor and the domains get replaced 25.22 + * with some other kernel. It is possible to kexec between vanilla 25.23 + * Linux and Xen and back again. Xen to Xen works well too. 25.24 + * 25.25 + * The hypercall interface for kexec can be divided into three main 25.26 + * types of hypercall operations: 25.27 + * 25.28 + * 1) Range information: 25.29 + * This is used by the dom0 kernel to ask the hypervisor about various 25.30 + * address information. This information is needed to allow kexec-tools 25.31 + * to fill in the ELF headers for /proc/vmcore properly. 25.32 + * 25.33 + * 2) Load and unload of images: 25.34 + * There are no big surprises here, the kexec binary from kexec-tools 25.35 + * runs in userspace in dom0. The tool loads/unloads data into the 25.36 + * dom0 kernel such as new kernel, initramfs and hypervisor. When 25.37 + * loaded the dom0 kernel performs a load hypercall operation, and 25.38 + * before releasing all page references the dom0 kernel calls unload. 25.39 + * 25.40 + * 3) Kexec operation: 25.41 + * This is used to start a previously loaded kernel. 25.42 + */ 25.43 + 25.44 +#include "xen.h" 25.45 + 25.46 +/* 25.47 + * Prototype for this hypercall is: 25.48 + * int kexec_op(int cmd, void *args) 25.49 + * @cmd == KEXEC_CMD_... 25.50 + * KEXEC operation to perform 25.51 + * @args == Operation-specific extra arguments (NULL if none). 25.52 + */ 25.53 + 25.54 +/* 25.55 + * Kexec supports two types of operation: 25.56 + * - kexec into a regular kernel, very similar to a standard reboot 25.57 + * - KEXEC_TYPE_DEFAULT is used to specify this type 25.58 + * - kexec into a special "crash kernel", aka kexec-on-panic 25.59 + * - KEXEC_TYPE_CRASH is used to specify this type 25.60 + * - parts of our system may be broken at kexec-on-panic time 25.61 + * - the code should be kept as simple and self-contained as possible 25.62 + */ 25.63 + 25.64 +#define KEXEC_TYPE_DEFAULT 0 25.65 +#define KEXEC_TYPE_CRASH 1 25.66 + 25.67 + 25.68 +/* The kexec implementation for Xen allows the user to load two 25.69 + * types of kernels, KEXEC_TYPE_DEFAULT and KEXEC_TYPE_CRASH. 25.70 + * All data needed for a kexec reboot is kept in one xen_kexec_image_t 25.71 + * per "instance". The data mainly consists of machine address lists to pages 25.72 + * together with destination addresses. The data in xen_kexec_image_t 25.73 + * is passed to the "code page" which is one page of code that performs 25.74 + * the final relocations before jumping to the new kernel. 25.75 + */ 25.76 + 25.77 +typedef struct xen_kexec_image { 25.78 + unsigned long indirection_page; 25.79 + unsigned long start_address; 25.80 +} xen_kexec_image_t; 25.81 + 25.82 +/* 25.83 + * Perform kexec having previously loaded a kexec or kdump kernel 25.84 + * as appropriate. 25.85 + * type == KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH [in] 25.86 + */ 25.87 +#define KEXEC_CMD_kexec 0 25.88 +typedef struct xen_kexec_exec { 25.89 + int type; 25.90 +} xen_kexec_exec_t; 25.91 + 25.92 +/* 25.93 + * Load/Unload kernel image for kexec or kdump. 25.94 + * type == KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH [in] 25.95 + * image == relocation information for kexec (ignored for unload) [in] 25.96 + */ 25.97 +#define KEXEC_CMD_kexec_load 1 25.98 +#define KEXEC_CMD_kexec_unload 2 25.99 +typedef struct xen_kexec_load { 25.100 + int type; 25.101 + xen_kexec_image_t image; 25.102 +} xen_kexec_load_t; 25.103 + 25.104 +#define KEXEC_RANGE_MA_CRASH 0 /* machine address and size of crash area */ 25.105 +#define KEXEC_RANGE_MA_XEN 1 /* machine address and size of Xen itself */ 25.106 +#define KEXEC_RANGE_VA_XEN 2 /* virtual adrress and size of Xen itself */ 25.107 +#define KEXEC_RANGE_MA_CPU 3 /* machine address and size of a CPU note */ 25.108 + 25.109 +/* 25.110 + * Find the address and size of certain memory areas 25.111 + * range == KEXEC_RANGE_... [in] 25.112 + * nr == physical CPU number (starting from 0) if KEXEC_RANGE_MA_CPU [in] 25.113 + * size == number of bytes reserved in window [out] 25.114 + * start == address of the first byte in the window [out] 25.115 + */ 25.116 +#define KEXEC_CMD_kexec_get_range 3 25.117 +typedef struct xen_kexec_range { 25.118 + int range; 25.119 + int nr; 25.120 + unsigned long size; 25.121 + unsigned long start; 25.122 +} xen_kexec_range_t; 25.123 + 25.124 +#endif /* _XEN_PUBLIC_KEXEC_H */ 25.125 + 25.126 +/* 25.127 + * Local variables: 25.128 + * mode: C 25.129 + * c-set-style: "BSD" 25.130 + * c-basic-offset: 4 25.131 + * tab-width: 4 25.132 + * indent-tabs-mode: nil 25.133 + * End: 25.134 + */
26.1 --- a/xen/include/xen/elf.h Wed Nov 29 23:40:40 2006 +0000 26.2 +++ b/xen/include/xen/elf.h Thu Nov 30 12:38:50 2006 +0000 26.3 @@ -452,18 +452,12 @@ unsigned int elf_hash(const unsigned cha 26.4 /* 26.5 * Note Definitions 26.6 */ 26.7 -typedef struct { 26.8 - Elf32_Word namesz; 26.9 - Elf32_Word descsz; 26.10 - Elf32_Word type; 26.11 -} Elf32_Note; 26.12 26.13 typedef struct { 26.14 - Elf64_Half namesz; 26.15 - Elf64_Half descsz; 26.16 - Elf64_Half type; 26.17 -} Elf64_Note; 26.18 - 26.19 + u32 namesz; 26.20 + u32 descsz; 26.21 + u32 type; 26.22 +} Elf_Note; /* same format for both 32-bit and 64-bit ELF */ 26.23 26.24 #if defined(ELFSIZE) 26.25 #define CONCAT(x,y) __CONCAT(x,y) 26.26 @@ -486,7 +480,6 @@ typedef struct { 26.27 #define Elf_Addr Elf32_Addr 26.28 #define Elf_Off Elf32_Off 26.29 #define Elf_Nhdr Elf32_Nhdr 26.30 -#define Elf_Note Elf32_Note 26.31 26.32 #define ELF_R_SYM ELF32_R_SYM 26.33 #define ELF_R_TYPE ELF32_R_TYPE 26.34 @@ -511,7 +504,6 @@ typedef struct { 26.35 #define Elf_Addr Elf64_Addr 26.36 #define Elf_Off Elf64_Off 26.37 #define Elf_Nhdr Elf64_Nhdr 26.38 -#define Elf_Note Elf64_Note 26.39 26.40 #define ELF_R_SYM ELF64_R_SYM 26.41 #define ELF_R_TYPE ELF64_R_TYPE
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/xen/include/xen/elfcore.h Thu Nov 30 12:38:50 2006 +0000 27.3 @@ -0,0 +1,137 @@ 27.4 +/****************************************************************************** 27.5 + * elfcore.h 27.6 + * 27.7 + * Based heavily on include/linux/elfcore.h from Linux 2.6.16 27.8 + * Naming scheeme based on include/xen/elf.h (not include/linux/elfcore.h) 27.9 + * 27.10 + */ 27.11 + 27.12 +#ifndef __ELFCOREC_H__ 27.13 +#define __ELFCOREC_H__ 27.14 + 27.15 +#include <xen/types.h> 27.16 +#include <xen/elf.h> 27.17 +#include <asm/elf.h> 27.18 +#include <public/xen.h> 27.19 + 27.20 +#define NT_PRSTATUS 1 27.21 + 27.22 +typedef struct 27.23 +{ 27.24 + int signo; /* signal number */ 27.25 + int code; /* extra code */ 27.26 + int errno; /* errno */ 27.27 +} ELF_Signifo; 27.28 + 27.29 +/* These seem to be the same length on all architectures on Linux */ 27.30 +typedef int ELF_Pid; 27.31 +typedef struct { 27.32 + long tv_sec; 27.33 + long tv_usec; 27.34 +} ELF_Timeval; 27.35 + 27.36 +/* 27.37 + * Definitions to generate Intel SVR4-like core files. 27.38 + * These mostly have the same names as the SVR4 types with "elf_" 27.39 + * tacked on the front to prevent clashes with linux definitions, 27.40 + * and the typedef forms have been avoided. This is mostly like 27.41 + * the SVR4 structure, but more Linuxy, with things that Linux does 27.42 + * not support and which gdb doesn't really use excluded. 27.43 + */ 27.44 +typedef struct 27.45 +{ 27.46 + ELF_Signifo pr_info; /* Info associated with signal */ 27.47 + short pr_cursig; /* Current signal */ 27.48 + unsigned long pr_sigpend; /* Set of pending signals */ 27.49 + unsigned long pr_sighold; /* Set of held signals */ 27.50 + ELF_Pid pr_pid; 27.51 + ELF_Pid pr_ppid; 27.52 + ELF_Pid pr_pgrp; 27.53 + ELF_Pid pr_sid; 27.54 + ELF_Timeval pr_utime; /* User time */ 27.55 + ELF_Timeval pr_stime; /* System time */ 27.56 + ELF_Timeval pr_cutime; /* Cumulative user time */ 27.57 + ELF_Timeval pr_cstime; /* Cumulative system time */ 27.58 + ELF_Gregset pr_reg; /* GP registers - from asm header file */ 27.59 + int pr_fpvalid; /* True if math co-processor being used. */ 27.60 +} ELF_Prstatus; 27.61 + 27.62 +/* 27.63 + * The following data structures provide 64-bit ELF notes. In theory it should 27.64 + * be possible to support both 64-bit and 32-bit ELF files, but to keep it 27.65 + * simple we only do 64-bit. 27.66 + * 27.67 + * Please note that the current code aligns the 64-bit notes in the same 27.68 + * way as Linux does. We are not following the 64-bit ELF spec, no one does. 27.69 + * 27.70 + * We are avoiding two problems by restricting us to 64-bit notes only: 27.71 + * - Alignment of notes change with the word size. Ick. 27.72 + * - We would need to tell kexec-tools which format we are using in the 27.73 + * hypervisor to make sure the right ELF format is generated. 27.74 + * That requires infrastructure. Let's not. 27.75 + */ 27.76 + 27.77 +#define ALIGN(x, n) ((x + ((1 << n) - 1)) / (1 << n)) 27.78 +#define PAD32(x) u32 pad_data[ALIGN(x, 2)] 27.79 + 27.80 +#define TYPEDEF_NOTE(type, strlen, desctype) \ 27.81 + typedef struct { \ 27.82 + union { \ 27.83 + struct { \ 27.84 + Elf_Note note; \ 27.85 + unsigned char name[strlen]; \ 27.86 + } note; \ 27.87 + PAD32(sizeof(Elf_Note) + strlen); \ 27.88 + } note; \ 27.89 + union { \ 27.90 + desctype desc; \ 27.91 + PAD32(sizeof(desctype)); \ 27.92 + } desc; \ 27.93 + } __attribute__ ((packed)) type 27.94 + 27.95 +#define CORE_STR "CORE" 27.96 +#define CORE_STR_LEN 5 /* including terminating zero */ 27.97 + 27.98 +TYPEDEF_NOTE(crash_note_core_t, CORE_STR_LEN, ELF_Prstatus); 27.99 + 27.100 +#define XEN_STR "Xen" 27.101 +#define XEN_STR_LEN 4 /* including terminating zero */ 27.102 + 27.103 +TYPEDEF_NOTE(crash_note_xen_core_t, XEN_STR_LEN, crash_xen_core_t); 27.104 + 27.105 +typedef struct { 27.106 + unsigned long xen_major_version; 27.107 + unsigned long xen_minor_version; 27.108 + unsigned long xen_extra_version; 27.109 + unsigned long xen_changeset; 27.110 + unsigned long xen_compiler; 27.111 + unsigned long xen_compile_date; 27.112 + unsigned long xen_compile_time; 27.113 + unsigned long tainted; 27.114 +} crash_xen_info_t; 27.115 + 27.116 +TYPEDEF_NOTE(crash_note_xen_info_t, XEN_STR_LEN, crash_xen_info_t); 27.117 + 27.118 +typedef struct { 27.119 + crash_note_core_t core; 27.120 + crash_note_xen_core_t xen_regs; 27.121 + crash_note_xen_info_t xen_info; 27.122 +} __attribute__ ((packed)) crash_note_t; 27.123 + 27.124 +#define setup_crash_note(np, member, str, str_len, id) \ 27.125 + np->member.note.note.note.namesz = str_len; \ 27.126 + np->member.note.note.note.descsz = sizeof(np->member.desc.desc); \ 27.127 + np->member.note.note.note.type = id; \ 27.128 + memcpy(np->member.note.note.name, str, str_len) 27.129 + 27.130 +#endif /* __ELFCOREC_H__ */ 27.131 + 27.132 +/* 27.133 + * Local variables: 27.134 + * mode: C 27.135 + * c-set-style: "BSD" 27.136 + * c-basic-offset: 4 27.137 + * tab-width: 4 27.138 + * indent-tabs-mode: nil 27.139 + * End: 27.140 + */
28.1 --- a/xen/include/xen/hypercall.h Wed Nov 29 23:40:40 2006 +0000 28.2 +++ b/xen/include/xen/hypercall.h Thu Nov 30 12:38:50 2006 +0000 28.3 @@ -102,4 +102,10 @@ do_hvm_op( 28.4 unsigned long op, 28.5 XEN_GUEST_HANDLE(void) arg); 28.6 28.7 +extern long 28.8 +do_kexec_op( 28.9 + unsigned long op, 28.10 + int arg1, 28.11 + XEN_GUEST_HANDLE(void) arg); 28.12 + 28.13 #endif /* __XEN_HYPERCALL_H__ */
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/xen/include/xen/kexec.h Thu Nov 30 12:38:50 2006 +0000 29.3 @@ -0,0 +1,43 @@ 29.4 +#ifndef __XEN_KEXEC_H__ 29.5 +#define __XEN_KEXEC_H__ 29.6 + 29.7 +#include <public/kexec.h> 29.8 +#include <asm/percpu.h> 29.9 +#include <xen/elfcore.h> 29.10 + 29.11 +extern int crashing_cpu; 29.12 + 29.13 +typedef struct xen_kexec_reserve { 29.14 + unsigned long size; 29.15 + unsigned long start; 29.16 +} xen_kexec_reserve_t; 29.17 + 29.18 +/* We have space for 4 images to support atomic update 29.19 + * of images. This is important for CRASH images since 29.20 + * a panic can happen at any time... 29.21 + */ 29.22 + 29.23 +#define KEXEC_IMAGE_DEFAULT_BASE 0 29.24 +#define KEXEC_IMAGE_CRASH_BASE 2 29.25 +#define KEXEC_IMAGE_NR 4 29.26 + 29.27 +int machine_kexec_load(int type, int slot, xen_kexec_image_t *image); 29.28 +void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image); 29.29 +void machine_kexec_reserved(xen_kexec_reserve_t *reservation); 29.30 +void machine_shutdown(xen_kexec_image_t *image); 29.31 +void machine_crash_kexec(void); 29.32 +void machine_crash_save_cpu(void); 29.33 +crash_xen_info_t *machine_crash_save_info(void); 29.34 +void machine_crash_shutdown(void); 29.35 + 29.36 +#endif /* __XEN_KEXEC_H__ */ 29.37 + 29.38 +/* 29.39 + * Local variables: 29.40 + * mode: C 29.41 + * c-set-style: "BSD" 29.42 + * c-basic-offset: 4 29.43 + * tab-width: 4 29.44 + * indent-tabs-mode: nil 29.45 + * End: 29.46 + */
30.1 --- a/xen/include/xen/mm.h Wed Nov 29 23:40:40 2006 +0000 30.2 +++ b/xen/include/xen/mm.h Thu Nov 30 12:38:50 2006 +0000 30.3 @@ -40,6 +40,7 @@ struct page_info; 30.4 paddr_t init_boot_allocator(paddr_t bitmap_start); 30.5 void init_boot_pages(paddr_t ps, paddr_t pe); 30.6 unsigned long alloc_boot_pages(unsigned long nr_pfns, unsigned long pfn_align); 30.7 +unsigned long alloc_boot_pages_at(unsigned long nr_pfns, unsigned long pfn_at); 30.8 void end_boot_allocator(void); 30.9 30.10 /* Generic allocator. These functions are *not* interrupt-safe. */