# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1186478446 -32400 # Node ID c1602a983042319aa65f75ad5f3f25c30635bb74 # Parent 41b87d2ad60708cbb2dd8e81605d3c2a0c4d1a26 [linux, xencomm] linux xencomm consolidation. use common xencomm.c and remove ia64 xencomm.c PATCHNAME: linux_xencomm_consolidation Signed-off-by: Isaku Yamahata diff -r 41b87d2ad607 -r c1602a983042 arch/ia64/Kconfig --- a/arch/ia64/Kconfig Wed Aug 01 15:03:59 2007 +0900 +++ b/arch/ia64/Kconfig Tue Aug 07 18:20:46 2007 +0900 @@ -61,6 +61,7 @@ config XEN config XEN bool "Xen hypervisor support" default y + select XEN_XENCOMM help Enable Xen hypervisor support. Resulting kernel runs both as a guest OS on Xen and natively on hardware. diff -r 41b87d2ad607 -r c1602a983042 arch/ia64/kernel/setup.c --- a/arch/ia64/kernel/setup.c Wed Aug 01 15:03:59 2007 +0900 +++ b/arch/ia64/kernel/setup.c Tue Aug 07 18:20:46 2007 +0900 @@ -449,7 +449,7 @@ setup_arch (char **cmdline_p) struct xen_ia64_opt_feature optf; /* Must be done before any hypercall. */ - xencomm_init(); + xencomm_initialize(); setup_xen_features(); /* Register a call for panic conditions. */ diff -r 41b87d2ad607 -r c1602a983042 arch/ia64/xen/hypervisor.c --- a/arch/ia64/xen/hypervisor.c Wed Aug 01 15:03:59 2007 +0900 +++ b/arch/ia64/xen/hypervisor.c Tue Aug 07 18:20:46 2007 +0900 @@ -447,7 +447,7 @@ HYPERVISOR_grant_table_op(unsigned int c (struct gnttab_map_grant_ref*)uop + i); } } - return xencomm_mini_hypercall_grant_table_op(cmd, uop, count); + return xencomm_hypercall_grant_table_op(cmd, uop, count); } EXPORT_SYMBOL(HYPERVISOR_grant_table_op); diff -r 41b87d2ad607 -r c1602a983042 arch/ia64/xen/xcom_hcall.c --- a/arch/ia64/xen/xcom_hcall.c Wed Aug 01 15:03:59 2007 +0900 +++ b/arch/ia64/xen/xcom_hcall.c Tue Aug 07 18:20:46 2007 +0900 @@ -14,6 +14,11 @@ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Tristan Gingold + * + * Copyright (c) 2007 + * Isaku Yamahata + * VA Linux Systems Japan K.K. + * consolidate mini and inline version. */ #include #include @@ -42,8 +47,8 @@ /* Xencomm notes: * This file defines hypercalls to be used by xencomm. The hypercalls simply - * create inlines descriptors for pointers and then call the raw arch hypercall - * xencomm_arch_hypercall_XXX + * create inlines or mini descriptors for pointers and then call the raw arch + * hypercall xencomm_arch_hypercall_XXX * * If the arch wants to directly use these hypercalls, simply define macros * in asm/hypercall.h, eg: @@ -52,107 +57,206 @@ * The arch may also define HYPERVISOR_xxx as a function and do more operations * before/after doing the hypercall. * - * Note: because only inline descriptors are created these functions must only - * be called with in kernel memory parameters. + * Note: because only inline or mini descriptors are created these functions + * must only be called with in kernel memory parameters. */ int xencomm_hypercall_console_io(int cmd, int count, char *str) { return xencomm_arch_hypercall_console_io - (cmd, count, xencomm_create_inline(str)); -} + (cmd, count, xencomm_map_no_alloc(str, count)); +} +EXPORT_SYMBOL_GPL(xencomm_hypercall_console_io); int xencomm_hypercall_event_channel_op(int cmd, void *op) { - return xencomm_arch_hypercall_event_channel_op - (cmd, xencomm_create_inline(op)); -} + struct xencomm_handle *desc; + desc = xencomm_map_no_alloc(op, sizeof(evtchn_op_t)); + if (desc == NULL) + return -EINVAL; + + return xencomm_arch_hypercall_event_channel_op(cmd, desc); +} +EXPORT_SYMBOL_GPL(xencomm_hypercall_event_channel_op); int xencomm_hypercall_xen_version(int cmd, void *arg) { + struct xencomm_handle *desc; + unsigned int argsize; + 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: - break; - default: - printk("%s: unknown version cmd %d\n", __func__, cmd); - return -ENOSYS; - } - - return xencomm_arch_hypercall_xen_version - (cmd, xencomm_create_inline(arg)); -} + argsize = (arg == NULL) ? 0 : sizeof(xen_feature_info_t); + break; + + default: + printk("%s: unknown version op %d\n", __func__, cmd); + return -ENOSYS; + } + + desc = xencomm_map_no_alloc(arg, argsize); + if (desc == NULL) + return -EINVAL; + + return xencomm_arch_hypercall_xen_version(cmd, desc); +} +EXPORT_SYMBOL_GPL(xencomm_hypercall_xen_version); int xencomm_hypercall_physdev_op(int cmd, void *op) { + unsigned int argsize; + + switch (cmd) { + case PHYSDEVOP_apic_read: + case PHYSDEVOP_apic_write: + argsize = sizeof(physdev_apic_t); + break; + case PHYSDEVOP_alloc_irq_vector: + case PHYSDEVOP_free_irq_vector: + argsize = sizeof(physdev_irq_t); + break; + case PHYSDEVOP_irq_status_query: + argsize = sizeof(physdev_irq_status_query_t); + break; + + default: + printk("%s: unknown physdev op %d\n", __func__, cmd); + return -ENOSYS; + } + return xencomm_arch_hypercall_physdev_op - (cmd, xencomm_create_inline(op)); -} - -static void * -xencommize_grant_table_op(unsigned int cmd, void *op, unsigned int count) -{ + (cmd, xencomm_map_no_alloc(op, argsize)); +} + +static int +xencommize_grant_table_op(struct xencomm_mini **xc_area, + unsigned int cmd, void *op, unsigned int count, + struct xencomm_handle **desc) +{ + struct xencomm_handle *desc1; + unsigned int argsize; + 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_unmap_and_replace: + argsize = sizeof(struct gnttab_unmap_and_replace); break; case GNTTABOP_setup_table: { struct gnttab_setup_table *setup = op; - struct xencomm_handle *frame_list; - - frame_list = xencomm_create_inline - (xen_guest_handle(setup->frame_list)); - - set_xen_guest_handle(setup->frame_list, (void *)frame_list); + + argsize = sizeof(*setup); + + if (count != 1) + return -EINVAL; + desc1 = __xencomm_map_no_alloc + (xen_guest_handle(setup->frame_list), + setup->nr_frames * + sizeof(*xen_guest_handle(setup->frame_list)), + *xc_area); + if (desc1 == NULL) + return -EINVAL; + (*xc_area)++; + set_xen_guest_handle(setup->frame_list, (void *)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: - break; - default: - printk("%s: unknown grant table op %d\n", __func__, cmd); + argsize = sizeof(struct gnttab_copy); + break; + case GNTTABOP_query_size: + argsize = sizeof(struct gnttab_query_size); + break; + default: + printk("%s: unknown hypercall grant table op %d\n", + __func__, cmd); BUG(); } - return xencomm_create_inline(op); -} - -int -xencomm_hypercall_grant_table_op(unsigned int cmd, void *op, unsigned int count) -{ - void *desc = xencommize_grant_table_op (cmd, op, count); + *desc = __xencomm_map_no_alloc(op, count * argsize, *xc_area); + if (*desc == NULL) + return -EINVAL; + (*xc_area)++; + + return 0; +} + +int +xencomm_hypercall_grant_table_op(unsigned int cmd, void *op, + unsigned int count) +{ + int rc; + struct xencomm_handle *desc; + XENCOMM_MINI_ALIGNED(xc_area, 2); + + rc = xencommize_grant_table_op(&xc_area, cmd, op, count, &desc); + if (rc) + return rc; return xencomm_arch_hypercall_grant_table_op(cmd, desc, count); } +EXPORT_SYMBOL_GPL(xencomm_hypercall_grant_table_op); int xencomm_hypercall_sched_op(int cmd, void *arg) { + struct xencomm_handle *desc; + unsigned int argsize; + switch (cmd) { case SCHEDOP_yield: case SCHEDOP_block: + argsize = 0; + break; case SCHEDOP_shutdown: + argsize = sizeof(sched_shutdown_t); + break; case SCHEDOP_remote_shutdown: + argsize = sizeof(sched_remote_shutdown_t); break; case SCHEDOP_poll: { sched_poll_t *poll = arg; struct xencomm_handle *ports; - ports = xencomm_create_inline(xen_guest_handle(poll->ports)); + argsize = sizeof(sched_poll_t); + ports = xencomm_map_no_alloc(xen_guest_handle(poll->ports), + sizeof(*xen_guest_handle(poll->ports))); set_xen_guest_handle(poll->ports, (void *)ports); break; @@ -162,14 +266,22 @@ xencomm_hypercall_sched_op(int cmd, void return -ENOSYS; } - return xencomm_arch_hypercall_sched_op(cmd, xencomm_create_inline(arg)); -} + desc = xencomm_map_no_alloc(arg, argsize); + if (desc == NULL) + return -EINVAL; + + return xencomm_arch_hypercall_sched_op(cmd, desc); +} +EXPORT_SYMBOL_GPL(xencomm_hypercall_sched_op); int xencomm_hypercall_multicall(void *call_list, int nr_calls) { + int rc; int i; multicall_entry_t *mce; + struct xencomm_handle *desc; + XENCOMM_MINI_ALIGNED(xc_area, nr_calls * 2); for (i = 0; i < nr_calls; i++) { mce = (multicall_entry_t *)call_list + i; @@ -180,9 +292,13 @@ xencomm_hypercall_multicall(void *call_l /* No-op on ia64. */ break; case __HYPERVISOR_grant_table_op: - mce->args[1] = (unsigned long)xencommize_grant_table_op - (mce->args[0], (void *)mce->args[1], - mce->args[2]); + rc = xencommize_grant_table_op + (&xc_area, + mce->args[0], (void *)mce->args[1], + mce->args[2], &desc); + if (rc) + return rc; + mce->args[1] = (unsigned long)desc; break; case __HYPERVISOR_memory_op: default: @@ -192,17 +308,26 @@ xencomm_hypercall_multicall(void *call_l } } - return xencomm_arch_hypercall_multicall - (xencomm_create_inline(call_list), nr_calls); -} + desc = xencomm_map_no_alloc(call_list, + nr_calls * sizeof(multicall_entry_t)); + if (desc == NULL) + return -EINVAL; + + return xencomm_arch_hypercall_multicall(desc, nr_calls); +} +EXPORT_SYMBOL_GPL(xencomm_hypercall_multicall); int xencomm_hypercall_callback_op(int cmd, void *arg) { + unsigned int argsize; switch (cmd) { case CALLBACKOP_register: + argsize = sizeof(struct callback_register); + break; case CALLBACKOP_unregister: + argsize = sizeof(struct callback_unregister); break; default: printk("%s: unknown callback op %d\n", __func__, cmd); @@ -210,16 +335,24 @@ xencomm_hypercall_callback_op(int cmd, v } return xencomm_arch_hypercall_callback_op - (cmd, xencomm_create_inline(arg)); -} - -static void -xencommize_memory_reservation (xen_memory_reservation_t *mop) -{ - struct xencomm_handle *desc; - - desc = xencomm_create_inline(xen_guest_handle(mop->extent_start)); + (cmd, xencomm_map_no_alloc(arg, argsize)); +} + +static int +xencommize_memory_reservation(struct xencomm_mini *xc_area, + xen_memory_reservation_t *mop) +{ + struct xencomm_handle *desc; + + desc = __xencomm_map_no_alloc(xen_guest_handle(mop->extent_start), + mop->nr_extents * + sizeof(*xen_guest_handle(mop->extent_start)), + xc_area); + if (desc == NULL) + return -EINVAL; + set_xen_guest_handle(mop->extent_start, (void *)desc); + return 0; } int @@ -230,39 +363,61 @@ xencomm_hypercall_memory_op(unsigned int xen_memory_map_t *memmap = NULL; XEN_GUEST_HANDLE(void) buffer; int rc; + struct xencomm_handle *desc; + unsigned int argsize; + XENCOMM_MINI_ALIGNED(xc_area, 2); switch (cmd) { case XENMEM_increase_reservation: case XENMEM_decrease_reservation: case XENMEM_populate_physmap: xmr = (xen_memory_reservation_t *)arg; - xen_guest_handle(extent_start_va[0]) = - xen_guest_handle(xmr->extent_start); - xencommize_memory_reservation((xen_memory_reservation_t *)arg); + set_xen_guest_handle(extent_start_va[0], + xen_guest_handle(xmr->extent_start)); + + argsize = sizeof(*xmr); + rc = xencommize_memory_reservation(xc_area, xmr); + if (rc) + return rc; + xc_area++; break; case XENMEM_maximum_ram_page: + argsize = 0; break; case XENMEM_exchange: xme_in = &((xen_memory_exchange_t *)arg)->in; xme_out = &((xen_memory_exchange_t *)arg)->out; - xen_guest_handle(extent_start_va[0]) = - xen_guest_handle(xme_in->extent_start); - xen_guest_handle(extent_start_va[1]) = - xen_guest_handle(xme_out->extent_start); - xencommize_memory_reservation - (&((xen_memory_exchange_t *)arg)->in); - xencommize_memory_reservation - (&((xen_memory_exchange_t *)arg)->out); + set_xen_guest_handle(extent_start_va[0], + xen_guest_handle(xme_in->extent_start)); + set_xen_guest_handle(extent_start_va[1], + xen_guest_handle(xme_out->extent_start)); + + argsize = sizeof(xen_memory_exchange_t); + rc = xencommize_memory_reservation(xc_area, xme_in); + if (rc) + return rc; + xc_area++; + rc = xencommize_memory_reservation(xc_area, xme_out); + if (rc) + return rc; + xc_area++; + break; + + case XENMEM_add_to_physmap: + argsize = sizeof(xen_add_to_physmap_t); break; case XENMEM_machine_memory_map: + argsize = sizeof(*memmap); memmap = (xen_memory_map_t *)arg; - xen_guest_handle(buffer) = xen_guest_handle(memmap->buffer); - set_xen_guest_handle(memmap->buffer, - (void *)xencomm_create_inline( - xen_guest_handle(memmap->buffer))); + set_xen_guest_handle(buffer, xen_guest_handle(memmap->buffer)); + desc = xencomm_map_no_alloc(xen_guest_handle(memmap->buffer), + memmap->nr_entries); + if (desc == NULL) + return -EINVAL; + set_xen_guest_handle(memmap->buffer, (void *)desc); break; default: @@ -270,45 +425,59 @@ xencomm_hypercall_memory_op(unsigned int return -ENOSYS; } - rc = xencomm_arch_hypercall_memory_op(cmd, xencomm_create_inline(arg)); + desc = xencomm_map_no_alloc(arg, argsize); + if (desc == NULL) + return -EINVAL; + + rc = xencomm_arch_hypercall_memory_op(cmd, desc); switch (cmd) { case XENMEM_increase_reservation: case XENMEM_decrease_reservation: case XENMEM_populate_physmap: - xen_guest_handle(xmr->extent_start) = - xen_guest_handle(extent_start_va[0]); + set_xen_guest_handle(xmr->extent_start, + xen_guest_handle(extent_start_va[0])); break; case XENMEM_exchange: - xen_guest_handle(xme_in->extent_start) = - xen_guest_handle(extent_start_va[0]); - xen_guest_handle(xme_out->extent_start) = - xen_guest_handle(extent_start_va[1]); + set_xen_guest_handle(xme_in->extent_start, + xen_guest_handle(extent_start_va[0])); + set_xen_guest_handle(xme_out->extent_start, + xen_guest_handle(extent_start_va[1])); break; case XENMEM_machine_memory_map: - xen_guest_handle(memmap->buffer) = xen_guest_handle(buffer); + set_xen_guest_handle(memmap->buffer, xen_guest_handle(buffer)); break; } return rc; } +EXPORT_SYMBOL_GPL(xencomm_hypercall_memory_op); unsigned long xencomm_hypercall_hvm_op(int cmd, void *arg) { - switch (cmd) { + struct xencomm_handle *desc; + unsigned int argsize; + + switch (cmd) { + case HVMOP_get_param: case HVMOP_set_param: - case HVMOP_get_param: - break; - default: - printk("%s: unknown hvm op %d\n", __func__, cmd); - return -ENOSYS; - } - - return xencomm_arch_hypercall_hvm_op(cmd, xencomm_create_inline(arg)); -} + argsize = sizeof(xen_hvm_param_t); + break; + default: + printk("%s: unknown HVMOP %d\n", __func__, cmd); + return -EINVAL; + } + + desc = xencomm_map_no_alloc(arg, argsize); + if (desc == NULL) + return -EINVAL; + + return xencomm_arch_hypercall_hvm_op(cmd, desc); +} +EXPORT_SYMBOL_GPL(xencomm_hypercall_hvm_op); int xencomm_hypercall_suspend(unsigned long srec) @@ -317,18 +486,31 @@ xencomm_hypercall_suspend(unsigned long arg.reason = SHUTDOWN_suspend; - return xencomm_arch_hypercall_suspend(xencomm_create_inline(&arg)); + return xencomm_arch_hypercall_suspend( + xencomm_map_no_alloc(&arg, sizeof(arg))); } int xencomm_hypercall_xenoprof_op(int op, void *arg) { + unsigned int argsize; + struct xencomm_handle *desc; + switch (op) { case XENOPROF_init: + argsize = sizeof(xenoprof_init_t); + break; case XENOPROF_set_active: + argsize = sizeof(domid_t); + break; case XENOPROF_set_passive: + argsize = sizeof(xenoprof_passive_t); + break; case XENOPROF_counter: + argsize = sizeof(xenoprof_counter_t); + break; case XENOPROF_get_buffer: + argsize = sizeof(xenoprof_get_buffer_t); break; case XENOPROF_reset_active_list: @@ -342,25 +524,40 @@ xencomm_hypercall_xenoprof_op(int op, vo case XENOPROF_release_counters: case XENOPROF_shutdown: return xencomm_arch_hypercall_xenoprof_op(op, arg); - break; default: printk("%s: op %d isn't supported\n", __func__, op); return -ENOSYS; } - return xencomm_arch_hypercall_xenoprof_op(op, - xencomm_create_inline(arg)); -} - -int -xencomm_hypercall_perfmon_op(unsigned long cmd, void* arg, unsigned long count) -{ + + desc = xencomm_map_no_alloc(arg, argsize); + if (desc == NULL) + return -EINVAL; + + return xencomm_arch_hypercall_xenoprof_op(op, desc); +} +EXPORT_SYMBOL_GPL(xencomm_hypercall_xenoprof_op); + +int +xencomm_hypercall_perfmon_op(unsigned long cmd, void* arg, + unsigned long count) +{ + unsigned int argsize; + struct xencomm_handle *desc; + switch (cmd) { case PFM_GET_FEATURES: + argsize = sizeof(pfarg_features_t); + break; case PFM_CREATE_CONTEXT: + argsize = sizeof(pfarg_context_t); + break; + case PFM_LOAD_CONTEXT: + argsize = sizeof(pfarg_load_t); + break; case PFM_WRITE_PMCS: case PFM_WRITE_PMDS: - case PFM_LOAD_CONTEXT: + argsize = sizeof(pfarg_reg_t) * count; break; case PFM_DESTROY_CONTEXT: @@ -371,22 +568,32 @@ xencomm_hypercall_perfmon_op(unsigned lo default: printk("%s:%d cmd %ld isn't supported\n", - __func__,__LINE__, cmd); + __func__, __LINE__, cmd); BUG(); } - return xencomm_arch_hypercall_perfmon_op(cmd, - xencomm_create_inline(arg), - count); -} + desc = xencomm_map_no_alloc(arg, argsize); + if (desc == NULL) + return -EINVAL; + + return xencomm_arch_hypercall_perfmon_op(cmd, desc, count); +} +EXPORT_SYMBOL_GPL(xencomm_hypercall_perfmon_op); long xencomm_hypercall_vcpu_op(int cmd, int cpu, void *arg) { - switch (cmd) { - case VCPUOP_register_runstate_memory_area: - xencommize_memory_reservation((xen_memory_reservation_t *)arg); - break; + unsigned int argsize; + switch (cmd) { + case VCPUOP_register_runstate_memory_area: { + vcpu_register_runstate_memory_area_t *area = + (vcpu_register_runstate_memory_area_t *)arg; + argsize = sizeof(*arg); + set_xen_guest_handle(area->addr.h, + (void *)xencomm_map_no_alloc(area->addr.v, + sizeof(area->addr.v))); + break; + } default: printk("%s: unknown vcpu op %d\n", __func__, cmd); @@ -394,18 +601,26 @@ xencomm_hypercall_vcpu_op(int cmd, int c } return xencomm_arch_hypercall_vcpu_op(cmd, cpu, - xencomm_create_inline(arg)); + xencomm_map_no_alloc(arg, argsize)); } long xencomm_hypercall_opt_feature(void *arg) { - return xencomm_arch_hypercall_opt_feature(xencomm_create_inline(arg)); + return xencomm_arch_hypercall_opt_feature( + xencomm_map_no_alloc(arg, + sizeof(struct xen_ia64_opt_feature))); } int xencomm_hypercall_fpswa_revision(unsigned int *revision) { - return xencomm_arch_hypercall_fpswa_revision( - xencomm_create_inline(revision)); -} + struct xencomm_handle *desc; + + desc = xencomm_map_no_alloc(revision, sizeof(*revision)); + if (desc == NULL) + return -EINVAL; + + return xencomm_arch_hypercall_fpswa_revision(desc); +} +EXPORT_SYMBOL_GPL(xencomm_hypercall_fpswa_revision); diff -r 41b87d2ad607 -r c1602a983042 arch/ia64/xen/xcom_mini.c --- a/arch/ia64/xen/xcom_mini.c Wed Aug 01 15:03:59 2007 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,488 +0,0 @@ -/* - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Tristan Gingold - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_VMX_GUEST -#include -#else -#include -#endif -#include -#include - -int -xencomm_mini_hypercall_event_channel_op(int cmd, void *op) -{ - struct xencomm_mini xc_area[2]; - int nbr_area = 2; - struct xencomm_handle *desc; - int rc; - - rc = xencomm_create_mini(xc_area, &nbr_area, - op, sizeof(evtchn_op_t), &desc); - if (rc) - return rc; - - return xencomm_arch_hypercall_event_channel_op(cmd, desc); -} -EXPORT_SYMBOL(xencomm_mini_hypercall_event_channel_op); - -static int -xencommize_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; - 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_unmap_and_replace: - argsize = sizeof(struct gnttab_unmap_and_replace); - 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, - xen_guest_handle(setup->frame_list), - setup->nr_frames - * sizeof(*xen_guest_handle(setup->frame_list)), - &desc1); - if (rc) - return rc; - set_xen_guest_handle(setup->frame_list, (void *)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; - case GNTTABOP_query_size: - argsize = sizeof(struct gnttab_query_size); - 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); - if (rc) - return rc; - - return 0; -} - -int -xencomm_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); -} -EXPORT_SYMBOL(xencomm_mini_hypercall_grant_table_op); - -int -xencomm_mini_hypercall_multicall(void *call_list, int nr_calls) -{ - int i; - multicall_entry_t *mce; - int nbr_area = 2 + nr_calls * 3; - struct xencomm_mini xc_area[nbr_area]; - struct xencomm_handle *desc; - int rc; - - for (i = 0; i < nr_calls; i++) { - mce = (multicall_entry_t *)call_list + i; - - switch (mce->op) { - case __HYPERVISOR_update_va_mapping: - case __HYPERVISOR_mmu_update: - /* No-op on ia64. */ - break; - case __HYPERVISOR_grant_table_op: - rc = xencommize_mini_grant_table_op - (xc_area, &nbr_area, - mce->args[0], (void *)mce->args[1], - mce->args[2], &desc); - if (rc) - return rc; - mce->args[1] = (unsigned long)desc; - break; - case __HYPERVISOR_memory_op: - default: - printk("%s: unhandled multicall op entry op %lu\n", - __func__, mce->op); - return -ENOSYS; - } - } - - rc = xencomm_create_mini(xc_area, &nbr_area, call_list, - nr_calls * sizeof(multicall_entry_t), &desc); - if (rc) - return rc; - - return xencomm_arch_hypercall_multicall(desc, nr_calls); -} -EXPORT_SYMBOL(xencomm_mini_hypercall_multicall); - -static int -xencommize_mini_memory_reservation(struct xencomm_mini *area, int *nbr_area, - xen_memory_reservation_t *mop) -{ - struct xencomm_handle *desc; - int rc; - - rc = xencomm_create_mini - (area, nbr_area, - xen_guest_handle(mop->extent_start), - mop->nr_extents - * sizeof(*xen_guest_handle(mop->extent_start)), - &desc); - if (rc) - return rc; - - set_xen_guest_handle(mop->extent_start, (void *)desc); - - return 0; -} - -int -xencomm_mini_hypercall_memory_op(unsigned int cmd, void *arg) -{ - int nbr_area = 4; - struct xencomm_mini xc_area[4]; - struct xencomm_handle *desc; - int rc; - unsigned int argsize; - - switch (cmd) { - case XENMEM_increase_reservation: - case XENMEM_decrease_reservation: - case XENMEM_populate_physmap: - argsize = sizeof(xen_memory_reservation_t); - rc = xencommize_mini_memory_reservation - (xc_area, &nbr_area, (xen_memory_reservation_t *)arg); - if (rc) - return rc; - break; - - case XENMEM_maximum_ram_page: - argsize = 0; - break; - - case XENMEM_exchange: - argsize = sizeof(xen_memory_exchange_t); - rc = xencommize_mini_memory_reservation - (xc_area, &nbr_area, - &((xen_memory_exchange_t *)arg)->in); - if (rc) - return rc; - rc = xencommize_mini_memory_reservation - (xc_area, &nbr_area, - &((xen_memory_exchange_t *)arg)->out); - if (rc) - return rc; - break; - - case XENMEM_add_to_physmap: - argsize = sizeof (xen_add_to_physmap_t); - break; - - case XENMEM_machine_memory_map: - { - xen_memory_map_t *memmap = (xen_memory_map_t *)arg; - argsize = sizeof(*memmap); - rc = xencomm_create_mini(xc_area, &nbr_area, - xen_guest_handle(memmap->buffer), - memmap->nr_entries, &desc); - if (rc) - return rc; - set_xen_guest_handle(memmap->buffer, (void *)desc); - break; - } - - default: - printk("%s: unknown mini memory op %d\n", __func__, cmd); - return -ENOSYS; - } - - rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc); - if (rc) - return rc; - - return xencomm_arch_hypercall_memory_op(cmd, desc); -} -EXPORT_SYMBOL(xencomm_mini_hypercall_memory_op); - -unsigned long -xencomm_mini_hypercall_hvm_op(int cmd, void *arg) -{ - struct xencomm_handle *desc; - int nbr_area = 2; - struct xencomm_mini xc_area[2]; - unsigned int argsize; - int rc; - - switch (cmd) { - case HVMOP_get_param: - case HVMOP_set_param: - argsize = sizeof(xen_hvm_param_t); - break; - default: - printk("%s: unknown HVMOP %d\n", __func__, cmd); - return -EINVAL; - } - - rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc); - if (rc) - return rc; - - return xencomm_arch_hypercall_hvm_op(cmd, desc); -} -EXPORT_SYMBOL(xencomm_mini_hypercall_hvm_op); - -int -xencomm_mini_hypercall_xen_version(int cmd, void *arg) -{ - struct xencomm_handle *desc; - int nbr_area = 2; - struct xencomm_mini xc_area[2]; - unsigned int 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_mini(xc_area, &nbr_area, arg, argsize, &desc); - if (rc) - return rc; - - return xencomm_arch_hypercall_xen_version(cmd, desc); -} -EXPORT_SYMBOL(xencomm_mini_hypercall_xen_version); - -int -xencomm_mini_hypercall_xenoprof_op(int op, void *arg) -{ - unsigned int argsize; - struct xencomm_mini xc_area[2]; - int nbr_area = 2; - struct xencomm_handle *desc; - int rc; - - switch (op) { - case XENOPROF_init: - argsize = sizeof(xenoprof_init_t); - break; - case XENOPROF_set_active: - argsize = sizeof(domid_t); - break; - case XENOPROF_set_passive: - argsize = sizeof(xenoprof_passive_t); - break; - case XENOPROF_counter: - argsize = sizeof(xenoprof_counter_t); - break; - case XENOPROF_get_buffer: - argsize = sizeof(xenoprof_get_buffer_t); - break; - - case XENOPROF_reset_active_list: - case XENOPROF_reset_passive_list: - case XENOPROF_reserve_counters: - case XENOPROF_setup_events: - case XENOPROF_enable_virq: - case XENOPROF_start: - case XENOPROF_stop: - case XENOPROF_disable_virq: - case XENOPROF_release_counters: - case XENOPROF_shutdown: - return xencomm_arch_hypercall_xenoprof_op(op, arg); - - default: - printk("%s: op %d isn't supported\n", __func__, op); - return -ENOSYS; - } - rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc); - if (rc) - return rc; - return xencomm_arch_hypercall_xenoprof_op(op, desc); -} -EXPORT_SYMBOL_GPL(xencomm_mini_hypercall_xenoprof_op); - -int -xencomm_mini_hypercall_perfmon_op(unsigned long cmd, void* arg, - unsigned long count) -{ - unsigned int argsize; - struct xencomm_mini xc_area[2]; - int nbr_area = 2; - struct xencomm_handle *desc; - int rc; - - switch (cmd) { - case PFM_GET_FEATURES: - argsize = sizeof(pfarg_features_t); - break; - case PFM_CREATE_CONTEXT: - argsize = sizeof(pfarg_context_t); - break; - case PFM_LOAD_CONTEXT: - argsize = sizeof(pfarg_load_t); - break; - case PFM_WRITE_PMCS: - case PFM_WRITE_PMDS: - argsize = sizeof(pfarg_reg_t) * count; - break; - - case PFM_DESTROY_CONTEXT: - case PFM_UNLOAD_CONTEXT: - case PFM_START: - case PFM_STOP: - return xencomm_arch_hypercall_perfmon_op(cmd, arg, count); - - default: - printk("%s:%d cmd %ld isn't supported\n", - __func__, __LINE__, cmd); - BUG(); - } - - rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc); - if (rc) - return rc; - return xencomm_arch_hypercall_perfmon_op(cmd, desc, count); -} -EXPORT_SYMBOL_GPL(xencomm_mini_hypercall_perfmon_op); - -int -xencomm_mini_hypercall_sched_op(int cmd, void *arg) -{ - int rc, nbr_area = 2; - struct xencomm_mini xc_area[2]; - struct xencomm_handle *desc; - unsigned int argsize; - - switch (cmd) { - case SCHEDOP_yield: - case SCHEDOP_block: - argsize = 0; - break; - case SCHEDOP_shutdown: - argsize = sizeof(sched_shutdown_t); - break; - case SCHEDOP_poll: - argsize = sizeof(sched_poll_t); - break; - case SCHEDOP_remote_shutdown: - argsize = sizeof(sched_remote_shutdown_t); - break; - - default: - printk("%s: unknown sched op %d\n", __func__, cmd); - return -ENOSYS; - } - - rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc); - if (rc) - return rc; - - return xencomm_arch_hypercall_sched_op(cmd, desc); -} -EXPORT_SYMBOL_GPL(xencomm_mini_hypercall_sched_op); - -int -xencomm_mini_hypercall_fpswa_revision(unsigned int *revision) -{ - int nbr_area = 2; - struct xencomm_mini xc_area[2]; - struct xencomm_handle *desc; - int rc; - - rc = xencomm_create_mini(xc_area, &nbr_area, - revision, sizeof(*revision), &desc); - if (rc) - return rc; - return xencomm_arch_hypercall_fpswa_revision(desc); -} -EXPORT_SYMBOL_GPL(xencomm_mini_hypercall_fpswa_revision); diff -r 41b87d2ad607 -r c1602a983042 arch/ia64/xen/xcom_privcmd.c --- a/arch/ia64/xen/xcom_privcmd.c Wed Aug 01 15:03:59 2007 +0900 +++ b/arch/ia64/xen/xcom_privcmd.c Tue Aug 07 18:20:46 2007 +0900 @@ -54,7 +54,7 @@ xencomm_privcmd_platform_op(privcmd_hype if (kern_op.interface_version != XENPF_INTERFACE_VERSION) return -EACCES; - op_desc = xencomm_create_inline(&kern_op); + op_desc = xencomm_map_no_alloc(&kern_op, sizeof(kern_op)); switch (kern_op.cmd) { default: @@ -73,8 +73,7 @@ xencomm_privcmd_platform_op(privcmd_hype if (copy_to_user(user_op, &kern_op, sizeof(struct xen_platform_op))) ret = -EFAULT; - if (desc) - xencomm_free(desc); + xencomm_free(desc); return ret; } @@ -96,14 +95,16 @@ xencomm_privcmd_sysctl(privcmd_hypercall if (kern_op.interface_version != XEN_SYSCTL_INTERFACE_VERSION) return -EACCES; - op_desc = xencomm_create_inline(&kern_op); + op_desc = xencomm_map_no_alloc(&kern_op, sizeof(kern_op)); switch (kern_op.cmd) { case XEN_SYSCTL_readconsole: - ret = xencomm_create( + desc = xencomm_map( xen_guest_handle(kern_op.u.readconsole.buffer), - kern_op.u.readconsole.count, - &desc, GFP_KERNEL); + kern_op.u.readconsole.count); + if (xen_guest_handle(kern_op.u.readconsole.buffer) != NULL && + kern_op.u.readconsole.count > 0 && desc == NULL) + return -ENOMEM; set_xen_guest_handle(kern_op.u.readconsole.buffer, (void *)desc); break; @@ -130,55 +131,62 @@ xencomm_privcmd_sysctl(privcmd_hypercall } /* query the buffer size for xencomm */ - tmp_desc = xencomm_create_inline(&tmp_op); + tmp_desc = xencomm_map_no_alloc(&tmp_op, sizeof(tmp_op)); ret = xencomm_arch_hypercall_sysctl(tmp_desc); if (ret) return ret; - ret = xencomm_create(xen_guest_handle(kern_op.u.perfc_op.desc), - tmp_op.u.perfc_op.nr_counters * - sizeof(xen_sysctl_perfc_desc_t), - &desc, GFP_KERNEL); - if (ret) - return ret; + desc = xencomm_map(xen_guest_handle(kern_op.u.perfc_op.desc), + tmp_op.u.perfc_op.nr_counters * + sizeof(xen_sysctl_perfc_desc_t)); + if (xen_guest_handle(kern_op.u.perfc_op.desc) != NULL && + tmp_op.u.perfc_op.nr_counters > 0 && desc == NULL) + return -ENOMEM; set_xen_guest_handle(kern_op.u.perfc_op.desc, (void *)desc); - ret = xencomm_create(xen_guest_handle(kern_op.u.perfc_op.val), - tmp_op.u.perfc_op.nr_vals * - sizeof(xen_sysctl_perfc_val_t), - &desc1, GFP_KERNEL); - if (ret) + desc1 = xencomm_map(xen_guest_handle(kern_op.u.perfc_op.val), + tmp_op.u.perfc_op.nr_vals * + sizeof(xen_sysctl_perfc_val_t)); + if (xen_guest_handle(kern_op.u.perfc_op.val) != NULL && + tmp_op.u.perfc_op.nr_vals > 0 && desc1 == NULL) { xencomm_free(desc); + return -ENOMEM; + } set_xen_guest_handle(kern_op.u.perfc_op.val, (void *)desc1); break; } case XEN_SYSCTL_getdomaininfolist: - ret = xencomm_create( + desc = xencomm_map( xen_guest_handle(kern_op.u.getdomaininfolist.buffer), kern_op.u.getdomaininfolist.max_domains * - sizeof(xen_domctl_getdomaininfo_t), - &desc, GFP_KERNEL); + sizeof(xen_domctl_getdomaininfo_t)); + if (xen_guest_handle(kern_op.u.getdomaininfolist.buffer) != + NULL && kern_op.u.getdomaininfolist.max_domains > 0 && + desc == NULL) + return -ENOMEM; set_xen_guest_handle(kern_op.u.getdomaininfolist.buffer, (void *)desc); break; case XEN_SYSCTL_debug_keys: - ret = xencomm_create( + desc = xencomm_map( xen_guest_handle(kern_op.u.debug_keys.keys), - kern_op.u.debug_keys.nr_keys, - &desc, GFP_KERNEL); + kern_op.u.debug_keys.nr_keys); + if (xen_guest_handle(kern_op.u.debug_keys.keys) != NULL && + kern_op.u.debug_keys.nr_keys > 0 && desc == NULL) + return -ENOMEM; set_xen_guest_handle(kern_op.u.debug_keys.keys, (void *)desc); break; case XEN_SYSCTL_physinfo: - ret = xencomm_create( + desc = xencomm_map( xen_guest_handle(kern_op.u.physinfo.cpu_to_node), - kern_op.u.physinfo.max_cpu_id * sizeof(uint32_t), - &desc, GFP_KERNEL); - if (ret) - return ret; + kern_op.u.physinfo.max_cpu_id * sizeof(uint32_t)); + if (xen_guest_handle(kern_op.u.physinfo.cpu_to_node) != NULL && + kern_op.u.physinfo.max_cpu_id > 0 && desc == NULL) + return -ENOMEM; set_xen_guest_handle(kern_op.u.physinfo.cpu_to_node, (void *)desc); @@ -199,10 +207,8 @@ xencomm_privcmd_sysctl(privcmd_hypercall if (copy_to_user(user_op, &kern_op, sizeof(xen_sysctl_t))) ret = -EFAULT; - if (desc) - xencomm_free(desc); - if (desc1) - xencomm_free(desc1); + xencomm_free(desc); + xencomm_free(desc1); return ret; } @@ -223,7 +229,7 @@ xencomm_privcmd_domctl(privcmd_hypercall if (kern_op.interface_version != XEN_DOMCTL_INTERFACE_VERSION) return -EACCES; - op_desc = xencomm_create_inline(&kern_op); + op_desc = xencomm_map_no_alloc(&kern_op, sizeof(kern_op)); switch (kern_op.cmd) { case XEN_DOMCTL_createdomain: @@ -236,10 +242,12 @@ xencomm_privcmd_domctl(privcmd_hypercall { unsigned long nr_pages = kern_op.u.getmemlist.max_pfns; - ret = xencomm_create( + desc = xencomm_map( xen_guest_handle(kern_op.u.getmemlist.buffer), - nr_pages * sizeof(unsigned long), - &desc, GFP_KERNEL); + nr_pages * sizeof(unsigned long)); + if (xen_guest_handle(kern_op.u.getmemlist.buffer) != NULL && + nr_pages > 0 && desc == NULL) + return -ENOMEM; set_xen_guest_handle(kern_op.u.getmemlist.buffer, (void *)desc); break; @@ -247,18 +255,23 @@ xencomm_privcmd_domctl(privcmd_hypercall case XEN_DOMCTL_getpageframeinfo: break; case XEN_DOMCTL_getpageframeinfo2: - ret = xencomm_create( + desc = xencomm_map( xen_guest_handle(kern_op.u.getpageframeinfo2.array), - kern_op.u.getpageframeinfo2.num, - &desc, GFP_KERNEL); + kern_op.u.getpageframeinfo2.num); + if (xen_guest_handle(kern_op.u.getpageframeinfo2.array) != + NULL && kern_op.u.getpageframeinfo2.num > 0 && + desc == NULL) + return -ENOMEM; set_xen_guest_handle(kern_op.u.getpageframeinfo2.array, (void *)desc); break; case XEN_DOMCTL_shadow_op: - ret = xencomm_create( + desc = xencomm_map( xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap), - ROUND_DIV(kern_op.u.shadow_op.pages, 8), - &desc, GFP_KERNEL); + ROUND_DIV(kern_op.u.shadow_op.pages, 8)); + if (xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap) != NULL + && kern_op.u.shadow_op.pages > 0 && desc == NULL) + return -ENOMEM; set_xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap, (void *)desc); break; @@ -266,20 +279,25 @@ xencomm_privcmd_domctl(privcmd_hypercall break; case XEN_DOMCTL_setvcpucontext: case XEN_DOMCTL_getvcpucontext: - ret = xencomm_create( + desc = xencomm_map( xen_guest_handle(kern_op.u.vcpucontext.ctxt), - sizeof(vcpu_guest_context_t), - &desc, GFP_KERNEL); + sizeof(vcpu_guest_context_t)); + if (xen_guest_handle(kern_op.u.vcpucontext.ctxt) != NULL && + desc == NULL) + return -ENOMEM; set_xen_guest_handle(kern_op.u.vcpucontext.ctxt, (void *)desc); break; case XEN_DOMCTL_getvcpuinfo: break; case XEN_DOMCTL_setvcpuaffinity: case XEN_DOMCTL_getvcpuaffinity: - ret = xencomm_create( + desc = xencomm_map( xen_guest_handle(kern_op.u.vcpuaffinity.cpumap.bitmap), - ROUND_DIV(kern_op.u.vcpuaffinity.cpumap.nr_cpus, 8), - &desc, GFP_KERNEL); + ROUND_DIV(kern_op.u.vcpuaffinity.cpumap.nr_cpus, 8)); + if (xen_guest_handle(kern_op.u.vcpuaffinity.cpumap.bitmap) != + NULL && kern_op.u.vcpuaffinity.cpumap.nr_cpus > 0 && + desc == NULL) + return -ENOMEM; set_xen_guest_handle(kern_op.u.vcpuaffinity.cpumap.bitmap, (void *)desc); break; @@ -311,8 +329,7 @@ xencomm_privcmd_domctl(privcmd_hypercall if (copy_to_user(user_op, &kern_op, sizeof(xen_domctl_t))) ret = -EFAULT; - if (desc) - xencomm_free(desc); + xencomm_free(desc); return ret; } @@ -332,13 +349,14 @@ xencomm_privcmd_acm_op(privcmd_hypercall switch (kern_arg.cmd) { case ACMOP_getssid: { - op_desc = xencomm_create_inline(&kern_arg); - - ret = xencomm_create( + op_desc = xencomm_map_no_alloc(&kern_arg, sizeof(kern_arg)); + + desc = xencomm_map( xen_guest_handle(kern_arg.u.getssid.ssidbuf), - kern_arg.u.getssid.ssidbuf_size, &desc, GFP_KERNEL); - if (ret) - return ret; + kern_arg.u.getssid.ssidbuf_size); + if (xen_guest_handle(kern_arg.u.getssid.ssidbuf) != NULL && + kern_arg.u.getssid.ssidbuf_size > 0 && desc == NULL) + return -ENOMEM; set_xen_guest_handle(kern_arg.u.getssid.ssidbuf, (void *)desc); @@ -378,28 +396,28 @@ xencomm_privcmd_memory_op(privcmd_hyperc if (copy_from_user(&kern_op, user_op, sizeof(xen_memory_reservation_t))) return -EFAULT; - desc_op = xencomm_create_inline(&kern_op); + desc_op = xencomm_map_no_alloc(&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 + desc = xencomm_map (addr, kern_op.nr_extents * sizeof(*xen_guest_handle - (kern_op.extent_start)), - &desc, GFP_KERNEL); - if (ret) - return ret; + (kern_op.extent_start))); + if (addr != NULL && kern_op.nr_extents > 0 && + desc == NULL) + return -ENOMEM; + set_xen_guest_handle(kern_op.extent_start, (void *)desc); } ret = xencomm_arch_hypercall_memory_op(cmd, desc_op); - if (desc) - xencomm_free(desc); + xencomm_free(desc); if (ret != 0) return ret; @@ -419,7 +437,7 @@ xencomm_privcmd_memory_op(privcmd_hyperc user_domid = (domid_t __user *)hypercall->arg[1]; if (copy_from_user(&kern_domid, user_domid, sizeof(domid_t))) return -EFAULT; - desc = xencomm_create_inline(&kern_domid); + desc = xencomm_map_no_alloc(&kern_domid, sizeof(kern_domid)); ret = xencomm_arch_hypercall_memory_op(cmd, desc); @@ -439,41 +457,41 @@ xencomm_privcmd_memory_op(privcmd_hyperc if (copy_from_user(&kern_op, user_op, sizeof(xen_translate_gpfn_list_t))) return -EFAULT; - desc_op = xencomm_create_inline(&kern_op); + desc_op = xencomm_map_no_alloc(&kern_op, sizeof(kern_op)); if (kern_op.nr_gpfns) { /* gpfn_list. */ addr = xen_guest_handle(kern_op.gpfn_list); - ret = xencomm_create(addr, kern_op.nr_gpfns * + desc_gpfn = xencomm_map(addr, kern_op.nr_gpfns * sizeof(*xen_guest_handle - (kern_op.gpfn_list)), - &desc_gpfn, GFP_KERNEL); - if (ret) - return ret; + (kern_op.gpfn_list))); + if (addr != NULL && kern_op.nr_gpfns > 0 && + desc_gpfn == NULL) + return -ENOMEM; set_xen_guest_handle(kern_op.gpfn_list, (void *)desc_gpfn); /* mfn_list. */ addr = xen_guest_handle(kern_op.mfn_list); - ret = xencomm_create(addr, kern_op.nr_gpfns * + desc_mfn = xencomm_map(addr, kern_op.nr_gpfns * sizeof(*xen_guest_handle - (kern_op.mfn_list)), - &desc_mfn, GFP_KERNEL); - if (ret) - return ret; + (kern_op.mfn_list))); + if (addr != NULL && kern_op.nr_gpfns > 0 && + desc_mfn == NULL) { + xencomm_free(desc_gpfn); + return -ENOMEM; + } + set_xen_guest_handle(kern_op.mfn_list, (void *)desc_mfn); } ret = xencomm_arch_hypercall_memory_op(cmd, desc_op); - if (desc_gpfn) - xencomm_free(desc_gpfn); - - if (desc_mfn) - xencomm_free(desc_mfn); + xencomm_free(desc_gpfn); + xencomm_free(desc_mfn); if (ret != 0) return ret; @@ -527,9 +545,9 @@ xencomm_privcmd_xen_version(privcmd_hype return -ENOSYS; } - rc = xencomm_create(arg, argsize, &desc, GFP_KERNEL); - if (rc) - return rc; + desc = xencomm_map(arg, argsize); + if (arg != NULL && argsize > 0 && desc == NULL) + return -ENOMEM; rc = xencomm_arch_hypercall_xen_version(cmd, desc); @@ -560,10 +578,9 @@ xencomm_privcmd_event_channel_op(privcmd return -EINVAL; } - ret = xencomm_create((void *)hypercall->arg[1], argsize, - &desc, GFP_KERNEL); - if (ret) - return ret; + desc = xencomm_map((void *)hypercall->arg[1], argsize); + if ((void *)hypercall->arg[1] != NULL && argsize > 0 && desc == NULL) + return -ENOMEM; ret = xencomm_arch_hypercall_event_channel_op(cmd, desc); @@ -599,10 +616,9 @@ xencomm_privcmd_hvm_op(privcmd_hypercall return -EINVAL; } - ret = xencomm_create((void *)hypercall->arg[1], argsize, - &desc, GFP_KERNEL); - if (ret) - return ret; + desc = xencomm_map((void *)hypercall->arg[1], argsize); + if ((void *)hypercall->arg[1] != NULL && argsize > 0 && desc == NULL) + return -ENOMEM; ret = xencomm_arch_hypercall_hvm_op(cmd, desc); @@ -627,10 +643,9 @@ xencomm_privcmd_sched_op(privcmd_hyperca return -EINVAL; } - ret = xencomm_create((void *)hypercall->arg[1], argsize, - &desc, GFP_KERNEL); - if (ret) - return ret; + desc = xencomm_map((void *)hypercall->arg[1], argsize); + if ((void *)hypercall->arg[1] != NULL && argsize > 0 && desc == NULL) + return -ENOMEM; ret = xencomm_arch_hypercall_sched_op(cmd, desc); @@ -650,10 +665,10 @@ xencomm_privcmd_ia64_dom0vp_op(privcmd_h unsigned int __user *revision_user = (unsigned int* __user)hypercall->arg[1]; struct xencomm_handle *desc; - ret = xencomm_create(&revision, sizeof(revision), - &desc, GFP_KERNEL); - if (ret) - break; + desc = xencomm_map(&revision, sizeof(revision)); + if (desc == NULL) + return -ENOMEM; + ret = xencomm_arch_hypercall_fpswa_revision(desc); xencomm_free(desc); if (ret) diff -r 41b87d2ad607 -r c1602a983042 arch/ia64/xen/xencomm.c --- a/arch/ia64/xen/xencomm.c Wed Aug 01 15:03:59 2007 +0900 +++ b/arch/ia64/xen/xencomm.c Tue Aug 07 18:20:46 2007 +0900 @@ -27,19 +27,17 @@ #include -static int xencomm_debug = 0; - static unsigned long kernel_start_pa; void -xencomm_init (void) +xencomm_initialize (void) { kernel_start_pa = KERNEL_START - ia64_tpa(KERNEL_START); } /* Translate virtual address to physical address. */ unsigned long -xencomm_vaddr_to_paddr(unsigned long vaddr) +xencomm_vtop(unsigned long vaddr) { #ifndef CONFIG_VMX_GUEST struct page *page; @@ -109,155 +107,3 @@ xencomm_vaddr_to_paddr(unsigned long vad return (page_to_pfn(page) << PAGE_SHIFT) | (vaddr & ~PAGE_MASK); #endif } - -static int -xencomm_init_desc(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 = xencomm_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; -} - -static struct xencomm_desc * -xencomm_alloc(gfp_t gfp_mask) -{ - struct xencomm_desc *desc; - - 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(desc, buffer, bytes); - if (rc) { - printk("%s failure: %d\n", "xencomm_init_desc", rc); - xencomm_free(handle); - return rc; - } - - *ret = handle; - return 0; -} - -/* "mini" routines, for stack-based communications: */ - -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; -} - -int -xencomm_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; -} diff -r 41b87d2ad607 -r c1602a983042 include/asm-ia64/hypercall.h --- a/include/asm-ia64/hypercall.h Wed Aug 01 15:03:59 2007 +0900 +++ b/include/asm-ia64/hypercall.h Tue Aug 07 18:20:46 2007 +0900 @@ -405,19 +405,6 @@ HYPERVISOR_add_io_space(unsigned long ph #define HYPERVISOR_update_va_mapping(va, new_val, flags) (0) /* Use xencomm to do hypercalls. */ -#ifdef MODULE -#define HYPERVISOR_sched_op xencomm_mini_hypercall_sched_op -#define HYPERVISOR_event_channel_op xencomm_mini_hypercall_event_channel_op -#define HYPERVISOR_callback_op xencomm_mini_hypercall_callback_op -#define HYPERVISOR_multicall xencomm_mini_hypercall_multicall -#define HYPERVISOR_xen_version xencomm_mini_hypercall_xen_version -#define HYPERVISOR_console_io xencomm_mini_hypercall_console_io -#define HYPERVISOR_hvm_op xencomm_mini_hypercall_hvm_op -#define HYPERVISOR_memory_op xencomm_mini_hypercall_memory_op -#define HYPERVISOR_xenoprof_op xencomm_mini_hypercall_xenoprof_op -#define HYPERVISOR_perfmon_op xencomm_mini_hypercall_perfmon_op -#define HYPERVISOR_fpswa_revision xencomm_mini_hypercall_fpswa_revision -#else #define HYPERVISOR_sched_op xencomm_hypercall_sched_op #define HYPERVISOR_event_channel_op xencomm_hypercall_event_channel_op #define HYPERVISOR_callback_op xencomm_hypercall_callback_op @@ -429,8 +416,6 @@ HYPERVISOR_add_io_space(unsigned long ph #define HYPERVISOR_xenoprof_op xencomm_hypercall_xenoprof_op #define HYPERVISOR_perfmon_op xencomm_hypercall_perfmon_op #define HYPERVISOR_fpswa_revision xencomm_hypercall_fpswa_revision -#endif - #define HYPERVISOR_suspend xencomm_hypercall_suspend #define HYPERVISOR_vcpu_op xencomm_hypercall_vcpu_op #define HYPERVISOR_opt_feature xencomm_hypercall_opt_feature diff -r 41b87d2ad607 -r c1602a983042 include/asm-ia64/sal.h --- a/include/asm-ia64/sal.h Wed Aug 01 15:03:59 2007 +0900 +++ b/include/asm-ia64/sal.h Tue Aug 07 18:20:46 2007 +0900 @@ -701,9 +701,9 @@ ia64_sal_get_state_info (u64 sal_info_ty if (is_running_on_xen()) { struct xencomm_handle *desc; - if (xencomm_create(sal_info, - ia64_sal_get_state_info_size(sal_info_type), - &desc, GFP_KERNEL)) + desc = xencomm_map(sal_info, + ia64_sal_get_state_info_size(sal_info_type)); + if (desc == NULL) return 0; SAL_CALL_REENTRANT(isrv, SAL_GET_STATE_INFO, sal_info_type, 0, diff -r 41b87d2ad607 -r c1602a983042 include/asm-ia64/xen/xcom_hcall.h --- a/include/asm-ia64/xen/xcom_hcall.h Wed Aug 01 15:03:59 2007 +0900 +++ b/include/asm-ia64/xen/xcom_hcall.h Tue Aug 07 18:20:46 2007 +0900 @@ -19,7 +19,7 @@ #ifndef _LINUX_XENCOMM_HCALL_H_ #define _LINUX_XENCOMM_HCALL_H_ -/* These function creates inline descriptor for the parameters and +/* These function creates inline or mini descriptor for the parameters and calls the corresponding xencomm_arch_hypercall_X. Architectures should defines HYPERVISOR_xxx as xencomm_hypercall_xxx unless they want to use their own wrapper. */ @@ -55,33 +55,6 @@ extern long xencomm_hypercall_vcpu_op(in extern long xencomm_hypercall_opt_feature(void *arg); -/* Using mini xencomm. */ -extern int xencomm_mini_hypercall_console_io(int cmd, int count, char *str); - -extern int xencomm_mini_hypercall_event_channel_op(int cmd, void *op); - -extern int xencomm_mini_hypercall_xen_version(int cmd, void *arg); - -extern int xencomm_mini_hypercall_physdev_op(int cmd, void *op); - -extern int xencomm_mini_hypercall_grant_table_op(unsigned int cmd, void *op, - unsigned int count); - -extern int xencomm_mini_hypercall_sched_op(int cmd, void *arg); - -extern int xencomm_mini_hypercall_multicall(void *call_list, int nr_calls); - -extern int xencomm_mini_hypercall_callback_op(int cmd, void *arg); - -extern int xencomm_mini_hypercall_memory_op(unsigned int cmd, void *arg); - -extern unsigned long xencomm_mini_hypercall_hvm_op(int cmd, void *arg); - -extern int xencomm_mini_hypercall_xenoprof_op(int op, void *arg); - -extern int xencomm_mini_hypercall_perfmon_op(unsigned long cmd, void* arg, - unsigned long count); - /* For privcmd. Locally declare argument type to avoid include storm. Type coherency will be checked within privcmd.c */ struct privcmd_hypercall; diff -r 41b87d2ad607 -r c1602a983042 include/asm-ia64/xen/xencomm.h --- a/include/asm-ia64/xen/xencomm.h Wed Aug 01 15:03:59 2007 +0900 +++ b/include/asm-ia64/xen/xencomm.h Tue Aug 07 18:20:46 2007 +0900 @@ -16,45 +16,18 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _LINUX_XENCOMM_H_ -#define _LINUX_XENCOMM_H_ +#ifndef _ASM_IA64_XENCOMM_H_ +#define _ASM_IA64_XENCOMM_H_ -#include - -#define XENCOMM_MINI_ADDRS 3 -struct xencomm_mini { - struct xencomm_desc _desc; - uint64_t address[XENCOMM_MINI_ADDRS]; -}; +#define is_kernel_addr(x) \ + ((PAGE_OFFSET <= (x) && \ + (x) < (PAGE_OFFSET + (1UL << IA64_MAX_PHYS_BITS))) || \ + (KERNEL_START <= (x) && \ + (x) < KERNEL_START + KERNEL_TR_PAGE_SIZE)) /* Must be called before any hypercall. */ -extern void xencomm_init (void); +extern void xencomm_initialize (void); -/* To avoid additionnal virt to phys conversion, an opaque structure is - presented. */ -struct xencomm_handle; +#include -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(struct xencomm_mini *area, int *nbr_area, - void *buffer, unsigned long bytes, - struct xencomm_handle **ret); - -/* Translate virtual address to physical address. */ -extern unsigned long xencomm_vaddr_to_paddr(unsigned long vaddr); - -/* Inline version. To be used only on linear space (kernel space). */ -static inline struct xencomm_handle * -xencomm_create_inline(void *buffer) -{ - unsigned long paddr; - - paddr = xencomm_vaddr_to_paddr((unsigned long)buffer); - return (struct xencomm_handle *)(paddr | XENCOMM_INLINE_FLAG); -} - -#define xen_guest_handle(hnd) ((hnd).p) - -#endif /* _LINUX_XENCOMM_H_ */ +#endif /* _ASM_IA64_XENCOMM_H_ */