[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] Re: [XenPPC] RFC: xencomm - linux side
I apologize for my mailer line-wrapping the patch as I quote it below. On Mon, 2006-08-21 at 17:18 +0200, Tristan Gingold wrote: > diff -r b7db009d622c linux-2.6-xen-sparse/drivers/xen/Kconfig > --- a/linux-2.6-xen-sparse/drivers/xen/Kconfig Mon Aug 21 09:41:24 > 2006 +0200 > +++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig Mon Aug 21 15:04:32 > 2006 +0200 > @@ -257,4 +257,7 @@ config XEN_SMPBOOT > default y > depends on SMP > > +config XEN_XENCOMM > + bool > + default n > endif Shouldn't IA64 "select XEN_XENCOMM"? Or is your kernel in a separate tree? > diff -r b7db009d622c linux-2.6-xen-sparse/drivers/xen/Makefile > --- a/linux-2.6-xen-sparse/drivers/xen/Makefile Mon Aug 21 09:41:24 > 2006 +0200 > +++ b/linux-2.6-xen-sparse/drivers/xen/Makefile Mon Aug 21 15:04:32 > 2006 +0200 > @@ -1,10 +1,10 @@ obj-y += core/ > obj-y += core/ > obj-y += console/ > obj-y += evtchn/ > -obj-y += privcmd/ > obj-y += xenbus/ > > obj-$(CONFIG_XEN_UTIL) += util.o > +obj-$(CONFIG_XEN_PRIVCMD) += privcmd/ > obj-$(CONFIG_XEN_BALLOON) += balloon/ > obj-$(CONFIG_XEN_DEVMEM) += char/ > obj-$(CONFIG_XEN_BLKDEV_BACKEND) += blkback/ Not really part of this patch. > diff -r b7db009d622c linux-2.6-xen-sparse/drivers/xen/core/Makefile > --- a/linux-2.6-xen-sparse/drivers/xen/core/Makefile Mon Aug 21 > 09:41:24 2006 +0200 > +++ b/linux-2.6-xen-sparse/drivers/xen/core/Makefile Mon Aug 21 > 15:04:32 2006 +0200 > @@ -11,3 +11,4 @@ obj-$(CONFIG_XEN_SKBUFF) += skbuff.o > obj-$(CONFIG_XEN_SKBUFF) += skbuff.o > obj-$(CONFIG_XEN_REBOOT) += reboot.o > obj-$(CONFIG_XEN_SMPBOOT) += smpboot.o > +obj-$(CONFIG_XEN_XENCOMM) += xencomm.o xencomm_hcall.o > diff -r b7db009d622c linux-2.6-xen-sparse/drivers/xen/privcmd/Makefile > --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/Makefile Mon Aug 21 > 09:41:24 2006 +0200 > +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/Makefile Mon Aug 21 > 15:04:32 2006 +0200 > @@ -1,2 +1,3 @@ > +obj-y := privcmd.o > > -obj-$(CONFIG_XEN_PRIVCMD) := privcmd.o > +obj-$(CONFIG_XEN_XENCOMM) += xencomm.o I agree with the CONFIG_XEN_PRIVCMD stuff, but I think that should be a separate patch. > diff -r b7db009d622c > linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c > --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Mon > Aug 21 09:41:24 2006 +0200 > +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Mon > Aug 21 15:04:32 2006 +0200 > @@ -34,6 +34,10 @@ > > static struct proc_dir_entry *privcmd_intf; > static struct proc_dir_entry *capabilities_intf; > + > +#ifdef CONFIG_XEN_XENCOMM > +extern int xencomm_privcmd_hypercall(privcmd_hypercall_t *hypercall); > +#endif > > #define NR_HYPERCALLS 64 > static DECLARE_BITMAP(hypercall_permission_map, NR_HYPERCALLS); > @@ -91,19 +95,8 @@ static int privcmd_ioctl(struct inode *i > "g" ((unsigned long)hypercall.arg[4]) > : "r8", "r10", "memory" ); > } > -#elif defined (__ia64__) > - __asm__ __volatile__ ( > - ";; mov r14=%2; mov r15=%3; " > - "mov r16=%4; mov r17=%5; mov r18=%6;" > - "mov r2=%1; break 0x1000;; mov %0=r8 ;;" > - : "=r" (ret) > - : "r" (hypercall.op), > - "r" (hypercall.arg[0]), > - "r" (hypercall.arg[1]), > - "r" (hypercall.arg[2]), > - "r" (hypercall.arg[3]), > - "r" (hypercall.arg[4]) > - : > "r14","r15","r16","r17","r18","r2","r8","memory"); > +#elif defined (CONFIG_XEN_XENCOMM) > + ret = xencomm_privcmd_hypercall (&hypercall); > #endif > } > break; Move all the #ifdef stuff into appropriate header files, then have every arch unconditionally call arch_privcmd_hypercall(). > diff -r b7db009d622c linux-2.6-xen-sparse/drivers/xen/core/xencomm.c > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/linux-2.6-xen-sparse/drivers/xen/core/xencomm.c Mon Aug 21 > 15:04:32 2006 +0200 > @@ -0,0 +1,213 @@ > +/* > + * Copyright (C) 2006 Hollis Blanchard <hollisb@xxxxxxxxxx>, IBM > Corporation > + * > + * 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 > + */ > + > +#include <linux/gfp.h> > +#include <linux/mm.h> > +#include <asm/page.h> > +#include <xen/xencomm.h> > +#include <xen/interface/xen.h> > + > +int xencomm_debug; > + > +/* translate virtual address to physical address */ > +static unsigned long xen_vaddr_to_paddr(unsigned long vaddr) > +{ > + struct page *page; > + struct vm_area_struct *vma; > + > +#ifdef __ia64__ > + /* On ia64, TASK_SIZE refers to current. It is not > initialized > + during boot. > + Furthermore the kernel is relocatable and __pa() doesn't > work on > + kernel addresses. */ > + if (vaddr >= KERNEL_START > + && vaddr < (KERNEL_START + KERNEL_TR_PAGE_SIZE)) { > + extern unsigned long kernel_start_pa; > + return vaddr - kernel_start_pa; > + } > +#endif > + if (vaddr > TASK_SIZE) { > + /* kernel address */ > + return __pa(vaddr); > + } > + > + /* XXX double-check (lack of) locking */ > + vma = find_extend_vma(current->mm, vaddr); > + if (!vma) > + return ~0UL; > + > + page = follow_page(vma, vaddr, 0); > + if (!page) > + return ~0UL; > + > + return (page_to_pfn(page) << PAGE_SHIFT) | (vaddr & > ~PAGE_MASK); > +} If there really is no way to implement xen_vaddr_to_paddr() in an arch-neutral way (and I'm willing to believe that's true), just make the whole function arch-specific. It wouldn't be too much duplicated code. > +static int xencomm_init(struct xencomm_desc *desc, > + void *buffer, unsigned long bytes) > +{ > + unsigned long recorded = 0; > + int i = 0; > + > + BUG_ON((buffer == NULL) && (bytes > 0)); > + > + /* 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 = xen_vaddr_to_paddr(vaddr); > + if (paddr == ~0UL) { > + printk("%s: couldn't translate vaddr %lx\n", > + __func__, vaddr); > + return -EINVAL; > + } > + > + desc->address[i++] = 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++] = XENCOMM_INVALID; > + > + desc->magic = XENCOMM_MAGIC; > + > + return 0; > +} > + > +/* XXX use slab allocator */ > +static struct xencomm_desc *xencomm_alloc(gfp_t gfp_mask) > +{ > + struct xencomm_desc *desc; > + > + /* XXX could we call this from irq context? */ You can remove this comment. It's historical, and we're passing in gfp_mask now. > + desc = (struct xencomm_desc *)__get_free_page(gfp_mask); > + if (desc == NULL) { > + panic("%s: page allocation failed\n", __func__); > + } > + desc->nr_addrs = (PAGE_SIZE - sizeof(struct xencomm_desc)) / > + sizeof(*desc->address); > + > + return desc; > +} > + > +void xencomm_free(struct xencomm_handle *desc) > +{ > + if (desc) > + free_page((unsigned long)__va(desc)); > +} > + > +int xencomm_create(void *buffer, unsigned long bytes, > + struct xencomm_handle **ret, gfp_t gfp_mask) > +{ > + struct xencomm_desc *desc; > + struct xencomm_handle *handle; > + int rc; > + > + if (xencomm_debug) { > + printk("%s: %p[%ld]\n", __func__, buffer, bytes); > + } > + > + if (buffer == NULL || bytes == 0) { > + *ret = (struct xencomm_handle *)NULL; > + return 0; > + } > + > + desc = xencomm_alloc(gfp_mask); > + if (!desc) { > + printk("%s failure\n", "xencomm_alloc"); > + return -ENOMEM; > + } > + handle = (struct xencomm_handle *)__pa(desc); > + > + rc = xencomm_init(desc, buffer, bytes); > + if (rc) { > + printk("%s failure: %d\n", "xencomm_init", rc); > + xencomm_free(handle); > + return rc; > + } > + > + *ret = handle; > + return 0; > +} > + > +/* "mini" routines, for stack-based communications: */ > + > +static void *xencomm_alloc_mini(void *area, int arealen) > +{ > + unsigned long base = (unsigned long)area; > + unsigned int pageoffset; > + > + pageoffset = base % PAGE_SIZE; > + > + /* we probably fit right at the front of area */ > + if ((PAGE_SIZE - pageoffset) >= sizeof(struct xencomm_mini)) { > + return area; > + } > + > + /* if not, see if area is big enough to advance to the next > page */ > + if ((arealen - pageoffset) >= sizeof(struct xencomm_mini)) > + return (void *)(base + pageoffset); > + > + /* area was too small */ > + return NULL; > +} > + > +int xencomm_create_mini(void *area, int arealen, void *buffer, > + unsigned long bytes, struct xencomm_handle > **ret) > +{ > + struct xencomm_desc *desc; > + int rc; > + > + desc = xencomm_alloc_mini(area, arealen); > + if (!desc) > + return -ENOMEM; > + desc->nr_addrs = XENCOMM_MINI_ADDRS; > + > + rc = xencomm_init(desc, buffer, bytes); > + if (rc) > + return rc; > + > + *ret = (struct xencomm_handle *)__pa(desc); > + return 0; > +} *_mini are unused and should be removed entirely. > +struct xencomm_handle *xencomm_create_inline (void *buffer, > + unsigned long bytes) > +{ > + unsigned long paddr; > + > + paddr = xen_vaddr_to_paddr((unsigned long)buffer); > + return (struct xencomm_handle *)XENCOMM_INLINE_CREATE(paddr); > +} XENCOMM_INLINE_CREATE in undefined in this patch. I liked your old patch just fine: +struct xencomm_desc *xencomm_create_inline (void *buffer, unsigned long bytes) +{ + return (struct xencomm_desc *) + (__kern_paddr((unsigned long)buffer) | XENCOMM_INLINE); +} > diff -r b7db009d622c > linux-2.6-xen-sparse/drivers/xen/core/xencomm_hcall.c > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/linux-2.6-xen-sparse/drivers/xen/core/xencomm_hcall.c Mon > Aug 21 15:04:32 2006 +0200 > @@ -0,0 +1,311 @@ > +#include <linux/types.h> > +#include <linux/errno.h> > +#include <linux/kernel.h> > +#include <linux/gfp.h> > +#include <linux/module.h> > +#include <xen/interface/xen.h> > +#include <xen/interface/dom0_ops.h> > +#include <xen/interface/memory.h> > +#include <xen/interface/xencomm.h> > +#include <xen/interface/version.h> > +#include <xen/interface/sched.h> > +#include <xen/interface/event_channel.h> > +#include <xen/interface/physdev.h> > +#include <xen/interface/grant_table.h> > +#include <xen/interface/callback.h> > +#include <xen/interface/acm_ops.h> > +#include <xen/public/privcmd.h> > +#include <asm/hypercall.h> > +#include <asm/page.h> > +#include <asm/uaccess.h> > +#include <xen/xencomm.h> > + > +/* Xencomm notes: > + * > + * Some hypercalls are made before the memory subsystem is up, so > instead of > + * calling xencomm_create(), we allocate XENCOMM_MINI_AREA bytes from > the stack > + * to hold the xencomm descriptor. Remove above comment. > + * In general, we need a xencomm descriptor to cover the top-level > data > + * structure (e.g. the dom0 op), plus another for every embedded > pointer to > + * another data structure (i.e. for every GUEST_HANDLE). > + */ > + > +int xencomm_hypercall_console_io(int cmd, int count, char *str) > +{ > + struct xencomm_handle *desc; > + int rc; > + > + desc = xencomm_create_inline (str, count); > + > + rc = xencomm_arch_hypercall_console_io (cmd, count, desc); > + > + return rc; > +} I don't understand the point of all these routines if they just call arch_foo anyways. > diff -r b7db009d622c > linux-2.6-xen-sparse/drivers/xen/privcmd/xencomm.c > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/xencomm.c Mon > Aug 21 15:04:32 2006 +0200 > @@ -0,0 +1,358 @@ > +#include <linux/types.h> > +#include <linux/errno.h> > +#include <linux/kernel.h> > +#include <linux/gfp.h> > +#include <linux/module.h> > +#include <xen/interface/xen.h> > +#include <xen/interface/dom0_ops.h> > +#include <xen/interface/memory.h> > +#include <xen/interface/version.h> > +#include <xen/interface/event_channel.h> > +#include <xen/interface/acm_ops.h> > +#include <xen/public/privcmd.h> > +#include <asm/hypercall.h> > +#include <asm/page.h> > +#include <asm/uaccess.h> > +#include <xen/xencomm.h> > + > +static int xencomm_privcmd_dom0_op(privcmd_hypercall_t *hypercall) > +{ > + dom0_op_t kern_op; > + dom0_op_t __user *user_op = (dom0_op_t __user > *)hypercall->arg[0]; > + struct xencomm_handle *op_desc; > + struct xencomm_handle *desc = NULL; > + int ret = 0; > + > + if (copy_from_user(&kern_op, user_op, sizeof(dom0_op_t))) > + return -EFAULT; > + > + if (kern_op.interface_version != DOM0_INTERFACE_VERSION) > + return -EACCES; > + > + op_desc = xencomm_create_inline (&kern_op, sizeof(dom0_op_t)); > + > + switch (kern_op.cmd) { > + case DOM0_GETMEMLIST: > + { > + unsigned long nr_pages = > kern_op.u.getmemlist.max_pfns; > +#ifdef __ia64__ > + /* Xen/ia64 pass first_page and nr_pages in max_pfns! > */ > + nr_pages &= 0xffffffff; > +#endif I'm willing to put up with this only if you guys promise to fix this silly API incompatibility, at which point it will be removed. > + ret = xencomm_create( > + xen_guest_handle(kern_op.u.getmemlist.buffer), > + nr_pages * sizeof(unsigned long), > + &desc, GFP_KERNEL); > + set_xen_guest_handle(kern_op.u.getmemlist.buffer, > + (void *)desc); > + break; > + } > + case DOM0_SETVCPUCONTEXT: > + ret = xencomm_create( > + xen_guest_handle(kern_op.u.setvcpucontext.ctxt), > + sizeof(vcpu_guest_context_t), > + &desc, GFP_KERNEL); > + set_xen_guest_handle(kern_op.u.setvcpucontext.ctxt, > + (void *)desc); > + break; > + case DOM0_READCONSOLE: > + ret = xencomm_create( > + xen_guest_handle(kern_op.u.readconsole.buffer), > + kern_op.u.readconsole.count, > + &desc, GFP_KERNEL); > + set_xen_guest_handle(kern_op.u.readconsole.buffer, > + (void *)desc); > + break; > + case DOM0_GETPAGEFRAMEINFO2: > + ret = xencomm_create( > + xen_guest_handle(kern_op.u.getpageframeinfo2.array), > + kern_op.u.getpageframeinfo2.num, > + &desc, GFP_KERNEL); > + set_xen_guest_handle(kern_op.u.getpageframeinfo2.array, > + (void *)desc); > + break; > + case DOM0_PERFCCONTROL: > + ret = xencomm_create( > + xen_guest_handle(kern_op.u.perfccontrol.desc), > + kern_op.u.perfccontrol.nr_counters * > + sizeof(dom0_perfc_desc_t), > + &desc, GFP_KERNEL); > + set_xen_guest_handle(kern_op.u.perfccontrol.desc, > + (void *)desc); > + break; > + case DOM0_GETVCPUCONTEXT: > + ret = xencomm_create( > + xen_guest_handle(kern_op.u.getvcpucontext.ctxt), > + sizeof(vcpu_guest_context_t), > + &desc, GFP_KERNEL); > + set_xen_guest_handle(kern_op.u.getvcpucontext.ctxt, > + (void *)desc); > + break; > + case DOM0_GETDOMAININFOLIST: > + ret = xencomm_create( > + xen_guest_handle(kern_op.u.getdomaininfolist.buffer), > + kern_op.u.getdomaininfolist.num_domains * > + sizeof(dom0_getdomaininfo_t), > + &desc, GFP_KERNEL); > + set_xen_guest_handle(kern_op.u.getdomaininfolist.buffer, > + (void *)desc); > + break; > + case DOM0_PHYSICAL_MEMORY_MAP: > + ret = xencomm_create( > + > xen_guest_handle(kern_op.u.physical_memory_map.memory_map), > + kern_op.u.physical_memory_map.nr_map_entries * > + sizeof(struct dom0_memory_map_entry), > + &desc, GFP_KERNEL); > + set_xen_guest_handle(kern_op.u.physical_memory_map.memory_map, > + (void *)desc); > + break; > + > + case DOM0_SCHEDCTL: > + case DOM0_ADJUSTDOM: > + case DOM0_CREATEDOMAIN: > + case DOM0_DESTROYDOMAIN: > + case DOM0_PAUSEDOMAIN: > + case DOM0_UNPAUSEDOMAIN: > + case DOM0_GETDOMAININFO: > + case DOM0_MSR: > + case DOM0_SETTIME: > + case DOM0_GETPAGEFRAMEINFO: > + case DOM0_SETVCPUAFFINITY: > + case DOM0_TBUFCONTROL: > + case DOM0_PHYSINFO: > + case DOM0_SCHED_ID: > + case DOM0_SETDOMAINMAXMEM: > + case DOM0_ADD_MEMTYPE: > + case DOM0_DEL_MEMTYPE: > + case DOM0_READ_MEMTYPE: > + case DOM0_IOPORT_PERMISSION: > + case DOM0_GETVCPUINFO: > + case DOM0_PLATFORM_QUIRK: > + case DOM0_MAX_VCPUS: > + case DOM0_SETDOMAINHANDLE: > + case DOM0_SETDEBUGGING: > + case DOM0_DOMAIN_SETUP: > + /* no munging needed */ > + break; > + > + default: > + printk("%s: unknown dom0 cmd %d\n", __func__, > kern_op.cmd); > + return -ENOSYS; > + } > + > + if (ret) > + goto out; /* error mapping the nested pointer */ > + > + ret = xencomm_arch_hypercall_dom0_op (op_desc); > + > + /* FIXME: should we restore the handle? */ > + if (copy_to_user(user_op, &kern_op, sizeof(dom0_op_t))) > + ret = -EFAULT; > + > + if (desc) > + xencomm_free(desc); > +out: > + return ret; > +} You misplaced the out label; it needs to go before xencomm_free(desc); That's a good question about the copy_to_user(). I thought we never exposed the modified handles back to the user, but I guess I was wrong. Also please check whitespace throughout. In particular you seem to be doing this: function (args); and not even Keir's shall-we-say-unique style does that. ;) > +static int xencomm_privcmd_acm_op(privcmd_hypercall_t *hypercall) > +{ > + int cmd = hypercall->arg[0]; > + void __user *arg = (void __user *)hypercall->arg[1]; > + struct xencomm_handle *op_desc; > + struct xencomm_handle *desc = NULL; > + int ret; > + > + switch (cmd) { > + case ACMOP_getssid: > + { > + struct acm_getssid kern_arg; > + > + if (copy_from_user (&kern_arg, arg, sizeof > (kern_arg))) > + return -EFAULT; > + > + op_desc = xencomm_create_inline (&kern_arg, > sizeof(kern_arg)); > + > + ret = > xencomm_create(xen_guest_handle(kern_arg.ssidbuf), > + kern_arg.ssidbuf_size, > + &desc, GFP_KERNEL); > + if (ret) > + return ret; > + > + set_xen_guest_handle(kern_arg.ssidbuf, (void *)desc); > + > + ret = xencomm_arch_hypercall_acm_op (cmd, op_desc); > + > + xencomm_free (desc); > + > + if (copy_to_user (arg, &kern_arg, sizeof (kern_arg))) > + return -EFAULT; > + > + return ret; > + } > + default: > + printk("%s: unknown acm_op cmd %d\n", __func__, cmd); > + return -ENOSYS; > + } > + > + return ret; > +} > + > +static int xencomm_privcmd_memory_op(privcmd_hypercall_t *hypercall) > +{ > + const unsigned long cmd = hypercall->arg[0]; > + int ret = 0; > + > + switch (cmd) { > + case XENMEM_increase_reservation: > + case XENMEM_decrease_reservation: > + { > + xen_memory_reservation_t kern_op; > + xen_memory_reservation_t __user *user_op; > + struct xencomm_handle *desc = NULL; > + struct xencomm_handle *desc_op; > + > + user_op = (xen_memory_reservation_t __user > *)hypercall->arg[1]; > + if (copy_from_user(&kern_op, user_op, > + sizeof(xen_memory_reservation_t))) > + return -EFAULT; > + desc_op = xencomm_create_inline (&kern_op, sizeof > (kern_op)); > + > + if (xen_guest_handle(kern_op.extent_start)) { > + void * addr; > + > + addr = xen_guest_handle(kern_op.extent_start); > + ret = xencomm_create > + (addr, > + kern_op.nr_extents * > + sizeof(*xen_guest_handle > + (kern_op.extent_start)), > + &desc, GFP_KERNEL); > + if (ret) > + return ret; > + set_xen_guest_handle(kern_op.extent_start, > + (void *)desc); > + } > + > + ret = xencomm_arch_hypercall_memory_op (cmd, desc_op); > + > + if (desc) > + xencomm_free (desc); > + > + if (ret != 0) > + return ret; > + > + if (copy_to_user(user_op, &kern_op, > + sizeof(xen_memory_reservation_t))) > + return -EFAULT; > + > + return ret; > + } > + default: > + printk("%s: unknown memory op %lu\n", __func__, cmd); > + ret = -ENOSYS; > + } > + return ret; > +} > + > +static int xencomm_privcmd_xen_version(privcmd_hypercall_t > *hypercall) > +{ > + int cmd = hypercall->arg[0]; > + void __user *arg = (void __user *)hypercall->arg[1]; > + struct xencomm_handle *desc; > + size_t argsize; > + int rc; > + > + switch (cmd) { > + case XENVER_version: > + /* do not actually pass an argument */ > + return xencomm_arch_hypercall_xen_version (cmd, 0); > + case XENVER_extraversion: > + argsize = sizeof(xen_extraversion_t); > + break; > + case XENVER_compile_info: > + argsize = sizeof(xen_compile_info_t); > + break; > + case XENVER_capabilities: > + argsize = sizeof(xen_capabilities_info_t); > + break; > + case XENVER_changeset: > + argsize = sizeof(xen_changeset_info_t); > + break; > + case XENVER_platform_parameters: > + argsize = sizeof(xen_platform_parameters_t); > + break; > + case XENVER_pagesize: > + argsize = (arg == NULL) ? 0 : sizeof(void *); > + break; > + case XENVER_get_features: > + argsize = (arg == NULL) ? 0 : > sizeof(xen_feature_info_t); > + break; > + > + default: > + printk("%s: unknown version op %d\n", __func__, cmd); > + return -ENOSYS; > + } > + > + rc = xencomm_create(arg, argsize, &desc, GFP_KERNEL); > + if (rc) > + return rc; > + > + rc = xencomm_arch_hypercall_xen_version (cmd, desc); > + > + xencomm_free(desc); > + > + return rc; > +} > + > +static int xencomm_privcmd_event_channel_op(privcmd_hypercall_t > *hypercall) > +{ > + int cmd = hypercall->arg[0]; > + struct xencomm_handle *desc; > + unsigned int argsize; > + int ret; > + > + switch (cmd) { > + case EVTCHNOP_alloc_unbound: > + argsize = sizeof(evtchn_alloc_unbound_t); > + break; > + > + case EVTCHNOP_status: > + argsize = sizeof(evtchn_status_t); > + break; > + > + default: > + printk("%s: unknown EVTCHNOP %d\n", __func__, cmd); > + return -EINVAL; > + } > + > + ret = xencomm_create((void *)hypercall->arg[1], argsize, > + &desc, GFP_KERNEL); > + if (ret) > + return ret; > + > + ret = xencomm_arch_hypercall_event_channel_op (cmd, desc); > + > + xencomm_free(desc); > + return ret; > +} > + > +int xencomm_privcmd_hypercall(privcmd_hypercall_t *hypercall) > +{ > + switch (hypercall->op) { > + case __HYPERVISOR_dom0_op: > + return xencomm_privcmd_dom0_op(hypercall); > + case __HYPERVISOR_acm_op: > + return xencomm_privcmd_acm_op(hypercall); > + case __HYPERVISOR_xen_version: > + return xencomm_privcmd_xen_version(hypercall); > + case __HYPERVISOR_memory_op: > + return xencomm_privcmd_memory_op(hypercall); > + case __HYPERVISOR_event_channel_op: > + return xencomm_privcmd_event_channel_op(hypercall); > + default: > + printk("%s: unknown hcall (%ld)\n", __func__, > hypercall->op); > + return -ENOSYS; > + } > +} > + > diff -r b7db009d622c linux-2.6-xen-sparse/include/xen/xencomm.h > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/linux-2.6-xen-sparse/include/xen/xencomm.h Mon Aug 21 > 15:04:32 2006 +0200 > @@ -0,0 +1,45 @@ > +/* > + * Copyright (C) 2006 Hollis Blanchard <hollisb@xxxxxxxxxx>, IBM > Corporation > + * > + * 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 > + */ > + > +#ifndef _LINUX_XENCOMM_H_ > +#define _LINUX_XENCOMM_H_ > + > +#include <xen/interface/xencomm.h> > + > +#define XENCOMM_MINI_ADDRS 3 > +struct xencomm_mini { > + struct xencomm_desc _desc; > + uint64_t address[XENCOMM_MINI_ADDRS]; > +}; > +#define XENCOMM_MINI_AREA (sizeof(struct xencomm_mini) * 2) Remove above. > +/* To avoid additionnal virt to phys convertion, the user only sees > handle > + which are opaque structures. */ > +struct xencomm_handle; Typos in the comment. > +extern int xencomm_create(void *buffer, unsigned long bytes, > + struct xencomm_handle **desc, gfp_t type); > +extern void xencomm_free(struct xencomm_handle *desc); > +extern int xencomm_create_mini(void *area, int arealen, void *buffer, > + unsigned long bytes, struct xencomm_handle **ret); Remove above. > +struct xencomm_handle *xencomm_create_inline (void *buffer, > + unsigned long bytes); > + > +#define xen_guest_handle(hnd) ((hnd).p) > + > +#endif /* _LINUX_XENCOMM_H_ */ > diff -r b7db009d622c linux-2.6-xen-sparse/include/xen/xencomm_hcall.h > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/linux-2.6-xen-sparse/include/xen/xencomm_hcall.h Mon Aug 21 > 15:04:32 2006 +0200 > @@ -0,0 +1,45 @@ > +/* > + * Copyright (C) 2006 Tristan Gingold <tristan.gingold@xxxxxxxx>, > Bull SAS > + * > + * 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 > + */ > + > +#ifndef _LINUX_XENCOMM_HCALL_H_ > +#define _LINUX_XENCOMM_HCALL_H_ > + > +/* These function creates inline descriptor for the parameters and > + calls the correspondig xencomm_arch_hypercall_X. > + Architectures should defines HYPERVISOR_xxx as > xencomm_hypercall_xxx unless > + they want to use their own wrapper. */ "corresponding" And I'm not clear on the reason for all the xencomm_arch_*, especially because I haven't seen IA64's. If you're worried about the structure size conversion I mentioned earlier, I think PowerPC will need to fix that *before* the xencomm stuff is called anyways. So unless IA64 needs something funny in xencomm_arch_*, they should all be removed. -- Hollis Blanchard IBM Linux Technology Center _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |