[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [patch] Add kexec_ops & function pointers
Signed-off-by: Gerd Hoffmann <kraxel@xxxxxxx> --- linux-2.6-xen-sparse/arch/i386/kernel/machine_kexec.c | 2 linux-2.6-xen-sparse/arch/x86_64/kernel/machine_kexec.c | 2 linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c | 42 +++++++- linux-2.6-xen-sparse/include/asm-i386/kexec.h | 14 -- linux-2.6-xen-sparse/include/asm-x86_64/kexec.h | 13 -- linux-2.6-xen-sparse/include/linux/kexec.h | 24 ++-- linux-2.6-xen-sparse/kernel/kexec.c | 80 +++++++++++----- 7 files changed, 110 insertions(+), 67 deletions(-) Index: build-32-unstable-12809/linux-2.6-xen-sparse/arch/i386/kernel/machine_kexec.c =================================================================== --- build-32-unstable-12809.orig/linux-2.6-xen-sparse/arch/i386/kernel/machine_kexec.c +++ build-32-unstable-12809/linux-2.6-xen-sparse/arch/i386/kernel/machine_kexec.c @@ -92,7 +92,6 @@ void machine_kexec_cleanup(struct kimage { } -#ifndef CONFIG_XEN /* * Do not allocate memory (or fail in any way) in machine_kexec(). * We are past the point of no return, committed to rebooting now. @@ -126,4 +125,3 @@ NORET_TYPE void machine_kexec(struct kim relocate_kernel((unsigned long)image->head, (unsigned long)page_list, image->start, cpu_has_pae); } -#endif Index: build-32-unstable-12809/linux-2.6-xen-sparse/arch/x86_64/kernel/machine_kexec.c =================================================================== --- build-32-unstable-12809.orig/linux-2.6-xen-sparse/arch/x86_64/kernel/machine_kexec.c +++ build-32-unstable-12809/linux-2.6-xen-sparse/arch/x86_64/kernel/machine_kexec.c @@ -237,7 +237,6 @@ void machine_kexec_cleanup(struct kimage return; } -#ifndef CONFIG_XEN /* * Do not allocate memory (or fail in any way) in machine_kexec(). * We are past the point of no return, committed to rebooting now. @@ -276,4 +275,3 @@ NORET_TYPE void machine_kexec(struct kim relocate_kernel((unsigned long)image->head, (unsigned long)page_list, image->start); } -#endif Index: build-32-unstable-12809/linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c =================================================================== --- build-32-unstable-12809.orig/linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c +++ build-32-unstable-12809/linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c @@ -11,6 +11,7 @@ extern void machine_kexec_setup_load_arg(xen_kexec_image_t *xki, struct kimage *image); +static void xen0_set_hooks(void); int xen_max_nr_phys_cpus; struct resource xen_hypervisor_res; @@ -93,6 +94,7 @@ void xen_machine_kexec_setup_resources(v crashk_res.end = range.start + range.size - 1; } + xen0_set_hooks(); return; err: @@ -130,7 +132,7 @@ static void setup_load_arg(xen_kexec_ima * is currently called too early. It might make sense * to move prepare, but for now, just add an extra hook. */ -int xen_machine_kexec_load(struct kimage *image) +static int xen0_machine_kexec_load(struct kimage *image) { xen_kexec_load_t xkl; @@ -146,7 +148,7 @@ int xen_machine_kexec_load(struct kimage * is called too late, and its possible xen could try and kdump * using resources that have been freed. */ -void xen_machine_kexec_unload(struct kimage *image) +static void xen0_machine_kexec_unload(struct kimage *image) { xen_kexec_load_t xkl; @@ -163,7 +165,7 @@ void xen_machine_kexec_unload(struct kim * stop all CPUs and kexec. That is it combines machine_shutdown() * and machine_kexec() in Linux kexec terms. */ -NORET_TYPE void machine_kexec(struct kimage *image) +static NORET_TYPE ATTRIB_NORET void xen0_machine_kexec(struct kimage *image) { xen_kexec_exec_t xke; @@ -178,6 +180,40 @@ void machine_shutdown(void) /* do nothing */ } +static unsigned long xen0_page_to_pfn(struct page *page) +{ + return pfn_to_mfn(page_to_pfn(page)); +} + +static struct page* xen0_pfn_to_page(unsigned long pfn) +{ + return pfn_to_page(mfn_to_pfn(pfn)); +} + +static unsigned long xen0_virt_to_phys(void *addr) +{ + return virt_to_machine(addr); +} + +static void* xen0_phys_to_virt(unsigned long addr) +{ + return phys_to_virt(machine_to_phys(addr)); +} + + +static void xen0_set_hooks(void) +{ + kexec_ops.kpage_to_pfn = xen0_page_to_pfn; + kexec_ops.kpfn_to_page = xen0_pfn_to_page; + kexec_ops.kvirt_to_phys = xen0_virt_to_phys; + kexec_ops.kphys_to_virt = xen0_phys_to_virt; + + kexec_ops.kexec = xen0_machine_kexec; + kexec_ops.kexec_load = xen0_machine_kexec_load; + kexec_ops.kexec_unload = xen0_machine_kexec_unload; + + printk("%s: kexec hook setup done\n", __FUNCTION__); +} /* * Local variables: Index: build-32-unstable-12809/linux-2.6-xen-sparse/include/asm-i386/kexec.h =================================================================== --- build-32-unstable-12809.orig/linux-2.6-xen-sparse/include/asm-i386/kexec.h +++ build-32-unstable-12809/linux-2.6-xen-sparse/include/asm-i386/kexec.h @@ -98,20 +98,6 @@ relocate_kernel(unsigned long indirectio unsigned long start_address, unsigned int has_pae) ATTRIB_NORET; - -/* Under Xen we need to work with machine addresses. These macros give the - * machine address of a certain page to the generic kexec code instead of - * the pseudo physical address which would be given by the default macros. - */ - -#ifdef CONFIG_XEN -#define KEXEC_ARCH_HAS_PAGE_MACROS -#define kexec_page_to_pfn(page) pfn_to_mfn(page_to_pfn(page)) -#define kexec_pfn_to_page(pfn) pfn_to_page(mfn_to_pfn(pfn)) -#define kexec_virt_to_phys(addr) virt_to_machine(addr) -#define kexec_phys_to_virt(addr) phys_to_virt(machine_to_phys(addr)) -#endif - #endif /* __ASSEMBLY__ */ #endif /* _I386_KEXEC_H */ Index: build-32-unstable-12809/linux-2.6-xen-sparse/include/asm-x86_64/kexec.h =================================================================== --- build-32-unstable-12809.orig/linux-2.6-xen-sparse/include/asm-x86_64/kexec.h +++ build-32-unstable-12809/linux-2.6-xen-sparse/include/asm-x86_64/kexec.h @@ -91,19 +91,6 @@ relocate_kernel(unsigned long indirectio unsigned long page_list, unsigned long start_address) ATTRIB_NORET; -/* Under Xen we need to work with machine addresses. These macros give the - * machine address of a certain page to the generic kexec code instead of - * the pseudo physical address which would be given by the default macros. - */ - -#ifdef CONFIG_XEN -#define KEXEC_ARCH_HAS_PAGE_MACROS -#define kexec_page_to_pfn(page) pfn_to_mfn(page_to_pfn(page)) -#define kexec_pfn_to_page(pfn) pfn_to_page(mfn_to_pfn(pfn)) -#define kexec_virt_to_phys(addr) virt_to_machine(addr) -#define kexec_phys_to_virt(addr) phys_to_virt(machine_to_phys(addr)) -#endif - #endif /* __ASSEMBLY__ */ #endif /* _X86_64_KEXEC_H */ Index: build-32-unstable-12809/linux-2.6-xen-sparse/include/linux/kexec.h =================================================================== --- build-32-unstable-12809.orig/linux-2.6-xen-sparse/include/linux/kexec.h +++ build-32-unstable-12809/linux-2.6-xen-sparse/include/linux/kexec.h @@ -31,13 +31,6 @@ #error KEXEC_ARCH not defined #endif -#ifndef KEXEC_ARCH_HAS_PAGE_MACROS -#define kexec_page_to_pfn(page) page_to_pfn(page) -#define kexec_pfn_to_page(pfn) pfn_to_page(pfn) -#define kexec_virt_to_phys(addr) virt_to_phys(addr) -#define kexec_phys_to_virt(addr) phys_to_virt(addr) -#endif - /* * This structure is used to hold the arguments that are used when loading * kernel binaries. @@ -92,15 +85,26 @@ struct kimage { #define KEXEC_TYPE_CRASH 1 }; +/* kexec interface functions */ +struct kexec_machine_ops { + unsigned long (*kpage_to_pfn)(struct page *page); + struct page* (*kpfn_to_page)(unsigned long pfn); + unsigned long (*kvirt_to_phys)(void *addr); + void* (*kphys_to_virt)(unsigned long addr); + NORET_TYPE void (*kexec)(struct kimage *image) ATTRIB_NORET; + int (*kexec_prepare)(struct kimage *image); + int (*kexec_load)(struct kimage *image); + void (*kexec_unload)(struct kimage *image); + void (*kexec_cleanup)(struct kimage *image); +}; +extern struct kexec_machine_ops kexec_ops; -/* kexec interface functions */ extern NORET_TYPE void machine_kexec(struct kimage *image) ATTRIB_NORET; extern int machine_kexec_prepare(struct kimage *image); extern void machine_kexec_cleanup(struct kimage *image); + #ifdef CONFIG_XEN -extern int xen_machine_kexec_load(struct kimage *image); -extern void xen_machine_kexec_unload(struct kimage *image); extern void xen_machine_kexec_setup_resources(void); extern void xen_machine_kexec_register_resources(struct resource *res); #endif Index: build-32-unstable-12809/linux-2.6-xen-sparse/kernel/kexec.c =================================================================== --- build-32-unstable-12809.orig/linux-2.6-xen-sparse/kernel/kexec.c +++ build-32-unstable-12809/linux-2.6-xen-sparse/kernel/kexec.c @@ -27,6 +27,36 @@ #include <asm/system.h> #include <asm/semaphore.h> +static unsigned long default_page_to_pfn(struct page *page) +{ + return page_to_pfn(page); +} + +static struct page* default_pfn_to_page(unsigned long pfn) +{ + return pfn_to_page(pfn); +} + +static unsigned long default_virt_to_phys(void *addr) +{ + return virt_to_phys(addr); +} + +static void* default_phys_to_virt(unsigned long addr) +{ + return phys_to_virt(addr); +} + +struct kexec_machine_ops kexec_ops = { + .kpage_to_pfn = default_page_to_pfn, + .kpfn_to_page = default_pfn_to_page, + .kvirt_to_phys = default_virt_to_phys, + .kphys_to_virt = default_phys_to_virt, + .kexec = machine_kexec, + .kexec_prepare = machine_kexec_prepare, + .kexec_cleanup = machine_kexec_cleanup, +}; + /* Per cpu memory for storing cpu states in case of system crash. */ note_buf_t* crash_notes; @@ -403,7 +433,7 @@ static struct page *kimage_alloc_normal_ pages = kimage_alloc_pages(GFP_KERNEL, order); if (!pages) break; - pfn = kexec_page_to_pfn(pages); + pfn = kexec_ops.kpage_to_pfn(pages); epfn = pfn + count; addr = pfn << PAGE_SHIFT; eaddr = epfn << PAGE_SHIFT; @@ -491,7 +521,7 @@ static struct page *kimage_alloc_crash_c } /* If I don't overlap any segments I have found my hole! */ if (i == image->nr_segments) { - pages = kexec_pfn_to_page(hole_start >> PAGE_SHIFT); + pages = kexec_ops.kpfn_to_page(hole_start >> PAGE_SHIFT); break; } } @@ -540,7 +570,7 @@ static int kimage_add_entry(struct kimag return -ENOMEM; ind_page = page_address(page); - *image->entry = kexec_virt_to_phys(ind_page) | IND_INDIRECTION; + *image->entry = kexec_ops.kvirt_to_phys(ind_page) | IND_INDIRECTION; image->entry = ind_page; image->last_entry = ind_page + ((PAGE_SIZE/sizeof(kimage_entry_t)) - 1); @@ -601,13 +631,13 @@ static int kimage_terminate(struct kimag #define for_each_kimage_entry(image, ptr, entry) \ for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE); \ ptr = (entry & IND_INDIRECTION)? \ - kexec_phys_to_virt((entry & PAGE_MASK)): ptr +1) + kexec_ops.kphys_to_virt((entry & PAGE_MASK)): ptr +1) static void kimage_free_entry(kimage_entry_t entry) { struct page *page; - page = kexec_pfn_to_page(entry >> PAGE_SHIFT); + page = kexec_ops.kpfn_to_page(entry >> PAGE_SHIFT); kimage_free_pages(page); } @@ -619,9 +649,8 @@ static void kimage_free(struct kimage *i if (!image) return; -#ifdef CONFIG_XEN - xen_machine_kexec_unload(image); -#endif + if (kexec_ops.kexec_unload) + kexec_ops.kexec_unload(image); kimage_free_extra_pages(image); for_each_kimage_entry(image, ptr, entry) { @@ -642,7 +671,8 @@ static void kimage_free(struct kimage *i kimage_free_entry(ind); /* Handle any machine specific cleanup */ - machine_kexec_cleanup(image); + if (kexec_ops.kexec_cleanup) + kexec_ops.kexec_cleanup(image); /* Free the kexec control pages... */ kimage_free_page_list(&image->control_pages); @@ -698,7 +728,7 @@ static struct page *kimage_alloc_page(st * have a match. */ list_for_each_entry(page, &image->dest_pages, lru) { - addr = kexec_page_to_pfn(page) << PAGE_SHIFT; + addr = kexec_ops.kpage_to_pfn(page) << PAGE_SHIFT; if (addr == destination) { list_del(&page->lru); return page; @@ -713,12 +743,12 @@ static struct page *kimage_alloc_page(st if (!page) return NULL; /* If the page cannot be used file it away */ - if (kexec_page_to_pfn(page) > + if (kexec_ops.kpage_to_pfn(page) > (KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) { list_add(&page->lru, &image->unuseable_pages); continue; } - addr = kexec_page_to_pfn(page) << PAGE_SHIFT; + addr = kexec_ops.kpage_to_pfn(page) << PAGE_SHIFT; /* If it is the destination page we want use it */ if (addr == destination) @@ -741,7 +771,7 @@ static struct page *kimage_alloc_page(st struct page *old_page; old_addr = *old & PAGE_MASK; - old_page = kexec_pfn_to_page(old_addr >> PAGE_SHIFT); + old_page = kexec_ops.kpfn_to_page(old_addr >> PAGE_SHIFT); copy_highpage(page, old_page); *old = addr | (*old & ~PAGE_MASK); @@ -791,7 +821,7 @@ static int kimage_load_normal_segment(st result = -ENOMEM; goto out; } - result = kimage_add_page(image, kexec_page_to_pfn(page) + result = kimage_add_page(image, kexec_ops.kpage_to_pfn(page) << PAGE_SHIFT); if (result < 0) goto out; @@ -846,7 +876,7 @@ static int kimage_load_crash_segment(str char *ptr; size_t uchunk, mchunk; - page = kexec_pfn_to_page(maddr >> PAGE_SHIFT); + page = kexec_ops.kpfn_to_page(maddr >> PAGE_SHIFT); if (page == 0) { result = -ENOMEM; goto out; @@ -998,9 +1028,11 @@ asmlinkage long sys_kexec_load(unsigned if (result) goto out; - result = machine_kexec_prepare(image); - if (result) - goto out; + if (kexec_ops.kexec_prepare) { + result = kexec_ops.kexec_prepare(image); + if (result) + goto out; + } for (i = 0; i < nr_segments; i++) { result = kimage_load_segment(image, &image->segment[i]); @@ -1011,11 +1043,13 @@ asmlinkage long sys_kexec_load(unsigned if (result) goto out; } -#ifdef CONFIG_XEN - result = xen_machine_kexec_load(image); - if (result) - goto out; -#endif + + if (kexec_ops.kexec_load) { + result = kexec_ops.kexec_load(image); + if (result) + goto out; + } + /* Install the new kernel, and Uninstall the old */ image = xchg(dest_image, image); -- _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |