📄 dom0_ops.c
字号:
if (d == NULL) break; ret = -EPERM; if ( !IS_PRIV_FOR(current->domain, d) ) goto gethvmcontext_out;#ifdef CONFIG_X86 ret = xsm_hvmcontext(d, op->cmd); if (ret) goto gethvmcontext_out;#endif /* CONFIG_X86 */ ret = -EINVAL; if (!is_hvm_domain(d)) goto gethvmcontext_out; c.cur = 0; c.size = hvm_save_size(d); c.data = NULL; if (guest_handle_is_null(op->u.hvmcontext.buffer)) { /* Client is querying for the correct buffer size */ op->u.hvmcontext.size = c.size; ret = 0; goto gethvmcontext_out; } /* Check that the client has a big enough buffer */ ret = -ENOSPC; if (op->u.hvmcontext.size < c.size) goto gethvmcontext_out; /* Allocate our own marshalling buffer */ ret = -ENOMEM; c.data = xmalloc_bytes(c.size); if (c.data == NULL) goto gethvmcontext_out; domain_pause(d); ret = hvm_save(d, &c); domain_unpause(d); op->u.hvmcontext.size = c.cur; if (copy_to_guest(op->u.hvmcontext.buffer, c.data, c.size) != 0) ret = -EFAULT; gethvmcontext_out: if (copy_to_guest(u_domctl, op, 1)) ret = -EFAULT; if (c.data != NULL) xfree(c.data); rcu_unlock_domain(d); } break; case XEN_DOMCTL_set_opt_feature: { struct xen_ia64_opt_feature *optf = &op->u.set_opt_feature.optf; struct domain *d = rcu_lock_domain_by_id(op->domain); if (d == NULL) { ret = -EINVAL; break; } ret = -EPERM; if ( IS_PRIV_FOR(current->domain, d) ) ret = domain_opt_feature(d, optf); rcu_unlock_domain(d); } break; case XEN_DOMCTL_assign_device: ret = -ENOSYS; break; default: printk("arch_do_domctl: unrecognized domctl: %d!!!\n",op->cmd); ret = -ENOSYS; } return ret;}long arch_do_sysctl(xen_sysctl_t *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl){ long ret = 0; switch ( op->cmd ) { case XEN_SYSCTL_physinfo: { int i; uint32_t max_array_ent; XEN_GUEST_HANDLE_64(uint32) cpu_to_node_arr; xen_sysctl_physinfo_t *pi = &op->u.physinfo; max_array_ent = pi->max_cpu_id; cpu_to_node_arr = pi->cpu_to_node; memset(pi, 0, sizeof(*pi)); pi->cpu_to_node = cpu_to_node_arr; pi->threads_per_core = cpus_weight(cpu_sibling_map[0]); pi->cores_per_socket = cpus_weight(cpu_core_map[0]) / pi->threads_per_core; pi->nr_cpus = (u32)num_online_cpus(); pi->nr_nodes = num_online_nodes(); pi->total_pages = total_pages; pi->free_pages = avail_domheap_pages(); pi->scrub_pages = avail_scrub_pages(); pi->cpu_khz = local_cpu_data->proc_freq / 1000; pi->max_cpu_id = last_cpu(cpu_online_map); max_array_ent = min_t(uint32_t, max_array_ent, pi->max_cpu_id); ret = 0; if (!guest_handle_is_null(cpu_to_node_arr)) { for (i = 0; i <= max_array_ent; i++) { uint32_t node = cpu_online(i) ? cpu_to_node(i) : ~0u; if (copy_to_guest_offset(cpu_to_node_arr, i, &node, 1)) { ret = -EFAULT; break; } } } if ( copy_to_guest(u_sysctl, op, 1) ) ret = -EFAULT; } break; default: printk("arch_do_sysctl: unrecognized sysctl: %d!!!\n",op->cmd); ret = -ENOSYS; } return ret;}intdo_get_pm_info(struct xen_sysctl_get_pmstat *op){ /* * For now just place holder to compile. * xen/common/sysctl.c refers this function. */ return -ENOSYS;}static unsigned longdom0vp_ioremap(struct domain *d, unsigned long mpaddr, unsigned long size){ unsigned long end; /* Linux may use a 0 size! */ if (size == 0) size = PAGE_SIZE; if (size == 0) printk(XENLOG_WARNING "ioremap(): Trying to map %lx, size 0\n", mpaddr); end = PAGE_ALIGN(mpaddr + size); if (!iomem_access_permitted(d, mpaddr >> PAGE_SHIFT, (end >> PAGE_SHIFT) - 1)) return -EPERM; return assign_domain_mmio_page(d, mpaddr, mpaddr, size, ASSIGN_writable | ASSIGN_nocache);}static unsigned longdom0vp_fpswa_revision(XEN_GUEST_HANDLE(uint) revision){ if (fpswa_interface == NULL) return -ENOSYS; if (copy_to_guest(revision, &fpswa_interface->revision, 1)) return -EFAULT; return 0;}static unsigned longdom0vp_add_io_space(struct domain *d, unsigned long phys_base, unsigned long sparse, unsigned long space_number){ unsigned int fp, lp; /* * Registering new io_space roughly based on linux * arch/ia64/pci/pci.c:new_space() */ /* Skip legacy I/O port space, we already know about it */ if (phys_base == 0) return 0; /* * Dom0 Linux initializes io spaces sequentially, if that changes, * we'll need to add thread protection and the ability to handle * a sparsely populated io_space array. */ if (space_number > MAX_IO_SPACES || space_number != num_io_spaces) return -EINVAL; io_space[space_number].mmio_base = phys_base; io_space[space_number].sparse = sparse; num_io_spaces++; fp = space_number << IO_SPACE_BITS; lp = fp | 0xffff; return ioports_permit_access(d, fp, lp);}unsigned longdo_dom0vp_op(unsigned long cmd, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3){ unsigned long ret = 0; struct domain *d = current->domain; switch (cmd) { case IA64_DOM0VP_ioremap: ret = dom0vp_ioremap(d, arg0, arg1); break; case IA64_DOM0VP_phystomach: ret = ____lookup_domain_mpa(d, arg0 << PAGE_SHIFT); if (ret == INVALID_MFN) { dprintk(XENLOG_INFO, "%s: INVALID_MFN ret: 0x%lx\n", __func__, ret); } else { ret = (ret & _PFN_MASK) >> PAGE_SHIFT;//XXX pte_pfn() } perfc_incr(dom0vp_phystomach); break; case IA64_DOM0VP_machtophys: if (!mfn_valid(arg0)) { ret = INVALID_M2P_ENTRY; break; } ret = get_gpfn_from_mfn(arg0); perfc_incr(dom0vp_machtophys); break; case IA64_DOM0VP_zap_physmap: ret = dom0vp_zap_physmap(d, arg0, (unsigned int)arg1); break; case IA64_DOM0VP_add_physmap: if (!IS_PRIV(d)) return -EPERM; ret = dom0vp_add_physmap(d, arg0, arg1, (unsigned int)arg2, (domid_t)arg3); break; case IA64_DOM0VP_add_physmap_with_gmfn: if (!IS_PRIV(d)) return -EPERM; ret = dom0vp_add_physmap_with_gmfn(d, arg0, arg1, (unsigned int)arg2, (domid_t)arg3); break; case IA64_DOM0VP_expose_p2m: ret = dom0vp_expose_p2m(d, arg0, arg1, arg2, arg3); break; case IA64_DOM0VP_perfmon: { XEN_GUEST_HANDLE(void) hnd; set_xen_guest_handle(hnd, (void*)arg1); ret = do_perfmon_op(arg0, hnd, arg2); break; } case IA64_DOM0VP_fpswa_revision: { XEN_GUEST_HANDLE(uint) hnd; set_xen_guest_handle(hnd, (uint*)arg0); ret = dom0vp_fpswa_revision(hnd); break; } case IA64_DOM0VP_add_io_space: ret = dom0vp_add_io_space(d, arg0, arg1, arg2); break; case IA64_DOM0VP_expose_foreign_p2m: { XEN_GUEST_HANDLE(char) hnd; set_xen_guest_handle(hnd, (char*)arg2); ret = dom0vp_expose_foreign_p2m(d, arg0, (domid_t)arg1, hnd, arg3); break; } case IA64_DOM0VP_unexpose_foreign_p2m: ret = dom0vp_unexpose_foreign_p2m(d, arg0, arg1); break; default: ret = -1; printk("unknown dom0_vp_op 0x%lx\n", cmd); break; } return ret;}/* * Local variables: * mode: C * c-set-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -