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-changelog

[Xen-changelog] Fix x86/64 version of Mini-OS. It encompasses the follow

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Fix x86/64 version of Mini-OS. It encompasses the following:
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 02 May 2006 09:50:08 +0000
Delivery-date: Tue, 02 May 2006 02:51:19 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID f6507937cb7c95fbcf662b1c23e742ce9c076753
# Parent  dc3c59367403959b0ae135966c1acfe9678a8f0d
Fix x86/64 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>

diff -r dc3c59367403 -r f6507937cb7c extras/mini-os/console/console.c
--- a/extras/mini-os/console/console.c  Mon May 01 17:44:51 2006 +0100
+++ b/extras/mini-os/console/console.c  Tue May 02 09:12:39 2006 +0100
@@ -128,7 +128,7 @@ void printk(const char *fmt, ...)
 {
     va_list       args;
     va_start(args, fmt);
-    print(0, fmt, args);
+    print(1, fmt, args);
     va_end(args);        
 }
 
diff -r dc3c59367403 -r f6507937cb7c extras/mini-os/events.c
--- a/extras/mini-os/events.c   Mon May 01 17:44:51 2006 +0100
+++ b/extras/mini-os/events.c   Tue May 02 09:12:39 2006 +0100
@@ -106,6 +106,17 @@ void unbind_virq( u32 port )
        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)
 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 dc3c59367403 -r f6507937cb7c extras/mini-os/hypervisor.c
--- a/extras/mini-os/hypervisor.c       Mon May 01 17:44:51 2006 +0100
+++ b/extras/mini-os/hypervisor.c       Tue May 02 09:12:39 2006 +0100
@@ -41,8 +41,8 @@ void do_hypervisor_callback(struct pt_re
     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 dc3c59367403 -r f6507937cb7c extras/mini-os/include/mm.h
--- a/extras/mini-os/include/mm.h       Mon May 01 17:44:51 2006 +0100
+++ b/extras/mini-os/include/mm.h       Tue May 02 09:12:39 2006 +0100
@@ -148,7 +148,7 @@ static __inline__ unsigned long machine_
 }
 
 #if defined(__x86_64__)
-#define VIRT_START              0xFFFFFFFF00000000UL
+#define VIRT_START              0xFFFFFFFF80000000UL
 #elif defined(__i386__)
 #define VIRT_START              0xC0000000UL
 #endif
diff -r dc3c59367403 -r f6507937cb7c extras/mini-os/include/os.h
--- a/extras/mini-os/include/os.h       Mon May 01 17:44:51 2006 +0100
+++ b/extras/mini-os/include/os.h       Tue May 02 09:12:39 2006 +0100
@@ -434,6 +434,13 @@ static __inline__ unsigned long __ffs(un
      (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 dc3c59367403 -r f6507937cb7c extras/mini-os/include/sched.h
--- a/extras/mini-os/include/sched.h    Mon May 01 17:44:51 2006 +0100
+++ b/extras/mini-os/include/sched.h    Tue May 02 09:12:39 2006 +0100
@@ -7,8 +7,8 @@ struct thread
 {
     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 @@ static inline struct thread* get_current
     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 dc3c59367403 -r f6507937cb7c extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c   Mon May 01 17:44:51 2006 +0100
+++ b/extras/mini-os/kernel.c   Tue May 02 09:12:39 2006 +0100
@@ -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.
@@ -84,6 +86,26 @@ static void init_xs(void *ign)
 
     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 @@ void start_kernel(start_info_t *si)
     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 @@ void start_kernel(start_info_t *si)
  
     /* Init XenBus from a separate thread */
     create_thread("init_xs", init_xs, NULL);
-    
+
     /* Everything initialised, start idle thread */
     run_idle_thread();
 }
diff -r dc3c59367403 -r f6507937cb7c extras/mini-os/minios-x86_64.lds
--- a/extras/mini-os/minios-x86_64.lds  Mon May 01 17:44:51 2006 +0100
+++ b/extras/mini-os/minios-x86_64.lds  Tue May 02 09:12:39 2006 +0100
@@ -3,7 +3,7 @@ ENTRY(_start)
 ENTRY(_start)
 SECTIONS
 {
-  . = 0xFFFFFFFF00000000;
+  . = 0xFFFFFFFF80000000;
   _text = .;                   /* Text and read-only data */
   .text : {
        *(.text)
diff -r dc3c59367403 -r f6507937cb7c extras/mini-os/sched.c
--- a/extras/mini-os/sched.c    Mon May 01 17:44:51 2006 +0100
+++ b/extras/mini-os/sched.c    Tue May 02 09:12:39 2006 +0100
@@ -69,17 +69,27 @@ void idle_thread_fn(void *unused);
 
 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 @@ void dump_stack(struct thread *thread)
                          "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 @@ void schedule(void)
     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 @@ void exit_thread(struct thread *thread)
     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 @@ struct thread* create_thread(char *name,
     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 @@ struct thread* create_thread(char *name,
         BUG();
     }
     local_irq_restore(flags);
-
     return thread;
 }
 
@@ -240,11 +267,19 @@ void run_idle_thread(void)
 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 dc3c59367403 -r f6507937cb7c extras/mini-os/x86_32.S
--- a/extras/mini-os/x86_32.S   Mon May 01 17:44:51 2006 +0100
+++ b/extras/mini-os/x86_32.S   Tue May 02 09:12:39 2006 +0100
@@ -286,3 +286,11 @@ ENTRY(spurious_interrupt_bug)
        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 dc3c59367403 -r f6507937cb7c extras/mini-os/x86_64.S
--- a/extras/mini-os/x86_64.S   Mon May 01 17:44:51 2006 +0100
+++ b/extras/mini-os/x86_64.S   Tue May 02 09:12:39 2006 +0100
@@ -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:
 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 @@ ENTRY(exception_table)
         .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-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Fix x86/64 version of Mini-OS. It encompasses the following:, Xen patchbot -unstable <=