direct-io.hg

changeset 13475:01ea554f1c5e

[IA64] Hypercall optimizations

provide hypercall the same path with system
most of scrach registers don't need to be saved/restored
it is good for performance

Signed-off-by: Anthony Xu <anthony.xu@intel.com>
author awilliam@xenbuild2.aw
date Thu Jan 11 16:56:58 2007 -0700 (2007-01-11)
parents db72b85b81bb
children cd6598396086
files linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c linux-2.6-xen-sparse/include/asm-ia64/hypercall.h xen/arch/ia64/asm-offsets.c xen/arch/ia64/linux-xen/entry.S xen/arch/ia64/xen/faults.c xen/arch/ia64/xen/hypercall.c xen/arch/ia64/xen/ivt.S xen/include/asm-ia64/config.h xen/include/asm-ia64/hypercall.h xen/include/public/arch-ia64.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S	Thu Jan 11 14:42:24 2007 -0700
     1.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S	Thu Jan 11 16:56:58 2007 -0700
     1.3 @@ -306,4 +306,11 @@ GLOBAL_ENTRY(xen_ssm_i_1)
     1.4  	brl.cond.sptk	.vdso_ssm_i_1_ret
     1.5  	;; 
     1.6  END(xen_ssm_i_1)
     1.7 +
     1.8 +GLOBAL_ENTRY(__hypercall)
     1.9 +	mov r2=r37
    1.10 +	break 0x1000
    1.11 +	br.ret.sptk.many b0
    1.12 +	;; 
    1.13 +END(__hypercall)
    1.14  #endif
     2.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c	Thu Jan 11 14:42:24 2007 -0700
     2.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c	Thu Jan 11 16:56:58 2007 -0700
     2.3 @@ -49,6 +49,8 @@ static int p2m_expose_init(void);
     2.4  #define p2m_expose_init() (-ENOSYS)
     2.5  #endif
     2.6  
     2.7 +EXPORT_SYMBOL(__hypercall);
     2.8 +
     2.9  //XXX same as i386, x86_64 contiguous_bitmap_set(), contiguous_bitmap_clear()
    2.10  // move those to lib/contiguous_bitmap?
    2.11  //XXX discontigmem/sparsemem
     3.1 --- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h	Thu Jan 11 14:42:24 2007 -0700
     3.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h	Thu Jan 11 16:56:58 2007 -0700
     3.3 @@ -39,6 +39,9 @@
     3.4  
     3.5  #include <asm/xen/xcom_hcall.h>
     3.6  struct xencomm_handle;
     3.7 +extern unsigned long __hypercall(unsigned long a1, unsigned long a2,
     3.8 +                                 unsigned long a3, unsigned long a4,
     3.9 +                                 unsigned long a5, unsigned long cmd);
    3.10  
    3.11  /*
    3.12   * Assembler stubs for hyper-calls.
    3.13 @@ -47,115 +50,58 @@ struct xencomm_handle;
    3.14  #define _hypercall0(type, name)					\
    3.15  ({								\
    3.16  	long __res;						\
    3.17 -	__asm__ __volatile__ (";;\n"				\
    3.18 -			      "mov r2=%1\n"			\
    3.19 -			      "break 0x1000 ;;\n"		\
    3.20 -			      "mov %0=r8 ;;\n"			\
    3.21 -			      : "=r" (__res)			\
    3.22 -			      : "J" (__HYPERVISOR_##name)	\
    3.23 -			      : "r2","r8",			\
    3.24 -			        "memory" );			\
    3.25 +	__res=__hypercall(0, 0, 0, 0, 0, __HYPERVISOR_##name);	\
    3.26  	(type)__res;						\
    3.27  })
    3.28  
    3.29  #define _hypercall1(type, name, a1)				\
    3.30  ({								\
    3.31  	long __res;						\
    3.32 -	__asm__ __volatile__ (";;\n"				\
    3.33 -			      "mov r14=%2\n"			\
    3.34 -			      "mov r2=%1\n"			\
    3.35 -			      "break 0x1000 ;;\n"		\
    3.36 -			      "mov %0=r8 ;;\n"			\
    3.37 -			      : "=r" (__res)			\
    3.38 -			      : "J" (__HYPERVISOR_##name),	\
    3.39 -				"rI" ((unsigned long)(a1))	\
    3.40 -			      : "r14","r2","r8",		\
    3.41 -				"memory" );			\
    3.42 +	__res = __hypercall((unsigned long)a1,			\
    3.43 +	                     0, 0, 0, 0, __HYPERVISOR_##name);	\
    3.44  	(type)__res;						\
    3.45  })
    3.46  
    3.47  #define _hypercall2(type, name, a1, a2)				\
    3.48  ({								\
    3.49  	long __res;						\
    3.50 -	__asm__ __volatile__ (";;\n"				\
    3.51 -			      "mov r14=%2\n"			\
    3.52 -			      "mov r15=%3\n"			\
    3.53 -			      "mov r2=%1\n"			\
    3.54 -			      "break 0x1000 ;;\n"		\
    3.55 -			      "mov %0=r8 ;;\n"			\
    3.56 -			      : "=r" (__res)			\
    3.57 -			      : "J" (__HYPERVISOR_##name),	\
    3.58 -				"rI" ((unsigned long)(a1)),	\
    3.59 -				"rI" ((unsigned long)(a2))	\
    3.60 -			      : "r14","r15","r2","r8",		\
    3.61 -				"memory" );			\
    3.62 +	__res = __hypercall((unsigned long)a1,			\
    3.63 +	                    (unsigned long)a2,			\
    3.64 +	                    0, 0, 0, __HYPERVISOR_##name);	\
    3.65  	(type)__res;						\
    3.66  })
    3.67  
    3.68  #define _hypercall3(type, name, a1, a2, a3)			\
    3.69  ({								\
    3.70  	long __res;						\
    3.71 -	__asm__ __volatile__ (";;\n"                            \
    3.72 -			      "mov r14=%2\n"                    \
    3.73 -			      "mov r15=%3\n"                    \
    3.74 -			      "mov r16=%4\n"                    \
    3.75 -			      "mov r2=%1\n"                     \
    3.76 -			      "break 0x1000 ;;\n"               \
    3.77 -			      "mov %0=r8 ;;\n"                  \
    3.78 -			      : "=r" (__res)                    \
    3.79 -			      : "J" (__HYPERVISOR_##name),      \
    3.80 -				"rI" ((unsigned long)(a1)),     \
    3.81 -				"rI" ((unsigned long)(a2)),     \
    3.82 -				"rI" ((unsigned long)(a3))      \
    3.83 -			      : "r14","r15","r16","r2","r8",	\
    3.84 -			        "memory" );                     \
    3.85 -	(type)__res;                                            \
    3.86 +	__res = __hypercall((unsigned long)a1,			\
    3.87 +	                    (unsigned long)a2,			\
    3.88 +	                    (unsigned long)a3,			\
    3.89 +	                    0, 0, __HYPERVISOR_##name);		\
    3.90 +	(type)__res;						\
    3.91  })
    3.92  
    3.93  #define _hypercall4(type, name, a1, a2, a3, a4)			\
    3.94  ({								\
    3.95  	long __res;						\
    3.96 -	__asm__ __volatile__ (";;\n"                            \
    3.97 -			      "mov r14=%2\n"                    \
    3.98 -			      "mov r15=%3\n"                    \
    3.99 -			      "mov r16=%4\n"                    \
   3.100 -			      "mov r17=%5\n"                    \
   3.101 -			      "mov r2=%1\n"                     \
   3.102 -			      "break 0x1000 ;;\n"               \
   3.103 -			      "mov %0=r8 ;;\n"                  \
   3.104 -			      : "=r" (__res)                    \
   3.105 -			      : "J" (__HYPERVISOR_##name),      \
   3.106 -				"rI" ((unsigned long)(a1)),     \
   3.107 -				"rI" ((unsigned long)(a2)),     \
   3.108 -				"rI" ((unsigned long)(a3)),     \
   3.109 -				"rI" ((unsigned long)(a4))      \
   3.110 -			      : "r14","r15","r16","r2","r8",	\
   3.111 -			        "r17","memory" );               \
   3.112 -	(type)__res;                                            \
   3.113 +	__res = __hypercall((unsigned long)a1,			\
   3.114 +	                    (unsigned long)a2,			\
   3.115 +	                    (unsigned long)a3,			\
   3.116 +	                    (unsigned long)a4,			\
   3.117 +	                    0, __HYPERVISOR_##name);		\
   3.118 +	(type)__res;						\
   3.119  })
   3.120  
   3.121  #define _hypercall5(type, name, a1, a2, a3, a4, a5)		\
   3.122  ({								\
   3.123  	long __res;						\
   3.124 -	__asm__ __volatile__ (";;\n"                            \
   3.125 -			      "mov r14=%2\n"                    \
   3.126 -			      "mov r15=%3\n"                    \
   3.127 -			      "mov r16=%4\n"                    \
   3.128 -			      "mov r17=%5\n"                    \
   3.129 -			      "mov r18=%6\n"                    \
   3.130 -			      "mov r2=%1\n"                     \
   3.131 -			      "break 0x1000 ;;\n"               \
   3.132 -			      "mov %0=r8 ;;\n"                  \
   3.133 -			      : "=r" (__res)                    \
   3.134 -			      : "J" (__HYPERVISOR_##name),      \
   3.135 -				"rI" ((unsigned long)(a1)),     \
   3.136 -				"rI" ((unsigned long)(a2)),     \
   3.137 -				"rI" ((unsigned long)(a3)),     \
   3.138 -				"rI" ((unsigned long)(a4)),     \
   3.139 -				"rI" ((unsigned long)(a5))      \
   3.140 -			      : "r14","r15","r16","r2","r8",	\
   3.141 -			        "r17","r18","memory" );         \
   3.142 -	(type)__res;                                            \
   3.143 +	__res = __hypercall((unsigned long)a1,			\
   3.144 +	                    (unsigned long)a2,			\
   3.145 +	                    (unsigned long)a3,			\
   3.146 +	                    (unsigned long)a4,			\
   3.147 +	                    (unsigned long)a5,			\
   3.148 +	                    __HYPERVISOR_##name);		\
   3.149 +	(type)__res;						\
   3.150  })
   3.151  
   3.152  
     4.1 --- a/xen/arch/ia64/asm-offsets.c	Thu Jan 11 14:42:24 2007 -0700
     4.2 +++ b/xen/arch/ia64/asm-offsets.c	Thu Jan 11 16:56:58 2007 -0700
     4.3 @@ -56,6 +56,7 @@ void foo(void)
     4.4  	DEFINE(IA64_TASK_THREAD_ON_USTACK_OFFSET, offsetof (struct vcpu, arch._thread.on_ustack));
     4.5  
     4.6  	DEFINE(IA64_VCPU_DOMAIN_OFFSET, offsetof (struct vcpu, domain));
     4.7 +	DEFINE(IA64_VCPU_HYPERCALL_CONTINUATION_OFS, offsetof (struct vcpu, arch.hypercall_continuation));
     4.8  	DEFINE(IA64_VCPU_META_RR0_OFFSET, offsetof (struct vcpu, arch.metaphysical_rr0));
     4.9  	DEFINE(IA64_VCPU_META_SAVED_RR0_OFFSET, offsetof (struct vcpu, arch.metaphysical_saved_rr0));
    4.10  	DEFINE(IA64_VCPU_BREAKIMM_OFFSET, offsetof (struct vcpu, arch.breakimm));
     5.1 --- a/xen/arch/ia64/linux-xen/entry.S	Thu Jan 11 14:42:24 2007 -0700
     5.2 +++ b/xen/arch/ia64/linux-xen/entry.S	Thu Jan 11 16:56:58 2007 -0700
     5.3 @@ -676,7 +676,9 @@ GLOBAL_ENTRY(ia64_ret_from_syscall)
     5.4  	cmp.ge p6,p7=r8,r0			// syscall executed successfully?
     5.5  	adds r2=PT(R8)+16,sp			// r2 = &pt_regs.r8
     5.6  	mov r10=r0				// clear error indication in r10
     5.7 +#ifndef XEN    
     5.8  (p7)	br.cond.spnt handle_syscall_error	// handle potential syscall failure
     5.9 +#endif
    5.10  END(ia64_ret_from_syscall)
    5.11  	// fall through
    5.12  /*
    5.13 @@ -764,7 +766,9 @@ ENTRY(ia64_leave_syscall)
    5.14  	ld8 r19=[r2],PT(B6)-PT(LOADRS)		// load ar.rsc value for "loadrs"
    5.15  	nop.i 0
    5.16  	;;
    5.17 +#ifndef XEN    
    5.18  	mov r16=ar.bsp				// M2  get existing backing store pointer
    5.19 +#endif    
    5.20  	ld8 r18=[r2],PT(R9)-PT(B6)		// load b6
    5.21  #ifndef XEN
    5.22  (p6)	and r15=TIF_WORK_MASK,r31		// any work other than TIF_SYSCALL_TRACE?
    5.23 @@ -814,7 +818,11 @@ ENTRY(ia64_leave_syscall)
    5.24  	mov f8=f0				// F    clear f8
    5.25  	;;
    5.26  	ld8.fill r12=[r2]			// M0|1 restore r12 (sp)
    5.27 +#ifdef XEN    
    5.28 +	ld8.fill r2=[r3]			// M0|1
    5.29 +#else    
    5.30  	ld8.fill r15=[r3]			// M0|1 restore r15
    5.31 +#endif    
    5.32  	mov b6=r18				// I0   restore b6
    5.33  
    5.34  #ifdef XEN
    5.35 @@ -827,7 +835,9 @@ ENTRY(ia64_leave_syscall)
    5.36  
    5.37  	srlz.d				// M0   ensure interruption collection is off (for cover)
    5.38  	shr.u r18=r19,16		// I0|1 get byte size of existing "dirty" partition
    5.39 +#ifndef XEN    
    5.40  	cover				// B    add current frame into dirty partition & set cr.ifs
    5.41 +#endif    
    5.42  	;;
    5.43  (pUStk) ld4 r17=[r17]			// M0|1 r17 = cpu_data->phys_stacked_size_p8
    5.44  	mov r19=ar.bsp			// M2   get new backing store pointer
    5.45 @@ -893,24 +903,19 @@ GLOBAL_ENTRY(ia64_leave_kernel)
    5.46  .work_processed_kernel:
    5.47  #ifdef XEN
    5.48  	;;
    5.49 -(pUStk) ssm psr.i
    5.50 -(pUStk)    br.call.sptk.many b0=do_softirq
    5.51 -(pUStk) rsm psr.i
    5.52 -    ;;
    5.53 -	alloc loc0=ar.pfs,0,1,1,0
    5.54 -	adds out0=16,r12
    5.55 +(pUStk)	ssm psr.i
    5.56 +(pUStk)	br.call.sptk.many b0=do_softirq
    5.57 +(pUStk)	ssm psr.i
    5.58 +	;;
    5.59 +(pUStk)	br.call.sptk.many b0=reflect_event
    5.60 +	;;
    5.61  	adds r7 = PT(EML_UNAT)+16,r12
    5.62  	;;
    5.63  	ld8 r7 = [r7]
    5.64  	;;
    5.65 -(pUStk)	br.call.sptk.many b0=reflect_event
    5.66 -//(pUStk)	br.call.sptk.many b0=deliver_pending_interrupt
    5.67 -    ;;
    5.68 -	mov ar.pfs=loc0
    5.69  	mov ar.unat=r7  /* load eml_unat  */
    5.70  	mov r31=r0
    5.71  
    5.72 -
    5.73  #else
    5.74  	adds r17=TI_FLAGS+IA64_TASK_SIZE,r13
    5.75  	;;
    5.76 @@ -1184,8 +1189,11 @@ skip_rbs_switch:
    5.77  	mov cr.ipsr=r29		// M2
    5.78  	mov ar.pfs=r26		// I0
    5.79  (pLvSys)mov r17=r0		// A  clear r17 for leave_syscall, no-op otherwise
    5.80 -
    5.81 +#ifdef XEN
    5.82 +	mov cr.ifs=r30		// M2
    5.83 +#else    
    5.84  (p9)	mov cr.ifs=r30		// M2
    5.85 +#endif
    5.86  	mov b0=r21		// I0
    5.87  (pLvSys)mov r18=r0		// A  clear r18 for leave_syscall, no-op otherwise
    5.88  
    5.89 @@ -1195,7 +1203,11 @@ skip_rbs_switch:
    5.90  	;;
    5.91  (pUStk)	mov ar.rnat=r24		// M2 must happen with RSE in lazy mode
    5.92  	nop 0
    5.93 +#ifdef XEN    
    5.94 +(pLvSys)mov r15=r0
    5.95 +#else
    5.96  (pLvSys)mov r2=r0
    5.97 +#endif
    5.98  
    5.99  	mov ar.rsc=r27		// M2
   5.100  	mov pr=r31,-1		// I0
   5.101 @@ -1459,7 +1471,80 @@ 1:	mov gp=loc2				// restore gp
   5.102  	br.ret.sptk.many rp
   5.103  END(unw_init_running)
   5.104  
   5.105 -#ifndef XEN
   5.106 +#ifdef XEN
   5.107 +	.rodata
   5.108 +	.align 8
   5.109 +	.globl ia64_hypercall_table
   5.110 +ia64_hypercall_table:
   5.111 +	data8 do_ni_hypercall		/* do_set_trap_table *//*  0 */
   5.112 +	data8 do_ni_hypercall		/* do_mmu_update */
   5.113 +	data8 do_ni_hypercall		/* do_set_gdt */
   5.114 +	data8 do_ni_hypercall		/* do_stack_switch */
   5.115 +	data8 do_ni_hypercall		/* do_set_callbacks */
   5.116 +	data8 do_ni_hypercall		/* do_fpu_taskswitch *//*  5 */
   5.117 +	data8 do_sched_op_compat
   5.118 +	data8 do_ni_hypercall
   5.119 +	data8 do_ni_hypercall		/* do_set_debugreg */
   5.120 +	data8 do_ni_hypercall		/* do_get_debugreg */
   5.121 +	data8 do_ni_hypercall		/* do_update_descriptor * 10 */
   5.122 +	data8 do_ni_hypercall		/* do_ni_hypercall */
   5.123 +	data8 do_memory_op
   5.124 +	data8 do_multicall
   5.125 +	data8 do_ni_hypercall		/* do_update_va_mapping */
   5.126 +	data8 do_ni_hypercall		/* do_set_timer_op */  /* 15 */
   5.127 +	data8 do_ni_hypercall
   5.128 +	data8 do_xen_version
   5.129 +	data8 do_console_io
   5.130 +	data8 do_ni_hypercall
   5.131 +	data8 do_grant_table_op				       /* 20 */
   5.132 +	data8 do_ni_hypercall		/* do_vm_assist */
   5.133 +	data8 do_ni_hypercall		/* do_update_va_mapping_othe */
   5.134 +	data8 do_ni_hypercall		/* (x86 only) */
   5.135 +	data8 do_ni_hypercall		/* do_vcpu_op */
   5.136 +	data8 do_ni_hypercall		/* (x86_64 only) */    /* 25 */
   5.137 +	data8 do_ni_hypercall		/* do_mmuext_op */
   5.138 +	data8 do_ni_hypercall		/* do_acm_op */
   5.139 +	data8 do_ni_hypercall		/* do_nmi_op */
   5.140 +	data8 do_sched_op
   5.141 +	data8 do_callback_op		/*  */                 /* 30 */
   5.142 +	data8 do_xenoprof_op		/*  */
   5.143 +	data8 do_event_channel_op
   5.144 +	data8 do_physdev_op
   5.145 +	data8 do_hvm_op			/*  */
   5.146 +	data8 do_sysctl			/*  */                  /* 35 */
   5.147 +	data8 do_domctl			/*  */
   5.148 +	data8 do_ni_hypercall		/*  */
   5.149 +	data8 do_ni_hypercall		/*  */
   5.150 +	data8 do_ni_hypercall		/*  */
   5.151 +	data8 do_ni_hypercall		/*  */                 /* 40 */
   5.152 +	data8 do_ni_hypercall		/*  */
   5.153 +	data8 do_ni_hypercall		/*  */
   5.154 +	data8 do_ni_hypercall		/*  */
   5.155 +	data8 do_ni_hypercall		/*  */
   5.156 +	data8 do_ni_hypercall		/*  */                 /* 45 */
   5.157 +	data8 do_ni_hypercall		/*  */
   5.158 +	data8 do_ni_hypercall		/*  */
   5.159 +	data8 do_dom0vp_op              /* dom0vp_op */
   5.160 +	data8 do_pirq_guest_eoi		/* arch_1 */
   5.161 +	data8 do_ni_hypercall		/* arch_2 */           /* 50 */
   5.162 +	data8 do_ni_hypercall		/* arch_3 */
   5.163 +	data8 do_ni_hypercall		/* arch_4 */
   5.164 +	data8 do_ni_hypercall		/* arch_5 */
   5.165 +	data8 do_ni_hypercall		/* arch_6 */
   5.166 +	data8 do_ni_hypercall		/* arch_7 */           /* 55 */
   5.167 +	data8 do_ni_hypercall
   5.168 +	data8 do_ni_hypercall
   5.169 +	data8 do_ni_hypercall
   5.170 +	data8 do_ni_hypercall
   5.171 +	data8 do_ni_hypercall                                  /* 60 */
   5.172 +	data8 do_ni_hypercall
   5.173 +	data8 do_ni_hypercall
   5.174 +	data8 do_ni_hypercall
   5.175 +
   5.176 +	// guard against failures to increase NR_hypercalls
   5.177 +	.org ia64_hypercall_table + 8*NR_hypercalls
   5.178 +
   5.179 +#else
   5.180  	.rodata
   5.181  	.align 8
   5.182  	.globl sys_call_table
     6.1 --- a/xen/arch/ia64/xen/faults.c	Thu Jan 11 14:42:24 2007 -0700
     6.2 +++ b/xen/arch/ia64/xen/faults.c	Thu Jan 11 16:56:58 2007 -0700
     6.3 @@ -83,8 +83,8 @@ void reflect_interruption(unsigned long 
     6.4  		check_bad_nested_interruption(isr, regs, vector);
     6.5  	PSCB(v, unat) = regs->ar_unat;	// not sure if this is really needed?
     6.6  	PSCB(v, precover_ifs) = regs->cr_ifs;
     6.7 +	PSCB(v, ipsr) = vcpu_get_ipsr_int_state(v, regs->cr_ipsr);
     6.8  	vcpu_bsw0(v);
     6.9 -	PSCB(v, ipsr) = vcpu_get_ipsr_int_state(v, regs->cr_ipsr);
    6.10  	PSCB(v, isr) = isr;
    6.11  	PSCB(v, iip) = regs->cr_iip;
    6.12  	PSCB(v, ifs) = 0;
    6.13 @@ -120,33 +120,38 @@ void reflect_extint(struct pt_regs *regs
    6.14  	reflect_interruption(isr, regs, IA64_EXTINT_VECTOR);
    6.15  }
    6.16  
    6.17 -void reflect_event(struct pt_regs *regs)
    6.18 +void reflect_event(void)
    6.19  {
    6.20 -	unsigned long isr = regs->cr_ipsr & IA64_PSR_RI;
    6.21  	struct vcpu *v = current;
    6.22 +	struct pt_regs *regs;
    6.23 +	unsigned long isr;
    6.24 +
    6.25 +	if (!event_pending(v))
    6.26 +		return;
    6.27  
    6.28  	/* Sanity check */
    6.29 -	if (is_idle_vcpu(v) || !user_mode(regs)) {
    6.30 +	if (is_idle_vcpu(v)) {
    6.31  		//printk("WARN: invocation to reflect_event in nested xen\n");
    6.32  		return;
    6.33  	}
    6.34  
    6.35 -	if (!event_pending(v))
    6.36 -		return;
    6.37 +	regs = vcpu_regs(v);
    6.38  
    6.39  	// can't inject event, when XEN is emulating rfi 
    6.40  	// and both PSCB(v, ifs) and regs->ifs are valid
    6.41  	if (regs->cr_iip == *(unsigned long *)dorfirfi)
    6.42  		return;
    6.43  
    6.44 +	isr = regs->cr_ipsr & IA64_PSR_RI;
    6.45 +
    6.46  	if (!PSCB(v, interrupt_collection_enabled))
    6.47  		printk("psr.ic off, delivering event, ipsr=%lx,iip=%lx,"
    6.48  		       "isr=%lx,viip=0x%lx\n",
    6.49  		       regs->cr_ipsr, regs->cr_iip, isr, PSCB(v, iip));
    6.50  	PSCB(v, unat) = regs->ar_unat;	// not sure if this is really needed?
    6.51  	PSCB(v, precover_ifs) = regs->cr_ifs;
    6.52 +	PSCB(v, ipsr) = vcpu_get_ipsr_int_state(v, regs->cr_ipsr);
    6.53  	vcpu_bsw0(v);
    6.54 -	PSCB(v, ipsr) = vcpu_get_ipsr_int_state(v, regs->cr_ipsr);
    6.55  	PSCB(v, isr) = isr;
    6.56  	PSCB(v, iip) = regs->cr_iip;
    6.57  	PSCB(v, ifs) = 0;
     7.1 --- a/xen/arch/ia64/xen/hypercall.c	Thu Jan 11 14:42:24 2007 -0700
     7.2 +++ b/xen/arch/ia64/xen/hypercall.c	Thu Jan 11 16:56:58 2007 -0700
     7.3 @@ -17,6 +17,7 @@
     7.4  #include <asm/sal.h>	/* FOR struct ia64_sal_retval */
     7.5  #include <asm/fpswa.h>	/* FOR struct fpswa_ret_t */
     7.6  
     7.7 +#include <asm/vmx_vcpu.h>
     7.8  #include <asm/vcpu.h>
     7.9  #include <asm/dom_fw.h>
    7.10  #include <public/domctl.h>
    7.11 @@ -32,94 +33,14 @@
    7.12  #include <xen/event.h>
    7.13  #include <xen/perfc.h>
    7.14  
    7.15 -static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg);
    7.16 -static long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg);
    7.17 -
    7.18 -const hypercall_t ia64_hypercall_table[NR_hypercalls] =
    7.19 -{
    7.20 -	(hypercall_t)do_ni_hypercall,		/* do_set_trap_table *//*  0 */
    7.21 -	(hypercall_t)do_ni_hypercall,		/* do_mmu_update */
    7.22 -	(hypercall_t)do_ni_hypercall,		/* do_set_gdt */
    7.23 -	(hypercall_t)do_ni_hypercall,		/* do_stack_switch */
    7.24 -	(hypercall_t)do_ni_hypercall,		/* do_set_callbacks */
    7.25 -	(hypercall_t)do_ni_hypercall,		/* do_fpu_taskswitch *//*  5 */
    7.26 -	(hypercall_t)do_sched_op_compat,
    7.27 -	(hypercall_t)do_ni_hypercall,
    7.28 -	(hypercall_t)do_ni_hypercall,		/* do_set_debugreg */
    7.29 -	(hypercall_t)do_ni_hypercall,		/* do_get_debugreg */
    7.30 -	(hypercall_t)do_ni_hypercall,		/* do_update_descriptor * 10 */
    7.31 -	(hypercall_t)do_ni_hypercall,		/* do_ni_hypercall */
    7.32 -	(hypercall_t)do_memory_op,
    7.33 -	(hypercall_t)do_multicall,
    7.34 -	(hypercall_t)do_ni_hypercall,		/* do_update_va_mapping */
    7.35 -	(hypercall_t)do_ni_hypercall,		/* do_set_timer_op */  /* 15 */
    7.36 -	(hypercall_t)do_ni_hypercall,
    7.37 -	(hypercall_t)do_xen_version,
    7.38 -	(hypercall_t)do_console_io,
    7.39 -	(hypercall_t)do_ni_hypercall,
    7.40 -	(hypercall_t)do_grant_table_op,				       /* 20 */
    7.41 -	(hypercall_t)do_ni_hypercall,		/* do_vm_assist */
    7.42 -	(hypercall_t)do_ni_hypercall,		/* do_update_va_mapping_othe */
    7.43 -	(hypercall_t)do_ni_hypercall,		/* (x86 only) */
    7.44 -	(hypercall_t)do_ni_hypercall,		/* do_vcpu_op */
    7.45 -	(hypercall_t)do_ni_hypercall,		/* (x86_64 only) */    /* 25 */
    7.46 -	(hypercall_t)do_ni_hypercall,		/* do_mmuext_op */
    7.47 -	(hypercall_t)do_ni_hypercall,		/* do_acm_op */
    7.48 -	(hypercall_t)do_ni_hypercall,		/* do_nmi_op */
    7.49 -	(hypercall_t)do_sched_op,
    7.50 -	(hypercall_t)do_callback_op,		/*  */                 /* 30 */
    7.51 -	(hypercall_t)do_xenoprof_op,		/*  */
    7.52 -	(hypercall_t)do_event_channel_op,
    7.53 -	(hypercall_t)do_physdev_op,
    7.54 -	(hypercall_t)do_hvm_op,			/*  */
    7.55 -	(hypercall_t)do_sysctl,			/*  */                  /* 35 */
    7.56 -	(hypercall_t)do_domctl,			/*  */
    7.57 -	(hypercall_t)do_ni_hypercall,		/*  */
    7.58 -	(hypercall_t)do_ni_hypercall,		/*  */
    7.59 -	(hypercall_t)do_ni_hypercall,		/*  */
    7.60 -	(hypercall_t)do_ni_hypercall,		/*  */                 /* 40 */
    7.61 -	(hypercall_t)do_ni_hypercall,		/*  */
    7.62 -	(hypercall_t)do_ni_hypercall,		/*  */
    7.63 -	(hypercall_t)do_ni_hypercall,		/*  */
    7.64 -	(hypercall_t)do_ni_hypercall,		/*  */
    7.65 -	(hypercall_t)do_ni_hypercall,		/*  */                 /* 45 */
    7.66 -	(hypercall_t)do_ni_hypercall,		/*  */
    7.67 -	(hypercall_t)do_ni_hypercall,		/*  */
    7.68 -	(hypercall_t)do_dom0vp_op,              /* dom0vp_op */
    7.69 -	(hypercall_t)do_ni_hypercall,		/* arch_1 */
    7.70 -	(hypercall_t)do_ni_hypercall,		/* arch_2 */           /* 50 */
    7.71 -	(hypercall_t)do_ni_hypercall,		/* arch_3 */
    7.72 -	(hypercall_t)do_ni_hypercall,		/* arch_4 */
    7.73 -	(hypercall_t)do_ni_hypercall,		/* arch_5 */
    7.74 -	(hypercall_t)do_ni_hypercall,		/* arch_6 */
    7.75 -	(hypercall_t)do_ni_hypercall,		/* arch_7 */           /* 55 */
    7.76 -	(hypercall_t)do_ni_hypercall,
    7.77 -	(hypercall_t)do_ni_hypercall,
    7.78 -	(hypercall_t)do_ni_hypercall,
    7.79 -	(hypercall_t)do_ni_hypercall,
    7.80 -	(hypercall_t)do_ni_hypercall,                                  /* 60 */
    7.81 -	(hypercall_t)do_ni_hypercall,
    7.82 -	(hypercall_t)do_ni_hypercall,
    7.83 -	(hypercall_t)do_ni_hypercall
    7.84 -};
    7.85 +extern long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg);
    7.86 +extern long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg);
    7.87  
    7.88  static IA64FAULT
    7.89  xen_hypercall (struct pt_regs *regs)
    7.90  {
    7.91  	uint32_t cmd = (uint32_t)regs->r2;
    7.92 -
    7.93 -	if (cmd < NR_hypercalls) {
    7.94 -		perfc_incra(hypercalls, cmd);
    7.95 -		regs->r8 = (*ia64_hypercall_table[cmd])(
    7.96 -			regs->r14,
    7.97 -			regs->r15,
    7.98 -			regs->r16,
    7.99 -			regs->r17,
   7.100 -			regs->r18,
   7.101 -			regs->r19);
   7.102 -	} else
   7.103 -		regs->r8 = -ENOSYS;
   7.104 -	
   7.105 +	printk("Warning %s should not be called %d\n", __FUNCTION__, cmd);
   7.106  	return IA64_NO_FAULT;
   7.107  }
   7.108  
   7.109 @@ -129,7 +50,8 @@ xen_fast_hypercall (struct pt_regs *regs
   7.110  	uint32_t cmd = (uint32_t)regs->r2;
   7.111  	switch (cmd) {
   7.112  	case __HYPERVISOR_ia64_fast_eoi:
   7.113 -		regs->r8 = pirq_guest_eoi(current->domain, regs->r14);
   7.114 +		printk("Warning %s should not be called %d\n",
   7.115 +		       __FUNCTION__, cmd);
   7.116  		break;
   7.117  	default:
   7.118  		regs->r8 = -ENOSYS;
   7.119 @@ -137,6 +59,12 @@ xen_fast_hypercall (struct pt_regs *regs
   7.120  	return IA64_NO_FAULT;
   7.121  }
   7.122  
   7.123 +long do_pirq_guest_eoi(int pirq)
   7.124 +{
   7.125 +	return pirq_guest_eoi(current->domain, pirq);
   7.126 +}
   7.127 +    
   7.128 +
   7.129  static void
   7.130  fw_hypercall_ipi (struct pt_regs *regs)
   7.131  {
   7.132 @@ -320,42 +248,42 @@ unsigned long hypercall_create_continuat
   7.133      va_list args;
   7.134  
   7.135      va_start(args, format);
   7.136 -    if ( test_bit(_MCSF_in_multicall, &mcs->flags) ) {
   7.137 -	panic("PREEMPT happen in multicall\n");	// Not support yet
   7.138 -    } else {
   7.139 -	vcpu_set_gr(v, 2, op, 0);
   7.140 -	for ( i = 0; *p != '\0'; i++) {
   7.141 -            switch ( *p++ )
   7.142 -            {
   7.143 -            case 'i':
   7.144 -                arg = (unsigned long)va_arg(args, unsigned int);
   7.145 -                break;
   7.146 -            case 'l':
   7.147 -                arg = (unsigned long)va_arg(args, unsigned long);
   7.148 -                break;
   7.149 -            case 'h':
   7.150 -                arg = (unsigned long)va_arg(args, void *);
   7.151 -                break;
   7.152 -            default:
   7.153 -                arg = 0;
   7.154 -                BUG();
   7.155 -            }
   7.156 -	    switch (i) {
   7.157 -	    case 0: vcpu_set_gr(v, 14, arg, 0);
   7.158 -		    break;
   7.159 -	    case 1: vcpu_set_gr(v, 15, arg, 0);
   7.160 -		    break;
   7.161 -	    case 2: vcpu_set_gr(v, 16, arg, 0);
   7.162 -		    break;
   7.163 -	    case 3: vcpu_set_gr(v, 17, arg, 0);
   7.164 -		    break;
   7.165 -	    case 4: vcpu_set_gr(v, 18, arg, 0);
   7.166 -		    break;
   7.167 -	    default: panic("Too many args for hypercall continuation\n");
   7.168 -		    break;
   7.169 -	    }
   7.170 -	}
   7.171 +    if (test_bit(_MCSF_in_multicall, &mcs->flags))
   7.172 +        panic("PREEMPT happen in multicall\n");	// Not support yet
   7.173 +
   7.174 +    vcpu_set_gr(v, 15, op, 0);
   7.175 +
   7.176 +    for (i = 0; *p != '\0'; i++) {
   7.177 +        switch ( *p++ )
   7.178 +        {
   7.179 +        case 'i':
   7.180 +            arg = (unsigned long)va_arg(args, unsigned int);
   7.181 +            break;
   7.182 +        case 'l':
   7.183 +            arg = (unsigned long)va_arg(args, unsigned long);
   7.184 +            break;
   7.185 +        case 'h':
   7.186 +            arg = (unsigned long)va_arg(args, void *);
   7.187 +            break;
   7.188 +        default:
   7.189 +            arg = 0;
   7.190 +            BUG();
   7.191 +        }
   7.192 +        vcpu_set_gr(v, 16 + i, arg, 0);
   7.193      }
   7.194 +    
   7.195 +    if (i >= 6)
   7.196 +        panic("Too many args for hypercall continuation\n");
   7.197 +
   7.198 +    // Clean other argument to 0
   7.199 +    while (i < 6) {
   7.200 +        vcpu_set_gr(v, 16 + i, 0, 0);
   7.201 +        i++;
   7.202 +    }
   7.203 +
   7.204 +    // re-execute break;
   7.205 +    vcpu_decrement_iip(v);
   7.206 +    
   7.207      v->arch.hypercall_continuation = 1;
   7.208      va_end(args);
   7.209      return op;
   7.210 @@ -369,7 +297,7 @@ extern int
   7.211  iosapic_guest_write(
   7.212      unsigned long physbase, unsigned int reg, u32 pval);
   7.213  
   7.214 -static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
   7.215 +long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
   7.216  {
   7.217      int irq;
   7.218      long ret;
   7.219 @@ -524,7 +452,7 @@ static long unregister_guest_callback(st
   7.220  /* First time to add callback to xen/ia64, so let's just stick to
   7.221   * the newer callback interface.
   7.222   */
   7.223 -static long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg)
   7.224 +long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg)
   7.225  {
   7.226      long ret;
   7.227  
     8.1 --- a/xen/arch/ia64/xen/ivt.S	Thu Jan 11 14:42:24 2007 -0700
     8.2 +++ b/xen/arch/ia64/xen/ivt.S	Thu Jan 11 16:56:58 2007 -0700
     8.3 @@ -2,6 +2,7 @@
     8.4  #include <asm/debugger.h>
     8.5  #include <asm/vhpt.h>
     8.6  #include <public/arch-ia64.h>
     8.7 +#include <asm/config.h>
     8.8  #endif
     8.9  /*
    8.10   * arch/ia64/kernel/ivt.S
    8.11 @@ -1055,7 +1056,6 @@ ENTRY(break_fault)
    8.12  	 * level.
    8.13  	 */
    8.14  	DBG_FAULT(11)
    8.15 -#ifdef XEN
    8.16  	mov r16=cr.isr
    8.17  	mov r17=cr.iim
    8.18  	mov r31=pr
    8.19 @@ -1101,103 +1101,202 @@ ENTRY(break_fault)
    8.20  	;;
    8.21  	ld8 r22 = [r22]
    8.22  	;;
    8.23 -	adds r22=IA64_VCPU_BREAKIMM_OFFSET,r22
    8.24 +	adds r23=IA64_VCPU_BREAKIMM_OFFSET,r22
    8.25  	;;
    8.26 -	ld4 r23=[r22];;
    8.27 +	ld4 r23=[r23];;
    8.28  	cmp4.eq p6,p7=r23,r17			// Xen-reserved breakimm?
    8.29 -(p6)	br.spnt.many dispatch_break_fault
    8.30 +(p6)	br.spnt.many fast_hypercall
    8.31  	;;
    8.32  	br.sptk.many fast_break_reflect
    8.33  	;;
    8.34 -#else /* !XEN */
    8.35 -	movl r16=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
    8.36 -	ld8 r16=[r16]
    8.37 -	mov r17=cr.iim
    8.38 -	mov r18=__IA64_BREAK_SYSCALL
    8.39 -	mov r21=ar.fpsr
    8.40 -	mov r29=cr.ipsr
    8.41 -	mov r19=b6
    8.42 -	mov r25=ar.unat
    8.43 -	mov r27=ar.rsc
    8.44 -	mov r26=ar.pfs
    8.45 -	mov r28=cr.iip
    8.46 -#ifndef XEN
    8.47 -	mov r31=pr			// prepare to save predicates
    8.48 -#endif
    8.49 -	mov r20=r1
    8.50 +
    8.51 +
    8.52 +fast_hypercall:
    8.53 +	shr r25=r2,8;;
    8.54 +	cmp.ne p7,p0=r0,r25
    8.55 +(p7)	br.spnt.few dispatch_break_fault
    8.56  	;;
    8.57 -	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
    8.58 -	cmp.eq p0,p7=r18,r17		// is this a system call? 
    8.59 -					//   (p7 <- false, if so)
    8.60 -(p7)	br.cond.spnt non_syscall
    8.61 +	// fall through
    8.62 +   
    8.63 +
    8.64 +	/*
    8.65 +	 * The streamlined system call entry/exit paths only save/restore the initial part
    8.66 +	 * of pt_regs.  This implies that the callers of system-calls must adhere to the
    8.67 +	 * normal procedure calling conventions.
    8.68 +	 *
    8.69 +	 *   Registers to be saved & restored:
    8.70 +	 *	CR registers: cr.ipsr, cr.iip, cr.ifs
    8.71 +	 *	AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore, ar.fpsr
    8.72 +	 * 	others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15
    8.73 +	 *   Registers to be restored only:
    8.74 +	 * 	r8-r11: output value from the system call.
    8.75 +	 *
    8.76 +	 * During system call exit, scratch registers (including r15) are modified/cleared
    8.77 +	 * to prevent leaking bits from kernel to user level.
    8.78 +	 */
    8.79 +    
    8.80 +//	DBG_FAULT(11)
    8.81 +//	mov.m r16=IA64_KR(CURRENT)		// M2 r16 <- current task (12 cyc)
    8.82 +	mov r16=r22
    8.83 +	mov r29=cr.ipsr				// M2 (12 cyc)
    8.84 +//	mov r31=pr				// I0 (2 cyc)
    8.85 +	mov r15=r2
    8.86 +
    8.87 +//	mov r17=cr.iim				// M2 (2 cyc)
    8.88 +	mov.m r27=ar.rsc			// M2 (12 cyc)
    8.89 +//	mov r18=__IA64_BREAK_SYSCALL		// A
    8.90 +
    8.91 +	mov.m ar.rsc=0				// M2
    8.92 +	mov.m r21=ar.fpsr			// M2 (12 cyc)
    8.93 +	mov r19=b6				// I0 (2 cyc)
    8.94  	;;
    8.95 -	ld1 r17=[r16]			// load current->thread.on_ustack flag
    8.96 -	st1 [r16]=r0			// clear current->thread.on_ustack flag
    8.97 -	add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
    8.98 -					// set r1 for 
    8.99 -					//   MINSTATE_START_SAVE_MIN_VIRT
   8.100 -	;;
   8.101 -	invala
   8.102 +	mov.m r23=ar.bspstore			// M2 (12 cyc)
   8.103 +	mov.m r24=ar.rnat			// M2 (5 cyc)
   8.104 +	mov.i r26=ar.pfs			// I0 (2 cyc)
   8.105  
   8.106 -	/* adjust return address so we skip over the break instruction: */
   8.107 +	invala					// M0|1
   8.108 +	nop.m 0					// M
   8.109 +	mov r20=r1				// A			save r1
   8.110 +
   8.111 +	nop.m 0
   8.112 +//	movl r30=sys_call_table			// X
   8.113 +	movl r30=ia64_hypercall_table			// X
   8.114  
   8.115 -	extr.u r8=r29,41,2		// extract ei field from cr.ipsr
   8.116 -	;;
   8.117 -	cmp.eq p6,p7=2,r8		// isr.ei==2?
   8.118 -	mov r2=r1			// setup r2 for ia64_syscall_setup
   8.119 +	mov r28=cr.iip				// M2 (2 cyc)
   8.120 +//	cmp.eq p0,p7=r18,r17			// I0 is this a system call?
   8.121 +//(p7)	br.cond.spnt non_syscall		// B  no ->
   8.122 +	//
   8.123 +	// From this point on, we are definitely on the syscall-path
   8.124 +	// and we can use (non-banked) scratch registers.
   8.125 +	//
   8.126 +///////////////////////////////////////////////////////////////////////
   8.127 +	mov r1=r16				// A    move task-pointer to "addl"-addressable reg
   8.128 +	mov r2=r16				// A    setup r2 for ia64_syscall_setup
   8.129 +//	add r9=TI_FLAGS+IA64_TASK_SIZE,r16	// A	r9 = &current_thread_info()->flags
   8.130 +
   8.131 +	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
   8.132 +//	adds r15=-1024,r15			// A    subtract 1024 from syscall number
   8.133 +//	mov r3=NR_syscalls - 1
   8.134 +	mov r3=NR_hypercalls - 1
   8.135  	;;
   8.136 -(p6)	mov r8=0			// clear ei to 0
   8.137 -(p6)	adds r28=16,r28			// switch cr.iip to next bundle 
   8.138 -					//   cr.ipsr.ei wrapped
   8.139 -(p7)	adds r8=1,r8			// increment ei to next slot
   8.140 +	ld1.bias r17=[r16]			// M0|1 r17 = current->thread.on_ustack flag
   8.141 +//	ld4 r9=[r9]				// M0|1 r9 = current_thread_info()->flags
   8.142 +	mov r9=r0               // force flags = 0
   8.143 +	extr.u r8=r29,41,2			// I0   extract ei field from cr.ipsr
   8.144 +
   8.145 +	shladd r30=r15,3,r30			// A    r30 = sys_call_table + 8*(syscall-1024)
   8.146 +	addl r22=IA64_RBS_OFFSET,r1		// A    compute base of RBS
   8.147 +	cmp.leu p6,p7=r15,r3			// A    syscall number in range?
   8.148  	;;
   8.149 -	cmp.eq pKStk,pUStk=r0,r17	// are we in kernel mode already?
   8.150 -	dep r29=r8,r29,41,2		// insert new ei into cr.ipsr
   8.151 +
   8.152 +	lfetch.fault.excl.nt1 [r22]		// M0|1 prefetch RBS
   8.153 +(p6)	ld8 r30=[r30]				// M0|1 load address of syscall entry point
   8.154 +	tnat.nz.or p7,p0=r15			// I0	is syscall nr a NaT?
   8.155 +
   8.156 +	mov.m ar.bspstore=r22			// M2   switch to kernel RBS
   8.157 +	cmp.eq p8,p9=2,r8			// A    isr.ei==2?
   8.158  	;;
   8.159  
   8.160 -	// switch from user to kernel RBS:
   8.161 -	MINSTATE_START_SAVE_MIN_VIRT
   8.162 -	br.call.sptk.many b7=ia64_syscall_setup
   8.163 +(p8)	mov r8=0				// A    clear ei to 0
   8.164 +//(p7)	movl r30=sys_ni_syscall			// X
   8.165 +(p7)	movl r30=do_ni_hypercall			// X
   8.166 +
   8.167 +(p8)	adds r28=16,r28				// A    switch cr.iip to next bundle
   8.168 +(p9)	adds r8=1,r8				// A    increment ei to next slot
   8.169 +	nop.i 0
   8.170  	;;
   8.171 -	MINSTATE_END_SAVE_MIN_VIRT	// switch to bank 1
   8.172 -	ssm psr.ic | PSR_DEFAULT_BITS
   8.173 +
   8.174 +	mov.m r25=ar.unat			// M2 (5 cyc)
   8.175 +	dep r29=r8,r29,41,2			// I0   insert new ei into cr.ipsr
   8.176 +//	adds r15=1024,r15			// A    restore original syscall number
   8.177 +	//
   8.178 +	// If any of the above loads miss in L1D, we'll stall here until
   8.179 +	// the data arrives.
   8.180 +	//
   8.181 +///////////////////////////////////////////////////////////////////////
   8.182 +	st1 [r16]=r0				// M2|3 clear current->thread.on_ustack flag
   8.183 +	mov b6=r30				// I0   setup syscall handler branch reg early
   8.184 +	cmp.eq pKStk,pUStk=r0,r17		// A    were we on kernel stacks already?
   8.185 +
   8.186 +//	and r9=_TIF_SYSCALL_TRACEAUDIT,r9	// A    mask trace or audit
   8.187 +	mov r18=ar.bsp				// M2 (12 cyc)
   8.188  	;;
   8.189 -	srlz.i				// guarantee that interruption 
   8.190 -					//   collection is on
   8.191 -	mov r3=NR_syscalls - 1
   8.192 +(pUStk)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A    compute base of memory stack
   8.193 +//	cmp.eq p14,p0=r9,r0			// A    are syscalls being traced/audited?
   8.194 +	br.call.sptk.many b7=ia64_syscall_setup	// B
   8.195 +1:
   8.196 +	mov ar.rsc=0x3				// M2   set eager mode, pl 0, LE, loadrs=0
   8.197 +	nop 0
   8.198 +	bsw.1					// B (6 cyc) regs are saved, switch to bank 1
   8.199 +	;;
   8.200 +
   8.201 +	ssm psr.ic | PSR_DEFAULT_BITS		// M2	now it's safe to re-enable intr.-collection
   8.202 +//	movl r3=ia64_ret_from_syscall		// X
   8.203  	;;
   8.204 -(p15)	ssm psr.i			// restore psr.i
   8.205 -	// p10==true means out registers are more than 8 or r15's Nat is true
   8.206 -(p10)	br.cond.spnt.many ia64_ret_from_syscall
   8.207 +
   8.208 +	srlz.i					// M0   ensure interruption collection is on
   8.209 +//	mov rp=r3				// I0   set the real return addr
   8.210 +//(p10)	br.cond.spnt.many ia64_ret_from_syscall	// B    return if bad call-frame or r15 is a NaT
   8.211 +(p15)	ssm psr.i				// M2   restore psr.i
   8.212 +//(p14)	br.call.sptk.many b6=b6			// B    invoke syscall-handker (ignore return addr)
   8.213 +//	br.call.sptk.many b6=b6			// B    invoke syscall-handker (ignore return addr)
   8.214 +	br.call.sptk.many b0=b6			// B    invoke syscall-handker (ignore return addr)
   8.215 +//	br.cond.spnt.many ia64_trace_syscall	// B	do syscall-tracing thingamagic
   8.216  	;;
   8.217 -	movl r16=sys_call_table
   8.218 -
   8.219 -	adds r15=-1024,r15		// r15 contains the syscall number --
   8.220 -					//   subtract 1024 from it
   8.221 -	movl r2=ia64_ret_from_syscall
   8.222 +	adds r2=PT(R8)+16,r12
   8.223 +	;;
   8.224 +	st8 [r2]=r8
   8.225  	;;
   8.226 -	shladd r20=r15,3,r16		// r20 = sys_call_table + 
   8.227 -					//       8*(syscall-1024)
   8.228 -	cmp.leu p6,p7=r15,r3		// (syscall > 0 && syscall < 1024 +
   8.229 -					//  NR_syscalls) ?
   8.230 -	mov rp=r2			// set the real return addr
   8.231 +	br.call.sptk.many b0=do_softirq
   8.232 +	;;
   8.233 +	//restore hypercall argument if continuation
   8.234 +	adds r2=IA64_VCPU_HYPERCALL_CONTINUATION_OFS,r13
   8.235 +	;;
   8.236 +	ld1 r20=[r2]
   8.237 +	;;
   8.238 +	st1 [r2]=r0
   8.239 +	;;
   8.240 +	cmp.ne p6,p0=r20,r0
   8.241  	;;
   8.242 -(p6)	ld8 r20=[r20]			// load address of syscall entry point
   8.243 -(p7)	movl r20=sys_ni_syscall
   8.244 -
   8.245 -	add r2=TI_FLAGS+IA64_TASK_SIZE,r13
   8.246 +(p6)	adds r2=PT(R16)+16,r12
   8.247 +(p6)	adds r3=PT(R17)+16,r12
   8.248 +	;;
   8.249 +(p6)	ld8 r32=[r2],16
   8.250 +(p6)	ld8 r33=[r3],16
   8.251 +	;;
   8.252 +(p6)	ld8 r34=[r2],16
   8.253 +(p6)	ld8 r35=[r3],16
   8.254 +	;;
   8.255 +(p6)	ld8 r36=[r2],16
   8.256  	;;
   8.257 -	ld4 r2=[r2]			// r2 = current_thread_info()->flags
   8.258 +//save ar.bsp before cover
   8.259 +	mov r16=ar.bsp
   8.260 +	add r2=PT(R14)+16,r12
   8.261 +	;;
   8.262 +	st8 [r2]=r16
   8.263  	;;
   8.264 -	and r2=_TIF_SYSCALL_TRACEAUDIT,r2  // mask trace or audit
   8.265 +	rsm psr.i|psr.ic
   8.266 +	;;
   8.267 +	srlz.i
   8.268 +	;;
   8.269 +	cover
   8.270  	;;
   8.271 -	cmp.eq p8,p0=r2,r0
   8.272 -	mov b6=r20
   8.273 +	mov r20=cr.ifs    
   8.274 +	adds r2=PT(CR_IFS)+16,r12
   8.275 +	;;
   8.276 +	st8 [r2]=r20
   8.277 +	;;   
   8.278 +	br.call.sptk.many b0=reflect_event
   8.279  	;;
   8.280 -(p8)	br.call.sptk.many b6=b6		// ignore this return addr
   8.281 -	br.cond.sptk ia64_trace_syscall
   8.282 -	// NOT REACHED
   8.283 -#endif
   8.284 +	adds r2=PT(R14)+16,r12
   8.285 +	adds r3=PT(R8)+16,r12
   8.286 +	;;
   8.287 +	//r16 contains ar.bsp before cover
   8.288 +	ld8 r16=[r2]
   8.289 +	ld8 r8=[r3]
   8.290 +	;;
   8.291 +	br.sptk.many ia64_ret_from_syscall
   8.292 +	;;
   8.293  END(break_fault)
   8.294  
   8.295  	.org ia64_ivt+0x3000
   8.296 @@ -1297,7 +1396,150 @@ END(dispatch_break_fault)
   8.297  	DBG_FAULT(14)
   8.298  	FAULT(14)
   8.299  
   8.300 -#ifndef XEN
   8.301 +#ifdef XEN
   8.302 +    // this code segment is from 2.6.16.13
   8.303 +    
   8.304 +	/*
   8.305 +	 * There is no particular reason for this code to be here, other than that
   8.306 +	 * there happens to be space here that would go unused otherwise.  If this
   8.307 +	 * fault ever gets "unreserved", simply moved the following code to a more
   8.308 +	 * suitable spot...
   8.309 +	 *
   8.310 +	 * ia64_syscall_setup() is a separate subroutine so that it can
   8.311 +	 *	allocate stacked registers so it can safely demine any
   8.312 +	 *	potential NaT values from the input registers.
   8.313 +	 *
   8.314 +	 * On entry:
   8.315 +	 *	- executing on bank 0 or bank 1 register set (doesn't matter)
   8.316 +	 *	-  r1: stack pointer
   8.317 +	 *	-  r2: current task pointer
   8.318 +	 *	-  r3: preserved
   8.319 +	 *	- r11: original contents (saved ar.pfs to be saved)
   8.320 +	 *	- r12: original contents (sp to be saved)
   8.321 +	 *	- r13: original contents (tp to be saved)
   8.322 +	 *	- r15: original contents (syscall # to be saved)
   8.323 +	 *	- r18: saved bsp (after switching to kernel stack)
   8.324 +	 *	- r19: saved b6
   8.325 +	 *	- r20: saved r1 (gp)
   8.326 +	 *	- r21: saved ar.fpsr
   8.327 +	 *	- r22: kernel's register backing store base (krbs_base)
   8.328 +	 *	- r23: saved ar.bspstore
   8.329 +	 *	- r24: saved ar.rnat
   8.330 +	 *	- r25: saved ar.unat
   8.331 +	 *	- r26: saved ar.pfs
   8.332 +	 *	- r27: saved ar.rsc
   8.333 +	 *	- r28: saved cr.iip
   8.334 +	 *	- r29: saved cr.ipsr
   8.335 +	 *	- r31: saved pr
   8.336 +	 *	-  b0: original contents (to be saved)
   8.337 +	 * On exit:
   8.338 +	 *	-  p10: TRUE if syscall is invoked with more than 8 out
   8.339 +	 *		registers or r15's Nat is true
   8.340 +	 *	-  r1: kernel's gp
   8.341 +	 *	-  r3: preserved (same as on entry)
   8.342 +	 *	-  r8: -EINVAL if p10 is true
   8.343 +	 *	- r12: points to kernel stack
   8.344 +	 *	- r13: points to current task
   8.345 +	 *	- r14: preserved (same as on entry)
   8.346 +	 *	- p13: preserved
   8.347 +	 *	- p15: TRUE if interrupts need to be re-enabled
   8.348 +	 *	- ar.fpsr: set to kernel settings
   8.349 +	 *	-  b6: preserved (same as on entry)
   8.350 +	 */
   8.351 +GLOBAL_ENTRY(ia64_syscall_setup)
   8.352 +#if PT(B6) != 0
   8.353 +# error This code assumes that b6 is the first field in pt_regs.
   8.354 +#endif
   8.355 +	st8 [r1]=r19				// save b6
   8.356 +	add r16=PT(CR_IPSR),r1			// initialize first base pointer
   8.357 +	add r17=PT(R11),r1			// initialize second base pointer
   8.358 +	;;
   8.359 +	alloc r19=ar.pfs,8,0,0,0		// ensure in0-in7 are writable
   8.360 +	st8 [r16]=r29,PT(AR_PFS)-PT(CR_IPSR)	// save cr.ipsr
   8.361 +	tnat.nz p8,p0=in0
   8.362 +
   8.363 +	st8.spill [r17]=r11,PT(CR_IIP)-PT(R11)	// save r11
   8.364 +	tnat.nz p9,p0=in1
   8.365 +(pKStk)	mov r18=r0				// make sure r18 isn't NaT
   8.366 +	;;
   8.367 +
   8.368 +	st8 [r16]=r26,PT(CR_IFS)-PT(AR_PFS)	// save ar.pfs
   8.369 +	st8 [r17]=r28,PT(AR_UNAT)-PT(CR_IIP)	// save cr.iip
   8.370 +	mov r28=b0				// save b0 (2 cyc)
   8.371 +	;;
   8.372 +
   8.373 +	st8 [r17]=r25,PT(AR_RSC)-PT(AR_UNAT)	// save ar.unat
   8.374 +	dep r19=0,r19,38,26			// clear all bits but 0..37 [I0]
   8.375 +(p8)	mov in0=-1
   8.376 +	;;
   8.377 +
   8.378 +	st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS)	// store ar.pfs.pfm in cr.ifs
   8.379 +	extr.u r11=r19,7,7	// I0		// get sol of ar.pfs
   8.380 +	and r8=0x7f,r19		// A		// get sof of ar.pfs
   8.381 +
   8.382 +	st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc
   8.383 +	tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0
   8.384 +(p9)	mov in1=-1
   8.385 +	;;
   8.386 +
   8.387 +(pUStk) sub r18=r18,r22				// r18=RSE.ndirty*8
   8.388 +	tnat.nz p10,p0=in2
   8.389 +	add r11=8,r11
   8.390 +	;;
   8.391 +(pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16		// skip over ar_rnat field
   8.392 +(pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17	// skip over ar_bspstore field
   8.393 +	tnat.nz p11,p0=in3
   8.394 +	;;
   8.395 +(p10)	mov in2=-1
   8.396 +	tnat.nz p12,p0=in4				// [I0]
   8.397 +(p11)	mov in3=-1
   8.398 +	;;
   8.399 +(pUStk) st8 [r16]=r24,PT(PR)-PT(AR_RNAT)	// save ar.rnat
   8.400 +(pUStk) st8 [r17]=r23,PT(B0)-PT(AR_BSPSTORE)	// save ar.bspstore
   8.401 +	shl r18=r18,16				// compute ar.rsc to be used for "loadrs"
   8.402 +	;;
   8.403 +	st8 [r16]=r31,PT(LOADRS)-PT(PR)		// save predicates
   8.404 +	st8 [r17]=r28,PT(R1)-PT(B0)		// save b0
   8.405 +	tnat.nz p13,p0=in5				// [I0]
   8.406 +	;;
   8.407 +	st8 [r16]=r18,PT(R12)-PT(LOADRS)	// save ar.rsc value for "loadrs"
   8.408 +	st8.spill [r17]=r20,PT(R13)-PT(R1)	// save original r1
   8.409 +(p12)	mov in4=-1
   8.410 +	;;
   8.411 +
   8.412 +.mem.offset 0,0; st8.spill [r16]=r12,PT(AR_FPSR)-PT(R12)	// save r12
   8.413 +.mem.offset 8,0; st8.spill [r17]=r13,PT(R15)-PT(R13)		// save r13
   8.414 +(p13)	mov in5=-1
   8.415 +	;;
   8.416 +	st8 [r16]=r21,PT(R8)-PT(AR_FPSR)	// save ar.fpsr
   8.417 +	tnat.nz p13,p0=in6
   8.418 +	cmp.lt p10,p9=r11,r8	// frame size can't be more than local+8
   8.419 +	;;
   8.420 +	mov r8=1
   8.421 +(p9)	tnat.nz p10,p0=r15
   8.422 +	adds r12=-16,r1		// switch to kernel memory stack (with 16 bytes of scratch)
   8.423 +
   8.424 +	st8.spill [r17]=r15			// save r15
   8.425 +	tnat.nz p8,p0=in7
   8.426 +	nop.i 0
   8.427 +
   8.428 +	mov r13=r2				// establish `current'
   8.429 +	movl r1=__gp				// establish kernel global pointer
   8.430 +	;;
   8.431 +	st8 [r16]=r8		// ensure pt_regs.r8 != 0 (see handle_syscall_error)
   8.432 +(p13)	mov in6=-1
   8.433 +(p8)	mov in7=-1
   8.434 +
   8.435 +	cmp.eq pSys,pNonSys=r0,r0		// set pSys=1, pNonSys=0
   8.436 +	movl r17=FPSR_DEFAULT
   8.437 +	;;
   8.438 +	mov.m ar.fpsr=r17			// set ar.fpsr to kernel default value
   8.439 +(p10)	mov r8=-EINVAL
   8.440 +	br.ret.sptk.many b7
   8.441 +END(ia64_syscall_setup)
   8.442 +
   8.443 +
   8.444 +#else    
   8.445  	/*
   8.446  	 * There is no particular reason for this code to be here, other 
   8.447  	 * than that there happens to be space here that would go unused 
     9.1 --- a/xen/include/asm-ia64/config.h	Thu Jan 11 14:42:24 2007 -0700
     9.2 +++ b/xen/include/asm-ia64/config.h	Thu Jan 11 16:56:58 2007 -0700
     9.3 @@ -52,6 +52,9 @@
     9.4  
     9.5  #define CONFIG_VGA 1
     9.6  
     9.7 +
     9.8 +#define NR_hypercalls 64
     9.9 +
    9.10  #ifndef __ASSEMBLY__
    9.11  
    9.12  // can't find where this typedef was before?!?
    9.13 @@ -107,9 +110,6 @@ extern char _end[]; /* standard ELF symb
    9.14  // xen/include/asm/config.h
    9.15  //#define HZ 1000
    9.16  // FIXME SMP: leave SMP for a later time
    9.17 -
    9.18 -#define NR_hypercalls 64
    9.19 -
    9.20  ///////////////////////////////////////////////////////////////
    9.21  // xen/include/asm/config.h
    9.22  // Natural boundary upon TR size to define xenheap space
    10.1 --- a/xen/include/asm-ia64/hypercall.h	Thu Jan 11 14:42:24 2007 -0700
    10.2 +++ b/xen/include/asm-ia64/hypercall.h	Thu Jan 11 16:56:58 2007 -0700
    10.3 @@ -13,6 +13,8 @@ extern long
    10.4  do_event_channel_op_compat(
    10.5      XEN_GUEST_HANDLE(evtchn_op_t) uop);
    10.6  
    10.7 +extern long do_pirq_guest_eoi(int pirq);
    10.8 +
    10.9  extern int
   10.10  vmx_do_mmu_update(
   10.11      mmu_update_t *ureqs,
    11.1 --- a/xen/include/public/arch-ia64.h	Thu Jan 11 14:42:24 2007 -0700
    11.2 +++ b/xen/include/public/arch-ia64.h	Thu Jan 11 16:56:58 2007 -0700
    11.3 @@ -463,7 +463,7 @@ struct xen_ia64_boot_param {
    11.4  #define HYPERPRIVOP_MAX			(0x19)
    11.5  
    11.6  /* Fast and light hypercalls.  */
    11.7 -#define __HYPERVISOR_ia64_fast_eoi	0x0200
    11.8 +#define __HYPERVISOR_ia64_fast_eoi	__HYPERVISOR_arch_1
    11.9  
   11.10  /* Xencomm macros.  */
   11.11  #define XENCOMM_INLINE_MASK 0xf800000000000000UL