xencomm.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 271 行
C
271 行
/* * Copyright (C) 2006 Hollis Blanchard <hollisb@us.ibm.com>, IBM Corporation * Tristan Gingold <tristan.gingold@bull.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * This code is mostly taken from ia64-xen files xcom_mini.c and xencomm.c. * Changes: Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com */#include <os.h>#include <hypervisor.h>#include <xen/xencomm.h>#include <xen/grant_table.h>#define XENCOMM_MINI_ADDRS 3struct xencomm_mini{ struct xencomm_desc _desc; uint64_t address[XENCOMM_MINI_ADDRS];};#define xen_guest_handle(hnd) ((hnd).p)/* Translate virtual address to physical address. */uint64_txencomm_vaddr_to_paddr(uint64_t vaddr){ if (IA64_RR_EXTR(vaddr) == 5) return KERN_VIRT_2_PHYS(vaddr); if (IA64_RR_EXTR(vaddr) == 7) return __pa(vaddr); return 0;}#define min(a,b) (((a) < (b)) ? (a) : (b))static intxencomm_init_desc(struct xencomm_desc *desc, void *buffer, unsigned long bytes){ unsigned long recorded = 0; int i = 0; if ((buffer == NULL) && (bytes > 0)) BUG(); /* record the physical pages used */ if (buffer == NULL) desc->nr_addrs = 0; while ((recorded < bytes) && (i < desc->nr_addrs)) { unsigned long vaddr = (unsigned long)buffer + recorded; unsigned long paddr; int offset; int chunksz; offset = vaddr % PAGE_SIZE; /* handle partial pages */ chunksz = min(PAGE_SIZE - offset, bytes - recorded); paddr = xencomm_vaddr_to_paddr(vaddr); if (paddr == ~0UL) { printk("%s: couldn't translate vaddr %lx\n", __func__, vaddr); return -EINVAL; } desc->address[i++] = SWAP(paddr); recorded += chunksz; } if (recorded < bytes) { printk("%s: could only translate %ld of %ld bytes\n", __func__, recorded, bytes); return -ENOSPC; } /* mark remaining addresses invalid (just for safety) */ while (i < desc->nr_addrs) desc->address[i++] = SWAP(XENCOMM_INVALID); desc->magic = SWAP(XENCOMM_MAGIC); return 0;}static void *xencomm_alloc_mini(struct xencomm_mini *area, int *nbr_area){ unsigned long base; unsigned int pageoffset; while (*nbr_area >= 0) { /* Allocate an area. */ (*nbr_area)--; base = (unsigned long)(area + *nbr_area); pageoffset = base % PAGE_SIZE; /* If the area does not cross a page, use it. */ if ((PAGE_SIZE - pageoffset) >= sizeof(struct xencomm_mini)) return &area[*nbr_area]; } /* No more area. */ return NULL;}intxencomm_create_mini(struct xencomm_mini *area, int *nbr_area, void *buffer, unsigned long bytes, struct xencomm_handle **ret){ struct xencomm_desc *desc; int rc; unsigned long res; desc = xencomm_alloc_mini(area, nbr_area); if (!desc) return -ENOMEM; desc->nr_addrs = XENCOMM_MINI_ADDRS; rc = xencomm_init_desc(desc, buffer, bytes); if (rc) return rc; res = xencomm_vaddr_to_paddr((unsigned long)desc); if (res == ~0UL) return -EINVAL; *ret = (struct xencomm_handle*)res; return 0;}static intxencommize_mini_grant_table_op(struct xencomm_mini *xc_area, int *nbr_area, unsigned int cmd, void *op, unsigned int count, struct xencomm_handle **desc){ struct xencomm_handle *desc1; unsigned int argsize=0; int rc; switch (cmd) { case GNTTABOP_map_grant_ref: argsize = sizeof(struct gnttab_map_grant_ref); break; case GNTTABOP_unmap_grant_ref: argsize = sizeof(struct gnttab_unmap_grant_ref); break; case GNTTABOP_setup_table: { struct gnttab_setup_table *setup = op; argsize = sizeof(*setup); if (count != 1) return -EINVAL; rc = xencomm_create_mini (xc_area, nbr_area, (void*)SWAP((uint64_t) xen_guest_handle(setup->frame_list)), SWAP(setup->nr_frames) * sizeof(*xen_guest_handle(setup->frame_list)), &desc1); if (rc) return rc; set_xen_guest_handle(setup->frame_list, (void *)SWAP((uint64_t)desc1)); break; } case GNTTABOP_dump_table: argsize = sizeof(struct gnttab_dump_table); break; case GNTTABOP_transfer: argsize = sizeof(struct gnttab_transfer); break; case GNTTABOP_copy: argsize = sizeof(struct gnttab_copy); break; default: printk("%s: unknown mini grant table op %d\n", __func__, cmd); BUG(); } rc = xencomm_create_mini(xc_area, nbr_area, op, count * argsize, desc); return rc;}intxencomm_mini_hypercall_grant_table_op(unsigned int cmd, void *op, unsigned int count){ int rc; struct xencomm_handle *desc; int nbr_area = 2; struct xencomm_mini xc_area[2]; rc = xencommize_mini_grant_table_op(xc_area, &nbr_area, cmd, op, count, &desc); if (rc) return rc; return xencomm_arch_hypercall_grant_table_op(cmd, desc, count);}static voidgnttab_map_grant_ref_pre(struct gnttab_map_grant_ref *uop){ uint32_t flags; flags = uop->flags; if (flags & GNTMAP_host_map) { if (flags & GNTMAP_application_map) { printk("GNTMAP_application_map is not supported yet: " "flags 0x%x\n", flags); BUG(); } if (flags & GNTMAP_contains_pte) { printk("GNTMAP_contains_pte is not supported yet flags " "0x%x\n", flags); BUG(); } } else if (flags & GNTMAP_device_map) { printk("GNTMAP_device_map is not supported yet 0x%x\n", flags); BUG();//XXX not yet. actually this flag is not used. } else { BUG(); }}intHYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count){ if (cmd == GNTTABOP_map_grant_ref) { unsigned int i; for (i = 0; i < count; i++) { gnttab_map_grant_ref_pre( (struct gnttab_map_grant_ref*)uop + i); } } return xencomm_mini_hypercall_grant_table_op(cmd, uop, count);} /* In fw.S */extern int xencomm_arch_hypercall_suspend(struct xencomm_handle *arg);intHYPERVISOR_suspend(unsigned long srec){ struct sched_shutdown arg; arg.reason = (uint32_t)SWAP((uint32_t)SHUTDOWN_suspend); return xencomm_arch_hypercall_suspend(xencomm_create_inline(&arg));}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?