2 * arch/ia64/kvm/optvfault.S
3 * optimize virtualization fault handler
5 * Copyright (C) 2006 Intel Co
6 * Xuefei Xu (Anthony Xu) <anthony.xu@intel.com>
7 * Copyright (C) 2008 Intel Co
8 * Add the support for Tukwila processors.
9 * Xiantao Zhang <xiantao.zhang@intel.com>
12 #include <asm/asmmacro.h>
13 #include <asm/processor.h>
16 #include "asm-offsets.h"
18 #define ACCE_MOV_FROM_AR
19 #define ACCE_MOV_FROM_RR
20 #define ACCE_MOV_TO_RR
23 #define ACCE_MOV_TO_PSR
26 #define VMX_VPS_SYNC_READ \
27 add r16=VMM_VPD_BASE_OFFSET,r21; \
42 br.sptk.many kvm_vps_sync_read; \
50 adds r29 = VMM_VCPU_VSA_BASE_OFFSET,r21
62 * r24 : return address
67 GLOBAL_ENTRY(kvm_vps_sync_read)
68 movl r30 = PAL_VPS_SYNC_READ
70 br.sptk.many kvm_vps_entry
71 END(kvm_vps_sync_read)
75 * r24 : return address
80 GLOBAL_ENTRY(kvm_vps_sync_write)
81 movl r30 = PAL_VPS_SYNC_WRITE
83 br.sptk.many kvm_vps_entry
84 END(kvm_vps_sync_write)
93 GLOBAL_ENTRY(kvm_vps_resume_normal)
94 movl r30 = PAL_VPS_RESUME_NORMAL
97 br.sptk.many kvm_vps_entry
98 END(kvm_vps_resume_normal)
107 GLOBAL_ENTRY(kvm_vps_resume_handler)
108 movl r30 = PAL_VPS_RESUME_HANDLER
111 shr r17=r17,IA64_ISR_IR_BIT
113 dep r26=r17,r26,63,1 // bit 63 of r26 indicate whether enable CFLE
115 br.sptk.many kvm_vps_entry
116 END(kvm_vps_resume_handler)
119 GLOBAL_ENTRY(kvm_asm_mov_from_ar)
120 #ifndef ACCE_MOV_FROM_AR
121 br.many kvm_virtualization_fault_back
123 add r18=VMM_VCPU_ITC_OFS_OFFSET, r21
124 add r16=VMM_VCPU_LAST_ITC_OFFSET,r21
132 addl r20=@gprel(asm_mov_to_reg),gp
135 adds r30=kvm_resume_to_guest-asm_mov_to_reg,r20
141 END(kvm_asm_mov_from_ar)
145 GLOBAL_ENTRY(kvm_asm_mov_from_rr)
146 #ifndef ACCE_MOV_FROM_RR
147 br.many kvm_virtualization_fault_back
151 addl r20=@gprel(asm_mov_from_reg),gp
153 adds r30=kvm_asm_mov_from_rr_back_1-asm_mov_from_reg,r20
157 add r27=VMM_VCPU_VRR0_OFFSET,r21
161 kvm_asm_mov_from_rr_back_1:
162 adds r30=kvm_resume_to_guest-asm_mov_from_reg,r20
163 adds r22=asm_mov_to_reg-asm_mov_from_reg,r20
172 END(kvm_asm_mov_from_rr)
176 GLOBAL_ENTRY(kvm_asm_mov_to_rr)
177 #ifndef ACCE_MOV_TO_RR
178 br.many kvm_virtualization_fault_back
182 addl r20=@gprel(asm_mov_from_reg),gp
184 adds r30=kvm_asm_mov_to_rr_back_1-asm_mov_from_reg,r20
188 add r27=VMM_VCPU_VRR0_OFFSET,r21
192 kvm_asm_mov_to_rr_back_1:
193 adds r30=kvm_asm_mov_to_rr_back_2-asm_mov_from_reg,r20
200 (p6) br.cond.dpnt.many kvm_virtualization_fault_back
205 kvm_asm_mov_to_rr_back_2:
206 adds r30=kvm_resume_to_guest-asm_mov_from_reg,r20
208 ;; // vrr.rid<<4 |0xe
216 shladd r16 = r16, 4, r17
228 (p6) dep r19=r18,r19,2,6
232 cmp.eq.or p6,p0=4,r23
234 adds r16=VMM_VCPU_MODE_FLAGS_OFFSET,r21
235 (p6) adds r17=VMM_VCPU_META_SAVED_RR0_OFFSET,r21
239 (p6) shladd r17=r23,1,r17
242 (p6) tbit.nz p6,p7=r16,0
247 END(kvm_asm_mov_to_rr)
251 GLOBAL_ENTRY(kvm_asm_rsm)
253 br.many kvm_virtualization_fault_back
263 add r17=VPD_VPSR_START_OFFSET,r16
264 add r22=VMM_VCPU_MODE_FLAGS_OFFSET,r21
269 movl r28=IA64_PSR_IC+IA64_PSR_I+IA64_PSR_DT+IA64_PSR_SI
280 /* Comment it out due to short of fp lazy alorgithm support
281 adds r27=IA64_VCPU_FP_PSR_OFFSET,r21
285 tbit.nz p8,p0= r27,IA64_PSR_DFH_BIT
287 (p8) dep r20=-1,r20,IA64_PSR_DFH_BIT,1
293 tbit.z.or p6,p0=r26,IA64_PSR_DT_BIT
294 (p6) br.dptk kvm_resume_to_guest_with_sync
296 add r26=VMM_VCPU_META_RR0_OFFSET,r21
297 add r27=VMM_VCPU_META_RR0_OFFSET+8,r21
310 br.many kvm_resume_to_guest_with_sync
315 GLOBAL_ENTRY(kvm_asm_ssm)
317 br.many kvm_virtualization_fault_back
327 add r27=VPD_VPSR_START_OFFSET,r16
333 add r22=VMM_VCPU_MODE_FLAGS_OFFSET,r21
342 movl r28=IA64_PSR_DT+IA64_PSR_RT+IA64_PSR_IT
347 cmp.ne.or p6,p0=r28,r19
348 (p6) br.dptk kvm_asm_ssm_1
350 add r26=VMM_VCPU_META_SAVED_RR0_OFFSET,r21
351 add r27=VMM_VCPU_META_SAVED_RR0_OFFSET+8,r21
366 tbit.nz p6,p0=r29,IA64_PSR_I_BIT
368 tbit.z.or p6,p0=r19,IA64_PSR_I_BIT
369 (p6) br.dptk kvm_resume_to_guest_with_sync
371 add r29=VPD_VTPR_START_OFFSET,r16
372 add r30=VPD_VHPI_START_OFFSET,r16
383 (p6) br.dpnt.few kvm_asm_dispatch_vexirq
384 br.many kvm_resume_to_guest_with_sync
389 GLOBAL_ENTRY(kvm_asm_mov_to_psr)
390 #ifndef ACCE_MOV_TO_PSR
391 br.many kvm_virtualization_fault_back
395 extr.u r26=r25,13,7 //r2
396 addl r20=@gprel(asm_mov_from_reg),gp
398 adds r30=kvm_asm_mov_to_psr_back-asm_mov_from_reg,r20
402 add r27=VPD_VPSR_START_OFFSET,r16
406 kvm_asm_mov_to_psr_back:
408 add r22=VMM_VCPU_MODE_FLAGS_OFFSET,r21
415 movl r28=IA64_PSR_DT+IA64_PSR_RT+IA64_PSR_IT
423 (p5) br.many kvm_asm_mov_to_psr_1
425 //virtual to physical
426 (p7) add r26=VMM_VCPU_META_RR0_OFFSET,r21
427 (p7) add r27=VMM_VCPU_META_RR0_OFFSET+8,r21
428 (p7) dep r23=-1,r23,0,1
430 //physical to virtual
431 (p6) add r26=VMM_VCPU_META_SAVED_RR0_OFFSET,r21
432 (p6) add r27=VMM_VCPU_META_SAVED_RR0_OFFSET+8,r21
433 (p6) dep r23=0,r23,0,1
446 kvm_asm_mov_to_psr_1:
448 movl r28=IA64_PSR_IC+IA64_PSR_I+IA64_PSR_DT+IA64_PSR_SI+IA64_PSR_RT
456 /* Comment it out due to short of fp lazy algorithm support
457 adds r27=IA64_VCPU_FP_PSR_OFFSET,r21
461 tbit.nz p8,p0=r27,IA64_PSR_DFH_BIT
463 (p8) dep r20=-1,r20,IA64_PSR_DFH_BIT,1
469 tbit.nz.or p6,p0=r17,IA64_PSR_I_BIT
470 tbit.z.or p6,p0=r30,IA64_PSR_I_BIT
471 (p6) br.dpnt.few kvm_resume_to_guest_with_sync
473 add r29=VPD_VTPR_START_OFFSET,r16
474 add r30=VPD_VHPI_START_OFFSET,r16
485 (p6) br.dpnt.few kvm_asm_dispatch_vexirq
486 br.many kvm_resume_to_guest_with_sync
487 END(kvm_asm_mov_to_psr)
490 ENTRY(kvm_asm_dispatch_vexirq)
495 add r25=VMM_VPD_BASE_OFFSET,r21
503 br.sptk.many kvm_vps_sync_write
510 extr.u r17=r16,IA64_PSR_RI_BIT,2
511 tbit.nz p6,p7=r16,IA64_PSR_RI_BIT+1
517 (p6) add r18=0x10,r18
518 dep r16=r17,r16,IA64_PSR_RI_BIT,2
523 br.many kvm_dispatch_vexirq
524 END(kvm_asm_dispatch_vexirq)
527 // TODO: add support when pta.vf = 1
528 GLOBAL_ENTRY(kvm_asm_thash)
530 br.many kvm_virtualization_fault_back
532 extr.u r17=r25,20,7 // get r3 from opcode in r25
533 extr.u r18=r25,6,7 // get r1 from opcode in r25
534 addl r20=@gprel(asm_mov_from_reg),gp
536 adds r30=kvm_asm_thash_back1-asm_mov_from_reg,r20
537 shladd r17=r17,4,r20 // get addr of MOVE_FROM_REG(r17)
538 adds r16=VMM_VPD_BASE_OFFSET,r21 // get vcpu.arch.priveregs
542 ld8 r16=[r16] // get VPD addr
544 br.many b0 // r19 return value
547 shr.u r23=r19,61 // get RR number
548 adds r28=VMM_VCPU_VRR0_OFFSET,r21 // get vcpu->arch.vrr[0]'s addr
549 adds r16=VMM_VPD_VPTA_OFFSET,r16 // get vpta
551 shladd r27=r23,3,r28 // get vcpu->arch.vrr[r23]'s addr
552 ld8 r17=[r16] // get PTA
555 extr.u r29=r17,2,6 // get pta.size
556 ld8 r28=[r27] // get vcpu->arch.vrr[r23]'s value
559 //Fallback to C if pta.vf is set
562 (p6) mov r24=EVENT_THASH
563 (p6) br.cond.dpnt.many kvm_virtualization_fault_back
564 extr.u r28=r28,2,6 // get rr.ps
565 shl r22=r26,r29 // 1UL << pta.size
567 shr.u r23=r19,r28 // vaddr >> rr.ps
568 adds r26=3,r29 // pta.size + 3
569 shl r27=r17,3 // pta << 3
571 shl r23=r23,3 // (vaddr >> rr.ps) << 3
572 shr.u r27=r27,r26 // (pta << 3) >> (pta.size+3)
575 adds r22=-1,r22 // (1UL << pta.size) - 1
576 shl r27=r27,r29 // ((pta<<3)>>(pta.size+3))<<pta.size
577 and r19=r19,r16 // vaddr & VRN_MASK
579 and r22=r22,r23 // vhpt_offset
580 or r19=r19,r27 // (vadr&VRN_MASK)|(((pta<<3)>>(pta.size + 3))<<pta.size)
581 adds r26=asm_mov_to_reg-asm_mov_from_reg,r20
583 or r19=r19,r22 // calc pval
585 adds r30=kvm_resume_to_guest-asm_mov_from_reg,r20
591 #define MOV_TO_REG0 \
600 #define MOV_TO_REG(n) \
609 #define MOV_FROM_REG(n) \
618 #define MOV_TO_BANK0_REG(n) \
619 ENTRY_MIN_ALIGN(asm_mov_to_bank0_reg##n##); \
638 END(asm_mov_to_bank0_reg##n##)
641 #define MOV_FROM_BANK0_REG(n) \
642 ENTRY_MIN_ALIGN(asm_mov_from_bank0_reg##n##); \
666 END(asm_mov_from_bank0_reg##n##)
669 #define JMP_TO_MOV_TO_BANK0_REG(n) \
673 br.sptk.many asm_mov_to_bank0_reg##n##; \
678 #define JMP_TO_MOV_FROM_BANK0_REG(n) \
682 br.sptk.many asm_mov_from_bank0_reg##n##; \
687 MOV_FROM_BANK0_REG(16)
688 MOV_FROM_BANK0_REG(17)
689 MOV_FROM_BANK0_REG(18)
690 MOV_FROM_BANK0_REG(19)
691 MOV_FROM_BANK0_REG(20)
692 MOV_FROM_BANK0_REG(21)
693 MOV_FROM_BANK0_REG(22)
694 MOV_FROM_BANK0_REG(23)
695 MOV_FROM_BANK0_REG(24)
696 MOV_FROM_BANK0_REG(25)
697 MOV_FROM_BANK0_REG(26)
698 MOV_FROM_BANK0_REG(27)
699 MOV_FROM_BANK0_REG(28)
700 MOV_FROM_BANK0_REG(29)
701 MOV_FROM_BANK0_REG(30)
702 MOV_FROM_BANK0_REG(31)
705 // mov from reg table
706 ENTRY(asm_mov_from_reg)
723 JMP_TO_MOV_FROM_BANK0_REG(16)
724 JMP_TO_MOV_FROM_BANK0_REG(17)
725 JMP_TO_MOV_FROM_BANK0_REG(18)
726 JMP_TO_MOV_FROM_BANK0_REG(19)
727 JMP_TO_MOV_FROM_BANK0_REG(20)
728 JMP_TO_MOV_FROM_BANK0_REG(21)
729 JMP_TO_MOV_FROM_BANK0_REG(22)
730 JMP_TO_MOV_FROM_BANK0_REG(23)
731 JMP_TO_MOV_FROM_BANK0_REG(24)
732 JMP_TO_MOV_FROM_BANK0_REG(25)
733 JMP_TO_MOV_FROM_BANK0_REG(26)
734 JMP_TO_MOV_FROM_BANK0_REG(27)
735 JMP_TO_MOV_FROM_BANK0_REG(28)
736 JMP_TO_MOV_FROM_BANK0_REG(29)
737 JMP_TO_MOV_FROM_BANK0_REG(30)
738 JMP_TO_MOV_FROM_BANK0_REG(31)
835 END(asm_mov_from_reg)
843 ENTRY(kvm_resume_to_guest_with_sync)
844 adds r19=VMM_VPD_BASE_OFFSET,r21
857 br.sptk.many kvm_vps_sync_write
863 br.sptk.many kvm_resume_to_guest
864 END(kvm_resume_to_guest_with_sync)
866 ENTRY(kvm_resume_to_guest)
867 adds r16 = VMM_VCPU_SAVED_GP_OFFSET,r21
870 adds r20 = VMM_VCPU_VSA_BASE_OFFSET,r21
875 adds r19=VMM_VPD_BASE_OFFSET,r21
878 extr.u r17=r16,IA64_PSR_RI_BIT,2
879 tbit.nz p6,p7=r16,IA64_PSR_RI_BIT+1
884 (p6) add r18=0x10,r18
888 dep r16=r17,r16,IA64_PSR_RI_BIT,2
891 adds r19= VPD_VPSR_START_OFFSET,r25
892 add r28=PAL_VPS_RESUME_NORMAL,r20
893 add r29=PAL_VPS_RESUME_HANDLER,r20
899 tbit.z p6,p7 = r19,IA64_PSR_IC_BIT // p7=vpsr.ic
900 shr r27=r27,IA64_ISR_IR_BIT
905 (p6) dep r26=r27,r26,63,1
907 br.sptk.many b0 // call pal service
909 END(kvm_resume_to_guest)
931 ENTRY(asm_mov_to_reg)
948 JMP_TO_MOV_TO_BANK0_REG(16)
949 JMP_TO_MOV_TO_BANK0_REG(17)
950 JMP_TO_MOV_TO_BANK0_REG(18)
951 JMP_TO_MOV_TO_BANK0_REG(19)
952 JMP_TO_MOV_TO_BANK0_REG(20)
953 JMP_TO_MOV_TO_BANK0_REG(21)
954 JMP_TO_MOV_TO_BANK0_REG(22)
955 JMP_TO_MOV_TO_BANK0_REG(23)
956 JMP_TO_MOV_TO_BANK0_REG(24)
957 JMP_TO_MOV_TO_BANK0_REG(25)
958 JMP_TO_MOV_TO_BANK0_REG(26)
959 JMP_TO_MOV_TO_BANK0_REG(27)
960 JMP_TO_MOV_TO_BANK0_REG(28)
961 JMP_TO_MOV_TO_BANK0_REG(29)
962 JMP_TO_MOV_TO_BANK0_REG(30)
963 JMP_TO_MOV_TO_BANK0_REG(31)