Subject: xen3 arch-i386 From: http://xenbits.xensource.com/linux-2.6.18-xen.hg (tip 1017:948c933f8839) Patch-mainline: n/a Acked-by: jbeulich@novell.com --- head-2010-01-19.orig/arch/x86/kernel/asm-offsets_32.c 2009-09-10 00:13:59.000000000 +0200 +++ head-2010-01-19/arch/x86/kernel/asm-offsets_32.c 2010-01-19 16:00:16.000000000 +0100 @@ -93,9 +93,14 @@ void foo(void) OFFSET(pbe_orig_address, pbe, orig_address); OFFSET(pbe_next, pbe, next); +#ifndef CONFIG_X86_NO_TSS /* Offset from the sysenter stack to tss.sp0 */ - DEFINE(TSS_sysenter_sp0, offsetof(struct tss_struct, x86_tss.sp0) - + DEFINE(SYSENTER_stack_sp0, offsetof(struct tss_struct, x86_tss.sp0) - sizeof(struct tss_struct)); +#else + /* sysenter stack points directly to sp0 */ + DEFINE(SYSENTER_stack_sp0, 0); +#endif DEFINE(PAGE_SIZE_asm, PAGE_SIZE); DEFINE(PAGE_SHIFT_asm, PAGE_SHIFT); --- head-2010-01-19.orig/arch/x86/kernel/entry_32.S 2010-01-19 13:27:24.000000000 +0100 +++ head-2010-01-19/arch/x86/kernel/entry_32.S 2010-01-19 16:00:16.000000000 +0100 @@ -401,7 +401,7 @@ ENTRY(ia32_sysenter_target) CFI_SIGNAL_FRAME CFI_DEF_CFA esp, 0 CFI_REGISTER esp, ebp - movl TSS_sysenter_sp0(%esp),%esp + movl SYSENTER_stack_sp0(%esp),%esp sysenter_past_esp: /* * Interrupts are disabled here, but we can't trace it until @@ -1381,7 +1381,7 @@ END(page_fault) * that sets up the real kernel stack. Check here, since we can't * allow the wrong stack to be used. * - * "TSS_sysenter_sp0+12" is because the NMI/debug handler will have + * "SYSENTER_stack_sp0+12" is because the NMI/debug handler will have * already pushed 3 words if it hits on the sysenter instruction: * eflags, cs and eip. * @@ -1393,7 +1393,7 @@ END(page_fault) cmpw $__KERNEL_CS, 4(%esp) jne \ok \label: - movl TSS_sysenter_sp0 + \offset(%esp), %esp + movl SYSENTER_stack_sp0 + \offset(%esp), %esp CFI_DEF_CFA esp, 0 CFI_UNDEFINED eip pushfl --- head-2010-01-19.orig/arch/x86/kernel/machine_kexec_32.c 2010-01-19 14:51:07.000000000 +0100 +++ head-2010-01-19/arch/x86/kernel/machine_kexec_32.c 2010-01-19 16:00:16.000000000 +0100 @@ -27,6 +27,10 @@ #include #include +#ifdef CONFIG_XEN +#include +#endif + static void machine_kexec_free_page_tables(struct kimage *image) { free_page((unsigned long)image->arch.pgd); @@ -97,6 +101,55 @@ static void machine_kexec_prepare_page_t __pa(control_page), __pa(control_page)); } +#ifdef CONFIG_XEN + +#define __ma(x) (pfn_to_mfn(__pa((x)) >> PAGE_SHIFT) << PAGE_SHIFT) + +#if PAGES_NR > KEXEC_XEN_NO_PAGES +#error PAGES_NR is greater than KEXEC_XEN_NO_PAGES - Xen support will break +#endif + +#if PA_CONTROL_PAGE != 0 +#error PA_CONTROL_PAGE is non zero - Xen support will break +#endif + +void machine_kexec_setup_load_arg(xen_kexec_image_t *xki, struct kimage *image) +{ + void *control_page; + + memset(xki->page_list, 0, sizeof(xki->page_list)); + + control_page = page_address(image->control_code_page); + memcpy(control_page, relocate_kernel, PAGE_SIZE); + + xki->page_list[PA_CONTROL_PAGE] = __ma(control_page); + xki->page_list[PA_PGD] = __ma(kexec_pgd); +#ifdef CONFIG_X86_PAE + xki->page_list[PA_PMD_0] = __ma(kexec_pmd0); + xki->page_list[PA_PMD_1] = __ma(kexec_pmd1); +#endif + xki->page_list[PA_PTE_0] = __ma(kexec_pte0); + xki->page_list[PA_PTE_1] = __ma(kexec_pte1); + +} + +int __init machine_kexec_setup_resources(struct resource *hypervisor, + struct resource *phys_cpus, + int nr_phys_cpus) +{ + int k; + + /* The per-cpu crash note resources belong to the hypervisor resource */ + for (k = 0; k < nr_phys_cpus; k++) + request_resource(hypervisor, phys_cpus + k); + + return 0; +} + +void machine_kexec_register_resources(struct resource *res) { ; } + +#endif /* CONFIG_XEN */ + /* * A architecture hook called to validate the * proposed image and prepare the control pages @@ -134,6 +187,7 @@ void machine_kexec_cleanup(struct kimage machine_kexec_free_page_tables(image); } +#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. @@ -199,6 +253,7 @@ void machine_kexec(struct kimage *image) __ftrace_enabled_restore(save_ftrace_enabled); } +#endif void arch_crash_save_vmcoreinfo(void) { --- head-2010-01-19.orig/arch/x86/kernel/vm86_32.c 2010-01-19 13:26:11.000000000 +0100 +++ head-2010-01-19/arch/x86/kernel/vm86_32.c 2010-01-19 16:00:16.000000000 +0100 @@ -125,7 +125,9 @@ static int copy_vm86_regs_from_user(stru struct pt_regs *save_v86_state(struct kernel_vm86_regs *regs) { +#ifndef CONFIG_X86_NO_TSS struct tss_struct *tss; +#endif struct pt_regs *ret; unsigned long tmp; @@ -148,12 +150,16 @@ struct pt_regs *save_v86_state(struct ke do_exit(SIGSEGV); } +#ifndef CONFIG_X86_NO_TSS tss = &per_cpu(init_tss, get_cpu()); +#endif current->thread.sp0 = current->thread.saved_sp0; current->thread.sysenter_cs = __KERNEL_CS; load_sp0(tss, ¤t->thread); current->thread.saved_sp0 = 0; +#ifndef CONFIG_X86_NO_TSS put_cpu(); +#endif ret = KVM86->regs32; @@ -279,7 +285,9 @@ out: static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk) { +#ifndef CONFIG_X86_NO_TSS struct tss_struct *tss; +#endif /* * make sure the vm86() system call doesn't try to do anything silly */ @@ -323,12 +331,16 @@ static void do_sys_vm86(struct kernel_vm tsk->thread.saved_fs = info->regs32->fs; tsk->thread.saved_gs = get_user_gs(info->regs32); +#ifndef CONFIG_X86_NO_TSS tss = &per_cpu(init_tss, get_cpu()); +#endif tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0; if (cpu_has_sep) tsk->thread.sysenter_cs = 0; load_sp0(tss, &tsk->thread); +#ifndef CONFIG_X86_NO_TSS put_cpu(); +#endif tsk->thread.screen_bitmap = info->screen_bitmap; if (info->flags & VM86_SCREEN_BITMAP)