X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fi386%2Fkernel%2Fsysenter.c;h=b97719aa4127811ed198af5dce8e06f4191b3418;hb=4e76c8a9fa413ccc09d3f7f664183dcce3555d57;hp=ec4959f74736891cb8298fef35047f0640254778;hpb=43bc926fffd92024b46cafaf7350d669ba9ca884;p=linux-2.6.git diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c index ec4959f74..b97719aa4 100644 --- a/arch/i386/kernel/sysenter.c +++ b/arch/i386/kernel/sysenter.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -21,10 +22,15 @@ #include #include +#ifdef CONFIG_XEN +#include +#endif + extern asmlinkage void sysenter_entry(void); void enable_sep_cpu(void) { +#ifndef CONFIG_X86_NO_TSS int cpu = get_cpu(); struct tss_struct *tss = &per_cpu(init_tss, cpu); @@ -39,6 +45,7 @@ void enable_sep_cpu(void) wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0); wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0); put_cpu(); +#endif } /* @@ -47,7 +54,6 @@ void enable_sep_cpu(void) */ extern const char vsyscall_int80_start, vsyscall_int80_end; extern const char vsyscall_sysenter_start, vsyscall_sysenter_end; - static struct page *sysenter_pages[2]; int __init sysenter_setup(void) @@ -56,16 +62,28 @@ int __init sysenter_setup(void) sysenter_pages[0] = virt_to_page(page); - if (!boot_cpu_has(X86_FEATURE_SEP)) { +#ifdef CONFIG_XEN + if (boot_cpu_has(X86_FEATURE_SEP)) { + struct callback_register sysenter = { + .type = CALLBACKTYPE_sysenter, + .address = { __KERNEL_CS, (unsigned long)sysenter_entry }, + }; + + if (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) < 0) + clear_bit(X86_FEATURE_SEP, boot_cpu_data.x86_capability); + } +#endif + + if (boot_cpu_has(X86_FEATURE_SEP)) { memcpy(page, - &vsyscall_int80_start, - &vsyscall_int80_end - &vsyscall_int80_start); + &vsyscall_sysenter_start, + &vsyscall_sysenter_end - &vsyscall_sysenter_start); return 0; } memcpy(page, - &vsyscall_sysenter_start, - &vsyscall_sysenter_end - &vsyscall_sysenter_start); + &vsyscall_int80_start, + &vsyscall_int80_end - &vsyscall_int80_start); return 0; } @@ -130,6 +148,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, return err; } +#ifndef CONFIG_XEN int in_gate_area_no_task(unsigned long addr) { return 0; @@ -144,3 +163,4 @@ struct vm_area_struct *get_gate_vma(struct task_struct *tsk) { return NULL; } +#endif