# 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 =
¤t_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
|