Subject: xen3 arch-i386 From: http://xenbits.xensource.com/linux-2.6.18-xen.hg (tip 517:d71965a78c20) Patch-mainline: obsolete Acked-by: jbeulich@novell.com Index: head-2008-04-15/arch/x86/kernel/asm-offsets_32.c =================================================================== --- head-2008-04-15.orig/arch/x86/kernel/asm-offsets_32.c 2008-04-15 09:41:09.000000000 +0200 +++ head-2008-04-15/arch/x86/kernel/asm-offsets_32.c 2008-04-15 09:59:29.000000000 +0200 @@ -98,9 +98,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-04-15/arch/x86/kernel/entry_32.S =================================================================== --- head-2008-04-15.orig/arch/x86/kernel/entry_32.S 2008-04-15 09:41:09.000000000 +0200 +++ head-2008-04-15/arch/x86/kernel/entry_32.S 2008-04-15 09:59:29.000000000 +0200 @@ -288,7 +288,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: /* * No need to follow this irqs on/off section: the syscall @@ -744,7 +744,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. * @@ -756,7 +756,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-04-15/arch/x86/kernel/machine_kexec_32.c =================================================================== --- head-2008-04-15.orig/arch/x86/kernel/machine_kexec_32.c 2008-04-15 09:41:09.000000000 +0200 +++ head-2008-04-15/arch/x86/kernel/machine_kexec_32.c 2008-04-15 09:59:29.000000000 +0200 @@ -21,6 +21,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 @@ -30,6 +34,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 @@ -56,6 +109,7 @@ 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. @@ -89,6 +143,7 @@ NORET_TYPE void machine_kexec(struct kim relocate_kernel((unsigned long)image->head, (unsigned long)page_list, image->start, cpu_has_pae); } +#endif void arch_crash_save_vmcoreinfo(void) { Index: head-2008-04-15/arch/x86/kernel/traps_32.c =================================================================== --- head-2008-04-15.orig/arch/x86/kernel/traps_32.c 2008-04-15 09:41:09.000000000 +0200 +++ head-2008-04-15/arch/x86/kernel/traps_32.c 2008-04-15 09:59:29.000000000 +0200 @@ -764,18 +764,11 @@ mem_parity_error(unsigned char reason, s static __kprobes void io_check_error(unsigned char reason, struct pt_regs * regs) { - unsigned long i; - printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n"); show_registers(regs); /* Re-enable the IOCK line, wait for a few seconds */ - reason = (reason & 0xf) | 8; - outb(reason, 0x61); - i = 2000; - while (--i) udelay(1000); - reason &= ~8; - outb(reason, 0x61); + clear_io_check_error(reason); } static __kprobes void Index: head-2008-04-15/arch/x86/kernel/vm86_32.c =================================================================== --- head-2008-04-15.orig/arch/x86/kernel/vm86_32.c 2008-04-15 09:41:09.000000000 +0200 +++ head-2008-04-15/arch/x86/kernel/vm86_32.c 2008-04-15 09:59:29.000000000 +0200 @@ -122,7 +122,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; @@ -145,12 +147,16 @@ struct pt_regs * save_v86_state(struct k 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; @@ -276,7 +282,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 */ @@ -321,12 +329,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-04-15/arch/x86/pci/Makefile_32 =================================================================== --- head-2008-04-15.orig/arch/x86/pci/Makefile_32 2008-04-15 09:41:09.000000000 +0200 +++ head-2008-04-15/arch/x86/pci/Makefile_32 2008-04-15 09:59:29.000000000 +0200 @@ -4,6 +4,10 @@ obj-$(CONFIG_PCI_BIOS) += pcbios.o obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_32.o direct.o mmconfig-shared.o obj-$(CONFIG_PCI_DIRECT) += direct.o +# pcifront should be after pcbios.o, mmconfig.o, and direct.o as it should only +# take over if direct access to the PCI bus is unavailable +obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += pcifront.o + pci-y := fixup.o pci-$(CONFIG_ACPI) += acpi.o pci-y += legacy.o irq.o Index: head-2008-04-15/arch/x86/power/cpu_32.c =================================================================== --- head-2008-04-15.orig/arch/x86/power/cpu_32.c 2008-04-15 09:41:09.000000000 +0200 +++ head-2008-04-15/arch/x86/power/cpu_32.c 2008-04-15 09:59:29.000000000 +0200 @@ -63,11 +63,12 @@ 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); set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 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-04-15/arch/x86/vdso/vdso32-setup.c =================================================================== --- head-2008-04-15.orig/arch/x86/vdso/vdso32-setup.c 2008-04-15 09:41:09.000000000 +0200 +++ head-2008-04-15/arch/x86/vdso/vdso32-setup.c 2008-04-15 09:59:29.000000000 +0200 @@ -26,6 +26,10 @@ #include #include +#ifdef CONFIG_XEN +#include +#endif + enum { VDSO_DISABLED = 0, VDSO_ENABLED = 1, @@ -234,6 +238,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); @@ -248,6 +253,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; Index: head-2008-04-15/include/asm-x86/mach-default/mach_traps.h =================================================================== --- head-2008-04-15.orig/include/asm-x86/mach-default/mach_traps.h 2008-04-15 09:41:09.000000000 +0200 +++ head-2008-04-15/include/asm-x86/mach-default/mach_traps.h 2008-04-15 09:59:29.000000000 +0200 @@ -13,6 +13,18 @@ static inline void clear_mem_error(unsig outb(reason, 0x61); } +static inline void clear_io_check_error(unsigned char reason) +{ + unsigned long i; + + reason = (reason & 0xf) | 8; + outb(reason, 0x61); + i = 2000; + while (--i) udelay(1000); + reason &= ~8; + outb(reason, 0x61); +} + static inline unsigned char get_nmi_reason(void) { return inb(0x61);