From: Gerd Hoffmann <kraxel@suse.de>
To: xen-devel@lists.xensource.com
Cc: magnus.damm@gmail.com
Subject: [patch] Add kexec_ops & function pointers
Date: Fri, 08 Dec 2006 17:17:44 +0100 [thread overview]
Message-ID: <20061208161729.913385000@suse.de> (raw)
[-- Attachment #1: kexec-fixups.diff --]
[-- Type: text/plain, Size: 14399 bytes --]
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
---
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);
--
next reply other threads:[~2006-12-08 16:17 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-08 16:17 Gerd Hoffmann [this message]
2006-12-12 7:12 ` [patch] Add kexec_ops & function pointers Magnus Damm
2006-12-12 8:44 ` Gerd Hoffmann
2006-12-12 11:27 ` Ian Campbell
2006-12-12 12:48 ` Gerd Hoffmann
2006-12-12 15:45 ` Ian Campbell
2006-12-12 16:13 ` Gerd Hoffmann
2006-12-12 16:18 ` Ian Campbell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20061208161729.913385000@suse.de \
--to=kraxel@suse.de \
--cc=magnus.damm@gmail.com \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.