📄 vmx_interrupt.c
字号:
/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- *//* * vmx_interrupt.c: handle inject interruption. * Copyright (c) 2005, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307 USA. * * Shaofan Li (Susue Li) <susie.li@intel.com> * Xiaoyan Feng (Fleming Feng) <fleming.feng@intel.com> * Xuefei Xu (Anthony Xu) (Anthony.xu@intel.com) */#include <xen/types.h>#include <asm/vmx_vcpu.h>#include <asm/vmx_mm_def.h>#include <asm/vmx_pal_vsa.h>#include <asm/debugger.h>/* SDM vol2 5.5 - IVA based interruption handling */#define INITIAL_PSR_VALUE_AT_INTERRUPTION 0x0000001808028034static voidcollect_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);}voidinject_guest_interruption(VCPU *vcpu, u64 vec){ u64 viva; REGS *regs; ISR pt_isr; perfc_incra(vmx_inject_guest_interruption, vec >> 8); regs = vcpu_regs(vcpu); // clear cr.isr.ir (incomplete register frame) pt_isr.val = VMX(vcpu,cr_isr); pt_isr.ir = 0; VMX(vcpu,cr_isr) = pt_isr.val; collect_interruption(vcpu); vmx_ia64_set_dcr(vcpu); viva = vmx_vcpu_get_iva(vcpu); regs->cr_iip = viva + vec; debugger_event(vec == IA64_EXTINT_VECTOR ? XEN_IA64_DEBUG_ON_EXTINT : XEN_IA64_DEBUG_ON_EXCEPT);}/* * Set vIFA & vITIR & vIHA, when vPSR.ic =1 * Parameter: * set_ifa: if true, set vIFA * set_itir: if true, set vITIR * set_iha: if true, set vIHA */voidset_ifa_itir_iha (VCPU *vcpu, u64 vadr, int set_ifa, int set_itir, int set_iha){ IA64_PSR vpsr; u64 value; vpsr.val = VCPU(vcpu, vpsr); /* Vol2, Table 8-1 */ if ( vpsr.ic ) { if ( set_ifa){ vcpu_set_ifa(vcpu, vadr); } if ( set_itir) { value = vmx_vcpu_get_itir_on_fault(vcpu, vadr); vcpu_set_itir(vcpu, value); } if ( set_iha) { value = vmx_vcpu_thash(vcpu, vadr); vcpu_set_iha(vcpu, value); } }}/* * Data TLB Fault * @ Data TLB vector * Refer to SDM Vol2 Table 5-6 & 8-1 */voiddtlb_fault (VCPU *vcpu, u64 vadr){ /* If vPSR.ic, IFA, ITIR, IHA */ set_ifa_itir_iha (vcpu, vadr, 1, 1, 1); inject_guest_interruption(vcpu,IA64_DATA_TLB_VECTOR);}/* * Instruction TLB Fault * @ Instruction TLB vector * Refer to SDM Vol2 Table 5-6 & 8-1 */voiditlb_fault (VCPU *vcpu, u64 vadr){ /* If vPSR.ic, IFA, ITIR, IHA */ set_ifa_itir_iha (vcpu, vadr, 1, 1, 1); inject_guest_interruption(vcpu,IA64_INST_TLB_VECTOR);}/* * Data Nested TLB Fault * @ Data Nested TLB Vector * Refer to SDM Vol2 Table 5-6 & 8-1 */voidnested_dtlb (VCPU *vcpu){ inject_guest_interruption(vcpu,IA64_DATA_NESTED_TLB_VECTOR);}/* * Alternate Data TLB Fault * @ Alternate Data TLB vector * Refer to SDM Vol2 Table 5-6 & 8-1 */voidalt_dtlb (VCPU *vcpu, u64 vadr){ set_ifa_itir_iha (vcpu, vadr, 1, 1, 0); inject_guest_interruption(vcpu,IA64_ALT_DATA_TLB_VECTOR);}/* * Data TLB Fault * @ Data TLB vector * Refer to SDM Vol2 Table 5-6 & 8-1 */voidalt_itlb (VCPU *vcpu, u64 vadr){ set_ifa_itir_iha (vcpu, vadr, 1, 1, 0); inject_guest_interruption(vcpu,IA64_ALT_INST_TLB_VECTOR);}/* Deal with: * VHPT Translation Vector */static void_vhpt_fault(VCPU *vcpu, u64 vadr){ /* If vPSR.ic, IFA, ITIR, IHA*/ set_ifa_itir_iha (vcpu, vadr, 1, 1, 1); inject_guest_interruption(vcpu,IA64_VHPT_TRANS_VECTOR);}/* * VHPT Instruction Fault * @ VHPT Translation vector * Refer to SDM Vol2 Table 5-6 & 8-1 */voidivhpt_fault (VCPU *vcpu, u64 vadr){ _vhpt_fault(vcpu, vadr);}/* * VHPT Data Fault * @ VHPT Translation vector * Refer to SDM Vol2 Table 5-6 & 8-1 */voiddvhpt_fault (VCPU *vcpu, u64 vadr){ _vhpt_fault(vcpu, vadr);}/* * Deal with: * General Exception vector */void_general_exception (VCPU *vcpu){ inject_guest_interruption(vcpu,IA64_GENEX_VECTOR);}/* * Illegal Operation Fault * @ General Exception Vector * Refer to SDM Vol2 Table 5-6 & 8-1 */voidillegal_op (VCPU *vcpu){ _general_exception(vcpu);}/* * Illegal Dependency Fault * @ General Exception Vector * Refer to SDM Vol2 Table 5-6 & 8-1 */voidillegal_dep (VCPU *vcpu){ _general_exception(vcpu);}/* * Reserved Register/Field Fault * @ General Exception Vector * Refer to SDM Vol2 Table 5-6 & 8-1 */voidrsv_reg_field (VCPU *vcpu){ _general_exception(vcpu);}/* * Privileged Operation Fault * @ General Exception Vector * Refer to SDM Vol2 Table 5-6 & 8-1 */voidprivilege_op (VCPU *vcpu){ _general_exception(vcpu);}/* * Unimplement Data Address Fault * @ General Exception Vector * Refer to SDM Vol2 Table 5-6 & 8-1 */voidunimpl_daddr (VCPU *vcpu){ _general_exception(vcpu);}/* * Privileged Register Fault * @ General Exception Vector * Refer to SDM Vol2 Table 5-6 & 8-1 */voidprivilege_reg (VCPU *vcpu){ _general_exception(vcpu);}/* Deal with * Nat consumption vector * Parameter: * vaddr: Optional, if t == REGISTER */static void_nat_consumption_fault(VCPU *vcpu, u64 vadr, miss_type t){ /* If vPSR.ic && t == DATA/INST, IFA */ if ( t == DATA || t == INSTRUCTION ) { /* IFA */ set_ifa_itir_iha (vcpu, vadr, 1, 0, 0); } inject_guest_interruption(vcpu,IA64_NAT_CONSUMPTION_VECTOR);}/* * IR Data Nat Page Consumption Fault * @ Nat Consumption Vector * Refer to SDM Vol2 Table 5-6 & 8-1 */#if 0static voidir_nat_page_consumption (VCPU *vcpu, u64 vadr){ _nat_consumption_fault(vcpu, vadr, DATA);}#endif //shadow it due to no use currently /* * Instruction Nat Page Consumption Fault * @ Nat Consumption Vector * Refer to SDM Vol2 Table 5-6 & 8-1 */voidinat_page_consumption (VCPU *vcpu, u64 vadr){ _nat_consumption_fault(vcpu, vadr, INSTRUCTION);}/* * Register Nat Consumption Fault * @ Nat Consumption Vector * Refer to SDM Vol2 Table 5-6 & 8-1 */voidrnat_consumption (VCPU *vcpu){ _nat_consumption_fault(vcpu, 0, REGISTER);}/* * Data Nat Page Consumption Fault * @ Nat Consumption Vector * Refer to SDM Vol2 Table 5-6 & 8-1 */voiddnat_page_consumption (VCPU *vcpu, uint64_t vadr){ _nat_consumption_fault(vcpu, vadr, DATA);}/* Deal with * Page not present vector */static void__page_not_present(VCPU *vcpu, u64 vadr){ /* If vPSR.ic, IFA, ITIR */ set_ifa_itir_iha (vcpu, vadr, 1, 1, 0); inject_guest_interruption(vcpu, IA64_PAGE_NOT_PRESENT_VECTOR);}voiddata_page_not_present(VCPU *vcpu, u64 vadr){ __page_not_present(vcpu, vadr);}voidinst_page_not_present(VCPU *vcpu, u64 vadr){ __page_not_present(vcpu, vadr);}/* Deal with * Data access rights vector */voiddata_access_rights(VCPU *vcpu, u64 vadr){ /* If vPSR.ic, IFA, ITIR */ set_ifa_itir_iha (vcpu, vadr, 1, 1, 0); inject_guest_interruption(vcpu, IA64_DATA_ACCESS_RIGHTS_VECTOR);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -