[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [IA64] Optimize VTI domain hypercall path



# HG changeset patch
# User awilliam@xxxxxxxxxxxx
# Date 1170359614 25200
# Node ID 18a8e34e1211dca6c1f954f776ba6ae728f8731d
# Parent  ef646312685f8dfadd9edcaf594da7b99f3552ec
[IA64] Optimize VTI domain hypercall path

Signed-off-by: Anthony Xu <anthony.xu@xxxxxxxxx>
---
 xen/arch/ia64/vmx/vmx_entry.S    |  192 ++++++++++++++++++++++++-
 xen/arch/ia64/vmx/vmx_ivt.S      |  293 ++++++++++++++++++++++++++++++++++++++-
 xen/arch/ia64/vmx/vmx_minstate.h |    1 
 xen/arch/ia64/vmx/vmx_process.c  |    2 
 4 files changed, 474 insertions(+), 14 deletions(-)

diff -r ef646312685f -r 18a8e34e1211 xen/arch/ia64/vmx/vmx_entry.S
--- a/xen/arch/ia64/vmx/vmx_entry.S     Wed Jan 31 10:59:56 2007 -0700
+++ b/xen/arch/ia64/vmx/vmx_entry.S     Thu Feb 01 12:53:34 2007 -0700
@@ -190,12 +190,8 @@ GLOBAL_ENTRY(ia64_leave_hypervisor)
     PT_REGS_UNWIND_INFO(0)
     rsm psr.i
     ;;
-    alloc loc0=ar.pfs,0,1,1,0
-    ;;
-    adds out0=16,r12
     br.call.sptk.many b0=leave_hypervisor_tail
     ;;
-    mov ar.pfs=loc0
     adds r20=PT(PR)+16,r12
     adds r8=PT(EML_UNAT)+16,r12
     ;;
@@ -302,11 +298,9 @@ GLOBAL_ENTRY(ia64_leave_hypervisor)
     ;;
     mov ar.fpsr=r19
     mov ar.ccv=r18
-    ;;
-//rbs_switch
-    
     shr.u r18=r20,16
     ;;
+vmx_rbs_switch:    
     movl r19= THIS_CPU(ia64_phys_stacked_size_p8)
     ;;
     ld4 r19=[r19]
@@ -368,7 +362,7 @@ vmx_rse_clear_invalid:
     ;;
     mov cr.ipsr=r31
     mov cr.iip=r30
-    mov cr.ifs=r29
+(pNonSys) mov cr.ifs=r29
     mov ar.pfs=r27
     adds r18=IA64_VPD_BASE_OFFSET,r21
     ;;
@@ -425,6 +419,188 @@ END(ia64_vmm_entry)
 END(ia64_vmm_entry)
 
 
+
+/*
+ * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't
+ *  need to switch to bank 0 and doesn't restore the scratch registers.
+ *  To avoid leaking kernel bits, the scratch registers are set to
+ *  the following known-to-be-safe values:
+ *
+ *        r1: restored (global pointer)
+ *        r2: cleared
+ *        r3: 1 (when returning to user-level)
+ *        r8-r11: restored (syscall return value(s))
+ *       r12: restored (user-level stack pointer)
+ *       r13: restored (user-level thread pointer)
+ *       r14: set to __kernel_syscall_via_epc
+ *       r15: restored (syscall #)
+ *       r16-r17: cleared
+ *       r18: user-level b6
+ *       r19: cleared
+ *       r20: user-level ar.fpsr
+ *       r21: user-level b0
+ *       r22: cleared
+ *       r23: user-level ar.bspstore
+ *       r24: user-level ar.rnat
+ *       r25: user-level ar.unat
+ *       r26: user-level ar.pfs
+ *       r27: user-level ar.rsc
+ *       r28: user-level ip
+ *       r29: user-level psr
+ *       r30: user-level cfm
+ *       r31: user-level pr
+ *        f6-f11: cleared
+ *        pr: restored (user-level pr)
+ *        b0: restored (user-level rp)
+ *        b6: restored
+ *        b7: set to __kernel_syscall_via_epc
+ *        ar.unat: restored (user-level ar.unat)
+ *        ar.pfs: restored (user-level ar.pfs)
+ *        ar.rsc: restored (user-level ar.rsc)
+ *        ar.rnat: restored (user-level ar.rnat)
+ *        ar.bspstore: restored (user-level ar.bspstore)
+ *        ar.fpsr: restored (user-level ar.fpsr)
+ *        ar.ccv: cleared
+ *        ar.csd: cleared
+ *        ar.ssd: cleared
+ */
+GLOBAL_ENTRY(ia64_leave_hypercall)
+    PT_REGS_UNWIND_INFO(0)
+    /*
+     * work.need_resched etc. mustn't get changed by this CPU before it 
returns to
+     * user- or fsys-mode, hence we disable interrupts early on.
+     *
+     * p6 controls whether current_thread_info()->flags needs to be check for
+     * extra work.  We always check for extra work when returning to 
user-level.
+     * With CONFIG_PREEMPT, we also check for extra work when the preempt_count
+     * is 0.  After extra work processing has been completed, execution
+     * resumes at .work_processed_syscall with p6 set to 1 if the 
extra-work-check
+     * needs to be redone.
+     */
+(pUStk) rsm psr.i
+    cmp.eq pLvSys,p0=r0,r0             // pLvSys=1: leave from syscall
+(pUStk) cmp.eq.unc p6,p0=r0,r0         // p6 <- pUStk
+    ;;
+    br.call.sptk.many b0=leave_hypervisor_tail
+.work_processed_syscall:
+    //clean up bank 1 registers
+    mov r16=r0
+    mov r17=r0
+    mov r18=r0
+    mov r19=r0
+    mov r20=r0
+    mov r21=r0
+    mov r22=r0
+    mov r23=r0
+    mov r24=r0
+    mov r25=r0
+    mov r26=r0
+    mov r27=r0
+    mov r28=r0
+    mov r29=r0
+    mov r30=r0
+    mov r31=r0
+    bsw.0
+    ;;
+    adds r2=PT(LOADRS)+16,r12
+    adds r3=PT(AR_BSPSTORE)+16,r12
+#ifndef XEN
+    adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
+    ;;
+(p6) ld4 r31=[r18]                             // load 
current_thread_info()->flags
+#endif
+    ;;
+    ld8 r20=[r2],PT(B6)-PT(LOADRS)             // load ar.rsc value for 
"loadrs"
+    nop.i 0
+    ;;
+//  mov r16=ar.bsp                             // M2  get existing backing 
store pointer
+    ld8 r18=[r2],PT(R9)-PT(B6)         // load b6
+#ifndef XEN
+(p6)    and r15=TIF_WORK_MASK,r31              // any work other than 
TIF_SYSCALL_TRACE?
+#endif
+    ;;
+    ld8 r24=[r3],PT(R11)-PT(AR_BSPSTORE)       // load ar.bspstore (may be 
garbage)
+#ifndef XEN
+(p6)    cmp4.ne.unc p6,p0=r15, r0              // any special work pending?
+(p6)    br.cond.spnt .work_pending_syscall
+#endif
+    ;;
+    // start restoring the state saved on the kernel stack (struct pt_regs):
+    ld8 r9=[r2],PT(CR_IPSR)-PT(R9)
+    ld8 r11=[r3],PT(CR_IIP)-PT(R11)
+//(pNonSys) break 0            //      bug check: we shouldn't be here if 
pNonSys is TRUE!
+    ;;
+    invala                     // M0|1 invalidate ALAT
+    rsm psr.i | psr.ic // M2   turn off interrupts and interruption collection
+    cmp.eq p9,p0=r0,r0 // A    set p9 to indicate that we should restore cr.ifs
+
+    ld8 r31=[r2],32            // M0|1 load cr.ipsr
+    ld8 r30=[r3],16            // M0|1 load cr.iip
+    ;;
+//  ld8 r29=[r2],16            // M0|1 load cr.ifs
+    ld8 r28=[r3],16            // M0|1 load ar.unat
+//(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
+    ;;
+    ld8 r27=[r2],PT(B0)-PT(AR_PFS)     // M0|1 load ar.pfs
+(pKStk) mov r22=psr                    // M2   read PSR now that interrupts 
are disabled
+    nop 0
+    ;;
+    ld8 r22=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0
+    ld8 r26=[r3],PT(PR)-PT(AR_RSC)     // M0|1 load ar.rsc
+    mov f6=f0                  // F    clear f6
+    ;;
+    ld8 r25=[r2],PT(AR_FPSR)-PT(AR_RNAT)       // M0|1 load ar.rnat (may be 
garbage)
+    ld8 r23=[r3],PT(R1)-PT(PR)         // M0|1 load predicates
+    mov f7=f0                          // F    clear f7
+    ;;
+    ld8 r20=[r2],PT(R12)-PT(AR_FPSR)   // M0|1 load ar.fpsr
+    ld8.fill r1=[r3],16                        // M0|1 load r1
+//(pUStk) mov r17=1                            // A
+    ;;
+//(pUStk) st1 [r14]=r17                                // M2|3
+    ld8.fill r13=[r3],16                       // M0|1
+    mov f8=f0                          // F    clear f8
+    ;;
+    ld8.fill r12=[r2]                  // M0|1 restore r12 (sp)
+#ifdef XEN    
+    ld8.fill r2=[r3]                   // M0|1
+#else    
+    ld8.fill r15=[r3]                  // M0|1 restore r15
+#endif    
+    mov b6=r18                         // I0   restore b6
+    mov ar.fpsr=r20
+//  addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A
+    mov f9=f0                                  // F    clear f9
+//(pKStk) br.cond.dpnt.many skip_rbs_switch            // B
+
+//  srlz.d                             // M0   ensure interruption collection 
is off (for cover)
+//  shr.u r18=r19,16           // I0|1 get byte size of existing "dirty" 
partition
+    cover                              // B    add current frame into dirty 
partition & set cr.ifs
+    ;;
+//(pUStk) ld4 r17=[r17]                        // M0|1 r17 = 
cpu_data->phys_stacked_size_p8
+    mov r19=ar.bsp                     // M2   get new backing store pointer
+    adds r18=IA64_RBS_OFFSET, r21
+    ;;
+    sub r18=r19,r18     // get byte size of existing "dirty" partition
+    ;;
+    shl r20=r18,16     // set rsc.load 
+    mov f10=f0                 // F    clear f10
+#ifdef XEN
+    mov r14=r0
+#else
+    movl r14=__kernel_syscall_via_epc // X
+#endif
+    ;;
+    mov.m ar.csd=r0                    // M2   clear ar.csd
+    mov.m ar.ccv=r0                    // M2   clear ar.ccv
+    mov b7=r14                 // I0   clear b7 (hint with 
__kernel_syscall_via_epc)
+
+    mov.m ar.ssd=r0                    // M2   clear ar.ssd
+    mov f11=f0                 // F    clear f11
+    br.cond.sptk.many vmx_rbs_switch   // B
+END(ia64_leave_hypercall)
+
+
 /*
  * in0: new rr7
  * in1: virtual address of shared_info
diff -r ef646312685f -r 18a8e34e1211 xen/arch/ia64/vmx/vmx_ivt.S
--- a/xen/arch/ia64/vmx/vmx_ivt.S       Wed Jan 31 10:59:56 2007 -0700
+++ b/xen/arch/ia64/vmx/vmx_ivt.S       Thu Feb 01 12:53:34 2007 -0700
@@ -59,6 +59,14 @@
 #include <asm/unistd.h>
 #include <asm/vhpt.h>
 #include <asm/virt_event.h>
+#include <xen/errno.h>
+
+#if 1
+# define PSR_DEFAULT_BITS   psr.ac
+#else
+# define PSR_DEFAULT_BITS   0
+#endif
+
 
 #ifdef VTI_DEBUG
   /*
@@ -431,17 +439,152 @@ ENTRY(vmx_break_fault)
     VMX_DBG_FAULT(11)
     mov r31=pr
     mov r19=11
-    mov r30=cr.iim
+    mov r17=cr.iim
     ;;
 #ifdef VTI_DEBUG
     // break 0 is already handled in vmx_ia64_handle_break.
-    cmp.eq p6,p7=r30,r0
+    cmp.eq p6,p7=r17,r0
     (p6) br.sptk vmx_fault_11
     ;;
 #endif
-    br.sptk.many vmx_dispatch_break_fault
-    ;;
-    VMX_FAULT(11);
+    mov r29=cr.ipsr
+    adds r22=IA64_VCPU_BREAKIMM_OFFSET, r21
+    ;;
+    ld4 r22=[r22]
+    extr.u r24=r29,IA64_PSR_CPL0_BIT,2
+    cmp.eq p0,p6=r0,r0
+    ;;
+    cmp.ne.or p6,p0=r22,r17
+    cmp.ne.or p6,p0=r0,r24
+(p6) br.sptk.many vmx_dispatch_break_fault
+    ;;
+   /*
+    * The streamlined system call entry/exit paths only save/restore the 
initial part
+    * of pt_regs.  This implies that the callers of system-calls must adhere 
to the
+    * normal procedure calling conventions.
+    *
+    *   Registers to be saved & restored:
+    *   CR registers: cr.ipsr, cr.iip, cr.ifs
+    *   AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore, ar.fpsr
+    *   others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15
+    *   Registers to be restored only:
+    *   r8-r11: output value from the system call.
+    *
+    * During system call exit, scratch registers (including r15) are 
modified/cleared
+    * to prevent leaking bits from kernel to user level.
+    */
+   
+//  mov.m r16=IA64_KR(CURRENT)         // M2 r16 <- current task (12 cyc)
+    mov r14=r21
+    bsw.1                                      // B (6 cyc) regs are saved, 
switch to bank 1
+    ;;   
+    mov r29=cr.ipsr                            // M2 (12 cyc)
+    mov r31=pr                         // I0 (2 cyc)
+    mov r16=r14
+    mov r15=r2
+
+    mov r17=cr.iim                             // M2 (2 cyc)
+    mov.m r27=ar.rsc                   // M2 (12 cyc)
+//  mov r18=__IA64_BREAK_SYSCALL               // A
+
+    mov.m ar.rsc=0                             // M2
+    mov.m r21=ar.fpsr                  // M2 (12 cyc)
+    mov r19=b6                         // I0 (2 cyc)
+    ;;
+    mov.m r23=ar.bspstore                      // M2 (12 cyc)
+    mov.m r24=ar.rnat                  // M2 (5 cyc)
+    mov.i r26=ar.pfs                   // I0 (2 cyc)
+
+    invala                                     // M0|1
+    nop.m 0                                    // M
+    mov r20=r1                         // A                    save r1
+
+    nop.m 0
+//  movl r30=sys_call_table                    // X
+    movl r30=ia64_hypercall_table                      // X
+
+    mov r28=cr.iip                             // M2 (2 cyc)
+//  cmp.eq p0,p7=r18,r17                       // I0 is this a system call?
+//(p7)  br.cond.spnt non_syscall               // B  no ->
+   //
+   // From this point on, we are definitely on the syscall-path
+   // and we can use (non-banked) scratch registers.
+   //
+///////////////////////////////////////////////////////////////////////
+    mov r1=r16                         // A    move task-pointer to 
"addl"-addressable reg
+    mov r2=r16                         // A    setup r2 for ia64_syscall_setup
+//  add r9=TI_FLAGS+IA64_TASK_SIZE,r16 // A    r9 = 
&current_thread_info()->flags
+
+//  adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
+//  adds r15=-1024,r15                 // A    subtract 1024 from syscall 
number
+//  mov r3=NR_syscalls - 1
+    mov r3=NR_hypercalls - 1
+    ;;
+//  ld1.bias r17=[r16]                 // M0|1 r17 = current->thread.on_ustack 
flag
+//  ld4 r9=[r9]                                // M0|1 r9 = 
current_thread_info()->flags
+    mov r9=r0               // force flags = 0
+    extr.u r8=r29,41,2                 // I0   extract ei field from cr.ipsr
+
+    shladd r30=r15,3,r30                       // A    r30 = sys_call_table + 
8*(syscall-1024)
+    addl r22=IA64_RBS_OFFSET,r1                // A    compute base of RBS
+    cmp.leu p6,p7=r15,r3                       // A    syscall number in range?
+    ;;
+
+    lfetch.fault.excl.nt1 [r22]                // M0|1 prefetch RBS
+(p6) ld8 r30=[r30]                             // M0|1 load address of syscall 
entry point
+    tnat.nz.or p7,p0=r15                       // I0   is syscall nr a NaT?
+
+    mov.m ar.bspstore=r22                      // M2   switch to kernel RBS
+    cmp.eq p8,p9=2,r8                  // A    isr.ei==2?
+    ;;
+
+(p8) mov r8=0                          // A    clear ei to 0
+//(p7)  movl r30=sys_ni_syscall                        // X
+(p7) movl r30=do_ni_hypercall                  // X
+
+(p8) adds r28=16,r28                           // A    switch cr.iip to next 
bundle
+(p9) adds r8=1,r8                              // A    increment ei to next 
slot
+    nop.i 0
+    ;;
+
+    mov.m r25=ar.unat                  // M2 (5 cyc)
+    dep r29=r8,r29,41,2                        // I0   insert new ei into 
cr.ipsr
+//  adds r15=1024,r15                  // A    restore original syscall number
+   //
+   // If any of the above loads miss in L1D, we'll stall here until
+   // the data arrives.
+   //
+///////////////////////////////////////////////////////////////////////
+//    st1 [r16]=r0                             // M2|3 clear 
current->thread.on_ustack flag
+    mov b6=r30                         // I0   setup syscall handler branch 
reg early
+    cmp.ne pKStk,pUStk=r0,r0           // A    were we on kernel stacks 
already?
+
+//  and r9=_TIF_SYSCALL_TRACEAUDIT,r9  // A    mask trace or audit
+    mov r18=ar.bsp                             // M2 (12 cyc)
+   ;;
+(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A    compute base of 
memory stack
+//  cmp.eq p14,p0=r9,r0                        // A    are syscalls being 
traced/audited?
+//    br.call.sptk.many b7=ia64_syscall_setup  // B
+    br.call.sptk.many b7=ia64_hypercall_setup  // B
+1:
+    mov ar.rsc=0x3                             // M2   set eager mode, pl 0, 
LE, loadrs=0
+//    nop 0
+//    bsw.1                                    // B (6 cyc) regs are saved, 
switch to bank 1
+    ;;
+    ssm psr.ic | PSR_DEFAULT_BITS              // M2   now it's safe to 
re-enable intr.-collection
+//    movl r3=ia64_ret_from_syscall            // X
+    movl r3=ia64_leave_hypercall               // X
+    ;;
+
+    srlz.i                                     // M0   ensure interruption 
collection is on
+    mov rp=r3                          // I0   set the real return addr
+    //(p10) br.cond.spnt.many ia64_ret_from_syscall    // B    return if bad 
call-frame or r15 is a NaT
+    (p15)   ssm psr.i                          // M2   restore psr.i
+    //(p14) br.call.sptk.many b6=b6                    // B    invoke 
syscall-handker (ignore return addr)
+    br.call.sptk.many b6=b6                    // B    invoke syscall-handker 
(ignore return addr)
+//  br.cond.spnt.many ia64_trace_syscall       // B    do syscall-tracing 
thingamagic
+   ;;
+   VMX_FAULT(11)
 END(vmx_break_fault)
 
     .org vmx_ia64_ivt+0x3000
@@ -613,6 +756,146 @@ END(vmx_virtual_exirq)
 // 0x3800 Entry 14 (size 64 bundles) Reserved
     VMX_DBG_FAULT(14)
     VMX_FAULT(14)
+    // this code segment is from 2.6.16.13
+    
+    /*
+     * There is no particular reason for this code to be here, other than that
+     * there happens to be space here that would go unused otherwise.  If this
+     * fault ever gets "unreserved", simply moved the following code to a more
+     * suitable spot...
+     *
+     * ia64_syscall_setup() is a separate subroutine so that it can
+     * allocate stacked registers so it can safely demine any
+     * potential NaT values from the input registers.
+     *
+     * On entry:
+     * - executing on bank 0 or bank 1 register set (doesn't matter)
+     * -  r1: stack pointer
+     * -  r2: current task pointer
+     * -  r3: preserved
+     * - r11: original contents (saved ar.pfs to be saved)
+     * - r12: original contents (sp to be saved)
+     * - r13: original contents (tp to be saved)
+     * - r15: original contents (syscall # to be saved)
+     * - r18: saved bsp (after switching to kernel stack)
+     * - r19: saved b6
+     * - r20: saved r1 (gp)
+     * - r21: saved ar.fpsr
+     * - r22: kernel's register backing store base (krbs_base)
+     * - r23: saved ar.bspstore
+     * - r24: saved ar.rnat
+     * - r25: saved ar.unat
+     * - r26: saved ar.pfs
+     * - r27: saved ar.rsc
+     * - r28: saved cr.iip
+     * - r29: saved cr.ipsr
+     * - r31: saved pr
+     * -  b0: original contents (to be saved)
+     * On exit:
+     * -  p10: TRUE if syscall is invoked with more than 8 out
+     *         registers or r15's Nat is true
+     * -  r1: kernel's gp
+     * -  r3: preserved (same as on entry)
+     * -  r8: -EINVAL if p10 is true
+     * - r12: points to kernel stack
+     * - r13: points to current task
+     * - r14: preserved (same as on entry)
+     * - p13: preserved
+     * - p15: TRUE if interrupts need to be re-enabled
+     * - ar.fpsr: set to kernel settings
+     * -  b6: preserved (same as on entry)
+     */
+GLOBAL_ENTRY(ia64_hypercall_setup)
+#if PT(B6) != 0
+# error This code assumes that b6 is the first field in pt_regs.
+#endif
+    st8 [r1]=r19                               // save b6
+    add r16=PT(CR_IPSR),r1                     // initialize first base pointer
+    add r17=PT(R11),r1                 // initialize second base pointer
+    ;;
+    alloc r19=ar.pfs,8,0,0,0           // ensure in0-in7 are writable
+    st8 [r16]=r29,PT(AR_PFS)-PT(CR_IPSR)       // save cr.ipsr
+    tnat.nz p8,p0=in0
+
+    st8.spill [r17]=r11,PT(CR_IIP)-PT(R11)     // save r11
+    tnat.nz p9,p0=in1
+(pKStk) mov r18=r0                             // make sure r18 isn't NaT
+    ;;
+
+    st8 [r16]=r26,PT(CR_IFS)-PT(AR_PFS)        // save ar.pfs
+    st8 [r17]=r28,PT(AR_UNAT)-PT(CR_IIP)       // save cr.iip
+    mov r28=b0                         // save b0 (2 cyc)
+    ;;
+
+    st8 [r17]=r25,PT(AR_RSC)-PT(AR_UNAT)       // save ar.unat
+    dep r19=0,r19,38,26                        // clear all bits but 0..37 [I0]
+(p8)    mov in0=-1
+    ;;
+
+    st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS)       // store ar.pfs.pfm in cr.ifs
+    extr.u r11=r19,7,7 // I0           // get sol of ar.pfs
+    and r8=0x7f,r19            // A            // get sof of ar.pfs
+
+    st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc
+    tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0
+(p9)    mov in1=-1
+    ;;
+
+(pUStk) sub r18=r18,r22                                // r18=RSE.ndirty*8
+    tnat.nz p10,p0=in2
+    add r11=8,r11
+    ;;
+(pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16                // skip over ar_rnat 
field
+(pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17    // skip over ar_bspstore field
+    tnat.nz p11,p0=in3
+    ;;
+(p10)   mov in2=-1
+    tnat.nz p12,p0=in4                         // [I0]
+(p11)   mov in3=-1
+    ;;
+(pUStk) st8 [r16]=r24,PT(PR)-PT(AR_RNAT)       // save ar.rnat
+(pUStk) st8 [r17]=r23,PT(B0)-PT(AR_BSPSTORE)   // save ar.bspstore
+    shl r18=r18,16                             // compute ar.rsc to be used 
for "loadrs"
+    ;;
+    st8 [r16]=r31,PT(LOADRS)-PT(PR)            // save predicates
+    st8 [r17]=r28,PT(R1)-PT(B0)                // save b0
+    tnat.nz p13,p0=in5                         // [I0]
+    ;;
+    st8 [r16]=r18,PT(R12)-PT(LOADRS)   // save ar.rsc value for "loadrs"
+    st8.spill [r17]=r20,PT(R13)-PT(R1) // save original r1
+(p12)   mov in4=-1
+    ;;
+
+.mem.offset 0,0; st8.spill [r16]=r12,PT(AR_FPSR)-PT(R12)       // save r12
+.mem.offset 8,0; st8.spill [r17]=r13,PT(R15)-PT(R13)           // save r13
+(p13)   mov in5=-1
+    ;;
+    st8 [r16]=r21,PT(R8)-PT(AR_FPSR)   // save ar.fpsr
+    tnat.nz p13,p0=in6
+    cmp.lt p10,p9=r11,r8       // frame size can't be more than local+8
+    ;;
+    mov r8=1
+(p9)    tnat.nz p10,p0=r15
+    adds r12=-16,r1            // switch to kernel memory stack (with 16 bytes 
of scratch)
+
+    st8.spill [r17]=r15                        // save r15
+    tnat.nz p8,p0=in7
+    nop.i 0
+
+    mov r13=r2                         // establish `current'
+    movl r1=__gp                               // establish kernel global 
pointer
+    ;;
+    st8 [r16]=r8               // ensure pt_regs.r8 != 0 (see 
handle_syscall_error)
+(p13)   mov in6=-1
+(p8)    mov in7=-1
+
+    cmp.eq pSys,pNonSys=r0,r0          // set pSys=1, pNonSys=0
+    movl r17=FPSR_DEFAULT
+    ;;
+    mov.m ar.fpsr=r17                  // set ar.fpsr to kernel default value
+(p10)   mov r8=-EINVAL
+    br.ret.sptk.many b7
+END(ia64_hypercall_setup)
 
 
     .org vmx_ia64_ivt+0x3c00
