[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Linux support for sysenter/exit on x86_32.
# HG changeset patch # User Ian.Campbell@xxxxxxxxxxxxx # Node ID 42a398e1daf1fcc823156f33f85bfe1d785662c4 # Parent 3ffb6cc6b8d2a42dd4f3c6399783a5f99458023b Linux support for sysenter/exit on x86_32. This support is only active when supervisor_mode_kernel is enabled in the Xen build (and when the hardware supports sysenter). Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx> diff -r 3ffb6cc6b8d2 -r 42a398e1daf1 linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S --- a/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S Fri Apr 21 17:19:29 2006 +0100 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S Fri Apr 21 17:19:31 2006 +0100 @@ -239,7 +239,7 @@ 1: movl (%ebp),%ebp jae syscall_badsys call *sys_call_table(,%eax,4) movl %eax,EAX(%esp) - cli + DISABLE_INTERRUPTS movl TI_flags(%ebp), %ecx testw $_TIF_ALLWORK_MASK, %cx jne syscall_exit_work @@ -247,8 +247,23 @@ 1: movl (%ebp),%ebp movl EIP(%esp), %edx movl OLDESP(%esp), %ecx xorl %ebp,%ebp +#ifdef CONFIG_XEN + __ENABLE_INTERRUPTS +sysexit_scrit: /**** START OF SYSEXIT CRITICAL REGION ****/ + __TEST_PENDING + jnz 14f # process more events if necessary... + movl ESI(%esp), %esi + sysexit +14: __DISABLE_INTERRUPTS +sysexit_ecrit: /**** END OF SYSEXIT CRITICAL REGION ****/ + push %esp + call evtchn_do_upcall + add $4,%esp + jmp ret_from_intr +#else sti sysexit +#endif /* !CONFIG_XEN */ # system call handler stub @@ -530,6 +545,11 @@ error_code: # So, on entry to the handler we detect whether we interrupted an # existing activation in its critical region -- if so, we pop the current # activation and restart the handler using the previous one. +# +# The sysexit critical region is slightly different. sysexit +# atomically removes the entire stack frame. If we interrupt in the +# critical region we know that the entire frame is present and correct +# so we can simply throw away the new one. ENTRY(hypervisor_callback) pushl %eax SAVE_ALL @@ -538,6 +558,11 @@ ENTRY(hypervisor_callback) jb 11f cmpl $ecrit,%eax jb critical_region_fixup + cmpl $sysexit_scrit,%eax + jb 11f + cmpl $sysexit_ecrit,%eax + ja 11f + addl $0x34,%esp # Remove cs...ebx from stack frame. 11: push %esp call evtchn_do_upcall add $4,%esp diff -r 3ffb6cc6b8d2 -r 42a398e1daf1 linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c Fri Apr 21 17:19:29 2006 +0100 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c Fri Apr 21 17:19:31 2006 +0100 @@ -19,6 +19,10 @@ #include <asm/msr.h> #include <asm/pgtable.h> #include <asm/unistd.h> + +#ifdef CONFIG_XEN +#include <xen/interface/callback.h> +#endif extern asmlinkage void sysenter_entry(void); @@ -53,6 +57,18 @@ int __init sysenter_setup(void) int __init sysenter_setup(void) { syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); + +#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(syscall_page, _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |