[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-ia64-devel] [patch 01/16] Kexec: Pass TR to be unpinned by relocate_new_kernel as an array
This sets up an array that describes all the TR entries to be unpinned by relocate_new_kernel. As it stands relocate_new_kernel makes several false assumptions about constants in xen-linux being the same as xen, and fails to unpin several entries. This is desipite heavy additions of #ifdef XEN code. In order to pass all the required arguments to relocate_new_kernel, aproximately 15 parameters would be needed. This is untidy. And furthermore, only the first 8 parameters seem to get passed correctly. Instead of this, the vaules are packed into an array, and the base address of the array is passed. I am still concerned about the TC (TLB cache) entry clearing code in relocate_new_kernel, as it still makes assumptions about xen-linux and xen having the same contants - however these assumptions are currently valid. I believe that it should be possible to further restructure things such that the TR and TC unpinning portions of relocate_new_kernel are replaced by code supplied by xen. This should be possible because this code is run before the segmentation relocation takes place, and thus xen memory should be accessable at this time. Such an approach should be able to make use of ia64_do_tlb_purge, reducing the both the ammount of code and maintenence overhead in the future. The construction of such a change would likely remove all of the code incoporated in this patch. So I'm not aiming to have this change merged until I investigate the code-in-xen idea. There is also a xen-linux portion to this patch. Cc: Isaku Yamahata <yamahata@xxxxxxxxxxxxx> Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx> Index: xen-unstable.hg/xen/arch/ia64/xen/machine_kexec.c =================================================================== --- xen-unstable.hg.orig/xen/arch/ia64/xen/machine_kexec.c 2008-01-23 15:16:11.000000000 +0900 +++ xen-unstable.hg/xen/arch/ia64/xen/machine_kexec.c 2008-01-23 15:17:33.000000000 +0900 @@ -25,6 +25,7 @@ #include <linux/notifier.h> #include <asm/dom_fw_dom0.h> +#if 0 typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)( unsigned long indirection_page, unsigned long start_address, @@ -32,9 +33,23 @@ typedef asmlinkage NORET_TYPE void (*rel unsigned long pal_addr, unsigned long cpu_data_pa, unsigned long kernel_start, - unsigned long page_offset, + unsigned long percpu_addr, + unsigned long shared_info, + unsigned long shared_info_shift, + unsigned long priv_regs, + unsigned long priv_regs_shift, + unsigned long stack, unsigned long vhpt) ATTRIB_NORET; +#endif + +typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)( + unsigned long indirection_page, + unsigned long start_address, + struct ia64_boot_param *boot_param, + unsigned long cpu_data_pa, + unsigned long *tr_list) + ATTRIB_NORET; #define kexec_flush_icache_page(page) \ do { \ @@ -51,15 +66,19 @@ void machine_kexec_unload(int type, int { } +#define PURGE_DTLB (1LL<<62) +#define PURGE_ITLB (1LL<<63) + static void ia64_machine_kexec(struct unw_frame_info *info, void *arg) { + struct vcpu *v = current; xen_kexec_image_t *image = arg; relocate_new_kernel_t rnk; unsigned long code_addr = (unsigned long) __va(image->reboot_code_buffer); unsigned long cpu_data_pa = (unsigned long) __pa(cpu_data(smp_processor_id())); - unsigned long vhpt; + unsigned long tr[(7*2)+1]; int ii; /* Interrupts aren't acceptable while we reboot */ @@ -84,12 +103,50 @@ static void ia64_machine_kexec(struct un while (ia64_get_ivr() != IA64_SPURIOUS_INT_VECTOR) ia64_eoi(); platform_kernel_launch_event(); - vhpt = __va_ul(vcpu_vhpt_maddr(current)); - BUG_ON(!vhpt); + + ii = 0; + /* TR for kernel text and data */ + tr[ii++] = PURGE_ITLB|PURGE_DTLB|(KERNEL_TR_PAGE_SHIFT<<2); + tr[ii++] = KERNEL_START; + /* TR for percpu data */ + tr[ii++] = PURGE_DTLB|(PERCPU_PAGE_SHIFT<<2); + tr[ii++] = PERCPU_ADDR; + /* TR for shared_info + * v->domain->arch.shared_info_va is rubbis if + * v->domain->shared_info is zero. If this is + * a problem use a saved value. + */ + BUG_ON(!v->domain->shared_info); + tr[ii++] = PURGE_DTLB|(XSI_SHIFT<<2); + tr[ii++] = v->domain->arch.shared_info_va; + /* TR for mapped_regs */ + tr[ii++] = PURGE_DTLB|(XMAPPEDREGS_SHIFT<<2); + tr[ii++] = v->domain->arch.shared_info_va + XMAPPEDREGS_OFS; + /* TR for pal code */ + tr[ii++] = PURGE_ITLB|(IA64_GRANULE_SHIFT<<2); + /* XXX: GRANULEROUNDDOWN is probably not neccessary + * as ptr should ignore trailing bits + */ + tr[ii++] = GRANULEROUNDDOWN((unsigned long) pal_vaddr); + /* TR for stack + * Ony clear stack if it doesn't overlap with kernel text and data + * - which it seems to often + */ + if (((unsigned long)current & ~(KERNEL_TR_PAGE_SIZE-1)) != + KERNEL_START) { + tr[ii++] = PURGE_DTLB|(IA64_GRANULE_SHIFT<<2); + tr[ii++] = (unsigned long)current; + } +#if VHPT_ENABLED + // TR for VHPT + tr[ii++] = PURGE_DTLB|(IA64_GRANULE_SHIFT<<2); + tr[ii++] = __va_ul(vcpu_vhpt_maddr(current)); +#endif + tr[ii] = 0UL; + rnk = (relocate_new_kernel_t)&code_addr; (*rnk)(image->indirection_page, image->start_address, ia64_boot_param, - GRANULEROUNDDOWN((unsigned long) pal_vaddr), cpu_data_pa, - KERNEL_START, PAGE_OFFSET, vhpt); + cpu_data_pa, tr); BUG(); } -- -- Horms _______________________________________________ Xen-ia64-devel mailing list Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-ia64-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |