IA64FAULT vmx_vcpu_get_bgr(VCPU *vcpu, unsigned int reg, u64 *val) { IA64_PSR vpsr; vpsr.val = vmx_vcpu_get_psr(vcpu); if ( vpsr.bn ) { *val=VCPU(vcpu,vgr[reg-16]); // Check NAT bit if ( VCPU(vcpu,vnat) & (1UL<<(reg-16)) ) { // TODO //panic ("NAT consumption fault\n"); return IA64_FAULT; } } else { *val=VCPU(vcpu,vbgr[reg-16]); if ( VCPU(vcpu,vbnat) & (1UL<<reg) ) { //panic ("NAT consumption fault\n"); return IA64_FAULT; } } return IA64_NO_FAULT; }
IA64FAULT vmx_vcpu_set_psr_sm(VCPU *vcpu, u64 imm24) { u64 vpsr; vpsr = vmx_vcpu_get_psr(vcpu); vpsr |= imm24; vmx_vcpu_set_psr(vcpu, vpsr); return IA64_NO_FAULT; }
static void collect_interruption(VCPU *vcpu) { u64 ipsr; u64 vdcr; u64 vifs; IA64_PSR vpsr; REGS * regs = vcpu_regs(vcpu); vpsr.val = vmx_vcpu_get_psr(vcpu); vcpu_bsw0(vcpu); if(vpsr.ic){ /* Sync mpsr id/da/dd/ss/ed bits to vipsr * since after guest do rfi, we still want these bits on in * mpsr */ ipsr = regs->cr_ipsr; vpsr.val = vpsr.val | (ipsr & (IA64_PSR_ID | IA64_PSR_DA | IA64_PSR_DD |IA64_PSR_SS |IA64_PSR_ED)); vcpu_set_ipsr(vcpu, vpsr.val); /* Currently, for trap, we do not advance IIP to next * instruction. That's because we assume caller already * set up IIP correctly */ vcpu_set_iip(vcpu , regs->cr_iip); /* set vifs.v to zero */ vifs = VCPU(vcpu,ifs); vifs &= ~IA64_IFS_V; vcpu_set_ifs(vcpu, vifs); vcpu_set_iipa(vcpu, VMX(vcpu,cr_iipa)); } vdcr = VCPU(vcpu,dcr); /* Set guest psr * up/mfl/mfh/pk/dt/rt/mc/it keeps unchanged * be: set to the value of dcr.be * pp: set to the value of dcr.pp */ vpsr.val &= INITIAL_PSR_VALUE_AT_INTERRUPTION; vpsr.val |= ( vdcr & IA64_DCR_BE); /* VDCR pp bit position is different from VPSR pp bit */ if ( vdcr & IA64_DCR_PP ) { vpsr.val |= IA64_PSR_PP; } else { vpsr.val &= ~IA64_PSR_PP;; } vmx_vcpu_set_psr(vcpu, vpsr.val); }
IA64FAULT vmx_vcpu_set_bgr(VCPU *vcpu, unsigned int reg, u64 val,int nat) { IA64_PSR vpsr; vpsr.val = vmx_vcpu_get_psr(vcpu); if ( vpsr.bn ) { VCPU(vcpu,vgr[reg-16]) = val; if(nat){ VCPU(vcpu,vnat) |= ( 1UL<<(reg-16) ); }else{ VCPU(vcpu,vbnat) &= ~( 1UL<<(reg-16) ); } } else { VCPU(vcpu,vbgr[reg-16]) = val; if(nat){ VCPU(vcpu,vnat) |= ( 1UL<<(reg) ); }else{ VCPU(vcpu,vbnat) &= ~( 1UL<<(reg) ); } } return IA64_NO_FAULT; }
IA64FAULT vmx_vcpu_set_psr_l(VCPU *vcpu, u64 val) { val = (val & MASK(0, 32)) | (vmx_vcpu_get_psr(vcpu) & MASK(32, 32)); vmx_vcpu_set_psr(vcpu, val); return IA64_NO_FAULT; }