Subject: xen3 arch-i386 From: http://xenbits.xensource.com/linux-2.6.18-xen.hg (tip 728:832aac894efd) Patch-mainline: obsolete Acked-by: jbeulich@novell.com Index: head-2008-11-25/arch/x86/kernel/asm-offsets_32.c =================================================================== --- head-2008-11-25.orig/arch/x86/kernel/asm-offsets_32.c 2008-11-25 12:33:06.000000000 +0100 +++ head-2008-11-25/arch/x86/kernel/asm-offsets_32.c 2008-11-25 12:35:53.000000000 +0100 @@ -91,9 +91,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); Index: head-2008-11-25/arch/x86/kernel/entry_32.S =================================================================== --- head-2008-11-25.orig/arch/x86/kernel/entry_32.S 2008-11-25 12:33:06.000000000 +0100 +++ head-2008-11-25/arch/x86/kernel/entry_32.S 2008-11-25 12:35:53.000000000 +0100 @@ -293,7 +293,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 @@ -782,7 +782,7 @@ END(device_not_available) * 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. * @@ -794,7 +794,7 @@ END(device_not_available) 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; \ Index: head-2008-11-25/arch/x86/kernel/machine_kexec_32.c =================================================================== --- head-2008-11-25.orig/arch/x86/kernel/machine_kexec_32.c 2008-11-17 13:38:03.000000000 +0100 +++ head-2008-11-25/arch/x86/kernel/machine_kexec_32.c 2008-11-25 12:35:53.000000000 +0100 @@ -25,6 +25,10 @@ #include #include +#ifdef CONFIG_XEN +#include +#endif + #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) static u32 kexec_pgd[1024] PAGE_ALIGNED; #ifdef CONFIG_X86_PAE @@ -34,6 +38,55 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED static u32 kexec_pte0[1024] PAGE_ALIGNED; static u32 kexec_pte1[1024] PAGE_ALIGNED; +#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 @@ -64,6 +117,7 @@ void machine_kexec_cleanup(struct kimage set_pages_nx(image->control_code_page, 1); } +#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. @@ -137,6 +191,7 @@ void machine_kexec(struct kimage *image) __ftrace_enabled_restore(save_ftrace_enabled); } +#endif void arch_crash_save_vmcoreinfo(void) { Index: head-2008-11-25/arch/x86/kernel/vm86_32.c =================================================================== --- head-2008-11-25.orig/arch/x86/kernel/vm86_32.c 2008-11-25 12:33:06.000000000 +0100 +++ head-2008-11-25/arch/x86/kernel/vm86_32.c 2008-11-25 12:35:53.000000000 +0100 @@ -124,7 +124,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; @@ -147,12 +149,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 */ @@ -324,12 +332,16 @@ static void do_sys_vm86(struct kernel_vm tsk->thread.saved_fs = info->regs32->fs; savesegment(gs, tsk->thread.saved_gs); +#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) Index: head-2008-11-25/arch/x86/power/cpu_32.c =================================================================== --- head-2008-11-25.orig/arch/x86/power/cpu_32.c 2008-11-25 12:33:06.000000000 +0100 +++ head-2008-11-25/arch/x86/power/cpu_32.c 2008-11-25 12:35:53.000000000 +0100 @@ -65,6 +65,7 @@ static void do_fpu_end(void) static void fix_processor_context(void) { +#ifndef CONFIG_X86_NO_TSS int cpu = smp_processor_id(); struct tss_struct *t = &per_cpu(init_tss, cpu); @@ -74,6 +75,7 @@ static void fix_processor_context(void) * 386 hardware has concept of busy TSS or some * similar stupidity. */ +#endif load_TR_desc(); /* This does ltr */ load_LDT(¤t->active_mm->context); /* This does lldt */ Index: head-2008-11-25/arch/x86/vdso/vdso32-setup.c =================================================================== --- head-2008-11-25.orig/arch/x86/vdso/vdso32-setup.c 2008-11-25 12:33:06.000000000 +0100 +++ head-2008-11-25/arch/x86/vdso/vdso32-setup.c 2008-11-25 12:35:53.000000000 +0100 @@ -26,6 +26,10 @@ #include #include +#ifdef CONFIG_XEN +#include +#endif + enum { VDSO_DISABLED = 0, VDSO_ENABLED = 1, @@ -225,6 +229,7 @@ static inline void map_compat_vdso(int m void enable_sep_cpu(void) { +#ifndef CONFIG_XEN int cpu = get_cpu(); struct tss_struct *tss = &per_cpu(init_tss, cpu); @@ -239,6 +244,35 @@ void enable_sep_cpu(void) wrmsr(MSR_IA32_SYSENTER_ESP, tss->x86_tss.sp1, 0); wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) ia32_sysenter_target, 0); put_cpu(); +#else + extern asmlinkage void ia32pv_sysenter_target(void); + static struct callback_register sysenter = { + .type = CALLBACKTYPE_sysenter, + .address = { __KERNEL_CS, (unsigned long)ia32pv_sysenter_target }, + }; + + if (!boot_cpu_has(X86_FEATURE_SEP)) + return; + + get_cpu(); + + if (xen_feature(XENFEAT_supervisor_mode_kernel)) + sysenter.address.eip = (unsigned long)ia32_sysenter_target; + + switch (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter)) { + case 0: + break; +#if CONFIG_XEN_COMPAT < 0x030200 + case -ENOSYS: + sysenter.type = CALLBACKTYPE_sysenter_deprecated; + if (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) == 0) + break; +#endif + default: + clear_bit(X86_FEATURE_SEP, boot_cpu_data.x86_capability); + break; + } +#endif } static struct vm_area_struct gate_vma;