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
|