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

📄 vmx_fault.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
                /* 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);    } else 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;}static inline int unimpl_phys_addr (u64 paddr){    return (pa_clear_uc(paddr) >> MAX_PHYS_ADDR_BITS) != 0;}/* 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;    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. */    if (type == ISIDE_TLB) {        if (!vpsr.it) {            if (unlikely(unimpl_phys_addr(vadr))) {                unimpl_iaddr_trap(v, vadr);                return IA64_FAULT;            }            physical_tlb_miss(v, vadr, type);            return IA64_FAULT;        }    } else { /* DTLB miss. */        if (!misr.rs) {            if (!vpsr.dt) {                u64 pte;                if (misr.sp) /* Refer to SDM Vol2 Table 4-11,4-12 */                    return vmx_handle_lds(regs);                if (unlikely(unimpl_phys_addr(vadr))) {                    unimpl_daddr(v);                    return IA64_FAULT;                }                pte = lookup_domain_mpa(v->domain, pa_clear_uc(vadr), NULL);                if (v->domain != dom0 && (pte & _PAGE_IO)) {                    emulate_io_inst(v, pa_clear_uc(vadr), 4,                                    (pte & _PFN_MASK) >> PAGE_SHIFT);                    return IA64_FAULT;                }                physical_tlb_miss(v, vadr, type);                return IA64_FAULT;            }        } else { /* RSE fault. */            if (!vpsr.rt) {                if (unlikely(unimpl_phys_addr(vadr))) {                    unimpl_daddr(v);                    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) {            u64 pte;            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 = thash_translate(data, vadr);            pte = lookup_domain_mpa(v->domain, gppa, NULL);            if (pte & _PAGE_IO) {                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,                                     (pte & _PFN_MASK) >> PAGE_SHIFT);                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 (!vpsr.dt)            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;}voidvmx_ia64_shadow_fault(u64 ifa, u64 isr, u64 mpa, REGS *regs){    struct vcpu *v = current;    struct domain *d = v->domain;    u64 gpfn, pte;    thash_data_t *data;    if (!shadow_mode_enabled(d))        goto inject_dirty_bit;    gpfn = get_gpfn_from_mfn(mpa >> PAGE_SHIFT);    data = vhpt_lookup(ifa);    if (data) {        pte = data->page_flags;        // BUG_ON((pte ^ mpa) & (_PAGE_PPN_MASK & PAGE_MASK));        if (!(pte & _PAGE_VIRT_D))            goto inject_dirty_bit;        data->page_flags = pte | _PAGE_D;    } else {        data = vtlb_lookup(v, ifa, DSIDE_TLB);        if (data) {            if (!(data->page_flags & _PAGE_VIRT_D))                goto inject_dirty_bit;        }        pte = 0;    }    /* Set the dirty bit in the bitmap.  */    shadow_mark_page_dirty(d, gpfn);    /* Retry */    atomic64_inc(&d->arch.shadow_fault_count);    ia64_ptcl(ifa, PAGE_SHIFT << 2);    return;inject_dirty_bit:    /* Reflect. no need to purge.  */    VCPU(v, isr) = isr;    set_ifa_itir_iha (v, ifa, 1, 1, 1);    inject_guest_interruption(v, IA64_DIRTY_BIT_VECTOR);    return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -