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); -- _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Magnus Damm
2006-Dec-12 07:12 UTC
[Xen-devel] Re: [patch] Add kexec_ops & function pointers
Hi Gerd, On 12/9/06, Gerd Hoffmann <kraxel@suse.de> wrote:> 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(-)This version looks much cleaner. I''ve tested the code on i386 using version 12898 and there was one small piece missing, see the attached patch. Basically, machine_kexec() should be converted to kexec_ops.kexec() in two places. The second place is unfortunately located in linux/kernel/sys.c which does not exist in sparse yet. So that needs to be resolved somehow. So apart from that I think the code looks very good. Thanks. / magnus _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Gerd Hoffmann
2006-Dec-12 08:44 UTC
[Xen-devel] Re: [patch] Add kexec_ops & function pointers
Hi,> Basically, machine_kexec() should be converted to kexec_ops.kexec() in > two places. The second place is unfortunately located in > linux/kernel/sys.c which does not exist in sparse yet. So that needs > to be resolved somehow.Noticed that too meanwhile, while making domU kexec work again. Latest version has this fixed. http://www.suse.de/~kraxel/patches/unstable-hg12895-20061211-quilt/ kexec-add-kernel-sys.diff kexec-fixups.diff cheers, Gerd -- Gerd Hoffmann <kraxel@suse.de> _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2006-Dec-12 11:27 UTC
Re: [Xen-devel] Re: [patch] Add kexec_ops & function pointers
On Tue, 2006-12-12 at 16:12 +0900, Magnus Damm wrote:> Basically, machine_kexec() should be converted to kexec_ops.kexec() in > two places. The second place is unfortunately located in > linux/kernel/sys.c which does not exist in sparse yet. So that needs > to be resolved somehow.Hiding the indirections through the function table in the header via defines or inline functions would make things a lot cleaner in my opinion and as a bonus avoid this addition to the sparse tree. That is the approach taken by the paravirt_ops stuff so it would also make it easier to integrate with that in the future. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Gerd Hoffmann
2006-Dec-12 12:48 UTC
Re: [Xen-devel] Re: [patch] Add kexec_ops & function pointers
Ian Campbell wrote:> On Tue, 2006-12-12 at 16:12 +0900, Magnus Damm wrote: >> Basically, machine_kexec() should be converted to kexec_ops.kexec() in >> two places. The second place is unfortunately located in >> linux/kernel/sys.c which does not exist in sparse yet. So that needs >> to be resolved somehow. > > Hiding the indirections through the function table in the header via > defines or inline functions would make things a lot cleaner in my > opinion and as a bonus avoid this addition to the sparse tree.No. As machine_kexec() continues to exist (and is the default for kexec_ops.kexec) you can''t just turn that into a macro. You have to either fix the two callers (as done by the patch) or rename the function to something different in arch/*/kernel/machine_kexec.c in order to be able to reuse the name for the macro. cheers, Gerd -- Gerd Hoffmann <kraxel@suse.de> _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2006-Dec-12 15:45 UTC
Re: [Xen-devel] Re: [patch] Add kexec_ops & function pointers
On Tue, 2006-12-12 at 13:48 +0100, Gerd Hoffmann wrote:> Ian Campbell wrote: > > On Tue, 2006-12-12 at 16:12 +0900, Magnus Damm wrote: > >> Basically, machine_kexec() should be converted to kexec_ops.kexec() in > >> two places. The second place is unfortunately located in > >> linux/kernel/sys.c which does not exist in sparse yet. So that needs > >> to be resolved somehow. > > > > Hiding the indirections through the function table in the header via > > defines or inline functions would make things a lot cleaner in my > > opinion and as a bonus avoid this addition to the sparse tree. > > No. As machine_kexec() continues to exist (and is the default for > kexec_ops.kexec) you can''t just turn that into a macro. You have to > either fix the two callers (as done by the patch) or rename the function > to something different in arch/*/kernel/machine_kexec.c in order to be > able to reuse the name for the macro.Yes you may need to rename some bits. I was thinking of a solution where you have foo_native, foo_xen0 and foo_xenU functions (or whatever) with an inline foo() which calls through the function table to the correct version. Cheers, Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Gerd Hoffmann
2006-Dec-12 16:13 UTC
Re: [Xen-devel] Re: [patch] Add kexec_ops & function pointers
Ian Campbell wrote:>>> Hiding the indirections through the function table in the header via >>> defines or inline functions would make things a lot cleaner in my >>> opinion and as a bonus avoid this addition to the sparse tree. >> No. As machine_kexec() continues to exist (and is the default for >> kexec_ops.kexec) you can''t just turn that into a macro. You have to >> either fix the two callers (as done by the patch) or rename the function >> to something different in arch/*/kernel/machine_kexec.c in order to be >> able to reuse the name for the macro. > > Yes you may need to rename some bits. I was thinking of a solution where > you have foo_native, foo_xen0 and foo_xenU functions (or whatever) with > an inline foo() which calls through the function table to the correct > version.Sure. But renaming machine_kexec() to machine_kexec_native() or simliar means touching a big bunch of files, namely arch/{lots-of-directories-here}/kernel/machine_kexec.c. I''d prefer to touch only one (kernel/sys.c) to keep the number of changes in the xen tree small. We''ll have to see how we solve that finally, most likely it isn''t the final solution anyway. paravirt is still some way to go, we have to upgrade to 2.6.20-rc1 first, and even that gives us paravirt for x86_32 only, not yet x86_64 ... cheers, Gerd -- Gerd Hoffmann <kraxel@suse.de> _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2006-Dec-12 16:18 UTC
Re: [Xen-devel] Re: [patch] Add kexec_ops & function pointers
On Tue, 2006-12-12 at 17:13 +0100, Gerd Hoffmann wrote:> Ian Campbell wrote: > >>> Hiding the indirections through the function table in the header via > >>> defines or inline functions would make things a lot cleaner in my > >>> opinion and as a bonus avoid this addition to the sparse tree. > >> No. As machine_kexec() continues to exist (and is the default for > >> kexec_ops.kexec) you can''t just turn that into a macro. You have to > >> either fix the two callers (as done by the patch) or rename the function > >> to something different in arch/*/kernel/machine_kexec.c in order to be > >> able to reuse the name for the macro. > > > > Yes you may need to rename some bits. I was thinking of a solution where > > you have foo_native, foo_xen0 and foo_xenU functions (or whatever) with > > an inline foo() which calls through the function table to the correct > > version. > > Sure. But renaming machine_kexec() to machine_kexec_native() or simliar > means touching a big bunch of files, namely > arch/{lots-of-directories-here}/kernel/machine_kexec.c. I''d prefer to > touch only one (kernel/sys.c) to keep the number of changes in the xen > tree small.You mean the versions for arch''s other than i386 and x86_64? arch/{x86_64,i386}/kernel/machine_kexec.c are both in the sparse tree already. If you are adding the function table to all architectures then you are right, changing kernel/sys.c is much simpler. I thought the function table was an implementation detail on i386 and x86_64 only. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel