📄 vmx_fault.c
字号:
if ( v->arch.arch_vmx.pal_init_pending ) { /*inject INIT interruption to guest pal*/ v->arch.arch_vmx.pal_init_pending = 0; deliver_pal_init(v); return; } /* * val[63:56] == 1: val[55:0] is a delivery PCI INTx line: * Domain = val[47:32], Bus = val[31:16], * DevFn = val[15: 8], IntX = val[ 1: 0] * val[63:56] == 0: val[55:0] is a delivery as GSI */ if (callback_irq != 0 && local_events_need_delivery()) { /* change level for para-device callback irq */ /* use level irq to send discrete event */ if ((uint8_t)(callback_irq >> 56) == 1) { /* case of using PCI INTx line as callback irq */ int pdev = (callback_irq >> 11) & 0x1f; int pintx = callback_irq & 3; viosapic_set_pci_irq(d, pdev, pintx, 1); viosapic_set_pci_irq(d, pdev, pintx, 0); } else { /* case of using GSI as callback irq */ viosapic_set_irq(d, callback_irq, 1); viosapic_set_irq(d, callback_irq, 0); } } } rmb(); if (xchg(&v->arch.irq_new_pending, 0)) { v->arch.irq_new_condition = 0; vmx_check_pending_irq(v); return; } if (v->arch.irq_new_condition) { v->arch.irq_new_condition = 0; vhpi_detection(v); } }}static int vmx_handle_lds(REGS* regs){ regs->cr_ipsr |= IA64_PSR_ED; return IA64_FAULT;}/* We came here because the H/W VHPT walker failed to find an entry */IA64FAULTvmx_hpw_miss(u64 vadr, u64 vec, REGS* regs){ IA64_PSR vpsr; int type; unsigned int mmu_mode; u64 vhpt_adr, gppa, pteval, rr, itir; ISR misr; PTA vpta; thash_data_t *data; VCPU *v = current; vpsr.val = VCPU(v, vpsr); misr.val = VMX(v,cr_isr); if (vec == 1 || vec == 3) type = ISIDE_TLB; else if (vec == 2 || vec == 4) type = DSIDE_TLB; else panic_domain(regs, "wrong vec:%lx\n", vec); /* Physical mode and region is 0 or 4. */ mmu_mode = VMX_MMU_MODE(v); if ((mmu_mode == VMX_MMU_PHY_DT || (mmu_mode == VMX_MMU_PHY_D && type == DSIDE_TLB)) && !((vadr<<1)>>62)) { if (type == DSIDE_TLB) { /* DTLB miss. */ if (misr.sp) /* Refer to SDM Vol2 Table 4-11,4-12 */ return vmx_handle_lds(regs); /* Clear UC bit in vadr with the shifts. */ if (v->domain != dom0 && __gpfn_is_io(v->domain, (vadr << 1) >> (PAGE_SHIFT + 1))) { emulate_io_inst(v, ((vadr << 1) >> 1), 4); return IA64_FAULT; } } physical_tlb_miss(v, vadr, type); return IA64_FAULT; } try_again: /* Search in VTLB. */ data = vtlb_lookup(v, vadr, type); if (data != 0) { /* Found. */ if (v->domain != dom0 && type == DSIDE_TLB) { if (misr.sp) { /* Refer to SDM Vol2 Table 4-10,4-12 */ if ((data->ma == VA_MATTR_UC) || (data->ma == VA_MATTR_UCE)) return vmx_handle_lds(regs); } gppa = (vadr & ((1UL << data->ps) - 1)) + (data->ppn >> (data->ps - 12) << data->ps); if (__gpfn_is_io(v->domain, gppa >> PAGE_SHIFT)) { if (misr.sp) panic_domain(NULL, "ld.s on I/O page not with UC attr." " pte=0x%lx\n", data->page_flags); if (data->pl >= ((regs->cr_ipsr >> IA64_PSR_CPL0_BIT) & 3)) emulate_io_inst(v, gppa, data->ma); else { vcpu_set_isr(v, misr.val); data_access_rights(v, vadr); } return IA64_FAULT; } } thash_vhpt_insert(v, data->page_flags, data->itir, vadr, type); return IA64_NO_FAULT; } if (type == DSIDE_TLB) { struct opt_feature* optf = &(v->domain->arch.opt_feature); if (misr.sp) return vmx_handle_lds(regs); vcpu_get_rr(v, vadr, &rr); itir = rr & (RR_RID_MASK | RR_PS_MASK); if (!vhpt_enabled(v, vadr, misr.rs ? RSE_REF : DATA_REF)) { /* windows use region 4 and 5 for identity mapping */ if ((optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG4_FLG) && REGION_NUMBER(vadr) == 4 && !(regs->cr_ipsr & IA64_PSR_CPL) && REGION_OFFSET(vadr) <= _PAGE_PPN_MASK) { pteval = PAGEALIGN(REGION_OFFSET(vadr), itir_ps(itir)) | optf->im_reg4.pgprot; if (thash_purge_and_insert(v, pteval, itir, vadr, type)) goto try_again; return IA64_NO_FAULT; } if ((optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG5_FLG) && REGION_NUMBER(vadr) == 5 && !(regs->cr_ipsr & IA64_PSR_CPL) && REGION_OFFSET(vadr) <= _PAGE_PPN_MASK) { pteval = PAGEALIGN(REGION_OFFSET(vadr), itir_ps(itir)) | optf->im_reg5.pgprot; if (thash_purge_and_insert(v, pteval, itir, vadr, type)) goto try_again; return IA64_NO_FAULT; } if (vpsr.ic) { vcpu_set_isr(v, misr.val); alt_dtlb(v, vadr); } else { nested_dtlb(v); } return IA64_FAULT; } vpta.val = vmx_vcpu_get_pta(v); if (vpta.vf) { /* Long format is not yet supported. */ goto inject_dtlb_fault; } /* avoid recursively walking (short format) VHPT */ if (!(optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG4_FLG) && !(optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG5_FLG) && (((vadr ^ vpta.val) << 3) >> (vpta.size + 3)) == 0) { goto inject_dtlb_fault; } vhpt_adr = vmx_vcpu_thash(v, vadr); if (!guest_vhpt_lookup(vhpt_adr, &pteval)) { /* VHPT successfully read. */ if (!(pteval & _PAGE_P)) { goto inject_dtlb_fault; } else if ((pteval & _PAGE_MA_MASK) != _PAGE_MA_ST) { thash_purge_and_insert(v, pteval, itir, vadr, DSIDE_TLB); return IA64_NO_FAULT; } goto inject_dtlb_fault; } else { /* Can't read VHPT. */ if (vpsr.ic) { vcpu_set_isr(v, misr.val); dvhpt_fault(v, vadr); return IA64_FAULT; } else { nested_dtlb(v); return IA64_FAULT; } } } else if (type == ISIDE_TLB) { if (!vpsr.ic) misr.ni = 1; /* Don't bother with PHY_D mode (will require rr0+rr4 switches, and certainly used only within nested TLB handler (hence TR mapped and ic=0). */ if (mmu_mode == VMX_MMU_PHY_D) goto inject_itlb_fault; if (!vhpt_enabled(v, vadr, INST_REF)) { vcpu_set_isr(v, misr.val); alt_itlb(v, vadr); return IA64_FAULT; } vpta.val = vmx_vcpu_get_pta(v); if (vpta.vf) { /* Long format is not yet supported. */ goto inject_itlb_fault; } vhpt_adr = vmx_vcpu_thash(v, vadr); if (!guest_vhpt_lookup(vhpt_adr, &pteval)) { /* VHPT successfully read. */ if (pteval & _PAGE_P) { if ((pteval & _PAGE_MA_MASK) == _PAGE_MA_ST) { goto inject_itlb_fault; } vcpu_get_rr(v, vadr, &rr); itir = rr & (RR_RID_MASK | RR_PS_MASK); thash_purge_and_insert(v, pteval, itir, vadr, ISIDE_TLB); return IA64_NO_FAULT; } else { vcpu_set_isr(v, misr.val); inst_page_not_present(v, vadr); return IA64_FAULT; } } else { vcpu_set_isr(v, misr.val); ivhpt_fault(v, vadr); return IA64_FAULT; } } return IA64_NO_FAULT; inject_dtlb_fault: if (vpsr.ic) { vcpu_set_isr(v, misr.val); dtlb_fault(v, vadr); } else nested_dtlb(v); return IA64_FAULT; inject_itlb_fault: vcpu_set_isr(v, misr.val); itlb_fault(v, vadr); return IA64_FAULT;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -