# HG changeset patch # User Jerone Young # Date 1169498835 21600 # Node ID 82e1886955c349ee9c473560ead37f61b787fcd7 # Parent ab3b5849331da89e578ae0813021376d66b7f333 Initial Xencomm patch. Still have to remove xencomm_create usage. diff -r ab3b5849331d -r 82e1886955c3 arch/powerpc/platforms/xen/gnttab.c --- a/arch/powerpc/platforms/xen/gnttab.c Sun Jan 21 08:36:53 2007 -0500 +++ b/arch/powerpc/platforms/xen/gnttab.c Mon Jan 22 14:47:15 2007 -0600 @@ -263,8 +263,9 @@ int HYPERVISOR_grant_table_op(unsigned i memcpy(&setup, op, sizeof(setup)); argsize = sizeof(setup); - frame_list = xencomm_create_inline( - xen_guest_handle(setup.frame_list)); + frame_list = xencomm_map( + xen_guest_handle(setup.frame_list), + (sizeof(ulong) * setup.nr_frames)); set_xen_guest_handle(setup.frame_list, frame_list); memcpy(op, &setup, sizeof(setup)); @@ -286,7 +287,7 @@ int HYPERVISOR_grant_table_op(unsigned i return -ENOSYS; } - desc = xencomm_create_inline(op); + desc = xencomm_map(op, argsize); ret = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_grant_table_op), cmd, desc, count); diff -r ab3b5849331d -r 82e1886955c3 arch/powerpc/platforms/xen/hcall.c --- a/arch/powerpc/platforms/xen/hcall.c Sun Jan 21 08:36:53 2007 -0500 +++ b/arch/powerpc/platforms/xen/hcall.c Mon Jan 22 14:47:15 2007 -0600 @@ -54,7 +54,7 @@ int HYPERVISOR_console_io(int cmd, int count, char *str) { - void *desc = xencomm_create_inline(str); + void *desc = xencomm_map_early(str, count); return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_console_io), cmd, count, desc); @@ -63,19 +63,24 @@ EXPORT_SYMBOL(HYPERVISOR_console_io); int HYPERVISOR_event_channel_op(int cmd, void *op) { - void *desc = xencomm_create_inline(op); + void *desc = xencomm_map_early(op, sizeof(evtchn_op_t)); return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_event_channel_op), cmd, desc); } EXPORT_SYMBOL(HYPERVISOR_event_channel_op); -int HYPERVISOR_xen_version_userspace(int cmd, void *arg) +int HYPERVISOR_xen_version(int cmd, void *arg) { struct xencomm_desc *desc; const unsigned long hcall = __HYPERVISOR_xen_version; int argsize; int rc; + + if (is_phys_contiguous((unsigned long)arg)) { + desc = xencomm_map_early(arg, sizeof(__u64)); + return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_xen_version), cmd, desc); + } switch (cmd) { case XENVER_version: @@ -118,18 +123,10 @@ int HYPERVISOR_xen_version_userspace(int } EXPORT_SYMBOL(HYPERVISOR_xen_version); -int HYPERVISOR_xen_version(int cmd, void *arg) -{ - if (is_kernel_addr((unsigned long)arg)) { - void *desc = xencomm_create_inline(arg); - return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_xen_version), cmd, desc); - } - return HYPERVISOR_xen_version_userspace(cmd, arg); -} int HYPERVISOR_physdev_op(int cmd, void *op) { - void *desc = xencomm_create_inline(op); + void *desc = xencomm_map(op, sizeof(physdev_op_t)); return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_physdev_op), cmd, desc); @@ -138,6 +135,7 @@ EXPORT_SYMBOL(HYPERVISOR_physdev_op); int HYPERVISOR_sched_op(int cmd, void *arg) { + int argsize = 0; struct xencomm_desc *desc; switch (cmd) { @@ -151,24 +149,30 @@ int HYPERVISOR_sched_op(int cmd, void *a evtchn_port_t *ports; struct sched_poll sched_poll; + argsize = sizeof(struct sched_poll); + memcpy(&sched_poll, arg, sizeof(sched_poll)); - ports = xencomm_create_inline( - xen_guest_handle(sched_poll.ports)); + ports = xencomm_map( + xen_guest_handle(sched_poll.ports), + (sizeof(evtchn_port_t) * sched_poll.nr_ports)); set_xen_guest_handle(sched_poll.ports, ports); memcpy(arg, &sched_poll, sizeof(sched_poll)); } break; case SCHEDOP_shutdown: + argsize = sizeof(struct sched_shutdown); + break; case SCHEDOP_remote_shutdown: + argsize = sizeof(struct sched_remote_shutdown); break; default: printk(KERN_ERR "%s: unknown sched op %d\n", __func__, cmd); return -ENOSYS; } - desc = xencomm_create_inline(arg); + desc = xencomm_map(arg, argsize); return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_sched_op), cmd, desc); diff -r ab3b5849331d -r 82e1886955c3 drivers/xen/core/xencomm.c --- a/drivers/xen/core/xencomm.c Sun Jan 21 08:36:53 2007 -0500 +++ b/drivers/xen/core/xencomm.c Mon Jan 22 14:47:15 2007 -0600 @@ -123,9 +123,89 @@ void *xencomm_create_inline(void *ptr) { unsigned long paddr; - BUG_ON(!is_kernel_addr((unsigned long)ptr)); + BUG_ON(!is_phys_contiguous((unsigned long)ptr)); paddr = (unsigned long)xencomm_pa(ptr); BUG_ON(paddr & XENCOMM_INLINE_FLAG); return (void *)(paddr | XENCOMM_INLINE_FLAG); } + +/* "mini" routines, for stack-based communications: */ +static void *xencomm_alloc_mini(void *area, int arealen) +{ + unsigned long base = (unsigned long)area; + unsigned int left_in_page; + + left_in_page = PAGE_SIZE - base % PAGE_SIZE; + + /* we probably fit right at the front of area */ + if (left_in_page >= sizeof(struct xencomm_mini)) { + return area; + } + + /* if not, see if area is big enough to advance to the next page */ + if ((arealen - left_in_page) >= sizeof(struct xencomm_mini)) + return (void *)(base + left_in_page); + + /* area was too small */ + return NULL; +} + +int xencomm_create_mini(void *area, int arealen, void *buffer, + unsigned long bytes, struct xencomm_desc **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 = desc; + return 0; +} + +void *xencomm_map(void *ptr, unsigned long bytes) +{ + int rc; + struct xencomm_desc *desc; + + if (is_phys_contiguous((unsigned long)ptr)) + return xencomm_create_inline(ptr); + + rc = xencomm_create(ptr, bytes, &desc, GFP_KERNEL); + + if (rc) + return NULL; + + return xencomm_pa(desc); +} + +void *__xencomm_map_early(void *ptr, unsigned long bytes, + char *xc_area) +{ + int rc; + struct xencomm_desc *desc; + + if (is_phys_contiguous((unsigned long)ptr)) + return xencomm_create_inline(ptr); + + rc = xencomm_create_mini(xc_area, XENCOMM_MINI_AREA,ptr, bytes, + &desc); + + if (rc) + return NULL; + + return (void*)__pa(desc); +} + +/* check if is physically contiguous memory */ +int is_phys_contiguous(unsigned long addr) +{ + return (addr < VMALLOC_START) || (addr >= VMALLOC_END); +} diff -r ab3b5849331d -r 82e1886955c3 include/xen/xencomm.h --- a/include/xen/xencomm.h Sun Jan 21 08:36:53 2007 -0500 +++ b/include/xen/xencomm.h Mon Jan 22 14:47:15 2007 -0600 @@ -16,6 +16,7 @@ * Copyright (C) IBM Corp. 2006 * * Authors: Hollis Blanchard + * Jerone Young */ #ifndef _LINUX_XENCOMM_H_ @@ -23,10 +24,25 @@ #include -extern int xencomm_create(void *buffer, unsigned long bytes, - struct xencomm_desc **desc, gfp_t type); +#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) + extern void xencomm_free(struct xencomm_desc *desc); +extern int xencomm_create(void *buffer, unsigned long bytes, + struct xencomm_desc **ret, gfp_t gfp_mask); extern void *xencomm_create_inline(void *ptr); +extern void *xencomm_map(void *ptr, unsigned long bytes); +extern void *__xencomm_map_early(void *ptr, unsigned long bytes, + char *xc_area); +extern int is_phys_contiguous(unsigned long addr); + +#define xencomm_map_early(ptr, bytes) \ + ({char xc_area[XENCOMM_MINI_AREA];\ + __xencomm_map_early(ptr, bytes, xc_area);}) /* provided by architecture code: */ extern unsigned long xencomm_vtop(unsigned long vaddr); # HG changeset patch # User Jerone Young # Date 1169614163 21600 # Node ID c326865b79895e91ac57e548eda03cda3c4c0dcc # Parent 82e1886955c349ee9c473560ead37f61b787fcd7 Use structure instead of char diff -r 82e1886955c3 -r c326865b7989 drivers/xen/core/xencomm.c --- a/drivers/xen/core/xencomm.c Mon Jan 22 14:47:15 2007 -0600 +++ b/drivers/xen/core/xencomm.c Tue Jan 23 22:49:23 2007 -0600 @@ -187,7 +187,7 @@ void *xencomm_map(void *ptr, unsigned lo } void *__xencomm_map_early(void *ptr, unsigned long bytes, - char *xc_area) + struct xencomm_mini *xc_area) { int rc; struct xencomm_desc *desc; diff -r 82e1886955c3 -r c326865b7989 include/xen/xencomm.h --- a/include/xen/xencomm.h Mon Jan 22 14:47:15 2007 -0600 +++ b/include/xen/xencomm.h Tue Jan 23 22:49:23 2007 -0600 @@ -37,12 +37,13 @@ extern void *xencomm_create_inline(void extern void *xencomm_create_inline(void *ptr); extern void *xencomm_map(void *ptr, unsigned long bytes); extern void *__xencomm_map_early(void *ptr, unsigned long bytes, - char *xc_area); + struct xencomm_mini *xc_area); extern int is_phys_contiguous(unsigned long addr); #define xencomm_map_early(ptr, bytes) \ - ({char xc_area[XENCOMM_MINI_AREA];\ - __xencomm_map_early(ptr, bytes, xc_area);}) + ({struct xencomm_mini xc_area[XENCOMM_MINI_AREA]\ + __attribute__((__aligned__(sizeof(struct xencomm_mini))));\ + __xencomm_map_early(ptr, bytes, xc_area);}) /* provided by architecture code: */ extern unsigned long xencomm_vtop(unsigned long vaddr);