⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vmx_fault.c

📁 xen 3.2.2 源码
💻 C
📖 第 1 页 / 共 2 页
字号:
            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 + -