WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] 64bit arch patch for Mini-OS

To: xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>, Keir Fraser <Keir.Fraser@xxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] 64bit arch patch for Mini-OS
From: Grzegorz Milos <gm281@xxxxxxxxx>
Date: Mon, 01 May 2006 19:43:29 +0100
Delivery-date: Mon, 01 May 2006 11:43:53 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Thunderbird 1.5 (X11/20051025)
The patch fixes 64bit version of Mini-OS. It encompasses the following:
a) 64-bit switch_to scheduler macro (by Aravindh Puthiyaparambil)
b) implements 64-bit hypervisor_callback
c) fixes thread creation issues (thread_starter used to perform initialisation)

Signed-off-by: Grzegorz Milos <gm281@xxxxxxxxx>

Keir could you apply?

Thanks
Gregor

diff -r c9b0b655c052 -r 141811b3244c extras/mini-os/console/console.c
--- a/extras/mini-os/console/console.c  Thu Mar 23 19:13:12 2006
+++ b/extras/mini-os/console/console.c  Mon May  1 18:12:07 2006
@@ -128,7 +128,7 @@
 {
     va_list       args;
     va_start(args, fmt);
-    print(0, fmt, args);
+    print(1, fmt, args);
     va_end(args);        
 }
 
diff -r c9b0b655c052 -r 141811b3244c extras/mini-os/events.c
--- a/extras/mini-os/events.c   Thu Mar 23 19:13:12 2006
+++ b/extras/mini-os/events.c   Mon May  1 18:12:07 2006
@@ -106,6 +106,17 @@
        unbind_evtchn(port);
 }
 
+#if defined(__x86_64__)
+/* Allocate 4 pages for the irqstack */
+#define STACK_PAGES 4
+char irqstack[1024 * 4 * STACK_PAGES];
+
+static struct pda
+{
+    int irqcount;       /* offset 0 (used in x86_64.S) */
+    char *irqstackptr;  /*        8 */
+} cpu0_pda;
+#endif
 
 /*
  * Initially all events are without a handler and disabled
@@ -113,7 +124,12 @@
 void init_events(void)
 {
     int i;
-
+#if defined(__x86_64__)
+    asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
+    wrmsrl(0xc0000101, &cpu0_pda); /* 0xc0000101 is MSR_GS_BASE */
+    cpu0_pda.irqcount = -1;
+    cpu0_pda.irqstackptr = irqstack + 1024 * 4 * STACK_PAGES;
+#endif
     /* inintialise event handler */
     for ( i = 0; i < NR_EVS; i++ )
     {
diff -r c9b0b655c052 -r 141811b3244c extras/mini-os/hypervisor.c
--- a/extras/mini-os/hypervisor.c       Thu Mar 23 19:13:12 2006
+++ b/extras/mini-os/hypervisor.c       Mon May  1 18:12:07 2006
@@ -41,8 +41,8 @@
     shared_info_t *s = HYPERVISOR_shared_info;
     vcpu_info_t   *vcpu_info = &s->vcpu_info[cpu];
 
+   
     vcpu_info->evtchn_upcall_pending = 0;
-    
     /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
     l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
     while ( l1 != 0 )
diff -r c9b0b655c052 -r 141811b3244c extras/mini-os/include/mm.h
--- a/extras/mini-os/include/mm.h       Thu Mar 23 19:13:12 2006
+++ b/extras/mini-os/include/mm.h       Mon May  1 18:12:07 2006
@@ -148,7 +148,7 @@
 }
 
 #if defined(__x86_64__)
-#define VIRT_START              0xFFFFFFFF00000000UL
+#define VIRT_START              0xFFFFFFFF80000000UL
 #elif defined(__i386__)
 #define VIRT_START              0xC0000000UL
 #endif
diff -r c9b0b655c052 -r 141811b3244c extras/mini-os/include/os.h
--- a/extras/mini-os/include/os.h       Thu Mar 23 19:13:12 2006
+++ b/extras/mini-os/include/os.h       Mon May  1 18:12:07 2006
@@ -434,6 +434,13 @@
      (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
 } while(0)
 
+#define wrmsr(msr,val1,val2) \
+      __asm__ __volatile__("wrmsr" \
+                           : /* no outputs */ \
+                           : "c" (msr), "a" (val1), "d" (val2))
+
+#define wrmsrl(msr,val) wrmsr(msr,(u32)((u64)(val)),((u64)(val))>>32)
+
 
 #else /* ifdef __x86_64__ */
 #error "Unsupported architecture"
diff -r c9b0b655c052 -r 141811b3244c extras/mini-os/include/sched.h
--- a/extras/mini-os/include/sched.h    Thu Mar 23 19:13:12 2006
+++ b/extras/mini-os/include/sched.h    Mon May  1 18:12:07 2006
@@ -7,8 +7,8 @@
 {
     char *name;
     char *stack;
-    unsigned long eps;
-    unsigned long eip;
+    unsigned long sp;  /* Stack pointer */
+    unsigned long ip;  /* Instruction pointer */
     struct list_head thread_list;
     u32 flags;
 };
@@ -25,7 +25,9 @@
     struct thread **current;
 #ifdef __i386__    
     __asm__("andl %%esp,%0; ":"=r" (current) : "r" (~8191UL));
-#endif    
+#else
+    __asm__("andq %%rsp,%0; ":"=r" (current) : "r" (~8191UL));
+#endif 
     return *current;
 }
           
diff -r c9b0b655c052 -r 141811b3244c extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c   Thu Mar 23 19:13:12 2006
+++ b/extras/mini-os/kernel.c   Mon May  1 18:12:07 2006
@@ -35,6 +35,8 @@
 #include <lib.h>
 #include <sched.h>
 #include <xenbus.h>
+#include <xen/features.h>
+#include <xen/version.h>
 
 /*
  * Shared page for communicating with the hypervisor.
@@ -85,6 +87,26 @@
     test_xenbus();
 }
 
+
+u8 xen_features[XENFEAT_NR_SUBMAPS * 32];
+
+void setup_xen_features(void)
+{
+    xen_feature_info_t fi;
+    int i, j;
+
+    for (i = 0; i < XENFEAT_NR_SUBMAPS; i++) 
+    {
+        fi.submap_idx = i;
+        if (HYPERVISOR_xen_version(XENVER_get_features, &fi) < 0)
+            break;
+        
+        for (j=0; j<32; j++)
+            xen_features[i*32+j] = !!(fi.submap & 1<<j);
+    }
+}
+
+
 /*
  * INITIAL C ENTRY POINT.
  */
@@ -127,7 +149,9 @@
     printk("  flags:      0x%x\n",  (unsigned int)si->flags);
     printk("  cmd_line:   %s\n",  
            si->cmd_line ? (const char *)si->cmd_line : "NULL");
+    printk("  stack:      %p-%p\n", stack, stack + 8192);
 
+    setup_xen_features();
 
     /* Init memory management. */
     init_mm();
@@ -146,7 +170,7 @@
  
     /* Init XenBus from a separate thread */
     create_thread("init_xs", init_xs, NULL);
-    
+
     /* Everything initialised, start idle thread */
     run_idle_thread();
 }
diff -r c9b0b655c052 -r 141811b3244c extras/mini-os/minios-x86_64.lds
--- a/extras/mini-os/minios-x86_64.lds  Thu Mar 23 19:13:12 2006
+++ b/extras/mini-os/minios-x86_64.lds  Mon May  1 18:12:07 2006
@@ -3,7 +3,7 @@
 ENTRY(_start)
 SECTIONS
 {
-  . = 0xFFFFFFFF00000000;
+  . = 0xFFFFFFFF80000000;
   _text = .;                   /* Text and read-only data */
   .text : {
        *(.text)
diff -r c9b0b655c052 -r 141811b3244c extras/mini-os/sched.c
--- a/extras/mini-os/sched.c    Thu Mar 23 19:13:12 2006
+++ b/extras/mini-os/sched.c    Mon May  1 18:12:07 2006
@@ -69,17 +69,27 @@
 
 void dump_stack(struct thread *thread)
 {
-    unsigned long *bottom = (unsigned long *)thread->stack + 2048; 
-    unsigned long *pointer = (unsigned long *)thread->eps;
+    unsigned long *bottom = (unsigned long *)(thread->stack + 2*4*1024); 
+    unsigned long *pointer = (unsigned long *)thread->sp;
     int count;
+    if(thread == current)
+    {
+#ifdef __i386__    
+        asm("movl %%esp,%0"
+            : "=r"(pointer));
+#else
+        asm("movq %%rsp,%0"
+            : "=r"(pointer));
+#endif
+    }
     printk("The stack for \"%s\"\n", thread->name);
-    for(count = 0; count < 15 && pointer < bottom; count ++)
+    for(count = 0; count < 25 && pointer < bottom; count ++)
     {
         printk("[0x%lx] 0x%lx\n", pointer, *pointer);
         pointer++;
     }
     
-    if(pointer < bottom) printk("Not the whole stack printed\n");
+    if(pointer < bottom) printk(" ... continues.\n");
 }
 
 #ifdef __i386__
@@ -95,13 +105,29 @@
                          "1:\t"                                         \
                          "popl %%ebp\n\t"                               \
                          "popfl"                                        \
-                         :"=m" (prev->eps),"=m" (prev->eip),            \
+                         :"=m" (prev->sp),"=m" (prev->ip),            \
                           "=S" (esi),"=D" (edi)             \
-                         :"m" (next->eps),"m" (next->eip),              \
+                         :"m" (next->sp),"m" (next->ip),              \
                           "2" (prev), "d" (next));                      \
 } while (0)
 #elif __x86_64__
-/* FIXME */
+#define switch_threads(prev, next) do {                                 \
+    unsigned long rsi,rdi;                                              \
+    __asm__ __volatile__("pushfq\n\t"                                   \
+                         "pushq %%rbp\n\t"                              \
+                         "movq %%rsp,%0\n\t"         /* save RSP */     \
+                         "movq %4,%%rsp\n\t"        /* restore RSP */   \
+                         "movq $1f,%1\n\t"          /* save RIP */      \
+                         "pushq %5\n\t"             /* restore RIP */   \
+                         "ret\n\t"                                      \
+                         "1:\t"                                         \
+                         "popq %%rbp\n\t"                               \
+                         "popfq"                                        \
+                         :"=m" (prev->sp),"=m" (prev->ip),            \
+                          "=S" (rsi),"=D" (rdi)             \
+                         :"m" (next->sp),"m" (next->ip),              \
+                          "2" (prev), "d" (next));                      \
+} while (0)
 #endif
 
 void inline print_runqueue(void)
@@ -151,17 +177,19 @@
     local_irq_restore(flags);
     /* Interrupting the switch is equivalent to having the next thread
        inturrupted at the return instruction. And therefore at safe point. */
-/* The thread switching only works for i386 at the moment */    
-#ifdef __i386__    
     if(prev != next) switch_threads(prev, next);
-#endif    
-}
-
-
-
-void exit_thread(struct thread *thread)
+}
+
+
+/* Gets run when a new thread is scheduled the first time ever, 
+   defined in x86_[32/64].S */
+extern void thread_starter(void);
+
+
+void exit_thread(void)
 {
     unsigned long flags;
+    struct thread *thread = current;
     printk("Thread \"%s\" exited.\n", thread->name);
     local_irq_save(flags);
     /* Remove from the thread list */
@@ -174,6 +202,12 @@
     schedule();
 }
 
+/* Pushes the specified value onto the stack of the specified thread */
+static void stack_push(struct thread *thread, unsigned long value)
+{
+    thread->sp -= sizeof(unsigned long);
+    *((unsigned long *)thread->sp) = value;
+}
 
 struct thread* create_thread(char *name, void (*function)(void *), void *data)
 {
@@ -187,23 +221,17 @@
     printk("Thread \"%s\": pointer: 0x%lx, stack: 0x%lx\n", name, thread, 
             thread->stack);
     
-    thread->eps = (unsigned long)thread->stack + 4096 * 2 - 4;
+    thread->sp = (unsigned long)thread->stack + 4096 * 2;
     /* Save pointer to the thread on the stack, used by current macro */
     *((unsigned long *)thread->stack) = (unsigned long)thread;
-    *((unsigned long *)thread->eps) = (unsigned long)thread;
-    thread->eps -= 4; 
-    *((unsigned long *)thread->eps) = (unsigned long)data;
     
-    /* No return address */
-    thread->eps -= 4;
-    *((unsigned long *)thread->eps) = (unsigned long)exit_thread;
-    
-    thread->eip = (unsigned long)function;
+    stack_push(thread, (unsigned long) function);
+    stack_push(thread, (unsigned long) data);
+    thread->ip = (unsigned long) thread_starter;
      
     /* Not runable, not exited */ 
     thread->flags = 0;
     set_runnable(thread);
-    
     local_irq_save(flags);
     if(idle_thread != NULL) {
         list_add_tail(&thread->thread_list, &idle_thread->thread_list); 
@@ -213,7 +241,6 @@
         BUG();
     }
     local_irq_restore(flags);
-
     return thread;
 }
 
@@ -240,11 +267,19 @@
 void run_idle_thread(void)
 {
     /* Switch stacks and run the thread */ 
+#if defined(__i386__)
     __asm__ __volatile__("mov %0,%%esp\n\t"
                          "push %1\n\t" 
                          "ret"                                            
-                         :"=m" (idle_thread->eps)
-                         :"m" (idle_thread->eip));                          
+                         :"=m" (idle_thread->sp)
+                         :"m" (idle_thread->ip));                          
+#elif defined(__x86_64__)
+    __asm__ __volatile__("mov %0,%%rsp\n\t"
+                         "push %1\n\t" 
+                         "ret"                                            
+                         :"=m" (idle_thread->sp)
+                         :"m" (idle_thread->ip));                          
+#endif
 }
 
 
diff -r c9b0b655c052 -r 141811b3244c extras/mini-os/x86_32.S
--- a/extras/mini-os/x86_32.S   Thu Mar 23 19:13:12 2006
+++ b/extras/mini-os/x86_32.S   Mon May  1 18:12:07 2006
@@ -286,3 +286,11 @@
        pushl $0
        pushl $do_spurious_interrupt_bug
        jmp do_exception
+
+ENTRY(thread_starter)
+    popl %eax
+    popl %ebx
+    pushl %eax
+    call *%ebx
+    call exit_thread 
+    
diff -r c9b0b655c052 -r 141811b3244c extras/mini-os/x86_64.S
--- a/extras/mini-os/x86_64.S   Thu Mar 23 19:13:12 2006
+++ b/extras/mini-os/x86_64.S   Mon May  1 18:12:07 2006
@@ -1,4 +1,5 @@
 #include <os.h>
+#include <xen/features.h>
 
 .section __xen_guest
        .ascii  "GUEST_OS=Mini-OS"
@@ -65,10 +66,253 @@
 hypercall_page:
         .org 0x3000
 
+
+/* Offsets into shared_info_t. */                
+#define evtchn_upcall_pending          /* 0 */
+#define evtchn_upcall_mask             1
+
+NMI_MASK = 0x80000000
+
+#define RDI 112
+#define ORIG_RAX 120       /* + error_code */ 
+#define EFLAGS 144
+
+#define REST_SKIP 6*8                  
+.macro SAVE_REST
+       subq $REST_SKIP,%rsp
+#      CFI_ADJUST_CFA_OFFSET   REST_SKIP
+       movq %rbx,5*8(%rsp) 
+#      CFI_REL_OFFSET  rbx,5*8
+       movq %rbp,4*8(%rsp) 
+#      CFI_REL_OFFSET  rbp,4*8
+       movq %r12,3*8(%rsp) 
+#      CFI_REL_OFFSET  r12,3*8
+       movq %r13,2*8(%rsp) 
+#      CFI_REL_OFFSET  r13,2*8
+       movq %r14,1*8(%rsp) 
+#      CFI_REL_OFFSET  r14,1*8
+       movq %r15,(%rsp) 
+#      CFI_REL_OFFSET  r15,0*8
+.endm          
+
+
+.macro RESTORE_REST
+       movq (%rsp),%r15
+#      CFI_RESTORE r15
+       movq 1*8(%rsp),%r14
+#      CFI_RESTORE r14
+       movq 2*8(%rsp),%r13
+#      CFI_RESTORE r13
+       movq 3*8(%rsp),%r12
+#      CFI_RESTORE r12
+       movq 4*8(%rsp),%rbp
+#      CFI_RESTORE rbp
+       movq 5*8(%rsp),%rbx
+#      CFI_RESTORE rbx
+       addq $REST_SKIP,%rsp
+#      CFI_ADJUST_CFA_OFFSET   -(REST_SKIP)
+.endm
+
+
+#define ARG_SKIP 9*8
+.macro RESTORE_ARGS 
skiprax=0,addskip=0,skiprcx=0,skipr11=0,skipr8910=0,skiprdx=0
+       .if \skipr11
+       .else
+       movq (%rsp),%r11
+#      CFI_RESTORE r11
+       .endif
+       .if \skipr8910
+       .else
+       movq 1*8(%rsp),%r10
+#      CFI_RESTORE r10
+       movq 2*8(%rsp),%r9
+#      CFI_RESTORE r9
+       movq 3*8(%rsp),%r8
+#      CFI_RESTORE r8
+       .endif
+       .if \skiprax
+       .else
+       movq 4*8(%rsp),%rax
+#      CFI_RESTORE rax
+       .endif
+       .if \skiprcx
+       .else
+       movq 5*8(%rsp),%rcx
+#      CFI_RESTORE rcx
+       .endif
+       .if \skiprdx
+       .else
+       movq 6*8(%rsp),%rdx
+#      CFI_RESTORE rdx
+       .endif
+       movq 7*8(%rsp),%rsi
+#      CFI_RESTORE rsi
+       movq 8*8(%rsp),%rdi
+#      CFI_RESTORE rdi
+       .if ARG_SKIP+\addskip > 0
+       addq $ARG_SKIP+\addskip,%rsp
+#      CFI_ADJUST_CFA_OFFSET   -(ARG_SKIP+\addskip)
+       .endif
+.endm  
+
+
+.macro HYPERVISOR_IRET flag
+#    testb $3,1*8(%rsp)    /* Don't need to do that in Mini-os, as */
+#      jnz   2f               /* there is no userspace? */
+       testl $NMI_MASK,2*8(%rsp)
+       jnz   2f
+
+       testb $1,(xen_features+XENFEAT_supervisor_mode_kernel)
+       jnz   1f
+
+       /* Direct iret to kernel space. Correct CS and SS. */
+       orb   $3,1*8(%rsp)
+       orb   $3,4*8(%rsp)
+1:     iretq
+
+2:     /* Slow iret via hypervisor. */
+       andl  $~NMI_MASK, 16(%rsp)
+       pushq $\flag
+       jmp  hypercall_page + (__HYPERVISOR_iret * 32)
+.endm
+
+/*
+ * Exception entry point. This expects an error code/orig_rax on the stack
+ * and the exception handler in %rax.  
+ */                                            
+ENTRY(error_entry)
+#      _frame RDI
+       /* rdi slot contains rax, oldrax contains error code */
+       cld     
+       subq  $14*8,%rsp
+#      CFI_ADJUST_CFA_OFFSET   (14*8)
+       movq %rsi,13*8(%rsp)
+#      CFI_REL_OFFSET  rsi,RSI
+       movq 14*8(%rsp),%rsi    /* load rax from rdi slot */
+       movq %rdx,12*8(%rsp)
+#      CFI_REL_OFFSET  rdx,RDX
+       movq %rcx,11*8(%rsp)
+#      CFI_REL_OFFSET  rcx,RCX
+       movq %rsi,10*8(%rsp)    /* store rax */ 
+#      CFI_REL_OFFSET  rax,RAX
+       movq %r8, 9*8(%rsp)
+#      CFI_REL_OFFSET  r8,R8
+       movq %r9, 8*8(%rsp)
+#      CFI_REL_OFFSET  r9,R9
+       movq %r10,7*8(%rsp)
+#      CFI_REL_OFFSET  r10,R10
+       movq %r11,6*8(%rsp)
+#      CFI_REL_OFFSET  r11,R11
+       movq %rbx,5*8(%rsp) 
+#      CFI_REL_OFFSET  rbx,RBX
+       movq %rbp,4*8(%rsp) 
+#      CFI_REL_OFFSET  rbp,RBP
+       movq %r12,3*8(%rsp) 
+#      CFI_REL_OFFSET  r12,R12
+       movq %r13,2*8(%rsp) 
+#      CFI_REL_OFFSET  r13,R13
+       movq %r14,1*8(%rsp) 
+#      CFI_REL_OFFSET  r14,R14
+       movq %r15,(%rsp) 
+#      CFI_REL_OFFSET  r15,R15
+#if 0        
+       cmpl $__KERNEL_CS,CS(%rsp)
+       je  error_kernelspace
+#endif        
+error_call_handler:
+       movq %rdi, RDI(%rsp)            
+       movq %rsp,%rdi
+       movq ORIG_RAX(%rsp),%rsi        # get error code 
+       movq $-1,ORIG_RAX(%rsp)
+       call *%rax
+
+.macro zeroentry sym
+#      INTR_FRAME
+    movq (%rsp),%rcx
+    movq 8(%rsp),%r11
+    addq $0x10,%rsp /* skip rcx and r11 */
+       pushq $0        /* push error code/oldrax */ 
+#      CFI_ADJUST_CFA_OFFSET 8
+       pushq %rax      /* push real oldrax to the rdi slot */ 
+#      CFI_ADJUST_CFA_OFFSET 8
+       leaq  \sym(%rip),%rax
+       jmp error_entry
+#      CFI_ENDPROC
+.endm  
+
+
+
+#define XEN_GET_VCPU_INFO(reg) movq HYPERVISOR_shared_info,reg
+#define XEN_PUT_VCPU_INFO(reg)
+#define XEN_PUT_VCPU_INFO_fixup
+#define XEN_LOCKED_BLOCK_EVENTS(reg)   movb $1,evtchn_upcall_mask(reg)
+#define XEN_LOCKED_UNBLOCK_EVENTS(reg) movb $0,evtchn_upcall_mask(reg)
+#define XEN_TEST_PENDING(reg)  testb $0xFF,evtchn_upcall_pending(reg)
+
+#define XEN_BLOCK_EVENTS(reg)  XEN_GET_VCPU_INFO(reg)                  ; \
+                                       XEN_LOCKED_BLOCK_EVENTS(reg)    ; \
+                                           XEN_PUT_VCPU_INFO(reg)
+
+#define XEN_UNBLOCK_EVENTS(reg)        XEN_GET_VCPU_INFO(reg)                  
; \
+                                               XEN_LOCKED_UNBLOCK_EVENTS(reg)  
; \
+                                       XEN_PUT_VCPU_INFO(reg)
+
+
+
 ENTRY(hypervisor_callback)
-        popq  %rcx
-        popq  %r11
-        iretq
+    zeroentry hypervisor_callback2
+
+ENTRY(hypervisor_callback2)
+        movq %rdi, %rsp 
+11:     movq %gs:8,%rax
+        incl %gs:0
+        cmovzq %rax,%rsp
+        pushq %rdi
+        call do_hypervisor_callback 
+        popq %rsp
+        decl %gs:0
+        jmp error_exit
+
+#        ALIGN
+restore_all_enable_events:  
+       XEN_UNBLOCK_EVENTS(%rsi)        # %rsi is already set up...
+
+scrit: /**** START OF CRITICAL REGION ****/
+       XEN_TEST_PENDING(%rsi)
+       jnz  14f                        # process more events if necessary...
+       XEN_PUT_VCPU_INFO(%rsi)
+        RESTORE_ARGS 0,8,0
+        HYPERVISOR_IRET 0
+        
+14:    XEN_LOCKED_BLOCK_EVENTS(%rsi)
+       XEN_PUT_VCPU_INFO(%rsi)
+       SAVE_REST
+        movq %rsp,%rdi                  # set the argument again
+       jmp  11b
+ecrit:  /**** END OF CRITICAL REGION ****/
+
+
+retint_kernel:
+retint_restore_args:
+       movl EFLAGS-REST_SKIP(%rsp), %eax
+       shr $9, %eax                    # EAX[0] == IRET_EFLAGS.IF
+       XEN_GET_VCPU_INFO(%rsi)
+       andb evtchn_upcall_mask(%rsi),%al
+       andb $1,%al                     # EAX[0] == IRET_EFLAGS.IF & event_mask
+       jnz restore_all_enable_events   #        != 0 => enable event delivery
+       XEN_PUT_VCPU_INFO(%rsi)
+               
+       RESTORE_ARGS 0,8,0
+       HYPERVISOR_IRET 0
+
+
+error_exit:            
+       RESTORE_REST
+/*     cli */
+       XEN_BLOCK_EVENTS(%rsi)          
+       jmp retint_kernel
+
+
 
 ENTRY(failsafe_callback)
         popq  %rcx
@@ -228,3 +472,12 @@
         .quad do_alignment_check
         .quad do_machine_check
         .quad do_simd_coprocessor_error
+
+
+ENTRY(thread_starter)
+        popq %rdi
+        popq %rbx
+        call *%rbx
+        call exit_thread 
+        
+
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] 64bit arch patch for Mini-OS, Grzegorz Milos <=