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

📄 paging.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
        d->arch.paging.log_dirty.dirty_count++;    } out:    log_dirty_unlock(d);}/* Read a domain's log-dirty bitmap and stats.  If the operation is a CLEAN, * clear the bitmap and stats as well. */int paging_log_dirty_op(struct domain *d, struct xen_domctl_shadow_op *sc){    int rv = 0, clean = 0, peek = 1;    unsigned long pages = 0;    mfn_t *l4, *l3, *l2;    unsigned long *l1;    int i4, i3, i2;    domain_pause(d);    log_dirty_lock(d);    clean = (sc->op == XEN_DOMCTL_SHADOW_OP_CLEAN);    PAGING_DEBUG(LOGDIRTY, "log-dirty %s: dom %u faults=%u dirty=%u\n",                 (clean) ? "clean" : "peek",                 d->domain_id,                 d->arch.paging.log_dirty.fault_count,                 d->arch.paging.log_dirty.dirty_count);    sc->stats.fault_count = d->arch.paging.log_dirty.fault_count;    sc->stats.dirty_count = d->arch.paging.log_dirty.dirty_count;    if ( clean )    {        d->arch.paging.log_dirty.fault_count = 0;        d->arch.paging.log_dirty.dirty_count = 0;    }    if ( guest_handle_is_null(sc->dirty_bitmap) )        /* caller may have wanted just to clean the state or access stats. */        peek = 0;    if ( (peek || clean) && !mfn_valid(d->arch.paging.log_dirty.top) )    {        rv = -EINVAL; /* perhaps should be ENOMEM? */        goto out;    }    if ( unlikely(d->arch.paging.log_dirty.failed_allocs) ) {        printk("%s: %d failed page allocs while logging dirty pages\n",               __FUNCTION__, d->arch.paging.log_dirty.failed_allocs);        rv = -ENOMEM;        goto out;    }    pages = 0;    l4 = map_domain_page(mfn_x(d->arch.paging.log_dirty.top));    for ( i4 = 0;          (pages < sc->pages) && (i4 < LOGDIRTY_NODE_ENTRIES);          i4++ )    {        l3 = mfn_valid(l4[i4]) ? map_domain_page(mfn_x(l4[i4])) : NULL;        for ( i3 = 0;              (pages < sc->pages) && (i3 < LOGDIRTY_NODE_ENTRIES);              i3++ )        {            l2 = ((l3 && mfn_valid(l3[i3])) ?                  map_domain_page(mfn_x(l3[i3])) : NULL);            for ( i2 = 0;                  (pages < sc->pages) && (i2 < LOGDIRTY_NODE_ENTRIES);                  i2++ )            {                static unsigned long zeroes[PAGE_SIZE/BYTES_PER_LONG];                unsigned int bytes = PAGE_SIZE;                l1 = ((l2 && mfn_valid(l2[i2])) ?                      map_domain_page(mfn_x(l2[i2])) : zeroes);                if ( unlikely(((sc->pages - pages + 7) >> 3) < bytes) )                    bytes = (unsigned int)((sc->pages - pages + 7) >> 3);                if ( likely(peek) )                {                    if ( copy_to_guest_offset(sc->dirty_bitmap, pages >> 3,                                              (uint8_t *)l1, bytes) != 0 )                    {                        rv = -EFAULT;                        goto out;                    }                }                if ( clean && l1 != zeroes )                    clear_page(l1);                pages += bytes << 3;                if ( l1 != zeroes )                    unmap_domain_page(l1);            }            if ( l2 )                unmap_domain_page(l2);        }        if ( l3 )            unmap_domain_page(l3);    }    unmap_domain_page(l4);    if ( pages < sc->pages )        sc->pages = pages;    log_dirty_unlock(d);    if ( clean )    {        /* We need to further call clean_dirty_bitmap() functions of specific         * paging modes (shadow or hap).  Safe because the domain is paused. */        d->arch.paging.log_dirty.clean_dirty_bitmap(d);    }    domain_unpause(d);    return rv; out:    log_dirty_unlock(d);    domain_unpause(d);    return rv;}/* Note that this function takes three function pointers. Callers must supply * these functions for log dirty code to call. This function usually is * invoked when paging is enabled. Check shadow_enable() and hap_enable() for * reference. * * These function pointers must not be followed with the log-dirty lock held. */void paging_log_dirty_init(struct domain *d,                           int    (*enable_log_dirty)(struct domain *d),                           int    (*disable_log_dirty)(struct domain *d),                           void   (*clean_dirty_bitmap)(struct domain *d)){    /* We initialize log dirty lock first */    log_dirty_lock_init(d);    d->arch.paging.log_dirty.enable_log_dirty = enable_log_dirty;    d->arch.paging.log_dirty.disable_log_dirty = disable_log_dirty;    d->arch.paging.log_dirty.clean_dirty_bitmap = clean_dirty_bitmap;    d->arch.paging.log_dirty.top = _mfn(INVALID_MFN);}/* This function fress log dirty bitmap resources. */void paging_log_dirty_teardown(struct domain*d){    log_dirty_lock(d);    paging_free_log_dirty_bitmap(d);    log_dirty_unlock(d);}/************************************************//*           CODE FOR PAGING SUPPORT            *//************************************************//* Domain paging struct initialization. */int paging_domain_init(struct domain *d){    int rc;    if ( (rc = p2m_init(d)) != 0 )        return rc;    /* The order of the *_init calls below is important, as the later     * ones may rewrite some common fields.  Shadow pagetables are the     * default... */    shadow_domain_init(d);    /* ... but we will use hardware assistance if it's available. */    if ( hap_enabled(d) )        hap_domain_init(d);    return 0;}/* vcpu paging struct initialization goes here */void paging_vcpu_init(struct vcpu *v){    if ( hap_enabled(v->domain) )        hap_vcpu_init(v);    else        shadow_vcpu_init(v);}int paging_domctl(struct domain *d, xen_domctl_shadow_op_t *sc,                  XEN_GUEST_HANDLE(void) u_domctl){    int rc;    if ( unlikely(d == current->domain) )    {        gdprintk(XENLOG_INFO, "Tried to do a paging op on itself.\n");        return -EINVAL;    }    if ( unlikely(d->is_dying) )    {        gdprintk(XENLOG_INFO, "Ignoring paging op on dying domain %u\n",                 d->domain_id);        return 0;    }    if ( unlikely(d->vcpu[0] == NULL) )    {        PAGING_ERROR("Paging op on a domain (%u) with no vcpus\n",                     d->domain_id);        return -EINVAL;    }    rc = xsm_shadow_control(d, sc->op);    if ( rc )        return rc;    /* Code to handle log-dirty. Note that some log dirty operations     * piggy-back on shadow operations. For example, when     * XEN_DOMCTL_SHADOW_OP_OFF is called, it first checks whether log dirty     * mode is enabled. If does, we disables log dirty and continues with     * shadow code. For this reason, we need to further dispatch domctl     * to next-level paging code (shadow or hap).     */    switch ( sc->op )    {    case XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY:        return paging_log_dirty_enable(d);    case XEN_DOMCTL_SHADOW_OP_ENABLE:        if ( sc->mode & XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY )            return paging_log_dirty_enable(d);    case XEN_DOMCTL_SHADOW_OP_OFF:        if ( paging_mode_log_dirty(d) )            if ( (rc = paging_log_dirty_disable(d)) != 0 )                return rc;    case XEN_DOMCTL_SHADOW_OP_CLEAN:    case XEN_DOMCTL_SHADOW_OP_PEEK:        return paging_log_dirty_op(d, sc);    }    /* Here, dispatch domctl to the appropriate paging code */    if ( hap_enabled(d) )        return hap_domctl(d, sc, u_domctl);    else        return shadow_domctl(d, sc, u_domctl);}/* Call when destroying a domain */void paging_teardown(struct domain *d){    if ( hap_enabled(d) )        hap_teardown(d);    else        shadow_teardown(d);    /* clean up log dirty resources. */    paging_log_dirty_teardown(d);}/* Call once all of the references to the domain have gone away */void paging_final_teardown(struct domain *d){    if ( hap_enabled(d) )        hap_final_teardown(d);    else        shadow_final_teardown(d);    p2m_final_teardown(d);}/* Enable an arbitrary paging-assistance mode.  Call once at domain * creation. */int paging_enable(struct domain *d, u32 mode){    if ( hap_enabled(d) )        return hap_enable(d, mode | PG_HAP_enable);    else        return shadow_enable(d, mode | PG_SH_enable);}/* Print paging-assistance info to the console */void paging_dump_domain_info(struct domain *d){    if ( paging_mode_enabled(d) )    {        printk("    paging assistance: ");        if ( paging_mode_shadow(d) )            printk("shadow ");        if ( paging_mode_hap(d) )            printk("hap ");        if ( paging_mode_refcounts(d) )            printk("refcounts ");        if ( paging_mode_log_dirty(d) )            printk("log_dirty ");        if ( paging_mode_translate(d) )            printk("translate ");        if ( paging_mode_external(d) )            printk("external ");        printk("\n");    }}void paging_dump_vcpu_info(struct vcpu *v){    if ( paging_mode_enabled(v->domain) )    {        printk("    paging assistance: ");        if ( paging_mode_shadow(v->domain) )        {            if ( v->arch.paging.mode )                printk("shadowed %u-on-%u\n",                       v->arch.paging.mode->guest_levels,                       v->arch.paging.mode->shadow.shadow_levels);            else                printk("not shadowed\n");        }        else if ( paging_mode_hap(v->domain) && v->arch.paging.mode )            printk("hap, %u levels\n",                   v->arch.paging.mode->guest_levels);        else            printk("none\n");    }}/* * Local variables: * mode: C * c-set-style: "BSD" * c-basic-offset: 4 * indent-tabs-mode: nil * End: */

⌨️ 快捷键说明

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