diff -r ef646312685f -r 18a8e34e1211 xen/arch/ia64/vmx/vmx_minstate.h
--- a/xen/arch/ia64/vmx/vmx_minstate.h  Wed Jan 31 10:59:56 2007 -0700
+++ b/xen/arch/ia64/vmx/vmx_minstate.h  Thu Feb 01 12:53:34 2007 -0700
@@ -174,6 +174,7 @@
     ;;                                          \
     st8 [r16]=r29,16;   /* save b0 */                           \
     st8 [r17]=r18,16;   /* save ar.rsc value for "loadrs" */                \
+    cmp.eq pNonSys,pSys=r0,r0   /* initialize pSys=0, pNonSys=1 */          \
     ;;                                          \
 .mem.offset 0,0; st8.spill [r16]=r20,16;    /* save original r1 */             
 \
 .mem.offset 8,0; st8.spill [r17]=r12,16;                            \
diff -r ef646312685f -r 18a8e34e1211 xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c   Wed Jan 31 10:59:56 2007 -0700
+++ b/xen/arch/ia64/vmx/vmx_process.c   Thu Feb 01 12:53:34 2007 -0700
@@ -214,7 +214,7 @@ void save_banked_regs_to_vpd(VCPU *v, RE
 // ONLY gets called from ia64_leave_kernel
 // ONLY call with interrupts disabled?? (else might miss one?)
 // NEVER successful if already reflecting a trap/fault because psr.i==0
-void leave_hypervisor_tail(struct pt_regs *regs)
+void leave_hypervisor_tail(void)
 {
     struct domain *d = current->domain;
     struct vcpu *v = current;

_______________________________________________
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®.