ia64/xen-unstable

changeset 17369:6cf504b4de7d

[IA64] PAL virtualization services

- pal_vps_resume_handler: bit 63 of r26 is used to indicate whether
CFLE is set when resuming to guest
- Add sync_read and sync_write per spec.
- Use patching to reduce VPS call overhead

Signed-off-by: Anthony Xu <anthony.xu@intel.com>
author Alex Williamson <alex.williamson@hp.com>
date Mon Apr 14 13:59:45 2008 -0600 (2008-04-14)
parents feee6422144f
children c0f77a657547
files xen/arch/ia64/vmx/optvfault.S xen/arch/ia64/vmx/vmx_entry.S xen/arch/ia64/vmx/vmx_init.c xen/arch/ia64/vmx/vmx_ivt.S xen/arch/ia64/vmx/vmx_minstate.h xen/include/asm-ia64/vmx_pal_vsa.h
line diff
     1.1 --- a/xen/arch/ia64/vmx/optvfault.S	Tue Apr 01 11:29:03 2008 -0600
     1.2 +++ b/xen/arch/ia64/vmx/optvfault.S	Mon Apr 14 13:59:45 2008 -0600
     1.3 @@ -31,6 +31,72 @@
     1.4  
     1.5  // Inputs are: r21 (= current), r24 (= cause), r25 (= insn), r31 (=saved pr)
     1.6  
     1.7 +ENTRY(vmx_dummy_function)
     1.8 +    br.sptk.many vmx_dummy_function
     1.9 +END(vmx_dummy_function)
    1.10 +
    1.11 +/*
    1.12 + *	Inputs:
    1.13 + *		r24 : return address
    1.14 + *  	r25 : vpd
    1.15 + *		r29 : scratch
    1.16 + *
    1.17 + */
    1.18 +GLOBAL_ENTRY(vmx_vps_sync_read)
    1.19 +    movl r29 = vmx_dummy_function
    1.20 +    ;;
    1.21 +    mov b0=r29
    1.22 +    br.sptk.many b0
    1.23 +END(vmx_vps_sync_read)
    1.24 +
    1.25 +/*
    1.26 + *	Inputs:
    1.27 + *		r24 : return address
    1.28 + *  	r25 : vpd
    1.29 + *		r29 : scratch
    1.30 + *
    1.31 + */
    1.32 +GLOBAL_ENTRY(vmx_vps_sync_write)
    1.33 +    movl r29 = vmx_dummy_function
    1.34 +    ;;
    1.35 +    mov b0=r29
    1.36 +    br.sptk.many b0
    1.37 +END(vmx_vps_sync_write)
    1.38 +
    1.39 +/*
    1.40 + *	Inputs:
    1.41 + *		r23 : pr
    1.42 + *		r24 : guest b0
    1.43 + *  	r25 : vpd
    1.44 + *
    1.45 + */
    1.46 +GLOBAL_ENTRY(vmx_vps_resume_normal)
    1.47 +    movl r29 = vmx_dummy_function
    1.48 +    ;;
    1.49 +    mov b0=r29
    1.50 +    mov pr=r23,-2
    1.51 +    br.sptk.many b0
    1.52 +END(vmx_vps_resume_normal)
    1.53 +
    1.54 +/*
    1.55 + *	Inputs:
    1.56 + *		r23 : pr
    1.57 + *		r24 : guest b0
    1.58 + *  	r25 : vpd
    1.59 + *		r17 : isr
    1.60 + */
    1.61 +GLOBAL_ENTRY(vmx_vps_resume_handler)
    1.62 +    movl r29 = vmx_dummy_function
    1.63 +    ;;
    1.64 +    ld8 r26=[r25]
    1.65 +    shr r17=r17,IA64_ISR_IR_BIT
    1.66 +    ;;
    1.67 +    dep r26=r17,r26,63,1   // bit 63 of r26 indicate whether enable CFLE
    1.68 +    mov b0=r29
    1.69 +    mov pr=r23,-2
    1.70 +    br.sptk.many b0
    1.71 +END(vmx_vps_resume_handler)
    1.72 +
    1.73  
    1.74  //mov r1=ar3 (only itc is virtualized)
    1.75  GLOBAL_ENTRY(vmx_asm_mov_from_ar)
    1.76 @@ -185,6 +251,7 @@ GLOBAL_ENTRY(vmx_asm_rsm)
    1.77  #ifndef ACCE_RSM
    1.78      br.many vmx_virtualization_fault_back
    1.79  #endif
    1.80 +    mov r23=r31
    1.81      add r16=IA64_VPD_BASE_OFFSET,r21
    1.82      extr.u r26=r25,6,21 // Imm21
    1.83      extr.u r27=r25,31,2 // I2d
    1.84 @@ -194,47 +261,62 @@ GLOBAL_ENTRY(vmx_asm_rsm)
    1.85      dep r26=r27,r26,21,2
    1.86      ;;
    1.87      add r17=VPD_VPSR_START_OFFSET,r16
    1.88 -    add r22=IA64_VCPU_MMU_MODE_OFFSET,r21
    1.89 -    //r26 is imm24
    1.90 -    dep r26=r28,r26,23,1
    1.91 +    //r18 is imm24
    1.92 +    dep r18=r28,r26,23,1
    1.93      ;;
    1.94 -    ld8 r18=[r17]
    1.95 -	
    1.96 +    //sync read
    1.97 +    mov r25=r16
    1.98 +    movl r24=vmx_asm_rsm_sync_read_return
    1.99 +    mov r20=b0
   1.100 +    br.sptk.many vmx_vps_sync_read
   1.101 +    ;;
   1.102 +vmx_asm_rsm_sync_read_return:
   1.103 +    ld8 r26=[r17]
   1.104      // xenoprof
   1.105      // Don't change mPSR.pp.
   1.106      // It is manipulated by xenoprof.
   1.107      movl r28=IA64_PSR_IC+IA64_PSR_I+IA64_PSR_DT+IA64_PSR_SI+IA64_PSR_PP
   1.108  
   1.109 -    ld1 r23=[r22]
   1.110 -    sub r27=-1,r26 // ~r26
   1.111 -    mov r24=b0
   1.112 +    sub r27=-1,r18 // ~imm24
   1.113      ;;
   1.114 -    mov r20=cr.ipsr
   1.115      or r28=r27,r28 // Keep IC,I,DT,SI
   1.116 -    and r19=r18,r27 // Update vpsr
   1.117 -    ;;   
   1.118 +    and r19=r26,r27 // Update vpsr
   1.119 +    ;;
   1.120      st8 [r17]=r19
   1.121 -    and r20=r20,r28 // Update ipsr
   1.122 +    mov r24=cr.ipsr
   1.123 +    ;;
   1.124 +    and r24=r24,r28 // Update ipsr
   1.125      adds r27=IA64_VCPU_FP_PSR_OFFSET,r21
   1.126      ;;
   1.127      ld8 r27=[r27]
   1.128      ;;
   1.129      tbit.nz p8,p0=r27,IA64_PSR_DFH_BIT
   1.130      ;;
   1.131 -    (p8) dep r20=-1,r20,IA64_PSR_DFH_BIT,1  // Keep dfh
   1.132 +    (p8) dep r24=-1,r24,IA64_PSR_DFH_BIT,1  // Keep dfh
   1.133      ;;
   1.134 -    mov cr.ipsr=r20
   1.135 -    cmp.ne p6,p0=VMX_MMU_VIRTUAL,r23
   1.136 +    mov cr.ipsr=r24
   1.137 +    //sync write
   1.138 +    mov r25=r16
   1.139 +    movl r24=vmx_asm_rsm_sync_write_return
   1.140 +    br.sptk.many vmx_vps_sync_write
   1.141      ;;
   1.142 -    tbit.z.or p6,p0=r26,IA64_PSR_DT_BIT
   1.143 -    (p6) br.dptk vmx_resume_to_guest  // DT not cleared or already in phy mode
   1.144 +vmx_asm_rsm_sync_write_return:
   1.145 +    add r29=IA64_VCPU_MMU_MODE_OFFSET,r21
   1.146 +    ;;
   1.147 +    ld1 r27=[r29]
   1.148 +    ;;
   1.149 +    cmp.ne p6,p0=VMX_MMU_VIRTUAL,r27
   1.150 +    ;;
   1.151 +    tbit.z.or p6,p0=r18,IA64_PSR_DT_BIT
   1.152 +    (p6) br.dptk vmx_asm_rsm_out
   1.153 +    // DT not cleared or already in phy mode
   1.154      ;;
   1.155      // Switch to meta physical mode D.
   1.156      add r26=IA64_VCPU_META_RID_D_OFFSET,r21
   1.157 -    mov r23=VMX_MMU_PHY_D
   1.158 +    mov r27=VMX_MMU_PHY_D
   1.159      ;;
   1.160      ld8 r26=[r26]
   1.161 -    st1 [r22]=r23 
   1.162 +    st1 [r29]=r27 
   1.163      dep.z r28=4,61,3
   1.164      ;;
   1.165      mov rr[r0]=r26
   1.166 @@ -242,6 +324,9 @@ GLOBAL_ENTRY(vmx_asm_rsm)
   1.167      mov rr[r28]=r26
   1.168      ;;
   1.169      srlz.d
   1.170 +vmx_asm_rsm_out:	
   1.171 +    mov r31=r23
   1.172 +    mov r24=r20
   1.173      br.many vmx_resume_to_guest
   1.174  END(vmx_asm_rsm)
   1.175  
   1.176 @@ -251,6 +336,7 @@ GLOBAL_ENTRY(vmx_asm_ssm)
   1.177  #ifndef ACCE_SSM
   1.178      br.many vmx_virtualization_fault_back
   1.179  #endif
   1.180 +    mov r23=r31
   1.181      add r16=IA64_VPD_BASE_OFFSET,r21
   1.182      extr.u r26=r25,6,21
   1.183      extr.u r27=r25,31,2
   1.184 @@ -258,40 +344,55 @@ GLOBAL_ENTRY(vmx_asm_ssm)
   1.185      ld8 r16=[r16]
   1.186      extr.u r28=r25,36,1
   1.187      dep r26=r27,r26,21,2
   1.188 -    ;;  //r26 is imm24
   1.189 +    ;;  //r18 is imm24
   1.190 +    dep r18=r28,r26,23,1
   1.191 +    ;;  
   1.192 +    //sync read
   1.193 +    mov r25=r16
   1.194 +    movl r24=vmx_asm_ssm_sync_read_return
   1.195 +    mov r20=b0
   1.196 +    br.sptk.many vmx_vps_sync_read
   1.197 +    ;;
   1.198 +vmx_asm_ssm_sync_read_return:
   1.199      add r27=VPD_VPSR_START_OFFSET,r16
   1.200 -    dep r26=r28,r26,23,1
   1.201 -    ;;  //r19 vpsr
   1.202 -    ld8 r29=[r27]
   1.203 -    mov r24=b0
   1.204 -    dep r17=0,r26,IA64_PSR_PP_BIT,1 // For xenoprof
   1.205 +    ;;
   1.206 +    ld8 r17=[r27]		//r17 old vpsr
   1.207 +    dep r28=0,r18,IA64_PSR_PP_BIT,1 // For xenoprof
   1.208                                      // Don't change mPSR.pp
   1.209                                      // It is maintained by xenoprof.
   1.210      ;;
   1.211 -    add r22=IA64_VCPU_MMU_MODE_OFFSET,r21
   1.212 -    mov r20=cr.ipsr
   1.213 -    or r19=r29,r26
   1.214 +    or r19=r17,r18		//r19 new vpsr
   1.215      ;;
   1.216 -    ld1 r23=[r22] // mmu_mode
   1.217 -    st8 [r27]=r19 // vpsr
   1.218 -    or r20=r20,r17
   1.219 +    st8 [r27]=r19 // update vpsr
   1.220 +    mov r24=cr.ipsr
   1.221      ;;
   1.222 -    mov cr.ipsr=r20
   1.223 +    or r24=r24,r28
   1.224 +    ;;
   1.225 +    mov cr.ipsr=r24
   1.226 +    //sync_write
   1.227 +    mov r25=r16
   1.228 +    movl r24=vmx_asm_ssm_sync_write_return
   1.229 +    br.sptk.many vmx_vps_sync_write
   1.230 +    ;;
   1.231 +vmx_asm_ssm_sync_write_return:	
   1.232 +    add r29=IA64_VCPU_MMU_MODE_OFFSET,r21
   1.233      movl r28=IA64_PSR_DT+IA64_PSR_RT+IA64_PSR_IT
   1.234      ;;
   1.235 -    and r19=r28,r19
   1.236 -    cmp.eq p6,p0=VMX_MMU_VIRTUAL,r23
   1.237 +    ld1 r30=[r29] // mmu_mode
   1.238      ;;
   1.239 -    cmp.ne.or p6,p0=r28,r19 // (vpsr & (it+dt+rt)) /= (it+dt+rt) ie stay in phy
   1.240 +    and r27=r28,r19
   1.241 +    cmp.eq p6,p0=VMX_MMU_VIRTUAL,r30
   1.242 +    ;;
   1.243 +    cmp.ne.or p6,p0=r28,r27 // (vpsr & (it+dt+rt)) /= (it+dt+rt) ie stay in phy
   1.244      (p6) br.dptk vmx_asm_ssm_1
   1.245      ;;
   1.246      add r26=IA64_VCPU_META_SAVED_RR0_OFFSET,r21
   1.247      add r27=IA64_VCPU_META_SAVED_RR0_OFFSET+8,r21
   1.248 -    mov r23=VMX_MMU_VIRTUAL
   1.249 +    mov r30=VMX_MMU_VIRTUAL
   1.250      ;;
   1.251      ld8 r26=[r26]
   1.252      ld8 r27=[r27]
   1.253 -    st1 [r22]=r23
   1.254 +    st1 [r29]=r30
   1.255      dep.z r28=4,61,3
   1.256      ;;
   1.257      mov rr[r0]=r26
   1.258 @@ -301,10 +402,10 @@ GLOBAL_ENTRY(vmx_asm_ssm)
   1.259      srlz.d
   1.260      ;;
   1.261  vmx_asm_ssm_1:
   1.262 -    tbit.nz p6,p0=r29,IA64_PSR_I_BIT
   1.263 +    tbit.nz p6,p0=r17,IA64_PSR_I_BIT
   1.264      ;;
   1.265      tbit.z.or p6,p0=r19,IA64_PSR_I_BIT
   1.266 -    (p6) br.dptk vmx_resume_to_guest
   1.267 +    (p6) br.dptk vmx_asm_ssm_out
   1.268      ;;
   1.269      add r29=VPD_VTPR_START_OFFSET,r16
   1.270      add r30=VPD_VHPI_START_OFFSET,r16
   1.271 @@ -316,9 +417,14 @@ vmx_asm_ssm_1:
   1.272      extr.u r18=r29,16,1
   1.273      ;;
   1.274      dep r17=r18,r17,4,1
   1.275 +    mov r31=r23
   1.276 +    mov b0=r20
   1.277      ;;
   1.278      cmp.gt p6,p0=r30,r17
   1.279      (p6) br.dpnt.few vmx_asm_dispatch_vexirq
   1.280 +vmx_asm_ssm_out:	
   1.281 +    mov r31=r23
   1.282 +    mov r24=r20
   1.283      br.many vmx_resume_to_guest
   1.284  END(vmx_asm_ssm)
   1.285  
   1.286 @@ -328,33 +434,47 @@ GLOBAL_ENTRY(vmx_asm_mov_to_psr)
   1.287  #ifndef ACCE_MOV_TO_PSR
   1.288      br.many vmx_virtualization_fault_back
   1.289  #endif
   1.290 +    mov r23=r31
   1.291      add r16=IA64_VPD_BASE_OFFSET,r21
   1.292      extr.u r26=r25,13,7 //r2
   1.293      ;;
   1.294      ld8 r16=[r16]
   1.295 -    movl r20=asm_mov_from_reg
   1.296 +    movl r24=asm_mov_from_reg
   1.297      ;;
   1.298 -    adds r30=vmx_asm_mov_to_psr_back-asm_mov_from_reg,r20
   1.299 -    shladd r26=r26,4,r20
   1.300 -    mov r24=b0
   1.301 +    adds r30=vmx_asm_mov_to_psr_back-asm_mov_from_reg,r24
   1.302 +    shladd r26=r26,4,r24
   1.303 +    mov r20=b0
   1.304      ;;
   1.305 -    add r27=VPD_VPSR_START_OFFSET,r16
   1.306      mov b0=r26
   1.307      br.many b0
   1.308      ;;   
   1.309  vmx_asm_mov_to_psr_back:
   1.310 -    ld8 r17=[r27] // vpsr
   1.311 -    add r22=IA64_VCPU_MMU_MODE_OFFSET,r21
   1.312 +    //sync read
   1.313 +    mov r25=r16
   1.314 +    movl r24=vmx_asm_mov_to_psr_sync_read_return
   1.315 +    br.sptk.many vmx_vps_sync_read
   1.316 +    ;;
   1.317 +vmx_asm_mov_to_psr_sync_read_return:
   1.318 +    add r27=VPD_VPSR_START_OFFSET,r16
   1.319 +    ;;
   1.320 +    ld8 r17=[r27] // r17 old vpsr
   1.321      dep r19=0,r19,32,32 // Clear bits 32-63
   1.322      ;;   
   1.323 -    ld1 r23=[r22] // mmu_mode
   1.324      dep r18=0,r17,0,32
   1.325      ;; 
   1.326 -    or r30=r18,r19
   1.327 +    or r18=r18,r19 //r18 new vpsr
   1.328 +    ;;
   1.329 +    st8 [r27]=r18 // set vpsr
   1.330 +    //sync write
   1.331 +    mov r25=r16
   1.332 +    movl r24=vmx_asm_mov_to_psr_sync_write_return
   1.333 +    br.sptk.many vmx_vps_sync_write
   1.334 +    ;;
   1.335 +vmx_asm_mov_to_psr_sync_write_return:
   1.336 +    add r22=IA64_VCPU_MMU_MODE_OFFSET,r21
   1.337      movl r28=IA64_PSR_DT+IA64_PSR_RT+IA64_PSR_IT
   1.338      ;;
   1.339 -    st8 [r27]=r30 // set vpsr
   1.340 -    and r27=r28,r30
   1.341 +    and r27=r28,r18
   1.342      and r29=r28,r17
   1.343      ;;
   1.344      cmp.eq p5,p0=r29,r27 // (old_vpsr & (dt+rt+it)) == (new_vpsr & (dt+rt+it))
   1.345 @@ -364,16 +484,16 @@ vmx_asm_mov_to_psr_back:
   1.346      //virtual to physical D
   1.347      (p7) add r26=IA64_VCPU_META_RID_D_OFFSET,r21
   1.348      (p7) add r27=IA64_VCPU_META_RID_D_OFFSET,r21
   1.349 -    (p7) mov r23=VMX_MMU_PHY_D
   1.350 +    (p7) mov r30=VMX_MMU_PHY_D
   1.351      ;;
   1.352      //physical to virtual
   1.353      (p6) add r26=IA64_VCPU_META_SAVED_RR0_OFFSET,r21
   1.354      (p6) add r27=IA64_VCPU_META_SAVED_RR0_OFFSET+8,r21
   1.355 -    (p6) mov r23=VMX_MMU_VIRTUAL
   1.356 +    (p6) mov r30=VMX_MMU_VIRTUAL
   1.357      ;;
   1.358      ld8 r26=[r26]
   1.359      ld8 r27=[r27]
   1.360 -    st1 [r22]=r23
   1.361 +    st1 [r22]=r30
   1.362      dep.z r28=4,61,3
   1.363      ;;
   1.364      mov rr[r0]=r26
   1.365 @@ -383,18 +503,17 @@ vmx_asm_mov_to_psr_back:
   1.366      srlz.d
   1.367      ;;
   1.368  vmx_asm_mov_to_psr_1:
   1.369 -    mov r20=cr.ipsr
   1.370 +    mov r24=cr.ipsr
   1.371      movl r28=IA64_PSR_IC+IA64_PSR_I+IA64_PSR_DT+IA64_PSR_SI+IA64_PSR_RT
   1.372      ;;
   1.373 -    tbit.nz p7,p0=r20,IA64_PSR_PP_BIT           // For xenoprof
   1.374 -    or r19=r19,r28
   1.375 -    dep r20=0,r20,0,32
   1.376 +    tbit.nz p7,p0=r24,IA64_PSR_PP_BIT           // For xenoprof
   1.377 +    or r27=r19,r28
   1.378 +    dep r24=0,r24,0,32
   1.379      ;;
   1.380 -    add r20=r19,r20
   1.381 -    mov b0=r24
   1.382 +    add r24=r27,r24
   1.383      ;;
   1.384      adds r27=IA64_VCPU_FP_PSR_OFFSET,r21
   1.385 -    (p7) dep r20=-1,r20,IA64_PSR_PP_BIT,1       // For xenoprof
   1.386 +    (p7) dep r24=-1,r24,IA64_PSR_PP_BIT,1       // For xenoprof
   1.387                                                  // Dom't change mPSR.pp
   1.388                                                  // It is maintaned by xenoprof
   1.389      ;;
   1.390 @@ -402,14 +521,13 @@ vmx_asm_mov_to_psr_1:
   1.391      ;;
   1.392      tbit.nz p8,p0=r27,IA64_PSR_DFH_BIT
   1.393      ;;
   1.394 -    (p8) dep r20=-1,r20,IA64_PSR_DFH_BIT,1
   1.395 +    (p8) dep r24=-1,r24,IA64_PSR_DFH_BIT,1
   1.396      ;;
   1.397 -    mov cr.ipsr=r20
   1.398 -    cmp.ne p6,p0=r0,r0
   1.399 +    mov cr.ipsr=r24
   1.400 +    tbit.nz p6,p0=r17,IA64_PSR_I_BIT
   1.401      ;;
   1.402 -    tbit.nz.or p6,p0=r17,IA64_PSR_I_BIT
   1.403 -    tbit.z.or p6,p0=r30,IA64_PSR_I_BIT
   1.404 -    (p6) br.dpnt.few vmx_resume_to_guest
   1.405 +    tbit.z.or p6,p0=r18,IA64_PSR_I_BIT
   1.406 +    (p6) br.dpnt.few vmx_asm_mov_to_psr_out
   1.407      ;;
   1.408      add r29=VPD_VTPR_START_OFFSET,r16
   1.409      add r30=VPD_VHPI_START_OFFSET,r16
   1.410 @@ -421,9 +539,14 @@ vmx_asm_mov_to_psr_1:
   1.411      extr.u r18=r29,16,1
   1.412      ;;
   1.413      dep r17=r18,r17,4,1
   1.414 +    mov r31=r23
   1.415 +    mov b0=r20
   1.416      ;;
   1.417      cmp.gt p6,p0=r30,r17
   1.418      (p6) br.dpnt.few vmx_asm_dispatch_vexirq
   1.419 +vmx_asm_mov_to_psr_out:
   1.420 +    mov r31=r23
   1.421 +    mov r24=r20
   1.422      br.many vmx_resume_to_guest
   1.423  END(vmx_asm_mov_to_psr)
   1.424  
   1.425 @@ -767,40 +890,25 @@ END(asm_mov_from_reg)
   1.426   */
   1.427  ENTRY(vmx_resume_to_guest)
   1.428      mov r16=cr.ipsr
   1.429 -    movl r20=__vsa_base
   1.430      ;;
   1.431 -    ld8 r20=[r20]
   1.432      adds r19=IA64_VPD_BASE_OFFSET,r21
   1.433 +    extr.u r17=r16,IA64_PSR_RI_BIT,2
   1.434      ;;
   1.435      ld8 r25=[r19]
   1.436 -    extr.u r17=r16,IA64_PSR_RI_BIT,2
   1.437 -    tbit.nz p6,p7=r16,IA64_PSR_RI_BIT+1
   1.438 -    ;;	
   1.439 -    (p6) mov r18=cr.iip
   1.440 -    (p6) mov r17=r0
   1.441 -    ;;    
   1.442 -    (p6) add r18=0x10,r18
   1.443 -    (p7) add r17=1,r17
   1.444 -    ;;		
   1.445 -    (p6) mov cr.iip=r18
   1.446 +    add r17=1,r17
   1.447 +    ;;
   1.448 +    adds r19= VPD_VPSR_START_OFFSET,r25
   1.449      dep r16=r17,r16,IA64_PSR_RI_BIT,2
   1.450      ;;
   1.451      mov cr.ipsr=r16
   1.452 -    adds r19= VPD_VPSR_START_OFFSET,r25
   1.453 -    add r28=PAL_VPS_RESUME_NORMAL,r20
   1.454 -    add r29=PAL_VPS_RESUME_HANDLER,r20
   1.455 -    ;;
   1.456      ld8 r19=[r19]
   1.457 -    mov b0=r29
   1.458 -    cmp.ne p6,p7 = r0,r0
   1.459 -    ;;
   1.460 -    tbit.z p6,p7 = r19,IA64_PSR_IC_BIT		// p1=vpsr.ic
   1.461      ;;
   1.462 -    (p6) ld8 r26=[r25]
   1.463 -    (p7) mov b0=r28
   1.464 -    mov pr=r31,-2
   1.465 -    br.sptk.many b0             // call pal service
   1.466 -    ;;
   1.467 +    mov r23=r31
   1.468 +    mov r17=r0
   1.469 +    //vps_resume_normal/handler
   1.470 +    tbit.z p6,p7 = r19,IA64_PSR_IC_BIT		// p1=vpsr.ic
   1.471 +    (p6) br.cond.sptk.many vmx_vps_resume_handler
   1.472 +    (p7) br.cond.sptk.few vmx_vps_resume_normal
   1.473  END(vmx_resume_to_guest)
   1.474  
   1.475  
     2.1 --- a/xen/arch/ia64/vmx/vmx_entry.S	Tue Apr 01 11:29:03 2008 -0600
     2.2 +++ b/xen/arch/ia64/vmx/vmx_entry.S	Mon Apr 14 13:59:45 2008 -0600
     2.3 @@ -370,20 +370,16 @@ vmx_rse_clear_invalid:
     2.4      adds r19=VPD(VPSR),r18
     2.5      ;;
     2.6      ld8 r19=[r19]        //vpsr
     2.7 -    movl r20=__vsa_base
     2.8      ;;
     2.9  //vsa_sync_write_start
    2.10 -    ld8 r20=[r20]       // read entry point
    2.11 -    mov r25=r18
    2.12 -    ;;
    2.13      movl r24=ia64_vmm_entry  // calculate return address
    2.14 -    add r16=PAL_VPS_SYNC_WRITE,r20
    2.15 -    ;;
    2.16 -    mov b0=r16
    2.17 -    br.cond.sptk b0         // call the service
    2.18 +    mov r25=r18
    2.19 +    br.sptk.many vmx_vps_sync_write        // call the service
    2.20      ;;
    2.21  END(ia64_leave_hypervisor)
    2.22  // fall through
    2.23 +
    2.24 +
    2.25  GLOBAL_ENTRY(ia64_vmm_entry)
    2.26  /*
    2.27   *  must be at bank 0
    2.28 @@ -391,32 +387,18 @@ GLOBAL_ENTRY(ia64_vmm_entry)
    2.29   *  r17:cr.isr
    2.30   *  r18:vpd
    2.31   *  r19:vpsr
    2.32 - *  r20:__vsa_base
    2.33   *  r22:b0
    2.34   *  r23:predicate
    2.35   */
    2.36      mov r24=r22
    2.37      mov r25=r18
    2.38      tbit.nz p1,p2 = r19,IA64_PSR_IC_BIT        // p1=vpsr.ic
    2.39 -    ;;
    2.40 -    (p1) add r29=PAL_VPS_RESUME_NORMAL,r20
    2.41 -    (p1) br.sptk.many ia64_vmm_entry_out
    2.42 -    ;;
    2.43 -    tbit.nz p1,p2 = r17,IA64_ISR_IR_BIT		//p1=cr.isr.ir
    2.44 +    (p1) br.cond.sptk.few vmx_vps_resume_normal
    2.45 +    (p2) br.cond.sptk.many vmx_vps_resume_handler
    2.46      ;;
    2.47 -    (p1) add r29=PAL_VPS_RESUME_NORMAL,r20
    2.48 -    (p2) add r29=PAL_VPS_RESUME_HANDLER,r20
    2.49 -    (p2) ld8 r26=[r25]
    2.50 -    ;;
    2.51 -ia64_vmm_entry_out:    
    2.52 -    mov pr=r23,-2
    2.53 -    mov b0=r29
    2.54 -    ;;
    2.55 -    br.cond.sptk b0             // call pal service
    2.56  END(ia64_vmm_entry)
    2.57  
    2.58  
    2.59 -
    2.60  /*
    2.61   * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't
    2.62   *  need to switch to bank 0 and doesn't restore the scratch registers.
     3.1 --- a/xen/arch/ia64/vmx/vmx_init.c	Tue Apr 01 11:29:03 2008 -0600
     3.2 +++ b/xen/arch/ia64/vmx/vmx_init.c	Mon Apr 14 13:59:45 2008 -0600
     3.3 @@ -54,6 +54,7 @@
     3.4  #include <asm/vlsapic.h>
     3.5  #include <asm/vhpt.h>
     3.6  #include <asm/vmx_pal_vsa.h>
     3.7 +#include <asm/patch.h>
     3.8  #include "entry.h"
     3.9  
    3.10  /* Global flag to identify whether Intel vmx feature is on */
    3.11 @@ -64,6 +65,28 @@ static u64 vm_buffer = 0;	/* Buffer requ
    3.12  u64 __vsa_base = 0;	/* Run-time service base of VMX */
    3.13  
    3.14  /* Check whether vt feature is enabled or not. */
    3.15 +
    3.16 +void vmx_vps_patch(void)
    3.17 +{
    3.18 +	u64 addr;
    3.19 +	
    3.20 +	addr = (u64)&vmx_vps_sync_read;
    3.21 +	ia64_patch_imm64(addr, __vsa_base+PAL_VPS_SYNC_READ);
    3.22 +	ia64_fc((void *)addr);
    3.23 +	addr = (u64)&vmx_vps_sync_write;
    3.24 +	ia64_patch_imm64(addr, __vsa_base+PAL_VPS_SYNC_WRITE);
    3.25 +	ia64_fc((void *)addr);
    3.26 +	addr = (u64)&vmx_vps_resume_normal;
    3.27 +	ia64_patch_imm64(addr, __vsa_base+PAL_VPS_RESUME_NORMAL);
    3.28 +	ia64_fc((void *)addr);
    3.29 +	addr = (u64)&vmx_vps_resume_handler;
    3.30 +	ia64_patch_imm64(addr, __vsa_base+PAL_VPS_RESUME_HANDLER);
    3.31 +	ia64_fc((void *)addr);
    3.32 +	ia64_sync_i();
    3.33 +	ia64_srlz_i();	
    3.34 +}
    3.35 +
    3.36 +
    3.37  void
    3.38  identify_vmx_feature(void)
    3.39  {
    3.40 @@ -152,8 +175,10 @@ vmx_init_env(void *start, unsigned long 
    3.41  		return start;
    3.42  	}
    3.43  
    3.44 -	if (!__vsa_base)
    3.45 +	if (!__vsa_base){
    3.46  		__vsa_base = tmp_base;
    3.47 +		vmx_vps_patch();
    3.48 +	}
    3.49  	else
    3.50  		ASSERT(tmp_base == __vsa_base);
    3.51  
     4.1 --- a/xen/arch/ia64/vmx/vmx_ivt.S	Tue Apr 01 11:29:03 2008 -0600
     4.2 +++ b/xen/arch/ia64/vmx/vmx_ivt.S	Mon Apr 14 13:59:45 2008 -0600
     4.3 @@ -211,11 +211,8 @@ vmx_itlb_loop:
     4.4      ld8 r18=[r16]
     4.5      ;;
     4.6      adds r19=VPD(VPSR),r18
     4.7 -    movl r20=__vsa_base
     4.8      ;;
     4.9      ld8 r19=[r19]
    4.10 -    ld8 r20=[r20]
    4.11 -    ;;
    4.12      br.sptk ia64_vmm_entry
    4.13      ;;
    4.14  vmx_itlb_out:
    4.15 @@ -289,11 +286,8 @@ vmx_dtlb_loop:
    4.16      ld8 r18=[r16]
    4.17      ;;
    4.18      adds r19=VPD(VPSR),r18
    4.19 -    movl r20=__vsa_base
    4.20      ;;
    4.21      ld8 r19=[r19]
    4.22 -    ld8 r20=[r20]
    4.23 -    ;;
    4.24      br.sptk ia64_vmm_entry
    4.25      ;;
    4.26  vmx_dtlb_out:
    4.27 @@ -461,11 +455,8 @@ dirty_bit_tpa_fail:
    4.28      ld8 r18=[r16]
    4.29      ;;
    4.30      adds r19=VPD(VPSR),r18
    4.31 -    movl r20=__vsa_base
    4.32      ;;
    4.33      ld8 r19=[r19]
    4.34 -    ld8 r20=[r20]
    4.35 -    ;;
    4.36      br.sptk ia64_vmm_entry
    4.37      ;;
    4.38  END(vmx_dirty_bit)
     5.1 --- a/xen/arch/ia64/vmx/vmx_minstate.h	Tue Apr 01 11:29:03 2008 -0600
     5.2 +++ b/xen/arch/ia64/vmx/vmx_minstate.h	Mon Apr 14 13:59:45 2008 -0600
     5.3 @@ -57,24 +57,16 @@
     5.4  
     5.5  #define PAL_VSA_SYNC_READ                               \
     5.6      /* begin to call pal vps sync_read */               \
     5.7 +{ .mii;                                                 \
     5.8  (pUStk) add r25=IA64_VPD_BASE_OFFSET, r21;              \
     5.9 -(pUStk) movl r20=__vsa_base;                            \
    5.10 -    ;;                                                  \
    5.11 -(pUStk) ld8 r25=[r25];          /* read vpd base */     \
    5.12 -(pUStk) ld8 r20=[r20];          /* read entry point */  \
    5.13 -    ;;                                                  \
    5.14 -(pUStk) add r20=PAL_VPS_SYNC_READ,r20;                  \
    5.15 -    ;;                                                  \
    5.16 -{ .mii;                                                 \
    5.17  (pUStk) nop 0x0;                                        \
    5.18  (pUStk) mov r24=ip;                                     \
    5.19 -(pUStk) mov b0=r20;                                     \
    5.20      ;;                                                  \
    5.21  };                                                      \
    5.22  { .mmb;                                                 \
    5.23  (pUStk) add r24 = 0x20, r24;                            \
    5.24 -(pUStk) nop 0x0;                                        \
    5.25 -(pUStk) br.cond.sptk b0;        /*  call the service */ \
    5.26 +(pUStk) ld8 r25=[r25];          /* read vpd base */     \
    5.27 +(pUStk) br.cond.sptk vmx_vps_sync_read;        /*  call the service */ \
    5.28      ;;                                                  \
    5.29  };
    5.30  
     6.1 --- a/xen/include/asm-ia64/vmx_pal_vsa.h	Tue Apr 01 11:29:03 2008 -0600
     6.2 +++ b/xen/include/asm-ia64/vmx_pal_vsa.h	Mon Apr 14 13:59:45 2008 -0600
     6.3 @@ -28,6 +28,14 @@
     6.4  #ifndef __ASSEMBLY__
     6.5  extern u64 ia64_call_vsa(u64 proc, u64 arg1, u64 arg2, u64 arg3,
     6.6                           u64 arg4, u64 arg5, u64 arg6, u64 arg7);
     6.7 +
     6.8 +/* entry points in assembly code for calling vps services */
     6.9 +
    6.10 +extern char vmx_vps_sync_read;
    6.11 +extern char vmx_vps_sync_write;
    6.12 +extern char vmx_vps_resume_normal;
    6.13 +extern char vmx_vps_resume_handler;
    6.14 +
    6.15  extern u64 __vsa_base;
    6.16  #endif  /* __ASSEMBLY__ */
    6.17