2010-07-07 11:12:45 +00:00
|
|
|
Subject: xen3 arch-i386
|
2011-04-19 20:09:59 +00:00
|
|
|
From: http://xenbits.xensource.com/linux-2.6.18-xen.hg (tip 1073:8fe973d8fb98)
|
2010-07-07 11:12:45 +00:00
|
|
|
Patch-mainline: n/a
|
|
|
|
Acked-by: jbeulich@novell.com
|
|
|
|
|
2011-04-19 20:09:59 +00:00
|
|
|
--- head-2011-01-30.orig/arch/x86/kernel/asm-offsets_32.c 2011-02-01 13:47:44.000000000 +0100
|
|
|
|
+++ head-2011-01-30/arch/x86/kernel/asm-offsets_32.c 2011-01-31 14:54:00.000000000 +0100
|
2010-07-07 11:12:45 +00:00
|
|
|
@@ -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);
|
2011-04-19 20:09:59 +00:00
|
|
|
--- head-2011-01-30.orig/arch/x86/kernel/entry_32.S 2011-02-01 13:57:16.000000000 +0100
|
|
|
|
+++ head-2011-01-30/arch/x86/kernel/entry_32.S 2011-02-01 14:10:27.000000000 +0100
|
|
|
|
@@ -375,7 +375,7 @@ ENTRY(ia32_sysenter_target)
|
2010-07-07 11:12:45 +00:00
|
|
|
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
|
2011-04-19 20:09:59 +00:00
|
|
|
@@ -1307,7 +1307,7 @@ END(page_fault)
|
2010-07-07 11:12:45 +00:00
|
|
|
* 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.
|
|
|
|
*
|
2011-04-19 20:09:59 +00:00
|
|
|
@@ -1319,7 +1319,7 @@ END(page_fault)
|
2010-07-07 11:12:45 +00:00
|
|
|
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
|
2011-04-19 20:09:59 +00:00
|
|
|
pushfl_cfi
|
|
|
|
--- head-2011-01-30.orig/arch/x86/kernel/machine_kexec_32.c 2010-01-19 14:51:07.000000000 +0100
|
|
|
|
+++ head-2011-01-30/arch/x86/kernel/machine_kexec_32.c 2011-01-31 14:54:00.000000000 +0100
|
2010-07-07 11:12:45 +00:00
|
|
|
@@ -27,6 +27,10 @@
|
|
|
|
#include <asm/cacheflush.h>
|
|
|
|
#include <asm/debugreg.h>
|
|
|
|
|
|
|
|
+#ifdef CONFIG_XEN
|
|
|
|
+#include <xen/interface/kexec.h>
|
|
|
|
+#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)
|
|
|
|
{
|
2011-04-19 20:09:59 +00:00
|
|
|
--- head-2011-01-30.orig/arch/x86/kernel/vm86_32.c 2011-02-01 13:47:44.000000000 +0100
|
|
|
|
+++ head-2011-01-30/arch/x86/kernel/vm86_32.c 2011-01-31 14:54:00.000000000 +0100
|
2010-07-07 11:12:45 +00:00
|
|
|
@@ -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;
|
|
|
|
|
2011-04-19 20:09:59 +00:00
|
|
|
@@ -280,7 +286,9 @@ out:
|
2010-07-07 11:12:45 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
*/
|
2011-04-19 20:09:59 +00:00
|
|
|
@@ -324,12 +332,16 @@ static void do_sys_vm86(struct kernel_vm
|
2010-07-07 11:12:45 +00:00
|
|
|
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)
|