[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.