ia64/xen-unstable
changeset 13367: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>
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 = ¤t_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