📄 hyperprivop.s
字号:
bsw.1;; // FIXME?: ar.unat is not really handled correctly, // but may not matter if the OS is NaT-clean .mem.offset 0,0; ld8.fill r16=[r2],16 .mem.offset 8,0; ld8.fill r17=[r3],16 ;; .mem.offset 0,0; ld8.fill r18=[r2],16 .mem.offset 0,0; ld8.fill r19=[r3],16 ;; .mem.offset 8,0; ld8.fill r20=[r2],16 .mem.offset 8,0; ld8.fill r21=[r3],16 ;; .mem.offset 8,0; ld8.fill r22=[r2],16 .mem.offset 8,0; ld8.fill r23=[r3],16 ;; .mem.offset 8,0; ld8.fill r24=[r2],16 .mem.offset 8,0; ld8.fill r25=[r3],16 ;; .mem.offset 8,0; ld8.fill r26=[r2],16 .mem.offset 8,0; ld8.fill r27=[r3],16 ;; .mem.offset 8,0; ld8.fill r28=[r2],16 .mem.offset 8,0; ld8.fill r29=[r3],16 ;; .mem.offset 8,0; ld8.fill r30=[r2],16 .mem.offset 8,0; ld8.fill r31=[r3],16 ;; bsw.0 ;; mov ar.unat=r17 mov r2=r30 mov r3=r291: mov pr=r31,-1 ;; rfi ;;END(hyper_rfi) #ifdef RFI_TO_INTERRUPTENTRY(rfi_check_extint) //br.sptk.many dispatch_break_fault ;; // r18=&vpsr.i|vpsr.ic, r21==vpsr, r22=vcr.iip // make sure none of these get trashed in case going to just_do_rfi movl r30=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;; ld8 r30=[r30];; adds r24=IA64_VCPU_INSVC3_OFFSET,r30 mov r25=192 adds r16=IA64_VCPU_IRR3_OFFSET,r30;; ld8 r23=[r16];; cmp.eq p6,p0=r23,r0;;(p6) adds r16=-8,r16;;(p6) adds r24=-8,r24;;(p6) adds r25=-64,r25;;(p6) ld8 r23=[r16];;(p6) cmp.eq p6,p0=r23,r0;;(p6) adds r16=-8,r16;;(p6) adds r24=-8,r24;;(p6) adds r25=-64,r25;;(p6) ld8 r23=[r16];;(p6) cmp.eq p6,p0=r23,r0;;(p6) adds r16=-8,r16;;(p6) adds r24=-8,r24;;(p6) adds r25=-64,r25;;(p6) ld8 r23=[r16];; cmp.eq p6,p0=r23,r0(p6) br.cond.spnt.few just_do_rfi; // this is actually an error // r16 points to non-zero element of irr, r23 has value // r24 points to corr element of insvc, r25 has elt*64 ld8 r26=[r24];; cmp.geu p6,p0=r26,r23(p6) br.cond.spnt.many just_do_rfi; // not masked by insvc, get vector number shr.u r26=r23,1;; or r26=r23,r26;; shr.u r27=r26,2;; or r26=r26,r27;; shr.u r27=r26,4;; or r26=r26,r27;; shr.u r27=r26,8;; or r26=r26,r27;; shr.u r27=r26,16;; or r26=r26,r27;; shr.u r27=r26,32;; or r26=r26,r27;; andcm r26=0xffffffffffffffff,r26;; popcnt r26=r26;; sub r26=63,r26;; // r26 now contains the bit index (mod 64) mov r27=1;; shl r27=r27,r26;; // r27 now contains the (within the proper word) bit mask add r26=r25,r26 // r26 now contains the vector [0..255] adds r20=XSI_TPR_OFS-XSI_PSR_IC_OFS,r18 ;; ld8 r20=[r20] ;; extr.u r29=r20,4,4 tbit.nz p6,p0=r20,16 // if tpr.mmi is set, just rfi(p6) br.cond.spnt.few just_do_rfi;; shl r29=r29,4;; adds r29=15,r29;; cmp.ge p6,p0=r29,r26 // if tpr masks interrupt, just rfi(p6) br.cond.spnt.few just_do_rfi;;END(rfi_check_extint)// this doesn't work yet (dies early after getting to user mode)// but happens relatively infrequently, so fix it later.// NOTE that these will be counted incorrectly for now (for privcnt output)ENTRY(rfi_with_interrupt)#if 1 br.sptk.many dispatch_break_fault ;;#endif // OK, have an unmasked vector, so deliver extint to vcr.iva+0x3000 // r18 == XSI_PSR_IC // r21 == vipsr (ipsr in shared_mem) // r30 == IA64_KR(CURRENT) // r31 == pr mov r17=cr.ipsr mov r16=cr.isr;; // set shared_mem isr extr.u r16=r16,IA64_ISR_IR_BIT,1;; // grab cr.isr.ir bit dep r16=r16,r0,IA64_ISR_IR_BIT,1 // insert into cr.isr (rest of bits zero) extr.u r20=r21,IA64_PSR_RI_BIT,2 ;; // get v(!)psr.ri dep r16=r20,r16,IA64_PSR_RI_BIT,2 ;; // deposit cr.isr.ei adds r22=XSI_ISR_OFS-XSI_PSR_IC_OFS,r18 ;; st8 [r22]=r16;; movl r22=THIS_CPU(current_psr_i_addr) // set cr.ipsr (make sure cpl==2!) mov r29=r17 movl r27=~DELIVER_PSR_CLR movl r28=DELIVER_PSR_SET | (CONFIG_CPL0_EMUL << IA64_PSR_CPL0_BIT) mov r20=1;; ld8 r22=[r22] and r29=r29,r27;; or r29=r29,r28;; mov cr.ipsr=r29 // v.ipsr and v.iip are already set (and v.iip validated) as rfi target // set shared_mem interrupt_delivery_enabled to 0 // set shared_mem interrupt_collection_enabled to 0 st1 [r22]=r20 st4 [r18]=r0;; // cover and set shared_mem precover_ifs to cr.ifs // set shared_mem ifs to 0#if 0 cover ;; mov r20=cr.ifs adds r22=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18 ;; st8 [r22]=r0 ;; adds r22=XSI_PRECOVER_IFS_OFS-XSI_PSR_IC_OFS,r18 ;; st8 [r22]=r20 ;; // leave cr.ifs alone for later rfi#else adds r22=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18 ;; ld8 r20=[r22];; st8 [r22]=r0 ;; adds r22=XSI_PRECOVER_IFS_OFS-XSI_PSR_IC_OFS,r18 ;; st8 [r22]=r20 ;;#endif // set iip to go to domain IVA break instruction vector adds r22=IA64_VCPU_IVA_OFFSET,r30;; ld8 r23=[r22] movl r24=0x3000;; add r24=r24,r23;; mov cr.iip=r24;;#if 0 // OK, now all set to go except for switch to virtual bank0 mov r30=r2 mov r29=r3;; adds r2=XSI_BANK1_OFS-XSI_PSR_IC_OFS,r18 adds r3=(XSI_BANK1_OFS+8)-XSI_PSR_IC_OFS,r18;; bsw.1;; // FIXME: need to handle ar.unat! .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 ;; bsw.0 ;; mov r2=r30 mov r3=r29;;#endif adds r20=XSI_BANKNUM_OFS-XSI_PSR_IC_OFS,r18 ;; st4 [r20]=r0 mov pr=r31,-1 ;; rfiEND(rfi_with_interrupt)#endif // RFI_TO_INTERRUPTENTRY(hyper_cover)#ifdef FAST_HYPERPRIVOP_CNT movl r20=FAST_HYPERPRIVOP_PERFC(HYPERPRIVOP_COVER);; ld4 r21=[r20];; adds r21=1,r21;; st4 [r20]=r21;;#endif mov r24=cr.ipsr mov r25=cr.iip;; // skip test for vpsr.ic.. it's a prerequisite for hyperprivops cover ;; mov r30=cr.ifs adds r22=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18;; st8 [r22]=r30 mov cr.ifs=r0 // adjust return address to skip over break instruction extr.u r26=r24,41,2 ;; cmp.eq p6,p7=2,r26 ;;(p6) mov r26=0(p6) adds r25=16,r25(p7) adds r26=1,r26 ;; dep r24=r26,r24,IA64_PSR_RI_BIT,2 ;; mov cr.ipsr=r24 mov cr.iip=r25 mov pr=r31,-1 ;; rfi ;;END(hyper_cover)// return from metaphysical mode (meta=1) to virtual mode (meta=0)ENTRY(hyper_ssm_dt)#ifdef FAST_HYPERPRIVOP_CNT movl r20=FAST_HYPERPRIVOP_PERFC(HYPERPRIVOP_SSM_DT);; ld4 r21=[r20];; adds r21=1,r21;; st4 [r20]=r21;;#endif mov r24=cr.ipsr mov r25=cr.iip adds r20=XSI_METAPHYS_OFS-XSI_PSR_IC_OFS,r18 ;; ld4 r21=[r20];; cmp.eq p7,p0=r21,r0 // meta==0?(p7) br.spnt.many 1f ;; // already in virtual mode movl r22=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;; ld8 r22=[r22];; adds r22=IA64_VCPU_META_SAVED_RR0_OFFSET,r22;; ld8 r23=[r22];; mov rr[r0]=r23;; srlz.i;; st4 [r20]=r0 // adjust return address to skip over break instruction1: extr.u r26=r24,IA64_PSR_RI_BIT,2 ;; cmp.eq p6,p7=2,r26 ;;(p6) mov r26=0(p6) adds r25=16,r25(p7) adds r26=1,r26 ;; dep r24=r26,r24,IA64_PSR_RI_BIT,2 ;; mov cr.ipsr=r24 mov cr.iip=r25 mov pr=r31,-1 ;; rfi ;;END(hyper_ssm_dt)// go to metaphysical mode (meta=1) from virtual mode (meta=0)ENTRY(hyper_rsm_dt)#ifdef FAST_HYPERPRIVOP_CNT movl r20=FAST_HYPERPRIVOP_PERFC(HYPERPRIVOP_RSM_DT);; ld4 r21=[r20];; adds r21=1,r21;; st4 [r20]=r21;;#endif mov r24=cr.ipsr mov r25=cr.iip adds r20=XSI_METAPHYS_OFS-XSI_PSR_IC_OFS,r18 ;; ld4 r21=[r20];; cmp.ne p7,p0=r21,r0 // meta==0?(p7) br.spnt.many 1f ;; // already in metaphysical mode movl r22=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;; ld8 r22=[r22];; adds r22=IA64_VCPU_META_RID_DT_OFFSET,r22;; ld8 r23=[r22];; mov rr[r0]=r23;; srlz.i;; adds r21=1,r0 ;; st4 [r20]=r21 // adjust return address to skip over break instruction1: extr.u r26=r24,IA64_PSR_RI_BIT,2 ;; cmp.eq p6,p7=2,r26 ;;(p6) mov r26=0(p6) adds r25=16,r25(p7) adds r26=1,r26 ;; dep r24=r26,r24,IA64_PSR_RI_BIT,2 ;; mov cr.ipsr=r24 mov cr.iip=r25 mov pr=r31,-1 ;; rfi ;;END(hyper_rsm_dt)ENTRY(hyper_set_itm) // when we get to here r20=~=interrupts pending cmp.ne p7,p0=r20,r0(p7) br.spnt.many dispatch_break_fault ;;#ifdef FAST_HYPERPRIVOP_CNT movl r20=FAST_HYPERPRIVOP_PERFC(HYPERPRIVOP_SET_ITM);; ld4 r21=[r20];; adds r21=1,r21;; st4 [r20]=r21;;#endif movl r20=THIS_CPU(cpu_info)+IA64_CPUINFO_ITM_NEXT_OFFSET;; ld8 r21=[r20];; movl r20=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;; ld8 r20=[r20];; adds r20=IA64_VCPU_DOMAIN_ITM_OFFSET,r20;; st8 [r20]=r8 cmp.geu p6,p0=r21,r8;;(p6) mov r21=r8 // now "safe set" cr.itm=r21 mov r23=100;;2: mov cr.itm=r21;; srlz.d;; mov r22=ar.itc ;; cmp.leu p6,p0=r21,r22;; add r21=r21,r23;; shl r23=r23,1(p6) br.cond.spnt.few 2b;;1: mov r24=cr.ipsr mov r25=cr.iip;; extr.u r26=r24,IA64_PSR_RI_BIT,2 ;; cmp.eq p6,p7=2,r26 ;;(p6) mov r26=0(p6) adds r25=16,r25(p7) adds r26=1,r26 ;; dep r24=r26,r24,IA64_PSR_RI_BIT,2 ;; mov cr.ipsr=r24 mov cr.iip=r25 mov pr=r31,-1 ;; rfi ;;END(hyper_set_itm)ENTRY(hyper_get_psr)#ifdef FAST_HYPERPRIVOP_CNT movl r20=FAST_HYPERPRIVOP_PERFC(HYPERPRIVOP_GET_PSR);; ld4 r21=[r20];; adds r21=1,r21;; st4 [r20]=r21;;#endif mov r24=cr.ipsr movl r8=0xffffffff | IA64_PSR_MC | IA64_PSR_IT;; // only return PSR{36:35,31:0} and r8=r8,r24 // get vpsr.ic ld4 r21=[r18];; dep r8=r21,r8,IA64_PSR_IC_BIT,1 // get vpsr.pp adds r20=XSI_VPSR_PP_OFS-XSI_PSR_IC_OFS,r18 ;; ld1 r21=[r20];; dep r8=r21,r8,IA64_PSR_PP_BIT,1 // get vpsr.dt adds r20=XSI_METAPHYS_OFS-XSI_PSR_IC_OFS,r18 ;; ld4 r21=[r20];; cmp.ne p6,p0=r21,r0 ;;(p6) dep.z r8=r8,IA64_PSR_DT_BIT,1 // get vpsr.i adds r20=XSI_PSR_I_ADDR_OFS-XSI_PSR_IC_OFS,r18 ;; ld8 r20=[r20];; ld1 r21=[r20];; cmp.eq p8,p9=r0,r21 ;;(p8) dep r8=-1,r8,IA64_PSR_I_BIT,1(p9) dep r8=0,r8,IA64_PSR_I_BIT,1 // get vpsr.dfh adds r20=XSI_VPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;; ld1 r21=[r20];; dep r8=r21,r8,IA64_PSR_DFH_BIT,1 ;; mov r25=cr.iip extr.u r26=r24,IA64_PSR_RI_BIT,2 ;; cmp.eq p6,p7=2,r26 ;;(p6) mov r26=0(p6) adds r25=16,r25(p7) adds r26=1,r26 ;; dep r24=r26,r24,IA64_PSR_RI_BIT,2 ;; mov cr.ipsr=r24 mov cr.iip=r25 mov pr=r31,-1 ;; rfi ;;END(hyper_get_psr) ENTRY(hyper_get_rr)#ifdef FAST_HYPERPRIVOP_CNT movl r20=FAST_HYPERPRIVOP_PERFC(HYPERPRIVOP_GET_RR);; ld4 r21=[r20];; adds r21=1,r21;; st4 [r20]=r21;;#endif extr.u r25=r8,61,3;; adds r20=XSI_RR0_OFS-XSI_PSR_IC_OFS,r18 shl r25=r25,3;; add r20=r20,r25;; ld8 r8=[r20]1: mov r24=cr.ipsr mov r25=cr.iip;; extr.u r26=r24,IA64_PSR_RI_BIT,2 ;; cmp.eq p6,p7=2,r26 ;;(p6) mov r26=0(p6) adds r25=16,r25(p7) adds r26=1,r26 ;; dep r24=r26,r24,IA64_PSR_RI_BIT,2 ;; mov cr.ipsr=r24 mov cr.iip=r25 mov pr=r31,-1 ;; rfi ;;END(hyper_get_rr)ENTRY(hyper_set_rr) extr.u r25=r8,61,3;; cmp.leu p7,p0=7,r25 // punt on setting rr7(p7) br.spnt.many dispatch_break_fault ;;#ifdef FAST_HYPERPRIVOP_CNT movl r20=FAST_HYPERPRIVOP_PERFC(HYPERPRIVOP_SET_RR);; ld4 r21=[r20];; adds r21=1,r21;; st4 [r20]=r21;;#endif extr.u r26=r9,IA64_RR_RID,IA64_RR_RID_LEN // r26 = r9.rid movl r20=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;; ld8 r20=[r20];; adds r22=IA64_VCPU_STARTING_RID_OFFSET,r20 adds r23=IA64_VCPU_ENDING_RID_OFFSET,r20 adds r24=IA64_VCPU_META_SAVED_RR0_OFFSET,r20 adds r21=IA64_VCPU_VHPT_PG_SHIFT_OFFSET,r20;; ld4 r22=[r22] ld4 r23=[r23] ld1 r21=[r21];; add r22=r26,r22;; cmp.geu p6,p0=r22,r23 // if r9.rid + starting_rid >= ending_rid(p6) br.cond.spnt.few 1f; // this is an error, but just ignore/return adds r20=XSI_RR0_OFS-XSI_PSR_IC_OFS,r18 shl r25=r25,3;; add r20=r20,r25;; st8 [r20]=r9;; // store away exactly what was passed // but adjust value actually placed in rr[r8] // r22 contains adjusted rid, "mangle" it (see regionreg.c) // and set ps to v->arch.vhpt_pg_shift and ve to 1 extr.u r27=r22,0,8 extr.u r28=r22,8,8 extr.u r29=r22,16,8 dep.z r23=r21,IA64_RR_PS,IA64_RR_PS_LEN;; dep r23=-1,r23,0,1;; // mangling is swapping bytes 1 & 3 dep r23=r27,r23,24,8;; dep r23=r28,r23,16,8;; dep r23=r29,r23,8,8 cmp.eq p6,p0=r25,r0;; // if rr0, save for metaphysical(p6) st8 [r24]=r23 mov rr[r8]=r23;; // done, mosey on back1: mov r24=cr.ipsr mov r25=cr.iip;; extr.u r26=r24,IA64_PSR_RI_BIT,2 ;; cmp.eq p6,p7=2,r26 ;;(p6) mov r26=0(p6) adds r25=16,r25(p7) adds r26=1,r26 ;; dep r24=r26,r24,IA64_PSR_RI_BIT,2 ;; mov cr.ipsr=r24 mov cr.iip=r25 mov pr=r31,-1 ;; rfi ;;END(hyper_set_rr)// r8 = val0// r9 = val1// r10 = val2// r11 = val3// r14 = val4// mov rr[0x0000000000000000UL] = r8// mov rr[0x2000000000000000UL] = r9// mov rr[0x4000000000000000UL] = r10// mov rr[0x6000000000000000UL] = r11// mov rr[0x8000000000000000UL] = r14ENTRY(hyper_set_rr0_to_rr4)#ifndef FAST_SET_RR0_TO_RR4 br.spnt.few dispatch_break_fault ;;#endif#ifdef FAST_HYPERPRIVOP_CNT movl r20=FAST_HYPERPRIVOP_PERFC(HYPERPRIVOP_SET_RR0_TO_RR4);; ld4 r21=[r20];; adds r21=1,r21;; st4 [r20]=r21;;#endif movl r17=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;; ld8 r17=[r17];; adds r21=IA64_VCPU_STARTING_RID_OFFSET,r17 adds r22=IA64_VCPU_ENDING_RID_OFFSET,r17 adds r23=IA64_VCPU_VHPT_PG_SHIFT_OFFSET,r17 ;; ld4 r21=[r21] // r21 = current->starting_rid extr.u r26=r8,IA64_RR_RID,IA64_RR_RID_LEN // r26 = r8.rid extr.u r27=r9,IA64_RR_RID,IA64_RR_RID_LEN // r27 = r9.rid ld4 r22=[r22] // r22 = current->ending_rid extr.u r28=r10,IA64_RR_RID,IA64_RR_RID_LEN // r28 = r10.rid extr.u r29=r11,IA64_RR_RID,IA64_RR_RID_LEN // r29 = r11.rid adds r24=IA64_VCPU_META_SAVED_RR0_OFFSET,r17 extr.u r30=r14,IA64_RR_RID,IA64_RR_RID_LEN // r30 = r14.rid ld1 r23=[r23] // r23 = current->vhpt_pg_shift ;; add r16=r26,r21 add r17=r27,r21 add r19=r28,r21 add r20=r29,r21 add r21=r30,r21 dep.z r23=r23,IA64_RR_PS,IA64_RR_PS_LEN // r23 = rr.ps ;; cmp.geu p6,p0=r16,r22 // if r8.rid + starting_rid >= ending_rid cmp.geu p7,p0=r17,r22 // if r9.rid + starting_rid >= ending_rid cmp.geu p8,p0=r19,r22 // if r10.rid + starting_rid >= ending_rid(p6) br.cond.spnt.few 1f // this is an error, but just ignore/return(p7) br.cond.spnt.few 1f // this is an error, but just ignore/return cmp.geu p9,p0=r20,r22 // if r11.rid + starting_rid >= ending_rid(p8) br.cond.spnt.few 1f // this is an error, but just ignore/return(p9) br.cond.spnt.few 1f // this is an error, but just ignore/return cmp.geu p10,p0=r21,r22 // if r14.rid + starting_rid >= ending_rid(p10) br.cond.spnt.few 1f // this is an error, but just ignore/return dep r23=-1,r23,0,1 // add rr.ve ;; mov r25=1 adds r22=XSI_RR0_OFS-XSI_PSR_IC_OFS,r18 ;; shl r30=r25,61 // r30 = 0x2000000000000000#if 0 // simple plain version // rr0 st8 [r22]=r8, 8 // current->rrs[0] = r8 mov r26=0 // r26=0x0000000000000000 extr.u r27=r16,0,8 extr.u r28=r16,8,8 extr.u r29=r16,16,8;; dep r25=r27,r23,24,8;; // mangling is swapping bytes 1 & 3 dep r25=r28,r25,16,8;; dep r25=r29,r25,8,8;;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -