[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [IA64] Build new infrastructure for fast fault handling path.
# HG changeset patch # User Isaku Yamahata <yamahata@xxxxxxxxxxxxx> # Date 1210830828 -32400 # Node ID ef290f39ae6b8e3c58c224ec469ab09522cc7e0b # Parent b03e24f9c1d85e50fcd9cb07d8a517e7f6df2b9a [IA64] Build new infrastructure for fast fault handling path. 1. use jump table to dispatch virtualization faults. 2. for virtualization faults, handler is executed with psr.i=0, psr.ic=0, psr.bn=0. less context switch. 3. use register stack instead of memory stack to switch context. 4. Use C code to handle faults as possible, to reduce maintanance efforts, remove assembly handlers for rsm , ssm, mov to psr, mov to rr. 5. add fast path C handler for rsm, ssm, mov to psr, rfi. Signed-off-by: Anthony Xu <anthony.xu@xxxxxxxxx> --- xen/arch/ia64/asm-offsets.c | 5 xen/arch/ia64/vmx/optvfault.S | 1196 +++++++++++++++++++----------------- xen/arch/ia64/vmx/vmx_ivt.S | 39 - xen/arch/ia64/vmx/vmx_phy_mode.c | 27 xen/arch/ia64/vmx/vmx_vcpu.c | 162 ++++ xen/include/asm-ia64/vmx_phy_mode.h | 3 xen/include/asm-ia64/vmx_vcpu.h | 2 7 files changed, 862 insertions(+), 572 deletions(-) diff -r b03e24f9c1d8 -r ef290f39ae6b xen/arch/ia64/asm-offsets.c --- a/xen/arch/ia64/asm-offsets.c Thu May 15 14:18:38 2008 +0900 +++ b/xen/arch/ia64/asm-offsets.c Thu May 15 14:53:48 2008 +0900 @@ -204,6 +204,11 @@ void foo(void) DEFINE(IA64_VPD_BASE_OFFSET, offsetof (struct vcpu, arch.privregs)); DEFINE(IA64_VPD_VIFS_OFFSET, offsetof (mapped_regs_t, ifs)); + DEFINE(IA64_VPD_VHPI_OFFSET, offsetof (mapped_regs_t, vhpi)); + DEFINE(IA64_VPD_VB1REG_OFFSET, offsetof (mapped_regs_t, bank1_regs[0])); + DEFINE(IA64_VPD_VB0REG_OFFSET, offsetof (mapped_regs_t, bank0_regs[0])); + DEFINE(IA64_VPD_VB1NAT_OFFSET, offsetof (mapped_regs_t, vnat)); + DEFINE(IA64_VPD_VB0NAT_OFFSET, offsetof (mapped_regs_t, vbnat)); DEFINE(IA64_VLSAPIC_INSVC_BASE_OFFSET, offsetof (struct vcpu, arch.insvc[0])); DEFINE(IA64_VPD_VPTA_OFFSET, offsetof (struct mapped_regs, pta)); DEFINE(XXX_THASH_SIZE, sizeof (thash_data_t)); diff -r b03e24f9c1d8 -r ef290f39ae6b xen/arch/ia64/vmx/optvfault.S --- a/xen/arch/ia64/vmx/optvfault.S Thu May 15 14:18:38 2008 +0900 +++ b/xen/arch/ia64/vmx/optvfault.S Thu May 15 14:53:48 2008 +0900 @@ -3,10 +3,10 @@ * optimize virtualization fault handler * * Copyright (C) 2006 Intel Co - * Xuefei Xu (Anthony Xu) <anthony.xu@xxxxxxxxx> + * Xuefei Xu (Anthony Xu) <anthony.xu@xxxxxxxxx> */ -#include <linux/config.h> +#include <linux/config.h> #include <asm/config.h> #include <asm/pgtable.h> #include <asm/asmmacro.h> @@ -20,26 +20,230 @@ #include <asm/virt_event.h> #include <asm-ia64/vmx_mm_def.h> #include <asm-ia64/vmx_phy_mode.h> - -#define ACCE_MOV_FROM_AR -#define ACCE_MOV_FROM_RR -#define ACCE_MOV_TO_RR -#define ACCE_RSM -#define ACCE_SSM -#define ACCE_MOV_TO_PSR -#define ACCE_THASH +#include "entry.h" + +// r21 : current +// r23 : b0 +// r31 : pr + +#define VMX_VIRT_SAVE \ + mov r27=ar.rsc; /* M */ \ + ;; \ + cover; /* B;; (or nothing) */ \ + ;; \ + /* switch from user to kernel RBS: */ \ + invala; /* M */ \ + ;; \ + mov ar.rsc=0; /* set enforced lazy mode */ \ + ;; \ + mov.m r26=ar.rnat; \ + movl r28=IA64_RBS_OFFSET; /* compute base of RBS */ \ + ;; \ + mov r22=ar.bspstore; /* save ar.bspstore */ \ + add r28=r28,r21; \ + ;; \ + mov ar.bspstore=r28; /* switch to kernel RBS */ \ + ;; \ + mov r18=ar.bsp; \ + mov ar.rsc=0x3; /* set eager mode */ \ + ;; \ + alloc r32=ar.pfs,24,0,3,0 /* save pfs */ \ + ;; \ + sub r18=r18,r28; /* r18=RSE.ndirty*8 */ \ + ;; \ + shl r33=r18,16; /* save loadrs */ \ + mov r35=b6; /* save b6 */ \ + mov r36=b7; /* save b7 */ \ + mov r37=ar.csd; /* save ar.csd */ \ + mov r38=ar.ssd; /* save ar.ssd */ \ + mov r39=r8; /* save r8 */ \ + mov r40=r9; /* save r9 */ \ + mov r41=r10; /* save r10 */ \ + mov r42=r11; /* save r11 */ \ + mov r43=r27; /* save ar.rsc */ \ + mov r44=r26; /* save ar.rnat */ \ + mov r45=r22; /* save ar.bspstore */ \ + mov r46=r31; /* save pr */ \ + mov r47=r23; /* save b0 */ \ + mov r48=r1; /* save r1 */ \ + mov r49=r12; /* save r12 */ \ + mov r50=r13; /* save r13 */ \ + mov r51=r15; /* save r15 */ \ + mov r52=r14; /* save r14 */ \ + mov r53=r2; /* save r2 */ \ + mov r54=r3; /* save r3 */ \ + mov r34=ar.ccv; /* save ar.ccv */ \ + ;; \ + movl r1=__gp; \ + movl r29=IA64_STK_OFFSET-IA64_PT_REGS_SIZE-16; \ + ;; \ + add r12=r29,r21; /* compute base of memory stack */ \ + mov r13=r21; \ + ;; \ +{ .mii; /* call vps sync read */ \ + add r25=IA64_VPD_BASE_OFFSET, r21; \ + nop 0x0; \ + mov r24=ip; \ + ;; \ +}; \ +{ .mmb; \ + add r24 = 0x20, r24; \ + ld8 r25=[r25]; /* read vpd base */ \ + br.cond.sptk vmx_vps_sync_read; /* call the service */ \ + ;; \ +}; + + +ENTRY(ia64_leave_hypervisor_virt) + invala /* M */ + ;; + mov r21=r13 /* get current */ + mov b6=r35 /* restore b6 */ + mov b7=r36 /* restore b7 */ + mov ar.csd=r37 /* restore ar.csd */ + mov ar.ssd=r38 /* restore ar.ssd */ + mov r8=r39 /* restore r8 */ + mov r9=r40 /* restore r9 */ + mov r10=r41 /* restore r10 */ + mov r11=r42 /* restore r11 */ + mov ar.pfs=r32 /* restore ar.pfs */ + mov r27=r43 /* restore ar.rsc */ + mov r26=r44 /* restore ar.rnat */ + mov r25=r45 /* restore ar.bspstore */ + mov r23=r46 /* restore predicates */ + mov r22=r47 /* restore b0 */ + mov r1=r48 /* restore r1 */ + mov r12=r49 /* restore r12 */ + mov r13=r50 /* restore r13 */ + mov r15=r51 /* restore r15 */ + mov r14=r52 /* restore r14 */ + mov r2=r53 /* restore r2 */ + mov r3=r54 /* restore r3 */ + mov ar.ccv=r34 /* restore ar.ccv */ + mov ar.rsc=r33 /* load ar.rsc to be used for "loadrs" */ + ;; + alloc r16=ar.pfs,0,0,0,0 /* drop current register frame */ + ;; + loadrs + ;; + mov ar.bspstore=r25 + ;; + mov ar.rnat=r26 + ;; + mov ar.rsc=r27 + adds r18=IA64_VPD_BASE_OFFSET,r21 + ;; + ld8 r25=[r18] // load vpd + mov r17=r0 + ;; +//vsa_sync_write_start + ;; + movl r24=ia64_leave_hypervisor_virt_1 // calculate return address + br.cond.sptk vmx_vps_sync_write // call the service + ;; +ia64_leave_hypervisor_virt_1: + mov r24=r22 + mov r31=r23 + br.cond.sptk vmx_resume_to_guest +END(ia64_leave_hypervisor_virt) + + // Inputs are: r21 (= current), r24 (= cause), r25 (= insn), r31 (=saved pr) + +#define BACK_TO_SLOW_PATH \ +{; \ + nop.m 0x0; \ + mov b0=r23; \ + br.many vmx_virtualization_fault_back; \ +}; \ + +GLOBAL_ENTRY(virtualization_fault_table) + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH +{ /* Entry 3 */ + cmp.eq p2,p0=r0,r0 + mov b0=r23 + br.many vmx_asm_mov_from_ar +} + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH +{ /* Entry 6 */ + cmp.eq p2,p0=r0,r0 + mov b0=r23 + br.many vmx_asm_mov_to_psr +} + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH +{ /* Entry 10 */ + cmp.eq p2,p0=r0,r0 + mov b0=r23 + br.many vmx_asm_mov_to_rr +} + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH +{ /* Entry 18 */ + cmp.eq p2,p0=r0,r0 + mov b0=r23 + br.many vmx_asm_mov_from_rr +} + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH +{ /* Entry 24 */ + cmp.eq p2,p0=r0,r0 + mov b0=r23 + br.many vmx_asm_ssm +} +{ /* Entry 25 */ + cmp.eq p2,p0=r0,r0 + mov b0=r23 + br.many vmx_asm_rsm +} + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH +{ /* Entry 31 */ + cmp.eq p2,p0=r0,r0 + mov b0=r23 + br.many vmx_asm_thash +} + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH +{ /* Entry 37 */ + cmp.ne p2,p0=r0,r0 + mov b0=r23 + br.many vmx_asm_rfi +} + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH + BACK_TO_SLOW_PATH +END(virtualization_fault_table) + ENTRY(vmx_dummy_function) br.sptk.many vmx_dummy_function END(vmx_dummy_function) /* - * Inputs: - * r24 : return address - * r25 : vpd - * r29 : scratch + * Inputs: + * r24 : return address + * r25 : vpd + * r29 : scratch * */ GLOBAL_ENTRY(vmx_vps_sync_read) @@ -50,11 +254,10 @@ END(vmx_vps_sync_read) END(vmx_vps_sync_read) /* - * Inputs: - * r24 : return address - * r25 : vpd - * r29 : scratch - * + * Inputs: + * r24 : return address + * r25 : vpd + * r29 : scratch */ GLOBAL_ENTRY(vmx_vps_sync_write) movl r29 = vmx_dummy_function @@ -64,11 +267,10 @@ END(vmx_vps_sync_write) END(vmx_vps_sync_write) /* - * Inputs: - * r23 : pr - * r24 : guest b0 - * r25 : vpd - * + * Inputs: + * r23 : pr + * r24 : guest b0 + * r25 : vpd */ GLOBAL_ENTRY(vmx_vps_resume_normal) movl r29 = vmx_dummy_function @@ -79,11 +281,11 @@ END(vmx_vps_resume_normal) END(vmx_vps_resume_normal) /* - * Inputs: - * r23 : pr - * r24 : guest b0 - * r25 : vpd - * r17 : isr + * Inputs: + * r23 : pr + * r24 : guest b0 + * r25 : vpd + * r17 : isr */ GLOBAL_ENTRY(vmx_vps_resume_handler) movl r29 = vmx_dummy_function @@ -97,12 +299,203 @@ GLOBAL_ENTRY(vmx_vps_resume_handler) br.sptk.many b0 END(vmx_vps_resume_handler) +//r13 ->vcpu +//call with psr.bn = 0 +GLOBAL_ENTRY(vmx_asm_bsw0) + mov r15=ar.unat + ;; + adds r14=IA64_VPD_BASE_OFFSET,r13 + ;; + ld8 r14=[r14] + bsw.1 + ;; + adds r2=IA64_VPD_VB1REG_OFFSET, r14 + adds r3=IA64_VPD_VB1REG_OFFSET+8, r14 + ;; + .mem.offset 0,0; st8.spill [r2]=r16,16 + .mem.offset 8,0; st8.spill [r3]=r17,16 + ;; + .mem.offset 0,0; st8.spill [r2]=r18,16 + .mem.offset 8,0; st8.spill [r3]=r19,16 + ;; + .mem.offset 0,0; st8.spill [r2]=r20,16 + .mem.offset 8,0; st8.spill [r3]=r21,16 + ;; + .mem.offset 0,0; st8.spill [r2]=r22,16 + .mem.offset 8,0; st8.spill [r3]=r23,16 + ;; + .mem.offset 0,0; st8.spill [r2]=r24,16 + .mem.offset 8,0; st8.spill [r3]=r25,16 + ;; + .mem.offset 0,0; st8.spill [r2]=r26,16 + .mem.offset 8,0; st8.spill [r3]=r27,16 + ;; + .mem.offset 0,0; st8.spill [r2]=r28,16 + .mem.offset 8,0; st8.spill [r3]=r29,16 + ;; + .mem.offset 0,0; st8.spill [r2]=r30,16 + .mem.offset 8,0; st8.spill [r3]=r31,16 + ;; + mov r9=ar.unat + adds r8=IA64_VPD_VB1NAT_OFFSET, r14 + ;; + st8 [r8]=r9 + adds r8=IA64_VPD_VB0NAT_OFFSET, r14 + ;; + ld8 r9=[r8] + adds r2= IA64_VPD_VB0REG_OFFSET, r14 + adds r3= IA64_VPD_VB0REG_OFFSET+8, r14 + ;; + mov ar.unat=r9 + ;; + ld8.fill r16=[r2],16 + ld8.fill r17=[r3],16 + ;; + ld8.fill r18=[r2],16 + ld8.fill r19=[r3],16 + ;; + ld8.fill r20=[r2],16 + ld8.fill r21=[r3],16 + ;; + ld8.fill r22=[r2],16 + ld8.fill r23=[r3],16 + ;; + ld8.fill r24=[r2],16 + ld8.fill r25=[r3],16 + ;; + ld8.fill r26=[r2],16 + ld8.fill r27=[r3],16 + ;; + ld8.fill r28=[r2],16 + ld8.fill r29=[r3],16 + ;; + ld8.fill r30=[r2],16 + ld8.fill r31=[r3],16 + ;; + mov ar.unat=r15 + ;; + bsw.0 + ;; + br.ret.sptk.many b0 +END(vmx_asm_bsw0) + +//r13 ->vcpu +//call with psr.bn = 0 +GLOBAL_ENTRY(vmx_asm_bsw1) + mov r15=ar.unat + ;; + adds r14=IA64_VPD_BASE_OFFSET,r13 + ;; + ld8 r14=[r14] + bsw.1 + ;; + adds r2=IA64_VPD_VB0REG_OFFSET, r14 + adds r3=IA64_VPD_VB0REG_OFFSET+8, r14 + ;; + .mem.offset 0,0; st8.spill [r2]=r16,16 + .mem.offset 8,0; st8.spill [r3]=r17,16 + ;; + .mem.offset 0,0; st8.spill [r2]=r18,16 + .mem.offset 8,0; st8.spill [r3]=r19,16 + ;; + .mem.offset 0,0; st8.spill [r2]=r20,16 + .mem.offset 8,0; st8.spill [r3]=r21,16 + ;; + .mem.offset 0,0; st8.spill [r2]=r22,16 + .mem.offset 8,0; st8.spill [r3]=r23,16 + ;; + .mem.offset 0,0; st8.spill [r2]=r24,16 + .mem.offset 8,0; st8.spill [r3]=r25,16 + ;; + .mem.offset 0,0; st8.spill [r2]=r26,16 + .mem.offset 8,0; st8.spill [r3]=r27,16 + ;; + .mem.offset 0,0; st8.spill [r2]=r28,16 + .mem.offset 8,0; st8.spill [r3]=r29,16 + ;; + .mem.offset 0,0; st8.spill [r2]=r30,16 + .mem.offset 8,0; st8.spill [r3]=r31,16 + ;; + mov r9=ar.unat + adds r8=IA64_VPD_VB0NAT_OFFSET, r14 + ;; + st8 [r8]=r9 + adds r8=IA64_VPD_VB1NAT_OFFSET, r14 + ;; + ld8 r9=[r8] + adds r2=IA64_VPD_VB1REG_OFFSET, r14 + adds r3=IA64_VPD_VB1REG_OFFSET+8, r14 + ;; + mov ar.unat=r9 + ;; + ld8.fill r16=[r2],16 + ld8.fill r17=[r3],16 + ;; + ld8.fill r18=[r2],16 + ld8.fill r19=[r3],16 + ;; + ld8.fill r20=[r2],16 + ld8.fill r21=[r3],16 + ;; + ld8.fill r22=[r2],16 + ld8.fill r23=[r3],16 + ;; + ld8.fill r24=[r2],16 + ld8.fill r25=[r3],16 + ;; + ld8.fill r26=[r2],16 + ld8.fill r27=[r3],16 + ;; + ld8.fill r28=[r2],16 + ld8.fill r29=[r3],16 + ;; + ld8.fill r30=[r2],16 + ld8.fill r31=[r3],16 + ;; + mov ar.unat=r15 + ;; + bsw.0 + ;; + br.ret.sptk.many b0 +END(vmx_asm_bsw1) + + +// rfi +ENTRY(vmx_asm_rfi) + adds r18=IA64_VPD_BASE_OFFSET,r21 + ;; + ld8 r18=[r18] + ;; + adds r26=IA64_VPD_VIFS_OFFSET,r18 + ;; + ld8 r26=[r26] + ;; + tbit.z p6,p0=r26,63 + (p6) br.cond.dptk.few vmx_asm_rfi_1 + ;; + //if vifs.v=1 desert current register frame + alloc r27=ar.pfs,0,0,0,0 + ;; +vmx_asm_rfi_1: + adds r26=IA64_VPD_VHPI_OFFSET,r18 + ;; + ld8 r26=[r26] + ;; + cmp.ne p6,p0=r26,r0 + (p6) br.cond.dpnt.many vmx_virtualization_fault_back + ;; + VMX_VIRT_SAVE + ;; + mov out0=r21 + movl r14=ia64_leave_hypervisor_virt + ;; + mov rp=r14 + br.call.sptk.many b6=vmx_vcpu_rfi_fast +END(vmx_asm_rfi) + //mov r1=ar3 (only itc is virtualized) -GLOBAL_ENTRY(vmx_asm_mov_from_ar) -#ifndef ACCE_MOV_FROM_AR - br.many vmx_virtualization_fault_back -#endif +ENTRY(vmx_asm_mov_from_ar) add r18=VCPU_VTM_OFFSET_OFS,r21 add r16=VCPU_VTM_LAST_ITC_OFS,r21 extr.u r17=r25,6,7 @@ -127,10 +520,7 @@ END(vmx_asm_mov_from_ar) // mov r1=rr[r3] -GLOBAL_ENTRY(vmx_asm_mov_from_rr) -#ifndef ACCE_MOV_FROM_RR - br.many vmx_virtualization_fault_back -#endif +ENTRY(vmx_asm_mov_from_rr) extr.u r16=r25,20,7 extr.u r17=r25,6,7 movl r20=asm_mov_from_reg @@ -142,8 +532,8 @@ GLOBAL_ENTRY(vmx_asm_mov_from_rr) add r27=VCPU_VRR0_OFS,r21 mov b0=r16 br.many b0 - ;; -vmx_asm_mov_from_rr_back_1: + ;; +vmx_asm_mov_from_rr_back_1: adds r30=vmx_resume_to_guest-asm_mov_from_reg,r20 adds r22=asm_mov_to_reg-asm_mov_from_reg,r20 shr.u r26=r19,61 @@ -158,475 +548,204 @@ END(vmx_asm_mov_from_rr) // mov rr[r3]=r2 -GLOBAL_ENTRY(vmx_asm_mov_to_rr) -#ifndef ACCE_MOV_TO_RR - br.many vmx_virtualization_fault_back -#endif - add r22=IA64_VCPU_RID_BITS_OFFSET,r21 - extr.u r16=r25,20,7 // r3 - extr.u r17=r25,13,7 // r2 - ;; +ENTRY(vmx_asm_mov_to_rr) + extr.u r16=r25,20,7 // r3 + extr.u r17=r25,13,7 // r2 movl r20=asm_mov_from_reg ;; adds r30=vmx_asm_mov_to_rr_back_1-asm_mov_from_reg,r20 - shladd r16=r16,4,r20 // get r3 - mov r18=b0 // save b0 - ;; - add r27=VCPU_VRR0_OFS,r21 + shladd r16=r16,4,r20 // get r3 + ;; mov b0=r16 br.many b0 - ;; + ;; vmx_asm_mov_to_rr_back_1: adds r30=vmx_asm_mov_to_rr_back_2-asm_mov_from_reg,r20 - shr.u r23=r19,61 // get RR # - shladd r17=r17,4,r20 // get r2 + shr.u r16=r19,61 // get RR # ;; //if rr7, go back - cmp.eq p6,p0=7,r23 - mov b0=r18 // restore b0 + cmp.eq p6,p0=7,r16 + mov b0=r23// restore b0 (p6) br.cond.dpnt.many vmx_virtualization_fault_back ;; - mov r28=r19 // save r3 + mov r16=r19 + shladd r17=r17,4,r20 // get r2 + ;; mov b0=r17 br.many b0 -vmx_asm_mov_to_rr_back_2: - adds r30=vmx_resume_to_guest-asm_mov_from_reg,r20 - shladd r27=r23,3,r27 // address of VRR - ;; - ld1 r22=[r22] // Load rid_bits from domain - mov b0=r18 // restore b0 - adds r16=IA64_VCPU_STARTING_RID_OFFSET,r21 - ;; - ld4 r16=[r16] // load starting_rid - extr.u r17=r19,8,24 // Extract RID - ;; - shr r17=r17,r22 // Shift out used bits - shl r16=r16,8 - ;; - add r20=r19,r16 - cmp.ne p6,p0=0,r17 // If reserved RID bits are set, use C fall back. +vmx_asm_mov_to_rr_back_2: + mov r17=r19 // get value + ;; + // if invalid value , go back + adds r26=IA64_VCPU_RID_BITS_OFFSET,r21 + mov r27=r0 + ;; + ld1 r27=[r26] + ;; + shr r19=r19,r27 + ;; + cmp.ne p6,p0=r19,r0 + mov b0=r23// restore b0 (p6) br.cond.dpnt.many vmx_virtualization_fault_back - ;; //mangling rid 1 and 3 - extr.u r16=r20,8,8 - extr.u r17=r20,24,8 - mov r24=r18 // saved b0 for resume - ;; - extr.u r18=r20,2,6 // page size - dep r20=r16,r20,24,8 - mov b0=r30 - ;; - dep r20=r17,r20,8,8 - ;; //set ve 1 - dep r20=-1,r20,0,1 - // If ps > PAGE_SHIFT, use PAGE_SHIFT - cmp.lt p6,p0=PAGE_SHIFT,r18 - ;; - (p6) mov r18=PAGE_SHIFT - ;; - (p6) dep r20=r18,r20,2,6 - ;; - st8 [r27]=r19 // Write to vrr. - // Write to save_rr if rr=0 or rr=4. - cmp.eq p6,p0=0,r23 - ;; - cmp.eq.or p6,p0=4,r23 - ;; - adds r16=IA64_VCPU_MMU_MODE_OFFSET,r21 - (p6) adds r17=IA64_VCPU_META_SAVED_RR0_OFFSET,r21 - ;; - ld1 r16=[r16] - cmp.eq p7,p0=r0,r0 - (p6) shladd r17=r23,1,r17 - ;; - (p6) st8 [r17]=r20 - (p6) cmp.eq p7,p0=VMX_MMU_VIRTUAL,r16 // Set physical rr if in virt mode - ;; - (p7) mov rr[r28]=r20 - br.many b0 + ;; + VMX_VIRT_SAVE + ;; + mov out0=r21 + mov out1=r16 + mov out2=r17 + movl r14=ia64_leave_hypervisor_virt + ;; + mov rp=r14 + br.call.sptk.many b6=vmx_vcpu_set_rr_fast END(vmx_asm_mov_to_rr) -//rsm -GLOBAL_ENTRY(vmx_asm_rsm) -#ifndef ACCE_RSM - br.many vmx_virtualization_fault_back -#endif - mov r23=r31 - add r16=IA64_VPD_BASE_OFFSET,r21 +//rsm 25 +ENTRY(vmx_asm_rsm) extr.u r26=r25,6,21 // Imm21 extr.u r27=r25,31,2 // I2d ;; - ld8 r16=[r16] extr.u r28=r25,36,1 // I dep r26=r27,r26,21,2 ;; - add r17=VPD_VPSR_START_OFFSET,r16 //r18 is imm24 - dep r18=r28,r26,23,1 - ;; - //sync read - mov r25=r16 - movl r24=vmx_asm_rsm_sync_read_return - mov r20=b0 - br.sptk.many vmx_vps_sync_read - ;; -vmx_asm_rsm_sync_read_return: - ld8 r26=[r17] - // xenoprof - // Don't change mPSR.pp. - // It is manipulated by xenoprof. - movl r28=IA64_PSR_IC+IA64_PSR_I+IA64_PSR_DT+IA64_PSR_SI+IA64_PSR_PP - - sub r27=-1,r18 // ~imm24 - ;; - or r28=r27,r28 // Keep IC,I,DT,SI - and r19=r26,r27 // Update vpsr - ;; - st8 [r17]=r19 - mov r24=cr.ipsr - ;; - and r24=r24,r28 // Update ipsr - adds r27=IA64_VCPU_FP_PSR_OFFSET,r21 - ;; - ld8 r27=[r27] - ;; - tbit.nz p8,p0=r27,IA64_PSR_DFH_BIT - ;; - (p8) dep r24=-1,r24,IA64_PSR_DFH_BIT,1 // Keep dfh - ;; - mov cr.ipsr=r24 - //sync write - mov r25=r16 - movl r24=vmx_asm_rsm_sync_write_return - br.sptk.many vmx_vps_sync_write - ;; -vmx_asm_rsm_sync_write_return: - add r29=IA64_VCPU_MMU_MODE_OFFSET,r21 - ;; - ld1 r27=[r29] - ;; - cmp.ne p6,p0=VMX_MMU_VIRTUAL,r27 - ;; - tbit.z.or p6,p0=r18,IA64_PSR_DT_BIT - (p6) br.dptk vmx_asm_rsm_out - // DT not cleared or already in phy mode - ;; - // Switch to meta physical mode D. - add r26=IA64_VCPU_META_RID_D_OFFSET,r21 - mov r27=VMX_MMU_PHY_D + dep r16=r28,r26,23,1 + ;; + VMX_VIRT_SAVE + ;; + mov out0=r21 + mov out1=r16 + movl r14=ia64_leave_hypervisor_virt + ;; + mov rp=r14 + br.call.sptk.many b6=vmx_vcpu_rsm_fast +END(vmx_asm_rsm) + + +//ssm 24 +ENTRY(vmx_asm_ssm) + adds r18=IA64_VPD_BASE_OFFSET,r21 + ;; + ld8 r18=[r18] + ;; + adds r26=IA64_VPD_VHPI_OFFSET,r18 ;; ld8 r26=[r26] - st1 [r29]=r27 - dep.z r28=4,61,3 - ;; - mov rr[r0]=r26 - ;; - mov rr[r28]=r26 - ;; - srlz.d -vmx_asm_rsm_out: - mov r31=r23 - mov r24=r20 - br.many vmx_resume_to_guest -END(vmx_asm_rsm) - - -//ssm -GLOBAL_ENTRY(vmx_asm_ssm) -#ifndef ACCE_SSM - br.many vmx_virtualization_fault_back -#endif - mov r23=r31 - add r16=IA64_VPD_BASE_OFFSET,r21 + ;; + cmp.ne p6,p0=r26,r0 + (p6) br.cond.dpnt.many vmx_virtualization_fault_back + ;; extr.u r26=r25,6,21 extr.u r27=r25,31,2 ;; - ld8 r16=[r16] extr.u r28=r25,36,1 dep r26=r27,r26,21,2 ;; //r18 is imm24 - dep r18=r28,r26,23,1 - ;; - //sync read - mov r25=r16 - movl r24=vmx_asm_ssm_sync_read_return - mov r20=b0 - br.sptk.many vmx_vps_sync_read - ;; -vmx_asm_ssm_sync_read_return: - add r27=VPD_VPSR_START_OFFSET,r16 - ;; - ld8 r17=[r27] //r17 old vpsr - dep r28=0,r18,IA64_PSR_PP_BIT,1 // For xenoprof - // Don't change mPSR.pp - // It is maintained by xenoprof. - ;; - or r19=r17,r18 //r19 new vpsr - ;; - st8 [r27]=r19 // update vpsr - mov r24=cr.ipsr - ;; - or r24=r24,r28 - ;; - mov cr.ipsr=r24 - //sync_write - mov r25=r16 - movl r24=vmx_asm_ssm_sync_write_return - br.sptk.many vmx_vps_sync_write - ;; -vmx_asm_ssm_sync_write_return: - add r29=IA64_VCPU_MMU_MODE_OFFSET,r21 - movl r28=IA64_PSR_DT+IA64_PSR_RT+IA64_PSR_IT - ;; - ld1 r30=[r29] // mmu_mode - ;; - and r27=r28,r19 - cmp.eq p6,p0=VMX_MMU_VIRTUAL,r30 - ;; - cmp.ne.or p6,p0=r28,r27 // (vpsr & (it+dt+rt)) /= (it+dt+rt) ie stay in phy - (p6) br.dptk vmx_asm_ssm_1 - ;; - add r26=IA64_VCPU_META_SAVED_RR0_OFFSET,r21 - add r27=IA64_VCPU_META_SAVED_RR0_OFFSET+8,r21 - mov r30=VMX_MMU_VIRTUAL - ;; - ld8 r26=[r26] - ld8 r27=[r27] - st1 [r29]=r30 - dep.z r28=4,61,3 - ;; - mov rr[r0]=r26 - ;; - mov rr[r28]=r27 - ;; - srlz.d - ;; -vmx_asm_ssm_1: - tbit.nz p6,p0=r17,IA64_PSR_I_BIT - ;; - tbit.z.or p6,p0=r19,IA64_PSR_I_BIT - (p6) br.dptk vmx_asm_ssm_out - ;; - add r29=VPD_VTPR_START_OFFSET,r16 - add r30=VPD_VHPI_START_OFFSET,r16 - ;; - ld8 r29=[r29] - ld8 r30=[r30] - ;; - extr.u r17=r29,4,4 - extr.u r18=r29,16,1 - ;; - dep r17=r18,r17,4,1 - mov r31=r23 - mov b0=r20 - ;; - cmp.gt p6,p0=r30,r17 - (p6) br.dpnt.few vmx_asm_dispatch_vexirq -vmx_asm_ssm_out: - mov r31=r23 - mov r24=r20 - br.many vmx_resume_to_guest + dep r16=r28,r26,23,1 + ;; + VMX_VIRT_SAVE + ;; + mov out0=r21 + mov out1=r16 + movl r14=ia64_leave_hypervisor_virt + ;; + mov rp=r14 + br.call.sptk.many b6=vmx_vcpu_ssm_fast END(vmx_asm_ssm) -//mov psr.l=r2 -GLOBAL_ENTRY(vmx_asm_mov_to_psr) -#ifndef ACCE_MOV_TO_PSR - br.many vmx_virtualization_fault_back -#endif - mov r23=r31 - add r16=IA64_VPD_BASE_OFFSET,r21 +//mov psr.l=r2 +ENTRY(vmx_asm_mov_to_psr) extr.u r26=r25,13,7 //r2 - ;; - ld8 r16=[r16] - movl r24=asm_mov_from_reg - ;; - adds r30=vmx_asm_mov_to_psr_back-asm_mov_from_reg,r24 - shladd r26=r26,4,r24 - mov r20=b0 + movl r27=asm_mov_from_reg + ;; + adds r30=vmx_asm_mov_to_psr_back-asm_mov_from_reg,r27 + shladd r26=r26,4,r27 ;; mov b0=r26 br.many b0 - ;; + ;; vmx_asm_mov_to_psr_back: - //sync read - mov r25=r16 - movl r24=vmx_asm_mov_to_psr_sync_read_return - br.sptk.many vmx_vps_sync_read - ;; -vmx_asm_mov_to_psr_sync_read_return: - add r27=VPD_VPSR_START_OFFSET,r16 - ;; - ld8 r17=[r27] // r17 old vpsr - dep r19=0,r19,32,32 // Clear bits 32-63 - ;; - dep r18=0,r17,0,32 - ;; - or r18=r18,r19 //r18 new vpsr - ;; - st8 [r27]=r18 // set vpsr - //sync write - mov r25=r16 - movl r24=vmx_asm_mov_to_psr_sync_write_return - br.sptk.many vmx_vps_sync_write - ;; -vmx_asm_mov_to_psr_sync_write_return: - add r22=IA64_VCPU_MMU_MODE_OFFSET,r21 - movl r28=IA64_PSR_DT+IA64_PSR_RT+IA64_PSR_IT - ;; - and r27=r28,r18 - and r29=r28,r17 - ;; - cmp.eq p5,p0=r29,r27 // (old_vpsr & (dt+rt+it)) == (new_vpsr & (dt+rt+it)) - cmp.eq p6,p7=r28,r27 // (new_vpsr & (dt+rt+it)) == (dt+rt+it) - (p5) br.many vmx_asm_mov_to_psr_1 // no change - ;; - //virtual to physical D - (p7) add r26=IA64_VCPU_META_RID_D_OFFSET,r21 - (p7) add r27=IA64_VCPU_META_RID_D_OFFSET,r21 - (p7) mov r30=VMX_MMU_PHY_D - ;; - //physical to virtual - (p6) add r26=IA64_VCPU_META_SAVED_RR0_OFFSET,r21 - (p6) add r27=IA64_VCPU_META_SAVED_RR0_OFFSET+8,r21 - (p6) mov r30=VMX_MMU_VIRTUAL + adds r18=IA64_VPD_BASE_OFFSET,r21 + tbit.nz p6,p0 = r19, IA64_PSR_I_BIT + ;; + ld8 r18=[r18] + ;; + adds r26=IA64_VPD_VHPI_OFFSET,r18 ;; ld8 r26=[r26] - ld8 r27=[r27] - st1 [r22]=r30 - dep.z r28=4,61,3 - ;; - mov rr[r0]=r26 - ;; - mov rr[r28]=r27 - ;; - srlz.d - ;; -vmx_asm_mov_to_psr_1: - mov r24=cr.ipsr - movl r28=IA64_PSR_IC+IA64_PSR_I+IA64_PSR_DT+IA64_PSR_SI+IA64_PSR_RT - ;; - tbit.nz p7,p0=r24,IA64_PSR_PP_BIT // For xenoprof - or r27=r19,r28 - dep r24=0,r24,0,32 - ;; - add r24=r27,r24 - ;; - adds r27=IA64_VCPU_FP_PSR_OFFSET,r21 - (p7) dep r24=-1,r24,IA64_PSR_PP_BIT,1 // For xenoprof - // Dom't change mPSR.pp - // It is maintaned by xenoprof - ;; - ld8 r27=[r27] - ;; - tbit.nz p8,p0=r27,IA64_PSR_DFH_BIT - ;; - (p8) dep r24=-1,r24,IA64_PSR_DFH_BIT,1 - ;; - mov cr.ipsr=r24 - tbit.nz p6,p0=r17,IA64_PSR_I_BIT - ;; - tbit.z.or p6,p0=r18,IA64_PSR_I_BIT - (p6) br.dpnt.few vmx_asm_mov_to_psr_out - ;; - add r29=VPD_VTPR_START_OFFSET,r16 - add r30=VPD_VHPI_START_OFFSET,r16 - ;; - ld8 r29=[r29] - ld8 r30=[r30] - ;; - extr.u r17=r29,4,4 - extr.u r18=r29,16,1 - ;; - dep r17=r18,r17,4,1 - mov r31=r23 - mov b0=r20 - ;; - cmp.gt p6,p0=r30,r17 - (p6) br.dpnt.few vmx_asm_dispatch_vexirq -vmx_asm_mov_to_psr_out: - mov r31=r23 - mov r24=r20 - br.many vmx_resume_to_guest + ;; + // if enable interrupt and vhpi has value, return + cmp.ne.and p6,p0=r26,r0 + (p6) br.cond.dpnt.many vmx_virtualization_fault_back + ;; + mov r16=r19 + ;; + VMX_VIRT_SAVE + ;; + mov out0=r21 + mov out1=r16 + movl r14=ia64_leave_hypervisor_virt + ;; + mov rp=r14 + br.call.sptk.many b6=vmx_vcpu_mov_to_psr_fast END(vmx_asm_mov_to_psr) - -ENTRY(vmx_asm_dispatch_vexirq) -//increment iip - mov r16=cr.ipsr - ;; - extr.u r17=r16,IA64_PSR_RI_BIT,2 - tbit.nz p6,p7=r16,IA64_PSR_RI_BIT+1 - ;; - (p6) mov r18=cr.iip - (p6) mov r17=r0 - (p7) add r17=1,r17 - ;; - (p6) add r18=0x10,r18 - dep r16=r17,r16,IA64_PSR_RI_BIT,2 - ;; - (p6) mov cr.iip=r18 - mov cr.ipsr=r16 - br.many vmx_dispatch_vexirq -END(vmx_asm_dispatch_vexirq) // thash r1=r3 // TODO: add support when pta.vf = 1 -GLOBAL_ENTRY(vmx_asm_thash) -#ifndef ACCE_THASH - br.many vmx_virtualization_fault_back -#endif - extr.u r17=r25,20,7 // get r3 from opcode in r25 - extr.u r18=r25,6,7 // get r1 from opcode in r25 +ENTRY(vmx_asm_thash) + extr.u r17=r25,20,7 // get r3 from opcode in r25 + extr.u r18=r25,6,7 // get r1 from opcode in r25 movl r20=asm_mov_from_reg ;; adds r30=vmx_asm_thash_back1-asm_mov_from_reg,r20 - shladd r17=r17,4,r20 // get addr of MOVE_FROM_REG(r17) - adds r16=IA64_VPD_BASE_OFFSET,r21 // get vcpu.arch.priveregs - mov r24=b0 // save b0 - ;; - ld8 r16=[r16] // get VPD addr + shladd r17=r17,4,r20 // get addr of MOVE_FROM_REG(r17) + adds r16=IA64_VPD_BASE_OFFSET,r21 // get vcpu.arch.priveregs + mov r24=b0 // save b0 + ;; + ld8 r16=[r16] // get VPD addr mov b0=r17 - br.many b0 // r19 return value - ;; + br.many b0 // r19 return value + ;; vmx_asm_thash_back1: - shr.u r23=r19,61 // get RR number - adds r28=VCPU_VRR0_OFS,r21 // get vcpu->arch.arch_vmx.vrr[0]'s addr - adds r16=IA64_VPD_VPTA_OFFSET,r16 // get virtual pta - ;; - shladd r27=r23,3,r28 // get vcpu->arch.arch_vmx.vrr[r23]'s addr - ld8 r17=[r16] // get virtual PTA + shr.u r23=r19,61 // get RR number + adds r28=VCPU_VRR0_OFS,r21 // get vcpu->arch.arch_vmx.vrr[0]'s addr + adds r16=IA64_VPD_VPTA_OFFSET,r16 // get virtual pta + ;; + shladd r27=r23,3,r28 // get vcpu->arch.arch_vmx.vrr[r23]'s addr + ld8 r17=[r16] // get virtual PTA mov r26=1 ;; - extr.u r29=r17,2,6 // get pta.size - ld8 r28=[r27] // get vcpu->arch.arch_vmx.vrr[r23]'s value + extr.u r29=r17,2,6// get pta.size + ld8 r28=[r27] // get vcpu->arch.arch_vmx.vrr[r23]'s value ;; // Fall-back to C if VF (long format) is set tbit.nz p6,p0=r17,8 mov b0=r24 ;; -(p6) mov r24=EVENT_THASH -(p6) br.cond.dpnt.many vmx_virtualization_fault_back - extr.u r28=r28,2,6 // get rr.ps - shl r22=r26,r29 // 1UL << pta.size - ;; - shr.u r23=r19,r28 // vaddr >> rr.ps - adds r26=3,r29 // pta.size + 3 - shl r27=r17,3 // pta << 3 - ;; - shl r23=r23,3 // (vaddr >> rr.ps) << 3 - shr.u r27=r27,r26 // (pta << 3) >> (pta.size+3) + (p6) mov r24=EVENT_THASH + (p6) br.cond.dpnt.many vmx_virtualization_fault_back + extr.u r28=r28,2,6 // get rr.ps + shl r22=r26,r29 // 1UL << pta.size + ;; + shr.u r23=r19,r28 // vaddr >> rr.ps + adds r26=3,r29 // pta.size + 3 + shl r27=r17,3 // pta << 3 + ;; + shl r23=r23,3 // (vaddr >> rr.ps) << 3 + shr.u r27=r27,r26 // (pta << 3) >> (pta.size+3) movl r16=VRN_MASK ;; - adds r22=-1,r22 // (1UL << pta.size) - 1 - shl r27=r27,r29 // ((pta<<3)>>(pta.size+3))<<pta.size - and r19=r19,r16 // vaddr & VRN_MASK - ;; - and r22=r22,r23 // vhpt_offset - or r19=r19,r27 // (vadr&VRN_MASK) |(((pta<<3)>>(pta.size + 3))<<pta.size) + adds r22=-1,r22 // (1UL << pta.size) - 1 + shl r27=r27,r29 // ((pta<<3)>>(pta.size+3))<<pta.size + and r19=r19,r16 // vaddr & VRN_MASK + ;; + and r22=r22,r23 // vhpt_offset + or r19=r19,r27 // (vadr&VRN_MASK) |(((pta<<3)>>(pta.size + 3))<<pta.size) adds r26=asm_mov_to_reg-asm_mov_from_reg,r20 ;; - or r19=r19,r22 // calc pval + or r19=r19,r22 // calc pval shladd r17=r18,4,r26 adds r30=vmx_resume_to_guest-asm_mov_from_reg,r20 ;; @@ -634,99 +753,101 @@ vmx_asm_thash_back1: br.many b0 END(vmx_asm_thash) -#define MOV_TO_REG0 \ -{; \ - nop.b 0x0; \ - nop.b 0x0; \ - nop.b 0x0; \ - ;; \ + + +#define MOV_TO_REG0 \ +{; \ + nop.b 0x0; \ + nop.b 0x0; \ + nop.b 0x0; \ + ;; \ }; -#define MOV_TO_REG(n) \ -{; \ - mov r##n##=r19; \ - mov b0=r30; \ - br.sptk.many b0; \ - ;; \ +#define MOV_TO_REG(n) \ +{; \ + mov r##n##=r19; \ + mov b0=r30; \ + br.sptk.many b0; \ + ;; \ }; -#define MOV_FROM_REG(n) \ -{; \ - mov r19=r##n##; \ - mov b0=r30; \ - br.sptk.many b0; \ - ;; \ +#define MOV_FROM_REG(n) \ +{; \ + mov r19=r##n##; \ + mov b0=r30; \ + br.sptk.many b0; \ + ;; \ }; -#define MOV_TO_BANK0_REG(n) \ -ENTRY_MIN_ALIGN(asm_mov_to_bank0_reg##n##); \ -{; \ - mov r26=r2; \ - mov r2=r19; \ - bsw.1; \ - ;; \ -}; \ -{; \ - mov r##n##=r2; \ - nop.b 0x0; \ - bsw.0; \ - ;; \ -}; \ -{; \ - mov r2=r26; \ - mov b0=r30; \ - br.sptk.many b0; \ - ;; \ -}; \ +#define MOV_TO_BANK0_REG(n) \ +ENTRY_MIN_ALIGN(asm_mov_to_bank0_reg##n##); \ +{; \ + mov r26=r2; \ + mov r2=r19; \ + bsw.1; \ + ;; \ +}; \ +{; \ + mov r##n##=r2; \ + nop.b 0x0; \ + bsw.0; \ + ;; \ +}; \ +{; \ + mov r2=r26; \ + mov b0=r30; \ + br.sptk.many b0; \ + ;; \ +}; \ END(asm_mov_to_bank0_reg##n##) -#define MOV_FROM_BANK0_REG(n) \ -ENTRY_MIN_ALIGN(asm_mov_from_bank0_reg##n##); \ -{; \ - mov r26=r2; \ - nop.b 0x0; \ - bsw.1; \ - ;; \ -}; \ -{; \ - mov r2=r##n##; \ - nop.b 0x0; \ - bsw.0; \ - ;; \ -}; \ -{; \ - mov r19=r2; \ - mov r2=r26; \ - mov b0=r30; \ -}; \ -{; \ - nop.b 0x0; \ - nop.b 0x0; \ - br.sptk.many b0; \ - ;; \ -}; \ +#define MOV_FROM_BANK0_REG(n) \ +ENTRY_MIN_ALIGN(asm_mov_from_bank0_reg##n##); \ +{; \ + mov r26=r2; \ + nop.b 0x0; \ + bsw.1; \ + ;; \ +}; \ +{; \ + mov r2=r##n##; \ + nop.b 0x0; \ + bsw.0; \ + ;; \ +}; \ +{; \ + mov r19=r2; \ + mov r2=r26; \ + mov b0=r30; \ +}; \ +{; \ + nop.b 0x0; \ + nop.b 0x0; \ + br.sptk.many b0; \ + ;; \ +}; \ END(asm_mov_from_bank0_reg##n##) -#define JMP_TO_MOV_TO_BANK0_REG(n) \ -{; \ - nop.b 0x0; \ - nop.b 0x0; \ - br.sptk.many asm_mov_to_bank0_reg##n##; \ - ;; \ -} - - -#define JMP_TO_MOV_FROM_BANK0_REG(n) \ -{; \ - nop.b 0x0; \ - nop.b 0x0; \ - br.sptk.many asm_mov_from_bank0_reg##n##; \ - ;; \ +#define JMP_TO_MOV_TO_BANK0_REG(n) \ +{; \ + nop.b 0x0; \ + nop.b 0x0; \ + br.sptk.many asm_mov_to_bank0_reg##n##; \ + ;; \ +} + + +#define JMP_TO_MOV_FROM_BANK0_REG(n) \ +{; \ + nop.b 0x0; \ + nop.b 0x0; \ + br.sptk.many asm_mov_from_bank0_reg##n##; \ + ;; \ } @@ -749,7 +870,7 @@ MOV_FROM_BANK0_REG(31) // mov from reg table -// r19: value, r30: return address +// r19:value, r30: return address // r26 may be destroyed ENTRY(asm_mov_from_reg) MOV_FROM_REG(0) @@ -884,29 +1005,30 @@ END(asm_mov_from_reg) /* must be in bank 0 - * parameter: - * r31: pr - * r24: b0 + * parameter: + * r31: pr + * r24: b0 + * p2: whether increase IP + * p3: whether check vpsr.ic */ ENTRY(vmx_resume_to_guest) - mov r16=cr.ipsr - ;; + // ip ++ + (p2) mov r16=cr.ipsr + (p2)dep.z r30=1,IA64_PSR_RI_BIT,1 adds r19=IA64_VPD_BASE_OFFSET,r21 - extr.u r17=r16,IA64_PSR_RI_BIT,2 ;; ld8 r25=[r19] - add r17=1,r17 - ;; + (p2) add r16=r30,r16 + ;; + (p2) mov cr.ipsr=r16 adds r19= VPD_VPSR_START_OFFSET,r25 - dep r16=r17,r16,IA64_PSR_RI_BIT,2 - ;; - mov cr.ipsr=r16 + ;; ld8 r19=[r19] ;; mov r23=r31 mov r17=r0 //vps_resume_normal/handler - tbit.z p6,p7 = r19,IA64_PSR_IC_BIT // p1=vpsr.ic + tbit.z p6,p7 = r19,IA64_PSR_IC_BIT // p7=vpsr.ic (p6) br.cond.sptk.many vmx_vps_resume_handler (p7) br.cond.sptk.few vmx_vps_resume_normal END(vmx_resume_to_guest) @@ -931,7 +1053,7 @@ MOV_TO_BANK0_REG(31) // mov to reg table -// r19: value, r30: return address +// r19:value, r30: return address ENTRY(asm_mov_to_reg) MOV_TO_REG0 MOV_TO_REG(1) diff -r b03e24f9c1d8 -r ef290f39ae6b xen/arch/ia64/vmx/vmx_ivt.S --- a/xen/arch/ia64/vmx/vmx_ivt.S Thu May 15 14:18:38 2008 +0900 +++ b/xen/arch/ia64/vmx/vmx_ivt.S Thu May 15 14:53:48 2008 +0900 @@ -967,21 +967,13 @@ ENTRY(vmx_virtualization_fault) ENTRY(vmx_virtualization_fault) // VMX_DBG_FAULT(37) mov r31=pr - ;; - cmp.eq p6,p0=EVENT_MOV_FROM_AR,r24 - cmp.eq p7,p0=EVENT_MOV_FROM_RR,r24 - cmp.eq p8,p0=EVENT_MOV_TO_RR,r24 - cmp.eq p9,p0=EVENT_RSM,r24 - cmp.eq p10,p0=EVENT_SSM,r24 - cmp.eq p11,p0=EVENT_MOV_TO_PSR,r24 - cmp.eq p12,p0=EVENT_THASH,r24 - (p6) br.dptk.many vmx_asm_mov_from_ar - (p7) br.dptk.many vmx_asm_mov_from_rr - (p8) br.dptk.many vmx_asm_mov_to_rr - (p9) br.dptk.many vmx_asm_rsm - (p10) br.dptk.many vmx_asm_ssm - (p11) br.dptk.many vmx_asm_mov_to_psr - (p12) br.dptk.many vmx_asm_thash + movl r30 = virtualization_fault_table + mov r23=b0 + ;; + shladd r30=r24,4,r30 + ;; + mov b0=r30 + br.sptk.many b0 ;; vmx_virtualization_fault_back: mov r19=37 @@ -990,23 +982,6 @@ vmx_virtualization_fault_back: ;; st8 [r16] = r24 st8 [r17] = r25 - ;; - cmp.ne p6,p0=EVENT_RFI, r24 - (p6) br.sptk vmx_dispatch_virtualization_fault - ;; - adds r18=IA64_VPD_BASE_OFFSET,r21 - ;; - ld8 r18=[r18] - ;; - adds r18=IA64_VPD_VIFS_OFFSET,r18 - ;; - ld8 r18=[r18] - ;; - tbit.z p6,p0=r18,63 - (p6) br.sptk vmx_dispatch_virtualization_fault - ;; - //if vifs.v=1 desert current register frame - alloc r18=ar.pfs,0,0,0,0 br.sptk vmx_dispatch_virtualization_fault END(vmx_virtualization_fault) diff -r b03e24f9c1d8 -r ef290f39ae6b xen/arch/ia64/vmx/vmx_phy_mode.c --- a/xen/arch/ia64/vmx/vmx_phy_mode.c Thu May 15 14:18:38 2008 +0900 +++ b/xen/arch/ia64/vmx/vmx_phy_mode.c Thu May 15 14:53:48 2008 +0900 @@ -228,6 +228,33 @@ static int mm_switch_action(IA64_PSR ops return mm_switch_table[MODE_IND(opsr)][MODE_IND(npsr)]; } +/* In fast path, psr.ic = 0, psr.i = 0, psr.bn = 0 + * so that no tlb miss is allowed. + */ +void +switch_mm_mode_fast(VCPU *vcpu, IA64_PSR old_psr, IA64_PSR new_psr) +{ + int act; + act = mm_switch_action(old_psr, new_psr); + switch (act) { + case SW_2P_DT: + vcpu->arch.arch_vmx.mmu_mode = VMX_MMU_PHY_DT; + switch_to_physical_rid(vcpu); + break; + case SW_2P_D: + vcpu->arch.arch_vmx.mmu_mode = VMX_MMU_PHY_D; + switch_to_physical_rid(vcpu); + break; + case SW_2V: + vcpu->arch.arch_vmx.mmu_mode = VMX_MMU_VIRTUAL; + switch_to_virtual_rid(vcpu); + break; + default: + break; + } + return; +} + void switch_mm_mode(VCPU *vcpu, IA64_PSR old_psr, IA64_PSR new_psr) { diff -r b03e24f9c1d8 -r ef290f39ae6b xen/arch/ia64/vmx/vmx_vcpu.c --- a/xen/arch/ia64/vmx/vmx_vcpu.c Thu May 15 14:18:38 2008 +0900 +++ b/xen/arch/ia64/vmx/vmx_vcpu.c Thu May 15 14:53:48 2008 +0900 @@ -168,6 +168,34 @@ IA64FAULT vmx_vcpu_cover(VCPU *vcpu) return (IA64_NO_FAULT); } +/* In fast path, psr.ic = 0, psr.i = 0, psr.bn = 0 + * so that no tlb miss is allowed. + */ +void vmx_vcpu_set_rr_fast(VCPU *vcpu, u64 reg, u64 val) +{ + u64 rrval; + + VMX(vcpu, vrr[reg >> VRN_SHIFT]) = val; + switch((u64)(reg >> VRN_SHIFT)) { + case VRN4: + rrval = vrrtomrr(vcpu, val); + vcpu->arch.metaphysical_saved_rr4 = rrval; + if (is_virtual_mode(vcpu) && likely(vcpu == current)) + ia64_set_rr(reg, rrval); + break; + case VRN0: + rrval = vrrtomrr(vcpu, val); + vcpu->arch.metaphysical_saved_rr0 = rrval; + if (is_virtual_mode(vcpu) && likely(vcpu == current)) + ia64_set_rr(reg, rrval); + break; + default: + if (likely(vcpu == current)) + ia64_set_rr(reg, vrrtomrr(vcpu, val)); + break; + } +} + IA64FAULT vmx_vcpu_set_rr(VCPU *vcpu, u64 reg, u64 val) { u64 rrval; @@ -246,8 +274,138 @@ u64 vmx_vcpu_get_itir_on_fault(VCPU *vcp return (rr1.rrval); } - - +/* In fast path, psr.ic = 0, psr.i = 0, psr.bn = 0 + * so that no tlb miss is allowed. + */ +void vmx_vcpu_mov_to_psr_fast(VCPU *vcpu, u64 value) +{ + /* TODO: Only allowed for current vcpu */ + u64 old_vpsr, new_vpsr, mipsr, mask; + old_vpsr = VCPU(vcpu, vpsr); + + new_vpsr = (old_vpsr & 0xffffffff00000000) | (value & 0xffffffff); + VCPU(vcpu, vpsr) = new_vpsr; + + mipsr = ia64_getreg(_IA64_REG_CR_IPSR); + + /* xenoprof: + * don't change psr.pp. + * It is manipulated by xenoprof. + */ + mask = 0xffffffff00000000 | IA64_PSR_IC | IA64_PSR_I + | IA64_PSR_DT | IA64_PSR_PP | IA64_PSR_SI | IA64_PSR_RT; + + mipsr = (mipsr & mask) | (value & (~mask)); + + if (FP_PSR(vcpu) & IA64_PSR_DFH) + mipsr |= IA64_PSR_DFH; + + ia64_setreg(_IA64_REG_CR_IPSR, mipsr); + + switch_mm_mode_fast(vcpu, (IA64_PSR)old_vpsr, (IA64_PSR)new_vpsr); +} + +#define IA64_PSR_MMU_VIRT (IA64_PSR_DT | IA64_PSR_RT | IA64_PSR_IT) +/* In fast path, psr.ic = 0, psr.i = 0, psr.bn = 0 + * so that no tlb miss is allowed. + */ +void vmx_vcpu_rfi_fast(VCPU *vcpu) +{ + /* TODO: Only allowed for current vcpu */ + u64 vifs, vipsr, vpsr, mipsr, mask; + vipsr = VCPU(vcpu, ipsr); + vpsr = VCPU(vcpu, vpsr); + vifs = VCPU(vcpu, ifs); + if (vipsr & IA64_PSR_BN) { + if(!(vpsr & IA64_PSR_BN)) + vmx_asm_bsw1(); + } else if (vpsr & IA64_PSR_BN) + vmx_asm_bsw0(); + + /* + * For those IA64_PSR bits: id/da/dd/ss/ed/ia + * Since these bits will become 0, after success execution of each + * instruction, we will change set them to mIA64_PSR + */ + VCPU(vcpu, vpsr) = vipsr & (~ (IA64_PSR_ID |IA64_PSR_DA + | IA64_PSR_DD | IA64_PSR_ED | IA64_PSR_IA)); + + /* + * All vIA64_PSR bits shall go to mPSR (v->tf->tf_special.psr) + * , except for the following bits: + * ic/i/dt/si/rt/mc/it/bn/vm + */ + /* xenoprof */ + mask = (IA64_PSR_IC | IA64_PSR_I | IA64_PSR_DT | IA64_PSR_SI | + IA64_PSR_RT | IA64_PSR_MC | IA64_PSR_IT | IA64_PSR_BN | + IA64_PSR_VM | IA64_PSR_PP); + mipsr = ia64_getreg(_IA64_REG_CR_IPSR); + mipsr = (mipsr & mask) | (vipsr & (~mask)); + + if (FP_PSR(vcpu) & IA64_PSR_DFH) + mipsr |= IA64_PSR_DFH; + + ia64_setreg(_IA64_REG_CR_IPSR, mipsr); + vmx_ia64_set_dcr(vcpu); + + if(vifs >> 63) + ia64_setreg(_IA64_REG_CR_IFS, vifs); + + ia64_setreg(_IA64_REG_CR_IIP, VCPU(vcpu, iip)); + + switch_mm_mode_fast(vcpu, (IA64_PSR)vpsr, (IA64_PSR)vipsr); +} + +/* In fast path, psr.ic = 0, psr.i = 0, psr.bn = 0 + * so that no tlb miss is allowed. + */ +void vmx_vcpu_ssm_fast(VCPU *vcpu, u64 imm24) +{ + u64 old_vpsr, new_vpsr, mipsr; + + old_vpsr = VCPU(vcpu, vpsr); + new_vpsr = old_vpsr | imm24; + + VCPU(vcpu, vpsr) = new_vpsr; + + mipsr = ia64_getreg(_IA64_REG_CR_IPSR); + /* xenoprof: + * don't change psr.pp. + * It is manipulated by xenoprof. + */ + mipsr |= imm24 & (~IA64_PSR_PP); + ia64_setreg(_IA64_REG_CR_IPSR, mipsr); + + switch_mm_mode_fast(vcpu, (IA64_PSR)old_vpsr, (IA64_PSR)new_vpsr); +} + +/* In fast path, psr.ic = 0, psr.i = 0, psr.bn = 0 + * so that no tlb miss is allowed. + */ +void vmx_vcpu_rsm_fast(VCPU *vcpu, u64 imm24) +{ + u64 old_vpsr, new_vpsr, mipsr; + + old_vpsr = VCPU(vcpu, vpsr); + new_vpsr = old_vpsr & ~imm24; + + VCPU(vcpu, vpsr) = new_vpsr; + + mipsr = ia64_getreg(_IA64_REG_CR_IPSR); + /* xenoprof: + * don't change psr.pp. + * It is manipulated by xenoprof. + */ + mipsr &= (~imm24) | IA64_PSR_PP; + mipsr |= IA64_PSR_IC | IA64_PSR_I | IA64_PSR_DT | IA64_PSR_SI; + + if (FP_PSR(vcpu) & IA64_PSR_DFH) + mipsr |= IA64_PSR_DFH; + + ia64_setreg(_IA64_REG_CR_IPSR, mipsr); + + switch_mm_mode_fast(vcpu, (IA64_PSR)old_vpsr, (IA64_PSR)new_vpsr); +} IA64FAULT vmx_vcpu_rfi(VCPU *vcpu) { diff -r b03e24f9c1d8 -r ef290f39ae6b xen/include/asm-ia64/vmx_phy_mode.h --- a/xen/include/asm-ia64/vmx_phy_mode.h Thu May 15 14:18:38 2008 +0900 +++ b/xen/include/asm-ia64/vmx_phy_mode.h Thu May 15 14:53:48 2008 +0900 @@ -79,7 +79,8 @@ extern void switch_to_physical_rid(VCPU extern void switch_to_physical_rid(VCPU *); extern void switch_to_virtual_rid(VCPU *vcpu); extern void switch_mm_mode(VCPU *vcpu, IA64_PSR old_psr, IA64_PSR new_psr); -extern void check_mm_mode_switch (VCPU *vcpu, IA64_PSR old_psr, IA64_PSR new_psr); +extern void switch_mm_mode_fast(VCPU *vcpu, IA64_PSR old_psr, IA64_PSR new_psr); +extern void check_mm_mode_switch(VCPU *vcpu, IA64_PSR old_psr, IA64_PSR new_psr); extern void prepare_if_physical_mode(VCPU *vcpu); extern void recover_if_physical_mode(VCPU *vcpu); extern void vmx_init_all_rr(VCPU *vcpu); diff -r b03e24f9c1d8 -r ef290f39ae6b xen/include/asm-ia64/vmx_vcpu.h --- a/xen/include/asm-ia64/vmx_vcpu.h Thu May 15 14:18:38 2008 +0900 +++ b/xen/include/asm-ia64/vmx_vcpu.h Thu May 15 14:53:48 2008 +0900 @@ -106,6 +106,8 @@ extern void vmx_switch_rr7(unsigned long extern void vmx_switch_rr7(unsigned long, void *, void *, void *); extern void vmx_ia64_set_dcr(VCPU * v); extern void inject_guest_interruption(struct vcpu *vcpu, u64 vec); +extern void vmx_asm_bsw0(void); +extern void vmx_asm_bsw1(void); /************************************************************************** VCPU control register access routines _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |