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

📄 xlate.c

📁 xen 3.2.2 源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (f != NULL)        put_domain(f);    return H_PTEG_Full;}static void h_enter(struct cpu_user_regs *regs){    ulong flags = regs->gprs[4];    ulong ptex = regs->gprs[5];    ulong vsid = regs->gprs[6];    ulong rpn = regs->gprs[7];    long ret;    ret = pte_enter(flags, ptex, vsid, rpn);    if (ret >= 0) {        regs->gprs[3] = H_Success;        regs->gprs[4] = ret;    } else        regs->gprs[3] = ret;}static void h_protect(struct cpu_user_regs *regs){    ulong flags = regs->gprs[4];    ulong ptex = regs->gprs[5];    ulong avpn = regs->gprs[6];    struct vcpu *v = get_current();    struct domain *d = v->domain;    struct domain_htab *htab = &d->arch.htab;    union pte volatile *ppte;    union pte lpte;    DBG_LOW("%s: flags: 0x%lx ptex: 0x%lx avpn: 0x%lx\n", __func__,            flags, ptex, avpn);    if ( ptex > (1UL << htab->log_num_ptes) ) {        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);        regs->gprs[3] = H_Parameter;        return;    }    ppte = &htab->map[ptex];    lpte.words.vsid = ppte->words.vsid;    lpte.words.rpn = ppte->words.rpn;    /* the AVPN param occupies the bit-space of the word */    if ( (flags & H_AVPN) && lpte.bits.avpn != avpn >> 7 ) {        DBG_LOW("%s: %p: AVPN check failed: 0x%lx, 0x%lx\n", __func__,            ppte, lpte.words.vsid, lpte.words.rpn);        regs->gprs[3] = H_Not_Found;        return;    }    if (lpte.bits.v == 0) {        /* the PAPR does not specify what to do here, this is because         * we invalidate entires where the PAPR says to 0 the whole hi         * dword, so the AVPN should catch this first */        DBG("%s: pte invalid\n", __func__);        regs->gprs[3] =  H_Not_Found;        return;    }    lpte.bits.v = 0;        /* ppte->words.vsid = lpte.words.vsid; */    asm volatile(        "eieio; std %1, 0(%0); ptesync"        :         : "b" (ppte), "r" (0)        : "memory");    pte_tlbie(&lpte, ptex);    /* We never touch pp0, and PP bits in flags are in the right     * order */    lpte.bits.pp1 = flags & (H_PP1 | H_PP2);    lpte.bits.n = (flags & H_N) ? 1 : 0;    lpte.bits.v = 1;    lpte.bits.r = 0;    asm volatile(        "std  %1, 8(%0); eieio; std %2, 0(%0); ptesync"        :         : "b" (ppte), "r" (lpte.words.rpn), "r" (lpte.words.vsid)        : "memory");    regs->gprs[3] = H_Success;}static void h_clear_ref(struct cpu_user_regs *regs){    ulong ptex = regs->gprs[5];    struct vcpu *v = get_current();    struct domain *d = v->domain;    struct domain_htab *htab = &d->arch.htab;    union pte volatile *pte;    union pte lpte;    DBG_LOW("%s: flags: 0x%lx ptex: 0x%lx\n", __func__,            regs->gprs[4], ptex);#ifdef DEBUG    if (regs->gprs[4] != 0) {        DBG("WARNING: %s: "            "flags are undefined and should be 0: 0x%lx\n",            __func__, regs->gprs[4]);    }#endif    if (ptex > (1UL << htab->log_num_ptes)) {        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);        regs->gprs[3] = H_Parameter;        return;    }    pte = &htab->map[ptex];    lpte.words.rpn = pte->words.rpn;    regs->gprs[4] = lpte.words.rpn;    if (lpte.bits.r != 0) {        lpte.bits.r = 0;        asm volatile("std  %1, 8(%0); eieio; ptesync"                :                 : "b" (pte), "r" (lpte.words.rpn) : "memory");        pte_tlbie(&lpte, ptex);    }    regs->gprs[3] = H_Success;}static void h_clear_mod(struct cpu_user_regs *regs){    ulong ptex = regs->gprs[5];    struct vcpu *v = get_current();    struct domain *d = v->domain;    struct domain_htab *htab = &d->arch.htab;    union pte volatile *pte;    union pte lpte;    DBG_LOW("%s: flags: 0x%lx ptex: 0x%lx\n", __func__,          regs->gprs[4], ptex);#ifdef DEBUG    if (regs->gprs[4] != 0) {        DBG("WARNING: %s: "            "flags are undefined and should be 0: 0x%lx\n",            __func__, regs->gprs[4]);    }#endif    if (ptex > (1UL << htab->log_num_ptes)) {        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);        regs->gprs[3] = H_Parameter;        return;    }    pte = &htab->map[ptex];    lpte.words.vsid = pte->words.vsid;    lpte.words.rpn = pte->words.rpn;    regs->gprs[3] = H_Success;    regs->gprs[4] = lpte.words.rpn;    if (lpte.bits.c != 0) {        /* invalidate */        asm volatile(                "eieio; std %1, 0(%0); ptesync"                :                 : "b" (pte), "r" (0)                : "memory");        pte_tlbie(&lpte, ptex);        lpte.bits.c = 0;        asm volatile(                "std  %1, 8(%0); eieio; std %2, 0(%0); ptesync"                :                 : "b" (pte), "r" (lpte.words.rpn), "r" (lpte.words.vsid)                : "memory");    }}long pte_remove(ulong flags, ulong ptex, ulong avpn, ulong *hi, ulong *lo){    struct vcpu *v = get_current();    struct domain *d = v->domain;    struct domain_htab *htab = &d->arch.htab;    union pte volatile *pte;    union pte lpte;    DBG_LOW("%s: flags: 0x%lx ptex: 0x%lx avpn: 0x%lx\n", __func__,            flags, ptex, avpn);    if ( ptex > (1UL << htab->log_num_ptes) ) {        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);        return H_Parameter;    }    pte = &htab->map[ptex];    lpte.words.vsid = pte->words.vsid;    lpte.words.rpn = pte->words.rpn;    if ((flags & H_AVPN) && lpte.bits.avpn != (avpn >> 7)) {        DBG_LOW("%s: AVPN does not match\n", __func__);        return H_Not_Found;    }    if ((flags & H_ANDCOND) && ((avpn & pte->words.vsid) != 0)) {        DBG("%s: andcond does not match\n", __func__);        return H_Not_Found;    }    /* return old PTE in regs 4 and 5 */    *hi = lpte.words.vsid;    *lo = lpte.words.rpn;#ifdef DEBUG_LOW    /* XXX - I'm very skeptical of doing ANYTHING if not bits.v */    /* XXX - I think the spec should be questioned in this case (MFM) */    if (lpte.bits.v == 0) {        DBG_LOW("%s: removing invalid entry\n", __func__);    }#endif    if (lpte.bits.v) {        ulong mfn = lpte.bits.rpn;        if (!platform_io_mfn(mfn)) {            struct page_info *pg = mfn_to_page(mfn);            struct domain *f = page_get_owner(pg);                        if (f != d) {                put_domain(f);                put_page(pg);            }        }    }    asm volatile("eieio; std %1, 0(%0); ptesync"            :            : "b" (pte), "r" (0)            : "memory");    pte_tlbie(&lpte, ptex);    return H_Success;}static void h_remove(struct cpu_user_regs *regs){    ulong flags = regs->gprs[4];    ulong ptex = regs->gprs[5];    ulong avpn = regs->gprs[6];    ulong hi, lo;    long ret;    ret = pte_remove(flags, ptex, avpn, &hi, &lo);    regs->gprs[3] = ret;    if (ret == H_Success) {        regs->gprs[4] = hi;        regs->gprs[5] = lo;    }    return;}static void h_read(struct cpu_user_regs *regs){    ulong flags = regs->gprs[4];    ulong ptex = regs->gprs[5];    struct vcpu *v = get_current();    struct domain *d = v->domain;    struct domain_htab *htab = &d->arch.htab;    union pte volatile *pte;    if (flags & H_READ_4)        ptex &= ~0x3UL;    if (ptex > (1UL << htab->log_num_ptes)) {        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);        regs->gprs[3] = H_Parameter;        return;    }    pte = &htab->map[ptex];    regs->gprs[4] = pte[0].words.vsid;    regs->gprs[5] = pte[0].words.rpn;    if (!(flags & H_READ_4)) {        /* dump another 3 PTEs */        regs->gprs[6] = pte[1].words.vsid;        regs->gprs[7] = pte[1].words.rpn;        regs->gprs[8] = pte[2].words.vsid;        regs->gprs[9] = pte[2].words.rpn;        regs->gprs[10] = pte[3].words.vsid;        regs->gprs[11] = pte[3].words.rpn;    }    regs->gprs[3] = H_Success;}__init_papr_hcall(H_ENTER, h_enter);__init_papr_hcall(H_READ, h_read);__init_papr_hcall(H_REMOVE, h_remove);__init_papr_hcall(H_CLEAR_MOD, h_clear_mod);__init_papr_hcall(H_CLEAR_REF, h_clear_ref);__init_papr_hcall(H_PROTECT, h_protect);

⌨️ 快捷键说明

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