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

📄 dom0_ops.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * Arch-specific dom0_ops.c *  * Process command requests from domain-0 guest OS. *  * Copyright (c) 2002, K A Fraser */#include <xen/config.h>#include <xen/types.h>#include <xen/lib.h>#include <xen/mm.h>#include <public/domctl.h>#include <public/sysctl.h>#include <xen/sched.h>#include <xen/event.h>#include <asm/pdb.h>#include <xen/trace.h>#include <xen/console.h>#include <xen/guest_access.h>#include <asm/vmx.h>#include <asm/dom_fw.h>#include <asm/vhpt.h>#include <xen/iocap.h>#include <xen/errno.h>#include <xen/nodemask.h>#include <asm/dom_fw_utils.h>#include <asm/hvm/support.h>#include <xsm/xsm.h>#include <public/hvm/save.h>#define get_xen_guest_handle(val, hnd)  do { val = (hnd).p; } while (0)extern unsigned long total_pages;long arch_do_domctl(xen_domctl_t *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl){    long ret = 0;    switch ( op->cmd )    {    case XEN_DOMCTL_getmemlist:    {        unsigned long i;        struct domain *d = rcu_lock_domain_by_id(op->domain);        unsigned long start_page = op->u.getmemlist.start_pfn;        unsigned long nr_pages = op->u.getmemlist.max_pfns;        uint64_t mfn;        if ( d == NULL ) {            ret = -EINVAL;            break;        }        if ( !IS_PRIV_FOR(current->domain, d) ) {            ret = -EPERM;            rcu_unlock_domain(d);            break;        }        for (i = 0 ; i < nr_pages ; i++) {            pte_t *pte;            pte = (pte_t *)lookup_noalloc_domain_pte(d,                                               (start_page + i) << PAGE_SHIFT);            if (pte && pte_present(*pte))                mfn = start_page + i;            else                mfn = INVALID_MFN;            if ( copy_to_guest_offset(op->u.getmemlist.buffer, i, &mfn, 1) ) {                    ret = -EFAULT;                    break;            }        }        op->u.getmemlist.num_pfns = i;        if (copy_to_guest(u_domctl, op, 1))            ret = -EFAULT;        rcu_unlock_domain(d);    }    break;    case XEN_DOMCTL_arch_setup:    {        xen_domctl_arch_setup_t *ds = &op->u.arch_setup;        struct domain *d = rcu_lock_domain_by_id(op->domain);        if ( d == NULL) {            ret = -EINVAL;            break;        }        if ( !IS_PRIV_FOR(current->domain, d) ) {            ret = -EPERM;            rcu_unlock_domain(d);            break;        }        if (ds->flags & XEN_DOMAINSETUP_query) {            /* Set flags.  */            if (is_hvm_domain(d))                ds->flags |= XEN_DOMAINSETUP_hvm_guest;            /* Set params.  */            ds->bp = 0;		/* unknown.  */            ds->maxmem = d->arch.convmem_end;            ds->xsi_va = d->arch.shared_info_va;            ds->hypercall_imm = d->arch.breakimm;#ifdef CONFIG_XEN_IA64_PERVCPU_VHPT            ds->vhpt_size_log2 = d->arch.vhpt_size_log2;#endif            /* Copy back.  */            if ( copy_to_guest(u_domctl, op, 1) )                ret = -EFAULT;        }        else {            if (is_hvm_domain(d)                || (ds->flags & (XEN_DOMAINSETUP_hvm_guest                                 | XEN_DOMAINSETUP_sioemu_guest))) {                if (!vmx_enabled) {                    printk("No VMX hardware feature for vmx domain.\n");                    ret = -EINVAL;                } else {                    d->is_hvm = 1;                    if (ds->flags & XEN_DOMAINSETUP_sioemu_guest)                        d->arch.is_sioemu = 1;                    xen_ia64_set_convmem_end(d, ds->maxmem);                    ret = vmx_setup_platform(d);                }            }            else {                if (ds->hypercall_imm) {                    /* dom_fw_setup() reads d->arch.breakimm */                    struct vcpu *v;                    d->arch.breakimm = ds->hypercall_imm;                    for_each_vcpu (d, v)                        v->arch.breakimm = d->arch.breakimm;                }                domain_set_vhpt_size(d, ds->vhpt_size_log2);                if (ds->xsi_va)                    d->arch.shared_info_va = ds->xsi_va;                ret = dom_fw_setup(d, ds->bp, ds->maxmem);            }            if (ret == 0) {                /*                 * XXX IA64_SHARED_INFO_PADDR                 * assign these pages into guest psudo physical address                 * space for dom0 to map this page by gmfn.                 * this is necessary for domain build, save, restore and                  * dump-core.                 */                unsigned long i;                for (i = 0; i < XSI_SIZE; i += PAGE_SIZE)                    assign_domain_page(d, IA64_SHARED_INFO_PADDR + i,                                       virt_to_maddr(d->shared_info + i));            }        }        rcu_unlock_domain(d);    }    break;    case XEN_DOMCTL_shadow_op:    {        struct domain *d;         ret = -ESRCH;        d = rcu_lock_domain_by_id(op->domain);        if ( d != NULL )        {            if ( !IS_PRIV_FOR(current->domain, d) ) {                ret = -EPERM;                rcu_unlock_domain(d);                break;            }            ret = shadow_mode_control(d, &op->u.shadow_op);            rcu_unlock_domain(d);            if (copy_to_guest(u_domctl, op, 1))                ret = -EFAULT;        }     }    break;    case XEN_DOMCTL_ioport_permission:    {        struct domain *d;        unsigned int fp = op->u.ioport_permission.first_port;        unsigned int np = op->u.ioport_permission.nr_ports;        unsigned int lp = fp + np - 1;        ret = -ESRCH;        d = rcu_lock_domain_by_id(op->domain);        if (unlikely(d == NULL))            break;        if ( !IS_PRIV_FOR(current->domain, d) ) {            ret = -EPERM;            rcu_unlock_domain(d);            break;        }        if (np == 0)            ret = 0;        else {            if (op->u.ioport_permission.allow_access)                ret = ioports_permit_access(d, fp, lp);            else                ret = ioports_deny_access(d, fp, lp);        }        rcu_unlock_domain(d);    }    break;    case XEN_DOMCTL_sendtrigger:    {        struct domain *d;        struct vcpu *v;        ret = -ESRCH;        d = rcu_lock_domain_by_id(op->domain);        if ( d == NULL )            break;        ret = -EPERM;        if ( !IS_PRIV_FOR(current->domain, d) ) {            goto sendtrigger_out;        }        ret = -EINVAL;        if ( op->u.sendtrigger.vcpu >= MAX_VIRT_CPUS )            goto sendtrigger_out;        ret = -ESRCH;        if ( (v = d->vcpu[op->u.sendtrigger.vcpu]) == NULL )            goto sendtrigger_out;        ret = 0;        switch (op->u.sendtrigger.trigger)        {        case XEN_DOMCTL_SENDTRIGGER_INIT:        {            if (VMX_DOMAIN(v))                vmx_pend_pal_init(d);            else                ret = -ENOSYS;        }        break;        default:            ret = -ENOSYS;        }    sendtrigger_out:        rcu_unlock_domain(d);    }    break;    case XEN_DOMCTL_sethvmcontext:    {         struct hvm_domain_context c;        struct domain *d;        c.cur = 0;        c.size = op->u.hvmcontext.size;        c.data = NULL;                ret = -ESRCH;        d = rcu_lock_domain_by_id(op->domain);        if (d == NULL)            break;        ret = -EPERM;        if ( !IS_PRIV_FOR(current->domain, d) )            goto sethvmcontext_out;#ifdef CONFIG_X86        ret = xsm_hvmcontext(d, op->cmd);        if (ret)            goto sethvmcontext_out;#endif /* CONFIG_X86 */        ret = -EINVAL;        if (!is_hvm_domain(d))             goto sethvmcontext_out;        ret = -ENOMEM;        c.data = xmalloc_bytes(c.size);        if (c.data == NULL)            goto sethvmcontext_out;        ret = -EFAULT;        if (copy_from_guest(c.data, op->u.hvmcontext.buffer, c.size) != 0)            goto sethvmcontext_out;        domain_pause(d);        ret = hvm_load(d, &c);        domain_unpause(d);    sethvmcontext_out:        if (c.data != NULL)            xfree(c.data);        rcu_unlock_domain(d);    }    break;    case XEN_DOMCTL_gethvmcontext:    {         struct hvm_domain_context c;        struct domain *d;        ret = -ESRCH;        d = rcu_lock_domain_by_id(op->domain);

⌨️ 快捷键说明

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