diff options
author | Ian Campbell <ian.campbell@xensource.com> | 2007-02-08 11:03:32 +0000 |
---|---|---|
committer | Ian Campbell <ian.campbell@xensource.com> | 2007-02-08 11:03:32 +0000 |
commit | cc1b02ddd4b54154944d31a82f56b84cd616362e (patch) | |
tree | c75db1f33419a10dca4736a1bfe6f9879a1bdc83 /xen/arch/x86/machine_kexec.c | |
parent | 9c47bd3d1e8e66c787f3dbf1f475dd536ab5d184 (diff) | |
download | xen-cc1b02ddd4b54154944d31a82f56b84cd616362e.tar.gz xen-cc1b02ddd4b54154944d31a82f56b84cd616362e.tar.bz2 xen-cc1b02ddd4b54154944d31a82f56b84cd616362e.zip |
[XEN] kexec: add compatability shim for kexec in 32on64 mode.
Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
Diffstat (limited to 'xen/arch/x86/machine_kexec.c')
-rw-r--r-- | xen/arch/x86/machine_kexec.c | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/xen/arch/x86/machine_kexec.c b/xen/arch/x86/machine_kexec.c index 54fa466793..5e82975366 100644 --- a/xen/arch/x86/machine_kexec.c +++ b/xen/arch/x86/machine_kexec.c @@ -21,7 +21,7 @@ typedef void (*relocate_new_kernel_t)( unsigned long indirection_page, - unsigned long page_list, + unsigned long *page_list, unsigned long start_address); int machine_kexec_load(int type, int slot, xen_kexec_image_t *image) @@ -44,8 +44,26 @@ int machine_kexec_load(int type, int slot, xen_kexec_image_t *image) else { /* Odd pages: va for previous ma. */ - set_fixmap(fix_base + (k >> 1), prev_ma); - image->page_list[k] = fix_to_virt(fix_base + (k >> 1)); + if ( IS_COMPAT(dom0) ) + { + + /* + * The compatability bounce code sets up a page table + * with a 1-1 mapping of the first 1G of memory so + * VA==PA here. + * + * This Linux purgatory code still sets up separate + * high and low mappings on the control page (entries + * 0 and 1) but it is harmless if they are equal since + * that PT is not live at the time. + */ + image->page_list[k] = prev_ma; + } + else + { + set_fixmap(fix_base + (k >> 1), prev_ma); + image->page_list[k] = fix_to_virt(fix_base + (k >> 1)); + } } } @@ -100,11 +118,27 @@ void machine_reboot_kexec(xen_kexec_image_t *image) void machine_kexec(xen_kexec_image_t *image) { - relocate_new_kernel_t rnk; +#ifdef CONFIG_COMPAT + if ( IS_COMPAT(dom0) ) + { + extern void compat_machine_kexec(unsigned long rnk, + unsigned long indirection_page, + unsigned long *page_list, + unsigned long start_address); + compat_machine_kexec(image->page_list[1], + image->indirection_page, + image->page_list, + image->start_address); + } + else +#endif + { + relocate_new_kernel_t rnk; - rnk = (relocate_new_kernel_t) image->page_list[1]; - (*rnk)(image->indirection_page, (unsigned long)image->page_list, - image->start_address); + rnk = (relocate_new_kernel_t) image->page_list[1]; + (*rnk)(image->indirection_page, image->page_list, + image->start_address); + } } /* |