ia64/xen-unstable

changeset 11702:5c97ef4c7147

[IA64] Use xencomm for hypercalls.

With xencomm metaphysical addresses are passed to the hypervisor instead
of virtual addresses.
This patch breaks compatibility.

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
author awilliam@xenbuild.aw
date Mon Oct 02 14:03:42 2006 -0600 (2006-10-02)
parents 2bfd19fc1b79
children bacae4057790
files linux-2.6-xen-sparse/arch/ia64/kernel/setup.c linux-2.6-xen-sparse/arch/ia64/xen/Makefile linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c linux-2.6-xen-sparse/arch/ia64/xen/util.c linux-2.6-xen-sparse/arch/ia64/xen/xcom_hcall.c linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c linux-2.6-xen-sparse/arch/ia64/xen/xencomm.c linux-2.6-xen-sparse/arch/ia64/xen/xensetup.S linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c linux-2.6-xen-sparse/include/asm-ia64/hypercall.h linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h linux-2.6-xen-sparse/include/asm-ia64/xen/xcom_hcall.h linux-2.6-xen-sparse/include/asm-ia64/xen/xencomm.h tools/libxc/ia64/xc_ia64_linux_restore.c tools/libxc/ia64/xc_ia64_linux_save.c xen/arch/ia64/xen/Makefile xen/arch/ia64/xen/domain.c xen/arch/ia64/xen/faults.c xen/arch/ia64/xen/fw_emul.c xen/arch/ia64/xen/hypercall.c xen/arch/ia64/xen/mm.c xen/arch/ia64/xen/xencomm.c xen/include/asm-ia64/guest_access.h xen/include/public/arch-ia64.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c	Sun Oct 01 19:10:18 2006 -0600
     1.2 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c	Mon Oct 02 14:03:42 2006 -0600
     1.3 @@ -76,6 +76,8 @@ EXPORT_SYMBOL(__per_cpu_offset);
     1.4  #endif
     1.5  
     1.6  #ifdef CONFIG_XEN
     1.7 +unsigned long kernel_start_pa;
     1.8 +
     1.9  static int
    1.10  xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
    1.11  {
    1.12 @@ -433,6 +435,7 @@ setup_arch (char **cmdline_p)
    1.13  
    1.14  #ifdef CONFIG_XEN
    1.15  	if (is_running_on_xen()) {
    1.16 +		kernel_start_pa = KERNEL_START - ia64_tpa(KERNEL_START);
    1.17  		setup_xen_features();
    1.18  		/* Register a call for panic conditions. */
    1.19  		notifier_chain_register(&panic_notifier_list, &xen_panic_block);
     2.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/Makefile	Sun Oct 01 19:10:18 2006 -0600
     2.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/Makefile	Mon Oct 02 14:03:42 2006 -0600
     2.3 @@ -3,6 +3,7 @@
     2.4  #
     2.5  
     2.6  obj-y := hypercall.o xenivt.o xenentry.o xensetup.o xenpal.o xenhpski.o \
     2.7 -	 hypervisor.o pci-dma-xen.o util.o
     2.8 +	 hypervisor.o pci-dma-xen.o util.o xencomm.o xcom_hcall.o \
     2.9 +	 xcom_privcmd.o
    2.10  
    2.11  pci-dma-xen-y := ../../i386/kernel/pci-dma-xen.o
     3.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c	Sun Oct 01 19:10:18 2006 -0600
     3.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c	Mon Oct 02 14:03:42 2006 -0600
     3.3 @@ -40,60 +40,6 @@ EXPORT_SYMBOL(xen_start_info);
     3.4  int running_on_xen;
     3.5  EXPORT_SYMBOL(running_on_xen);
     3.6  
     3.7 -//XXX xen/ia64 copy_from_guest() is broken.
     3.8 -//    This is a temporal work around until it is fixed.
     3.9 -//    used by balloon.c netfront.c
    3.10 -
    3.11 -// get_xen_guest_handle is defined only when __XEN_TOOLS__ is defined
    3.12 -// if the definition in arch-ia64.h is changed, this must be updated.
    3.13 -#define get_xen_guest_handle(val, hnd)  do { val = (hnd).p; } while (0)
    3.14 -
    3.15 -int
    3.16 -ia64_xenmem_reservation_op(unsigned long op,
    3.17 -			   struct xen_memory_reservation* reservation__)
    3.18 -{
    3.19 -	struct xen_memory_reservation reservation = *reservation__;
    3.20 -	unsigned long* frame_list;
    3.21 -	unsigned long nr_extents = reservation__->nr_extents;
    3.22 -	int ret = 0;
    3.23 -	get_xen_guest_handle(frame_list, reservation__->extent_start);
    3.24 -
    3.25 -	BUG_ON(op != XENMEM_increase_reservation &&
    3.26 -	       op != XENMEM_decrease_reservation &&
    3.27 -	       op != XENMEM_populate_physmap);
    3.28 -
    3.29 -	while (nr_extents > 0) {
    3.30 -		int tmp_ret;
    3.31 -		volatile unsigned long dummy;
    3.32 -
    3.33 -		set_xen_guest_handle(reservation.extent_start, frame_list);
    3.34 -		reservation.nr_extents = nr_extents;
    3.35 -
    3.36 -		dummy = frame_list[0];// re-install tlb entry before hypercall
    3.37 -		tmp_ret = ____HYPERVISOR_memory_op(op, &reservation);
    3.38 -		if (tmp_ret < 0) {
    3.39 -			if (ret == 0) {
    3.40 -				ret = tmp_ret;
    3.41 -			}
    3.42 -			break;
    3.43 -		}
    3.44 -		if (tmp_ret == 0) {
    3.45 -			//XXX dirty work around for skbuff_ctor()
    3.46 -			//    of a non-privileged domain, 
    3.47 -			if ((op == XENMEM_increase_reservation ||
    3.48 -			     op == XENMEM_populate_physmap) &&
    3.49 -			    !is_initial_xendomain() &&
    3.50 -			    reservation.extent_order > 0)
    3.51 -				return ret;
    3.52 -		}
    3.53 -		frame_list += tmp_ret;
    3.54 -		nr_extents -= tmp_ret;
    3.55 -		ret += tmp_ret;
    3.56 -	}
    3.57 -	return ret;
    3.58 -}
    3.59 -EXPORT_SYMBOL(ia64_xenmem_reservation_op);
    3.60 -
    3.61  //XXX same as i386, x86_64 contiguous_bitmap_set(), contiguous_bitmap_clear()
    3.62  // move those to lib/contiguous_bitmap?
    3.63  //XXX discontigmem/sparsemem
    3.64 @@ -371,8 +317,6 @@ gnttab_map_grant_ref_pre(struct gnttab_m
    3.65  int
    3.66  HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
    3.67  {
    3.68 -	__u64 va1, va2, pa1, pa2;
    3.69 -
    3.70  	if (cmd == GNTTABOP_map_grant_ref) {
    3.71  		unsigned int i;
    3.72  		for (i = 0; i < count; i++) {
    3.73 @@ -380,29 +324,7 @@ HYPERVISOR_grant_table_op(unsigned int c
    3.74  				(struct gnttab_map_grant_ref*)uop + i);
    3.75  		}
    3.76  	}
    3.77 -	va1 = (__u64)uop & PAGE_MASK;
    3.78 -	pa1 = pa2 = 0;
    3.79 -	if ((REGION_NUMBER(va1) == 5) &&
    3.80 -	    ((va1 - KERNEL_START) >= KERNEL_TR_PAGE_SIZE)) {
    3.81 -		pa1 = ia64_tpa(va1);
    3.82 -		if (cmd <= GNTTABOP_transfer) {
    3.83 -			static uint32_t uop_size[GNTTABOP_transfer + 1] = {
    3.84 -				sizeof(struct gnttab_map_grant_ref),
    3.85 -				sizeof(struct gnttab_unmap_grant_ref),
    3.86 -				sizeof(struct gnttab_setup_table),
    3.87 -				sizeof(struct gnttab_dump_table),
    3.88 -				sizeof(struct gnttab_transfer),
    3.89 -			};
    3.90 -			va2 = (__u64)uop + (uop_size[cmd] * count) - 1;
    3.91 -			va2 &= PAGE_MASK;
    3.92 -			if (va1 != va2) {
    3.93 -				/* maximum size of uop is 2pages */
    3.94 -				BUG_ON(va2 > va1 + PAGE_SIZE);
    3.95 -				pa2 = ia64_tpa(va2);
    3.96 -			}
    3.97 -		}
    3.98 -	}
    3.99 -	return ____HYPERVISOR_grant_table_op(cmd, uop, count, pa1, pa2);
   3.100 +	return xencomm_mini_hypercall_grant_table_op(cmd, uop, count);
   3.101  }
   3.102  EXPORT_SYMBOL(HYPERVISOR_grant_table_op);
   3.103  
     4.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/util.c	Sun Oct 01 19:10:18 2006 -0600
     4.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/util.c	Mon Oct 02 14:03:42 2006 -0600
     4.3 @@ -28,6 +28,8 @@
     4.4  #include <linux/vmalloc.h>
     4.5  #include <asm/uaccess.h>
     4.6  #include <xen/driver_util.h>
     4.7 +#include <xen/interface/memory.h>
     4.8 +#include <asm/hypercall.h>
     4.9  
    4.10  struct vm_struct *alloc_vm_area(unsigned long size)
    4.11  {
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_hcall.c	Mon Oct 02 14:03:42 2006 -0600
     5.3 @@ -0,0 +1,468 @@
     5.4 +/*
     5.5 + * This program is free software; you can redistribute it and/or modify
     5.6 + * it under the terms of the GNU General Public License as published by
     5.7 + * the Free Software Foundation; either version 2 of the License, or
     5.8 + * (at your option) any later version.
     5.9 + *
    5.10 + * This program is distributed in the hope that it will be useful,
    5.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.13 + * GNU General Public License for more details.
    5.14 + *
    5.15 + * You should have received a copy of the GNU General Public License
    5.16 + * along with this program; if not, write to the Free Software
    5.17 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    5.18 + *
    5.19 + *          Tristan Gingold <tristan.gingold@bull.net>
    5.20 + */
    5.21 +#include <linux/types.h>
    5.22 +#include <linux/errno.h>
    5.23 +#include <linux/kernel.h>
    5.24 +#include <linux/gfp.h>
    5.25 +#include <linux/module.h>
    5.26 +#include <xen/interface/xen.h>
    5.27 +#include <xen/interface/dom0_ops.h>
    5.28 +#include <xen/interface/memory.h>
    5.29 +#include <xen/interface/xencomm.h>
    5.30 +#include <xen/interface/version.h>
    5.31 +#include <xen/interface/sched.h>
    5.32 +#include <xen/interface/event_channel.h>
    5.33 +#include <xen/interface/physdev.h>
    5.34 +#include <xen/interface/grant_table.h>
    5.35 +#include <xen/interface/callback.h>
    5.36 +#include <xen/interface/acm_ops.h>
    5.37 +#include <xen/interface/hvm/params.h>
    5.38 +#include <xen/public/privcmd.h>
    5.39 +#include <asm/hypercall.h>
    5.40 +#include <asm/page.h>
    5.41 +#include <asm/uaccess.h>
    5.42 +#include <asm/xen/xencomm.h>
    5.43 +
    5.44 +/* Xencomm notes:
    5.45 + * This file defines hypercalls to be used by xencomm.  The hypercalls simply
    5.46 + * create inlines descriptors for pointers and then call the raw arch hypercall
    5.47 + * xencomm_arch_hypercall_XXX
    5.48 + *
    5.49 + * If the arch wants to directly use these hypercalls, simply define macros
    5.50 + * in asm/hypercall.h, eg:
    5.51 + *  #define HYPERVISOR_sched_op xencomm_hypercall_sched_op
    5.52 + * 
    5.53 + * The arch may also define HYPERVISOR_xxx as a function and do more operations
    5.54 + * before/after doing the hypercall.
    5.55 + *
    5.56 + * Note: because only inline descriptors are created these functions must only
    5.57 + * be called with in kernel memory parameters.
    5.58 + */
    5.59 +
    5.60 +int
    5.61 +xencomm_hypercall_console_io(int cmd, int count, char *str)
    5.62 +{
    5.63 +	return xencomm_arch_hypercall_console_io
    5.64 +		(cmd, count, xencomm_create_inline(str));
    5.65 +}
    5.66 +
    5.67 +int
    5.68 +xencomm_hypercall_event_channel_op(int cmd, void *op)
    5.69 +{
    5.70 +	return xencomm_arch_hypercall_event_channel_op
    5.71 +		(cmd, xencomm_create_inline(op));
    5.72 +}
    5.73 +
    5.74 +int
    5.75 +xencomm_hypercall_xen_version(int cmd, void *arg)
    5.76 +{
    5.77 +	switch (cmd) {
    5.78 +	case XENVER_version:
    5.79 +	case XENVER_extraversion:
    5.80 +	case XENVER_compile_info:
    5.81 +	case XENVER_capabilities:
    5.82 +	case XENVER_changeset:
    5.83 +	case XENVER_platform_parameters:
    5.84 +	case XENVER_pagesize:
    5.85 +	case XENVER_get_features:
    5.86 +		break;
    5.87 +	default:
    5.88 +		printk("%s: unknown version cmd %d\n", __func__, cmd);
    5.89 +		return -ENOSYS;
    5.90 +	}
    5.91 +
    5.92 +	return xencomm_arch_hypercall_xen_version
    5.93 +		(cmd, xencomm_create_inline(arg));
    5.94 +}
    5.95 +
    5.96 +int
    5.97 +xencomm_hypercall_physdev_op(int cmd, void *op)
    5.98 +{
    5.99 +	return xencomm_arch_hypercall_physdev_op
   5.100 +		(cmd, xencomm_create_inline(op));
   5.101 +}
   5.102 +
   5.103 +static void *
   5.104 +xencommize_grant_table_op(unsigned int cmd, void *op, unsigned int count)
   5.105 +{
   5.106 +	switch (cmd) {
   5.107 +	case GNTTABOP_map_grant_ref:
   5.108 +	case GNTTABOP_unmap_grant_ref:
   5.109 +		break;
   5.110 +	case GNTTABOP_setup_table:
   5.111 +	{
   5.112 +		struct gnttab_setup_table *setup = op;
   5.113 +		struct xencomm_handle *frame_list;
   5.114 +
   5.115 +		frame_list = xencomm_create_inline
   5.116 +			(xen_guest_handle(setup->frame_list));
   5.117 +
   5.118 +		set_xen_guest_handle(setup->frame_list, (void *)frame_list);
   5.119 +		break;
   5.120 +	}
   5.121 +	case GNTTABOP_dump_table:
   5.122 +	case GNTTABOP_transfer:
   5.123 +		break;
   5.124 +	default:
   5.125 +		printk("%s: unknown grant table op %d\n", __func__, cmd);
   5.126 +		BUG();
   5.127 +	}
   5.128 +
   5.129 +	return  xencomm_create_inline(op);
   5.130 +}
   5.131 +
   5.132 +int
   5.133 +xencomm_hypercall_grant_table_op(unsigned int cmd, void *op, unsigned int count)
   5.134 +{
   5.135 +	void *desc = xencommize_grant_table_op (cmd, op, count);
   5.136 +
   5.137 +	return xencomm_arch_hypercall_grant_table_op(cmd, desc, count);
   5.138 +}
   5.139 +
   5.140 +int
   5.141 +xencomm_hypercall_sched_op(int cmd, void *arg)
   5.142 +{
   5.143 +	switch (cmd) {
   5.144 +	case SCHEDOP_yield:
   5.145 +	case SCHEDOP_block:
   5.146 +	case SCHEDOP_shutdown:
   5.147 +	case SCHEDOP_poll:
   5.148 +	case SCHEDOP_remote_shutdown:
   5.149 +		break;
   5.150 +	default:
   5.151 +		printk("%s: unknown sched op %d\n", __func__, cmd);
   5.152 +		return -ENOSYS;
   5.153 +	}
   5.154 +	
   5.155 +	return xencomm_arch_hypercall_sched_op(cmd, xencomm_create_inline(arg));
   5.156 +}
   5.157 +
   5.158 +int
   5.159 +xencomm_hypercall_multicall(void *call_list, int nr_calls)
   5.160 +{
   5.161 +	int i;
   5.162 +	multicall_entry_t *mce;
   5.163 +
   5.164 +	for (i = 0; i < nr_calls; i++) {
   5.165 +		mce = (multicall_entry_t *)call_list + i;
   5.166 +
   5.167 +		switch (mce->op) {
   5.168 +		case __HYPERVISOR_update_va_mapping:
   5.169 +		case __HYPERVISOR_mmu_update:
   5.170 +			/* No-op on ia64.  */
   5.171 +			break;
   5.172 +		case __HYPERVISOR_grant_table_op:
   5.173 +			mce->args[1] = (unsigned long)xencommize_grant_table_op
   5.174 +				(mce->args[0], (void *)mce->args[1],
   5.175 +				 mce->args[2]);
   5.176 +			break;
   5.177 +		case __HYPERVISOR_memory_op:
   5.178 +		default:
   5.179 +			printk("%s: unhandled multicall op entry op %lu\n",
   5.180 +			       __func__, mce->op);
   5.181 +			return -ENOSYS;
   5.182 +		}
   5.183 +	}
   5.184 +
   5.185 +	return xencomm_arch_hypercall_multicall
   5.186 +		(xencomm_create_inline(call_list), nr_calls);
   5.187 +}
   5.188 +
   5.189 +int
   5.190 +xencomm_hypercall_callback_op(int cmd, void *arg)
   5.191 +{
   5.192 +	switch (cmd)
   5.193 +	{
   5.194 +	case CALLBACKOP_register:
   5.195 +	case CALLBACKOP_unregister:
   5.196 +		break;
   5.197 +	default:
   5.198 +		printk("%s: unknown callback op %d\n", __func__, cmd);
   5.199 +		return -ENOSYS;
   5.200 +	}
   5.201 +
   5.202 +	return xencomm_arch_hypercall_callback_op
   5.203 +		(cmd, xencomm_create_inline(arg));
   5.204 +}
   5.205 +
   5.206 +static void
   5.207 +xencommize_memory_reservation (xen_memory_reservation_t *mop)
   5.208 +{
   5.209 +	struct xencomm_handle *desc;
   5.210 +
   5.211 +	desc = xencomm_create_inline(xen_guest_handle(mop->extent_start));
   5.212 +	set_xen_guest_handle(mop->extent_start, (void *)desc);
   5.213 +}
   5.214 +
   5.215 +int
   5.216 +xencomm_hypercall_memory_op(unsigned int cmd, void *arg)
   5.217 +{
   5.218 +	switch (cmd) {
   5.219 +	case XENMEM_increase_reservation:
   5.220 +	case XENMEM_decrease_reservation:
   5.221 +	case XENMEM_populate_physmap:
   5.222 +		xencommize_memory_reservation((xen_memory_reservation_t *)arg);
   5.223 +		break;
   5.224 +		
   5.225 +	case XENMEM_maximum_ram_page:
   5.226 +		break;
   5.227 +
   5.228 +	case XENMEM_exchange:
   5.229 +		xencommize_memory_reservation
   5.230 +			(&((xen_memory_exchange_t *)arg)->in);
   5.231 +		xencommize_memory_reservation
   5.232 +			(&((xen_memory_exchange_t *)arg)->out);
   5.233 +		break;
   5.234 +
   5.235 +	default:
   5.236 +		printk("%s: unknown memory op %d\n", __func__, cmd);
   5.237 +		return -ENOSYS;
   5.238 +	}
   5.239 +
   5.240 +	return xencomm_arch_hypercall_memory_op
   5.241 +		(cmd, xencomm_create_inline(arg));
   5.242 +}
   5.243 +
   5.244 +unsigned long
   5.245 +xencomm_hypercall_hvm_op(int cmd, void *arg)
   5.246 +{
   5.247 +	switch (cmd) {
   5.248 +	case HVMOP_set_param:
   5.249 +	case HVMOP_get_param:
   5.250 +		break;
   5.251 +	default:
   5.252 +		printk("%s: unknown hvm op %d\n", __func__, cmd);
   5.253 +		return -ENOSYS;
   5.254 +	}
   5.255 +
   5.256 +	return xencomm_arch_hypercall_hvm_op(cmd, xencomm_create_inline(arg));
   5.257 +}
   5.258 +
   5.259 +int
   5.260 +xencomm_hypercall_suspend(unsigned long srec)
   5.261 +{
   5.262 +	struct sched_shutdown arg;
   5.263 +
   5.264 +	arg.reason = SHUTDOWN_suspend;
   5.265 +
   5.266 +	return xencomm_arch_hypercall_suspend(xencomm_create_inline(&arg));
   5.267 +}
   5.268 +
   5.269 +int
   5.270 +xencomm_mini_hypercall_event_channel_op(int cmd, void *op)
   5.271 +{
   5.272 +	struct xencomm_mini xc_area[2];
   5.273 +	int nbr_area = 2;
   5.274 +	struct xencomm_handle *desc;
   5.275 +	int rc;
   5.276 +
   5.277 +	rc = xencomm_create_mini(xc_area, &nbr_area,
   5.278 +	                         op, sizeof(evtchn_op_t), &desc);
   5.279 +	if (rc)
   5.280 +		return rc;
   5.281 +
   5.282 +	return xencomm_arch_hypercall_event_channel_op(cmd, desc);
   5.283 +}
   5.284 +EXPORT_SYMBOL(xencomm_mini_hypercall_event_channel_op);
   5.285 +
   5.286 +static int
   5.287 +xencommize_mini_grant_table_op(struct xencomm_mini *xc_area, int *nbr_area,
   5.288 +                               unsigned int cmd, void *op, unsigned int count,
   5.289 +                               struct xencomm_handle **desc)
   5.290 +{
   5.291 +	struct xencomm_handle *desc1;
   5.292 +	unsigned int argsize;
   5.293 +	int rc;
   5.294 +
   5.295 +	switch (cmd) {
   5.296 +	case GNTTABOP_map_grant_ref:
   5.297 +		argsize = sizeof(struct gnttab_map_grant_ref);
   5.298 +		break;
   5.299 +	case GNTTABOP_unmap_grant_ref:
   5.300 +		argsize = sizeof(struct gnttab_unmap_grant_ref);
   5.301 +		break;
   5.302 +	case GNTTABOP_setup_table:
   5.303 +	{
   5.304 +		struct gnttab_setup_table *setup = op;
   5.305 +
   5.306 +		argsize = sizeof(*setup);
   5.307 +
   5.308 +		if (count != 1)
   5.309 +			return -EINVAL;
   5.310 +		rc = xencomm_create_mini
   5.311 +			(xc_area, nbr_area,
   5.312 +			 xen_guest_handle(setup->frame_list),
   5.313 +			 setup->nr_frames 
   5.314 +			 * sizeof(*xen_guest_handle(setup->frame_list)),
   5.315 +			 &desc1);
   5.316 +		if (rc)
   5.317 +			return rc;
   5.318 +		set_xen_guest_handle(setup->frame_list, (void *)desc1);
   5.319 +		break;
   5.320 +	}
   5.321 +	case GNTTABOP_dump_table:
   5.322 +		argsize = sizeof(struct gnttab_dump_table);
   5.323 +		break;
   5.324 +	case GNTTABOP_transfer:
   5.325 +		argsize = sizeof(struct gnttab_transfer);
   5.326 +		break;
   5.327 +	default:
   5.328 +		printk("%s: unknown mini grant table op %d\n", __func__, cmd);
   5.329 +		BUG();
   5.330 +	}
   5.331 +
   5.332 +	rc = xencomm_create_mini(xc_area, nbr_area, op, count * argsize, desc);
   5.333 +	if (rc)
   5.334 +		return rc;
   5.335 +
   5.336 +	return 0;
   5.337 +}
   5.338 +
   5.339 +int
   5.340 +xencomm_mini_hypercall_grant_table_op(unsigned int cmd, void *op,
   5.341 +                                      unsigned int count)
   5.342 +{
   5.343 +	int rc;
   5.344 +	struct xencomm_handle *desc;
   5.345 +	int nbr_area = 2;
   5.346 +	struct xencomm_mini xc_area[2];
   5.347 +
   5.348 +	rc = xencommize_mini_grant_table_op(xc_area, &nbr_area,
   5.349 +	                                    cmd, op, count, &desc);
   5.350 +	if (rc)
   5.351 +		return rc;
   5.352 +
   5.353 +	return xencomm_arch_hypercall_grant_table_op(cmd, desc, count);
   5.354 +}
   5.355 +EXPORT_SYMBOL(xencomm_mini_hypercall_grant_table_op);
   5.356 +
   5.357 +int
   5.358 +xencomm_mini_hypercall_multicall(void *call_list, int nr_calls)
   5.359 +{
   5.360 +	int i;
   5.361 +	multicall_entry_t *mce;
   5.362 +	int nbr_area = 2 + nr_calls * 3;
   5.363 +	struct xencomm_mini xc_area[nbr_area];
   5.364 +	struct xencomm_handle *desc;
   5.365 +	int rc;
   5.366 +
   5.367 +	for (i = 0; i < nr_calls; i++) {
   5.368 +		mce = (multicall_entry_t *)call_list + i;
   5.369 +
   5.370 +		switch (mce->op) {
   5.371 +		case __HYPERVISOR_update_va_mapping:
   5.372 +		case __HYPERVISOR_mmu_update:
   5.373 +			/* No-op on ia64.  */
   5.374 +			break;
   5.375 +		case __HYPERVISOR_grant_table_op:
   5.376 +			rc = xencommize_mini_grant_table_op
   5.377 +				(xc_area, &nbr_area,
   5.378 +				 mce->args[0], (void *)mce->args[1],
   5.379 +				 mce->args[2], &desc);
   5.380 +			if (rc)
   5.381 +				return rc;
   5.382 +			mce->args[1] = (unsigned long)desc;
   5.383 +			break;
   5.384 +		case __HYPERVISOR_memory_op:
   5.385 +		default:
   5.386 +			printk("%s: unhandled multicall op entry op %lu\n",
   5.387 +			       __func__, mce->op);
   5.388 +			return -ENOSYS;
   5.389 +		}
   5.390 +	}
   5.391 +
   5.392 +	rc = xencomm_create_mini(xc_area, &nbr_area, call_list,
   5.393 +	                         nr_calls * sizeof(multicall_entry_t), &desc);
   5.394 +	if (rc)
   5.395 +		return rc;
   5.396 +
   5.397 +	return xencomm_arch_hypercall_multicall(desc, nr_calls);
   5.398 +}
   5.399 +EXPORT_SYMBOL(xencomm_mini_hypercall_multicall);
   5.400 +
   5.401 +static int
   5.402 +xencommize_mini_memory_reservation(struct xencomm_mini *area, int *nbr_area,
   5.403 +                                   xen_memory_reservation_t *mop)
   5.404 +{
   5.405 +	struct xencomm_handle *desc;
   5.406 +	int rc;
   5.407 +
   5.408 +	rc = xencomm_create_mini
   5.409 +		(area, nbr_area,
   5.410 +		 xen_guest_handle(mop->extent_start),
   5.411 +		 mop->nr_extents 
   5.412 +		 * sizeof(*xen_guest_handle(mop->extent_start)),
   5.413 +		 &desc);
   5.414 +	if (rc)
   5.415 +		return rc;
   5.416 +
   5.417 +	set_xen_guest_handle(mop->extent_start, (void *)desc);
   5.418 +
   5.419 +	return 0;
   5.420 +}
   5.421 +
   5.422 +int
   5.423 +xencomm_mini_hypercall_memory_op(unsigned int cmd, void *arg)
   5.424 +{
   5.425 +	int nbr_area = 4;
   5.426 +	struct xencomm_mini xc_area[4];
   5.427 +	struct xencomm_handle *desc;
   5.428 +	int rc;
   5.429 +	unsigned int argsize;
   5.430 +
   5.431 +	switch (cmd) {
   5.432 +	case XENMEM_increase_reservation:
   5.433 +	case XENMEM_decrease_reservation:
   5.434 +	case XENMEM_populate_physmap:
   5.435 +		argsize = sizeof(xen_memory_reservation_t);
   5.436 +		rc = xencommize_mini_memory_reservation
   5.437 +			(xc_area, &nbr_area, (xen_memory_reservation_t *)arg);
   5.438 +		if (rc)
   5.439 +			return rc;
   5.440 +		break;
   5.441 +		
   5.442 +	case XENMEM_maximum_ram_page:
   5.443 +		argsize = 0;
   5.444 +		break;
   5.445 +
   5.446 +	case XENMEM_exchange:
   5.447 +		argsize = sizeof(xen_memory_exchange_t);
   5.448 +		rc = xencommize_mini_memory_reservation
   5.449 +			(xc_area, &nbr_area,
   5.450 +			 &((xen_memory_exchange_t *)arg)->in);
   5.451 +		if (rc)
   5.452 +			return rc;
   5.453 +		rc = xencommize_mini_memory_reservation
   5.454 +			(xc_area, &nbr_area,
   5.455 +			 &((xen_memory_exchange_t *)arg)->out);
   5.456 +		if (rc)
   5.457 +			return rc;
   5.458 +		break;
   5.459 +
   5.460 +	default:
   5.461 +		printk("%s: unknown mini memory op %d\n", __func__, cmd);
   5.462 +		return -ENOSYS;
   5.463 +	}
   5.464 +
   5.465 +	rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc);
   5.466 +	if (rc)
   5.467 +		return rc;
   5.468 +
   5.469 +	return xencomm_arch_hypercall_memory_op(cmd, desc);
   5.470 +}
   5.471 +EXPORT_SYMBOL(xencomm_mini_hypercall_memory_op);
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c	Mon Oct 02 14:03:42 2006 -0600
     6.3 @@ -0,0 +1,573 @@
     6.4 +/*
     6.5 + * This program is free software; you can redistribute it and/or modify
     6.6 + * it under the terms of the GNU General Public License as published by
     6.7 + * the Free Software Foundation; either version 2 of the License, or
     6.8 + * (at your option) any later version.
     6.9 + *
    6.10 + * This program is distributed in the hope that it will be useful,
    6.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.13 + * GNU General Public License for more details.
    6.14 + *
    6.15 + * You should have received a copy of the GNU General Public License
    6.16 + * along with this program; if not, write to the Free Software
    6.17 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    6.18 + *
    6.19 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
    6.20 + *          Tristan Gingold <tristan.gingold@bull.net>
    6.21 + */
    6.22 +#include <linux/types.h>
    6.23 +#include <linux/errno.h>
    6.24 +#include <linux/kernel.h>
    6.25 +#include <linux/gfp.h>
    6.26 +#include <linux/module.h>
    6.27 +#include <xen/interface/xen.h>
    6.28 +#include <xen/interface/dom0_ops.h>
    6.29 +#define __XEN__
    6.30 +#include <xen/interface/domctl.h>
    6.31 +#include <xen/interface/sysctl.h>
    6.32 +#include <xen/interface/memory.h>
    6.33 +#include <xen/interface/version.h>
    6.34 +#include <xen/interface/event_channel.h>
    6.35 +#include <xen/interface/acm_ops.h>
    6.36 +#include <xen/interface/hvm/params.h>
    6.37 +#include <xen/public/privcmd.h>
    6.38 +#include <asm/hypercall.h>
    6.39 +#include <asm/page.h>
    6.40 +#include <asm/uaccess.h>
    6.41 +#include <asm/xen/xencomm.h>
    6.42 +
    6.43 +#define ROUND_DIV(v,s) (((v) + (s) - 1) / (s))
    6.44 +
    6.45 +static int
    6.46 +xencomm_privcmd_dom0_op(privcmd_hypercall_t *hypercall)
    6.47 +{
    6.48 +	dom0_op_t kern_op;
    6.49 +	dom0_op_t __user *user_op = (dom0_op_t __user *)hypercall->arg[0];
    6.50 +	struct xencomm_handle *op_desc;
    6.51 +	struct xencomm_handle *desc = NULL;
    6.52 +	int ret = 0;
    6.53 +
    6.54 +	if (copy_from_user(&kern_op, user_op, sizeof(dom0_op_t)))
    6.55 +		return -EFAULT;
    6.56 +
    6.57 +	if (kern_op.interface_version != DOM0_INTERFACE_VERSION)
    6.58 +		return -EACCES;
    6.59 +
    6.60 +	op_desc = xencomm_create_inline(&kern_op);
    6.61 +
    6.62 +	switch (kern_op.cmd) {
    6.63 +	default:
    6.64 +		printk("%s: unknown dom0 cmd %d\n", __func__, kern_op.cmd);
    6.65 +		return -ENOSYS;
    6.66 +	}
    6.67 +
    6.68 +	if (ret) {
    6.69 +		/* error mapping the nested pointer */
    6.70 +		return ret;
    6.71 +	}
    6.72 +
    6.73 +	ret = xencomm_arch_hypercall_dom0_op(op_desc);
    6.74 +
    6.75 +	/* FIXME: should we restore the handle?  */
    6.76 +	if (copy_to_user(user_op, &kern_op, sizeof(dom0_op_t)))
    6.77 +		ret = -EFAULT;
    6.78 +
    6.79 +	if (desc)
    6.80 +		xencomm_free(desc);
    6.81 +	return ret;
    6.82 +}
    6.83 +
    6.84 +static int
    6.85 +xencomm_privcmd_sysctl(privcmd_hypercall_t *hypercall)
    6.86 +{
    6.87 +	xen_sysctl_t kern_op;
    6.88 +	xen_sysctl_t __user *user_op;
    6.89 +	struct xencomm_handle *op_desc;
    6.90 +	struct xencomm_handle *desc = NULL;
    6.91 +	struct xencomm_handle *desc1 = NULL;
    6.92 +	int ret = 0;
    6.93 +
    6.94 +	user_op = (xen_sysctl_t __user *)hypercall->arg[0];
    6.95 +
    6.96 +	if (copy_from_user(&kern_op, user_op, sizeof(xen_sysctl_t)))
    6.97 +		return -EFAULT;
    6.98 +
    6.99 +	if (kern_op.interface_version != XEN_SYSCTL_INTERFACE_VERSION)
   6.100 +		return -EACCES;
   6.101 +
   6.102 +	op_desc = xencomm_create_inline(&kern_op);
   6.103 +
   6.104 +	switch (kern_op.cmd) {
   6.105 +	case XEN_SYSCTL_readconsole:
   6.106 +		ret = xencomm_create(
   6.107 +			xen_guest_handle(kern_op.u.readconsole.buffer),
   6.108 +			kern_op.u.readconsole.count,
   6.109 +			&desc, GFP_KERNEL);
   6.110 +		set_xen_guest_handle(kern_op.u.readconsole.buffer,
   6.111 +		                     (void *)desc);
   6.112 +		break;
   6.113 +	case XEN_SYSCTL_tbuf_op:
   6.114 +	case XEN_SYSCTL_physinfo:
   6.115 +	case XEN_SYSCTL_sched_id:
   6.116 +		break;
   6.117 +	case XEN_SYSCTL_perfc_op:
   6.118 +		ret = xencomm_create(
   6.119 +			xen_guest_handle(kern_op.u.perfc_op.desc),
   6.120 +			kern_op.u.perfc_op.nr_counters *
   6.121 +			sizeof(xen_sysctl_perfc_desc_t),
   6.122 +			&desc, GFP_KERNEL);
   6.123 +		if (ret)
   6.124 +			return ret;
   6.125 +		set_xen_guest_handle(kern_op.u.perfc_op.val,
   6.126 +				     (void *)desc);
   6.127 +		ret = xencomm_create(
   6.128 +			xen_guest_handle(kern_op.u.perfc_op.val),
   6.129 +			kern_op.u.perfc_op.nr_vals *
   6.130 +			sizeof(xen_sysctl_perfc_desc_t),
   6.131 +			&desc1, GFP_KERNEL);
   6.132 +		if (ret)
   6.133 +			xencomm_free(desc);
   6.134 +		set_xen_guest_handle(kern_op.u.perfc_op.val,
   6.135 +				     (void *)desc1);
   6.136 +		break;
   6.137 +	case XEN_SYSCTL_getdomaininfolist:
   6.138 +		ret = xencomm_create(
   6.139 +			xen_guest_handle(kern_op.u.getdomaininfolist.buffer),
   6.140 +			kern_op.u.getdomaininfolist.max_domains *
   6.141 +			sizeof(xen_domctl_getdomaininfo_t),
   6.142 +			&desc, GFP_KERNEL);
   6.143 +		set_xen_guest_handle(kern_op.u.getdomaininfolist.buffer,
   6.144 +				     (void *)desc);
   6.145 +		break;
   6.146 +	default:
   6.147 +		printk("%s: unknown sysctl cmd %d\n", __func__, kern_op.cmd);
   6.148 +		return -ENOSYS;
   6.149 +	}
   6.150 +
   6.151 +	if (ret) {
   6.152 +		/* error mapping the nested pointer */
   6.153 +		return ret;
   6.154 +	}
   6.155 +
   6.156 +	ret = xencomm_arch_hypercall_sysctl(op_desc);
   6.157 +
   6.158 +	/* FIXME: should we restore the handle?  */
   6.159 +	if (copy_to_user(user_op, &kern_op, sizeof(xen_sysctl_t)))
   6.160 +		ret = -EFAULT;
   6.161 +
   6.162 +	if (desc)
   6.163 +		xencomm_free(desc);
   6.164 +	if (desc1)
   6.165 +		xencomm_free(desc1);
   6.166 +	return ret;
   6.167 +}
   6.168 +
   6.169 +static int
   6.170 +xencomm_privcmd_domctl(privcmd_hypercall_t *hypercall)
   6.171 +{
   6.172 +	xen_domctl_t kern_op;
   6.173 +	xen_domctl_t __user *user_op;
   6.174 +	struct xencomm_handle *op_desc;
   6.175 +	struct xencomm_handle *desc = NULL;
   6.176 +	int ret = 0;
   6.177 +
   6.178 +	user_op = (xen_domctl_t __user *)hypercall->arg[0];
   6.179 +
   6.180 +	if (copy_from_user(&kern_op, user_op, sizeof(xen_domctl_t)))
   6.181 +		return -EFAULT;
   6.182 +
   6.183 +	if (kern_op.interface_version != XEN_DOMCTL_INTERFACE_VERSION)
   6.184 +		return -EACCES;
   6.185 +
   6.186 +	op_desc = xencomm_create_inline(&kern_op);
   6.187 +
   6.188 +	switch (kern_op.cmd) {
   6.189 +	case XEN_DOMCTL_createdomain:
   6.190 +	case XEN_DOMCTL_destroydomain:
   6.191 +	case XEN_DOMCTL_pausedomain:
   6.192 +	case XEN_DOMCTL_unpausedomain:
   6.193 +	case XEN_DOMCTL_getdomaininfo:
   6.194 +		break;
   6.195 +	case XEN_DOMCTL_getmemlist:
   6.196 +	{
   6.197 +		unsigned long nr_pages = kern_op.u.getmemlist.max_pfns;
   6.198 +#ifdef __ia64__
   6.199 +		/* FIXME: Xen/ia64 pass first_page and nr_pages in max_pfns! */
   6.200 +		nr_pages &= 0xffffffff;
   6.201 +#endif
   6.202 +		ret = xencomm_create(
   6.203 +			xen_guest_handle(kern_op.u.getmemlist.buffer),
   6.204 +			nr_pages * sizeof(unsigned long),
   6.205 +			&desc, GFP_KERNEL);
   6.206 +		set_xen_guest_handle(kern_op.u.getmemlist.buffer,
   6.207 +		                     (void *)desc);
   6.208 +		break;
   6.209 +	}
   6.210 +	case XEN_DOMCTL_getpageframeinfo:
   6.211 +		break;
   6.212 +	case XEN_DOMCTL_getpageframeinfo2:
   6.213 +		ret = xencomm_create(
   6.214 +			xen_guest_handle(kern_op.u.getpageframeinfo2.array),
   6.215 +			kern_op.u.getpageframeinfo2.num,
   6.216 +			&desc, GFP_KERNEL);
   6.217 +		set_xen_guest_handle(kern_op.u.getpageframeinfo2.array,
   6.218 +		                     (void *)desc);
   6.219 +		break;
   6.220 +	case XEN_DOMCTL_shadow_op:
   6.221 +		ret = xencomm_create(
   6.222 +			xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap),
   6.223 +			ROUND_DIV(kern_op.u.shadow_op.pages, 8),
   6.224 +			&desc, GFP_KERNEL);
   6.225 +		set_xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap,
   6.226 +		                     (void *)desc);
   6.227 +		break;
   6.228 +	case XEN_DOMCTL_max_mem:
   6.229 +		break;
   6.230 +	case XEN_DOMCTL_setvcpucontext:
   6.231 +	case XEN_DOMCTL_getvcpucontext:
   6.232 +		ret = xencomm_create(
   6.233 +			xen_guest_handle(kern_op.u.vcpucontext.ctxt),
   6.234 +			sizeof(vcpu_guest_context_t),
   6.235 +			&desc, GFP_KERNEL);
   6.236 +		set_xen_guest_handle(kern_op.u.vcpucontext.ctxt, (void *)desc);
   6.237 +		break;
   6.238 +	case XEN_DOMCTL_getvcpuinfo:
   6.239 +		break;
   6.240 +	case XEN_DOMCTL_setvcpuaffinity:
   6.241 +	case XEN_DOMCTL_getvcpuaffinity:
   6.242 +		ret = xencomm_create(
   6.243 +			xen_guest_handle(kern_op.u.vcpuaffinity.cpumap.bitmap),
   6.244 +			ROUND_DIV(kern_op.u.vcpuaffinity.cpumap.nr_cpus, 8),
   6.245 +			&desc, GFP_KERNEL);
   6.246 +		set_xen_guest_handle(kern_op.u.vcpuaffinity.cpumap.bitmap,
   6.247 +		                     (void *)desc);
   6.248 +		break;
   6.249 +	case XEN_DOMCTL_max_vcpus:
   6.250 +	case XEN_DOMCTL_scheduler_op:
   6.251 +	case XEN_DOMCTL_setdomainhandle:
   6.252 +	case XEN_DOMCTL_setdebugging:
   6.253 +	case XEN_DOMCTL_irq_permission:
   6.254 +	case XEN_DOMCTL_iomem_permission:
   6.255 +	case XEN_DOMCTL_ioport_permission:
   6.256 +	case XEN_DOMCTL_hypercall_init:
   6.257 +	case XEN_DOMCTL_arch_setup:
   6.258 +	case XEN_DOMCTL_settimeoffset:
   6.259 +		break;
   6.260 +	default:
   6.261 +		printk("%s: unknown domctl cmd %d\n", __func__, kern_op.cmd);
   6.262 +		return -ENOSYS;
   6.263 +	}
   6.264 +
   6.265 +	if (ret) {
   6.266 +		/* error mapping the nested pointer */
   6.267 +		return ret;
   6.268 +	}
   6.269 +
   6.270 +	ret = xencomm_arch_hypercall_domctl (op_desc);
   6.271 +
   6.272 +	/* FIXME: should we restore the handle?  */
   6.273 +	if (copy_to_user(user_op, &kern_op, sizeof(xen_domctl_t)))
   6.274 +		ret = -EFAULT;
   6.275 +
   6.276 +	if (desc)
   6.277 +		xencomm_free(desc);
   6.278 +	return ret;
   6.279 +}
   6.280 +
   6.281 +static int
   6.282 +xencomm_privcmd_acm_op(privcmd_hypercall_t *hypercall)
   6.283 +{
   6.284 +	int cmd = hypercall->arg[0];
   6.285 +	void __user *arg = (void __user *)hypercall->arg[1];
   6.286 +	struct xencomm_handle *op_desc;
   6.287 +	struct xencomm_handle *desc = NULL;
   6.288 +	int ret;
   6.289 +
   6.290 +	switch (cmd) {
   6.291 +	case ACMOP_getssid:
   6.292 +	{
   6.293 +		struct acm_getssid kern_arg;
   6.294 +
   6.295 +		if (copy_from_user(&kern_arg, arg, sizeof (kern_arg)))
   6.296 +			return -EFAULT;
   6.297 +
   6.298 +		op_desc = xencomm_create_inline(&kern_arg);
   6.299 +
   6.300 +		ret = xencomm_create(xen_guest_handle(kern_arg.ssidbuf),
   6.301 +		                     kern_arg.ssidbuf_size, &desc, GFP_KERNEL);
   6.302 +		if (ret)
   6.303 +			return ret;
   6.304 +
   6.305 +		set_xen_guest_handle(kern_arg.ssidbuf, (void *)desc);
   6.306 +
   6.307 +		ret = xencomm_arch_hypercall_acm_op(cmd, op_desc);
   6.308 +
   6.309 +		xencomm_free(desc);
   6.310 +
   6.311 +		if (copy_to_user(arg, &kern_arg, sizeof (kern_arg)))
   6.312 +			return -EFAULT;
   6.313 +
   6.314 +		return ret;
   6.315 +	}
   6.316 +	default:
   6.317 +		printk("%s: unknown acm_op cmd %d\n", __func__, cmd);
   6.318 +		return -ENOSYS;
   6.319 +	}
   6.320 +
   6.321 +	return ret;
   6.322 +}
   6.323 +
   6.324 +static int
   6.325 +xencomm_privcmd_memory_op(privcmd_hypercall_t *hypercall)
   6.326 +{
   6.327 +	const unsigned long cmd = hypercall->arg[0];
   6.328 +	int ret = 0;
   6.329 +
   6.330 +	switch (cmd) {
   6.331 +	case XENMEM_increase_reservation:
   6.332 +	case XENMEM_decrease_reservation:
   6.333 +	case XENMEM_populate_physmap:
   6.334 +	{
   6.335 +		xen_memory_reservation_t kern_op;
   6.336 +		xen_memory_reservation_t __user *user_op;
   6.337 +		struct xencomm_handle *desc = NULL;
   6.338 +		struct xencomm_handle *desc_op;
   6.339 +
   6.340 +		user_op = (xen_memory_reservation_t __user *)hypercall->arg[1];
   6.341 +		if (copy_from_user(&kern_op, user_op,
   6.342 +		                   sizeof(xen_memory_reservation_t)))
   6.343 +			return -EFAULT;
   6.344 +		desc_op = xencomm_create_inline(&kern_op);
   6.345 +
   6.346 +		if (xen_guest_handle(kern_op.extent_start)) {
   6.347 +			void * addr;
   6.348 +
   6.349 +			addr = xen_guest_handle(kern_op.extent_start);
   6.350 +			ret = xencomm_create
   6.351 +				(addr,
   6.352 +				 kern_op.nr_extents *
   6.353 +				 sizeof(*xen_guest_handle
   6.354 +					(kern_op.extent_start)),
   6.355 +				 &desc, GFP_KERNEL);
   6.356 +			if (ret)
   6.357 +				return ret;
   6.358 +			set_xen_guest_handle(kern_op.extent_start,
   6.359 +			                     (void *)desc);
   6.360 +		}
   6.361 +
   6.362 +		ret = xencomm_arch_hypercall_memory_op(cmd, desc_op);
   6.363 +
   6.364 +		if (desc)
   6.365 +			xencomm_free(desc);
   6.366 +
   6.367 +		if (ret != 0)
   6.368 +			return ret;
   6.369 +
   6.370 +		if (copy_to_user(user_op, &kern_op,
   6.371 +		                 sizeof(xen_memory_reservation_t)))
   6.372 +			return -EFAULT;
   6.373 +
   6.374 +		return ret;
   6.375 +	}
   6.376 +	case XENMEM_translate_gpfn_list:
   6.377 +	{
   6.378 +		xen_translate_gpfn_list_t kern_op;
   6.379 +		xen_translate_gpfn_list_t __user *user_op;
   6.380 +		struct xencomm_handle *desc_gpfn = NULL;
   6.381 +		struct xencomm_handle *desc_mfn = NULL;
   6.382 +		struct xencomm_handle *desc_op;
   6.383 +		void *addr;
   6.384 +
   6.385 +		user_op = (xen_translate_gpfn_list_t __user *)
   6.386 +			hypercall->arg[1];
   6.387 +		if (copy_from_user(&kern_op, user_op,
   6.388 +		                   sizeof(xen_translate_gpfn_list_t)))
   6.389 +			return -EFAULT;
   6.390 +		desc_op = xencomm_create_inline(&kern_op);
   6.391 +
   6.392 +		if (kern_op.nr_gpfns) {
   6.393 +			/* gpfn_list.  */
   6.394 +			addr = xen_guest_handle(kern_op.gpfn_list);
   6.395 +
   6.396 +			ret = xencomm_create(addr, kern_op.nr_gpfns *
   6.397 +			                     sizeof(*xen_guest_handle
   6.398 +			                            (kern_op.gpfn_list)),
   6.399 +			                     &desc_gpfn, GFP_KERNEL);
   6.400 +			if (ret)
   6.401 +				return ret;
   6.402 +			set_xen_guest_handle(kern_op.gpfn_list,
   6.403 +			                     (void *)desc_gpfn);
   6.404 +
   6.405 +			/* mfn_list.  */
   6.406 +			addr = xen_guest_handle(kern_op.mfn_list);
   6.407 +
   6.408 +			ret = xencomm_create(addr, kern_op.nr_gpfns *
   6.409 +			                     sizeof(*xen_guest_handle
   6.410 +			                            (kern_op.mfn_list)),
   6.411 +			                     &desc_mfn, GFP_KERNEL);
   6.412 +			if (ret)
   6.413 +				return ret;
   6.414 +			set_xen_guest_handle(kern_op.mfn_list,
   6.415 +			                     (void *)desc_mfn);
   6.416 +		}
   6.417 +
   6.418 +		ret = xencomm_arch_hypercall_memory_op(cmd, desc_op);
   6.419 +
   6.420 +		if (desc_gpfn)
   6.421 +			xencomm_free(desc_gpfn);
   6.422 +
   6.423 +		if (desc_mfn)
   6.424 +			xencomm_free(desc_mfn);
   6.425 +
   6.426 +		if (ret != 0)
   6.427 +			return ret;
   6.428 +
   6.429 +		return ret;
   6.430 +	}
   6.431 +	default:
   6.432 +		printk("%s: unknown memory op %lu\n", __func__, cmd);
   6.433 +		ret = -ENOSYS;
   6.434 +	}
   6.435 +	return ret;
   6.436 +}
   6.437 +
   6.438 +static int
   6.439 +xencomm_privcmd_xen_version(privcmd_hypercall_t *hypercall)
   6.440 +{
   6.441 +	int cmd = hypercall->arg[0];
   6.442 +	void __user *arg = (void __user *)hypercall->arg[1];
   6.443 +	struct xencomm_handle *desc;
   6.444 +	size_t argsize;
   6.445 +	int rc;
   6.446 +
   6.447 +	switch (cmd) {
   6.448 +	case XENVER_version:
   6.449 +		/* do not actually pass an argument */
   6.450 +		return xencomm_arch_hypercall_xen_version(cmd, 0);
   6.451 +	case XENVER_extraversion:
   6.452 +		argsize = sizeof(xen_extraversion_t);
   6.453 +		break;
   6.454 +	case XENVER_compile_info:
   6.455 +		argsize = sizeof(xen_compile_info_t);
   6.456 +		break;
   6.457 +	case XENVER_capabilities:
   6.458 +		argsize = sizeof(xen_capabilities_info_t);
   6.459 +		break;
   6.460 +	case XENVER_changeset:
   6.461 +		argsize = sizeof(xen_changeset_info_t);
   6.462 +		break;
   6.463 +	case XENVER_platform_parameters:
   6.464 +		argsize = sizeof(xen_platform_parameters_t);
   6.465 +		break;
   6.466 +	case XENVER_pagesize:
   6.467 +		argsize = (arg == NULL) ? 0 : sizeof(void *);
   6.468 +		break;
   6.469 +	case XENVER_get_features:
   6.470 +		argsize = (arg == NULL) ? 0 : sizeof(xen_feature_info_t);
   6.471 +		break;
   6.472 +
   6.473 +	default:
   6.474 +		printk("%s: unknown version op %d\n", __func__, cmd);
   6.475 +		return -ENOSYS;
   6.476 +	}
   6.477 +
   6.478 +	rc = xencomm_create(arg, argsize, &desc, GFP_KERNEL);
   6.479 +	if (rc)
   6.480 +		return rc;
   6.481 +
   6.482 +	rc = xencomm_arch_hypercall_xen_version(cmd, desc);
   6.483 +
   6.484 +	xencomm_free(desc);
   6.485 +
   6.486 +	return rc;
   6.487 +}
   6.488 +
   6.489 +static int
   6.490 +xencomm_privcmd_event_channel_op(privcmd_hypercall_t *hypercall)
   6.491 +{
   6.492 +	int cmd = hypercall->arg[0];
   6.493 +	struct xencomm_handle *desc;
   6.494 +	unsigned int argsize;
   6.495 +	int ret;
   6.496 +
   6.497 +	switch (cmd) {
   6.498 +	case EVTCHNOP_alloc_unbound:
   6.499 +		argsize = sizeof(evtchn_alloc_unbound_t);
   6.500 +		break;
   6.501 +
   6.502 +	case EVTCHNOP_status:
   6.503 +		argsize = sizeof(evtchn_status_t);
   6.504 +		break;
   6.505 +
   6.506 +	default:
   6.507 +		printk("%s: unknown EVTCHNOP %d\n", __func__, cmd);
   6.508 +		return -EINVAL;
   6.509 +	}
   6.510 +
   6.511 +	ret = xencomm_create((void *)hypercall->arg[1], argsize,
   6.512 +	                     &desc, GFP_KERNEL);
   6.513 +	if (ret)
   6.514 +		return ret;
   6.515 +
   6.516 +	ret = xencomm_arch_hypercall_event_channel_op(cmd, desc);
   6.517 +
   6.518 +	xencomm_free(desc);
   6.519 +	return ret;
   6.520 +}
   6.521 +
   6.522 +static int
   6.523 +xencomm_privcmd_hvm_op(privcmd_hypercall_t *hypercall)
   6.524 +{
   6.525 +	int cmd = hypercall->arg[0];
   6.526 +	struct xencomm_handle *desc;
   6.527 +	unsigned int argsize;
   6.528 +	int ret;
   6.529 +
   6.530 +	switch (cmd) {
   6.531 +	case HVMOP_get_param:
   6.532 +	case HVMOP_set_param:
   6.533 +		argsize = sizeof(xen_hvm_param_t);
   6.534 +		break;
   6.535 +	default:
   6.536 +		printk("%s: unknown HVMOP %d\n", __func__, cmd);
   6.537 +		return -EINVAL;
   6.538 +	}
   6.539 +
   6.540 +	ret = xencomm_create((void *)hypercall->arg[1], argsize,
   6.541 +	                     &desc, GFP_KERNEL);
   6.542 +	if (ret)
   6.543 +		return ret;
   6.544 +
   6.545 +	ret = xencomm_arch_hypercall_hvm_op(cmd, desc);
   6.546 +
   6.547 +	xencomm_free(desc);
   6.548 +	return ret;
   6.549 +}
   6.550 +
   6.551 +int
   6.552 +privcmd_hypercall(privcmd_hypercall_t *hypercall)
   6.553 +{
   6.554 +	switch (hypercall->op) {
   6.555 +	case __HYPERVISOR_dom0_op:
   6.556 +		return xencomm_privcmd_dom0_op(hypercall);
   6.557 +	case __HYPERVISOR_domctl:
   6.558 +		return xencomm_privcmd_domctl(hypercall);
   6.559 +	case __HYPERVISOR_sysctl:
   6.560 +		return xencomm_privcmd_sysctl(hypercall);
   6.561 +        case __HYPERVISOR_acm_op:
   6.562 +		return xencomm_privcmd_acm_op(hypercall);
   6.563 +	case __HYPERVISOR_xen_version:
   6.564 +		return xencomm_privcmd_xen_version(hypercall);
   6.565 +	case __HYPERVISOR_memory_op:
   6.566 +		return xencomm_privcmd_memory_op(hypercall);
   6.567 +	case __HYPERVISOR_event_channel_op:
   6.568 +		return xencomm_privcmd_event_channel_op(hypercall);
   6.569 +	case __HYPERVISOR_hvm_op:
   6.570 +		return xencomm_privcmd_hvm_op(hypercall);
   6.571 +	default:
   6.572 +		printk("%s: unknown hcall (%ld)\n", __func__, hypercall->op);
   6.573 +		return -ENOSYS;
   6.574 +	}
   6.575 +}
   6.576 +
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xencomm.c	Mon Oct 02 14:03:42 2006 -0600
     7.3 @@ -0,0 +1,244 @@
     7.4 +/*
     7.5 + * Copyright (C) 2006 Hollis Blanchard <hollisb@us.ibm.com>, IBM Corporation
     7.6 + *
     7.7 + * This program is free software; you can redistribute it and/or modify
     7.8 + * it under the terms of the GNU General Public License as published by
     7.9 + * the Free Software Foundation; either version 2 of the License, or
    7.10 + * (at your option) any later version.
    7.11 + * 
    7.12 + * This program is distributed in the hope that it will be useful,
    7.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.15 + * GNU General Public License for more details.
    7.16 + * 
    7.17 + * You should have received a copy of the GNU General Public License
    7.18 + * along with this program; if not, write to the Free Software
    7.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
    7.20 + */
    7.21 +
    7.22 +#include <linux/gfp.h>
    7.23 +#include <linux/mm.h>
    7.24 +#include <asm/page.h>
    7.25 +#include <asm/xen/xencomm.h>
    7.26 +#include <xen/interface/xen.h>
    7.27 +
    7.28 +static int xencomm_debug = 0;
    7.29 +
    7.30 +/* Translate virtual address to physical address.  */
    7.31 +unsigned long
    7.32 +xencomm_vaddr_to_paddr(unsigned long vaddr)
    7.33 +{
    7.34 +	struct page *page;
    7.35 +	struct vm_area_struct *vma;
    7.36 +
    7.37 +	if (vaddr == 0)
    7.38 +		return 0;
    7.39 +
    7.40 +#ifdef __ia64__
    7.41 +	if (REGION_NUMBER(vaddr) == 5) {
    7.42 +		pgd_t *pgd;
    7.43 +		pud_t *pud;
    7.44 +		pmd_t *pmd;
    7.45 +		pte_t *ptep;
    7.46 +
    7.47 +		/* On ia64, TASK_SIZE refers to current.  It is not initialized
    7.48 +		   during boot.
    7.49 +		   Furthermore the kernel is relocatable and __pa() doesn't
    7.50 +		   work on  addresses.  */
    7.51 +		if (vaddr >= KERNEL_START
    7.52 +		    && vaddr < (KERNEL_START + KERNEL_TR_PAGE_SIZE)) {
    7.53 +			extern unsigned long kernel_start_pa;
    7.54 +			
    7.55 +			return vaddr - kernel_start_pa;
    7.56 +		}
    7.57 +
    7.58 +		/* In kernel area -- virtually mapped.  */
    7.59 +		pgd = pgd_offset_k(vaddr);
    7.60 +		if (pgd_none(*pgd) || pgd_bad(*pgd))
    7.61 +			return ~0UL;
    7.62 +
    7.63 +		pud = pud_offset(pgd, vaddr);
    7.64 +		if (pud_none(*pud) || pud_bad(*pud))
    7.65 +			return ~0UL;
    7.66 +
    7.67 +		pmd = pmd_offset(pud, vaddr);
    7.68 +		if (pmd_none(*pmd) || pmd_bad(*pmd))
    7.69 +			return ~0UL;
    7.70 +
    7.71 +		ptep = pte_offset_kernel(pmd, vaddr);
    7.72 +		if (!ptep)
    7.73 +			return ~0UL;
    7.74 +
    7.75 +		return (pte_val(*ptep) & _PFN_MASK) | (vaddr & ~PAGE_MASK);
    7.76 +	}
    7.77 +#endif
    7.78 +
    7.79 +	if (vaddr > TASK_SIZE) {
    7.80 +		/* kernel address */
    7.81 +		return __pa(vaddr);
    7.82 +	}
    7.83 +
    7.84 +	/* XXX double-check (lack of) locking */
    7.85 +	vma = find_extend_vma(current->mm, vaddr);
    7.86 +	if (!vma)
    7.87 +		return ~0UL;
    7.88 +
    7.89 +	/* We assume the page is modified.  */
    7.90 +	page = follow_page(vma, vaddr, FOLL_WRITE | FOLL_TOUCH);
    7.91 +	if (!page)
    7.92 +		return ~0UL;
    7.93 +
    7.94 +	return (page_to_pfn(page) << PAGE_SHIFT) | (vaddr & ~PAGE_MASK);
    7.95 +}
    7.96 +
    7.97 +static int
    7.98 +xencomm_init(struct xencomm_desc *desc, void *buffer, unsigned long bytes)
    7.99 +{
   7.100 +	unsigned long recorded = 0;
   7.101 +	int i = 0;
   7.102 +
   7.103 +	BUG_ON((buffer == NULL) && (bytes > 0));
   7.104 +
   7.105 +	/* record the physical pages used */
   7.106 +	if (buffer == NULL)
   7.107 +		desc->nr_addrs = 0;
   7.108 +
   7.109 +	while ((recorded < bytes) && (i < desc->nr_addrs)) {
   7.110 +		unsigned long vaddr = (unsigned long)buffer + recorded;
   7.111 +		unsigned long paddr;
   7.112 +		int offset;
   7.113 +		int chunksz;
   7.114 +
   7.115 +		offset = vaddr % PAGE_SIZE; /* handle partial pages */
   7.116 +		chunksz = min(PAGE_SIZE - offset, bytes - recorded);
   7.117 +
   7.118 +		paddr = xencomm_vaddr_to_paddr(vaddr);
   7.119 +		if (paddr == ~0UL) {
   7.120 +			printk("%s: couldn't translate vaddr %lx\n",
   7.121 +			       __func__, vaddr);
   7.122 +			return -EINVAL;
   7.123 +		}
   7.124 +
   7.125 +		desc->address[i++] = paddr;
   7.126 +		recorded += chunksz;
   7.127 +	}
   7.128 +
   7.129 +	if (recorded < bytes) {
   7.130 +		printk("%s: could only translate %ld of %ld bytes\n",
   7.131 +		       __func__, recorded, bytes);
   7.132 +		return -ENOSPC;
   7.133 +	}
   7.134 +
   7.135 +	/* mark remaining addresses invalid (just for safety) */
   7.136 +	while (i < desc->nr_addrs)
   7.137 +		desc->address[i++] = XENCOMM_INVALID;
   7.138 +
   7.139 +	desc->magic = XENCOMM_MAGIC;
   7.140 +
   7.141 +	return 0;
   7.142 +}
   7.143 +
   7.144 +static struct xencomm_desc *
   7.145 +xencomm_alloc(gfp_t gfp_mask)
   7.146 +{
   7.147 +	struct xencomm_desc *desc;
   7.148 +
   7.149 +	desc = (struct xencomm_desc *)__get_free_page(gfp_mask);
   7.150 +	if (desc == NULL)
   7.151 +		panic("%s: page allocation failed\n", __func__);
   7.152 +
   7.153 +	desc->nr_addrs = (PAGE_SIZE - sizeof(struct xencomm_desc)) /
   7.154 +	                 sizeof(*desc->address);
   7.155 +
   7.156 +	return desc;
   7.157 +}
   7.158 +
   7.159 +void
   7.160 +xencomm_free(struct xencomm_handle *desc)
   7.161 +{
   7.162 +	if (desc)
   7.163 +		free_page((unsigned long)__va(desc));
   7.164 +}
   7.165 +
   7.166 +int
   7.167 +xencomm_create(void *buffer, unsigned long bytes,
   7.168 +               struct xencomm_handle **ret, gfp_t gfp_mask)
   7.169 +{
   7.170 +	struct xencomm_desc *desc;
   7.171 +	struct xencomm_handle *handle;
   7.172 +	int rc;
   7.173 +
   7.174 +	if (xencomm_debug)
   7.175 +		printk("%s: %p[%ld]\n", __func__, buffer, bytes);
   7.176 +
   7.177 +	if (buffer == NULL || bytes == 0) {
   7.178 +		*ret = (struct xencomm_handle *)NULL;
   7.179 +		return 0;
   7.180 +	}
   7.181 +
   7.182 +	desc = xencomm_alloc(gfp_mask);
   7.183 +	if (!desc) {
   7.184 +		printk("%s failure\n", "xencomm_alloc");
   7.185 +		return -ENOMEM;
   7.186 +	}
   7.187 +	handle = (struct xencomm_handle *)__pa(desc);
   7.188 +
   7.189 +	rc = xencomm_init(desc, buffer, bytes);
   7.190 +	if (rc) {
   7.191 +		printk("%s failure: %d\n", "xencomm_init", rc);
   7.192 +		xencomm_free(handle);
   7.193 +		return rc;
   7.194 +	}
   7.195 +
   7.196 +	*ret = handle;
   7.197 +	return 0;
   7.198 +}
   7.199 +
   7.200 +/* "mini" routines, for stack-based communications: */
   7.201 +
   7.202 +static void *
   7.203 +xencomm_alloc_mini(struct xencomm_mini *area, int *nbr_area)
   7.204 +{
   7.205 +	unsigned long base;
   7.206 +	unsigned int pageoffset;
   7.207 +
   7.208 +	while (*nbr_area >= 0) {
   7.209 +		/* Allocate an area.  */
   7.210 +		(*nbr_area)--;
   7.211 +
   7.212 +		base = (unsigned long)(area + *nbr_area);
   7.213 +		pageoffset = base % PAGE_SIZE;
   7.214 +
   7.215 +		/* If the area does not cross a page, use it.  */
   7.216 +		if ((PAGE_SIZE - pageoffset) >= sizeof(struct xencomm_mini))
   7.217 +			return &area[*nbr_area];
   7.218 +	}
   7.219 +	/* No more area.  */
   7.220 +	return NULL;
   7.221 +}
   7.222 +
   7.223 +int
   7.224 +xencomm_create_mini(struct xencomm_mini *area, int *nbr_area,
   7.225 +                    void *buffer, unsigned long bytes,
   7.226 +                    struct xencomm_handle **ret)
   7.227 +{
   7.228 +	struct xencomm_desc *desc;
   7.229 +	int rc;
   7.230 +	unsigned long res;
   7.231 +
   7.232 +	desc = xencomm_alloc_mini(area, nbr_area);
   7.233 +	if (!desc)
   7.234 +		return -ENOMEM;
   7.235 +	desc->nr_addrs = XENCOMM_MINI_ADDRS;
   7.236 +
   7.237 +	rc = xencomm_init(desc, buffer, bytes);
   7.238 +	if (rc)
   7.239 +		return rc;
   7.240 +
   7.241 +	res = xencomm_vaddr_to_paddr((unsigned long)desc);
   7.242 +	if (res == ~0UL)
   7.243 +		return -EINVAL;
   7.244 +
   7.245 +	*ret = (struct xencomm_handle*)res;
   7.246 +	return 0;
   7.247 +}
     8.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/xensetup.S	Sun Oct 01 19:10:18 2006 -0600
     8.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xensetup.S	Mon Oct 02 14:03:42 2006 -0600
     8.3 @@ -37,18 +37,18 @@ END(early_xen_setup)
     8.4  
     8.5  /* Stub for suspend.
     8.6     Just force the stacked registers to be written in memory.  */	
     8.7 -GLOBAL_ENTRY(HYPERVISOR_suspend)
     8.8 +GLOBAL_ENTRY(xencomm_arch_hypercall_suspend)
     8.9 +	mov r15=r32
    8.10 +	;; 
    8.11  	alloc r20=ar.pfs,0,0,0,0
    8.12 -	mov r14=2
    8.13 -	mov r15=r12
    8.14 -	;;
    8.15 +	mov r2=__HYPERVISOR_sched_op
    8.16 +	;; 
    8.17  	/* We don't want to deal with RSE.  */
    8.18  	flushrs
    8.19 -	mov r2=__HYPERVISOR_sched_op
    8.20 -	st4 [r12]=r14
    8.21 +	mov r14=2 // SCHEDOP_shutdown
    8.22  	;;
    8.23  	break 0x1000
    8.24  	;; 
    8.25  	mov ar.pfs=r20
    8.26  	br.ret.sptk.many b0
    8.27 -END(HYPERVISOR_suspend)
    8.28 +END(xencomm_arch_hypercall_suspend)
     9.1 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Sun Oct 01 19:10:18 2006 -0600
     9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Mon Oct 02 14:03:42 2006 -0600
     9.3 @@ -83,18 +83,7 @@ static int privcmd_ioctl(struct inode *i
     9.4  				: "r8", "r10", "memory" );
     9.5  		}
     9.6  #elif defined (__ia64__)
     9.7 -		__asm__ __volatile__ (
     9.8 -			";; mov r14=%2; mov r15=%3; "
     9.9 -			"mov r16=%4; mov r17=%5; mov r18=%6;"
    9.10 -			"mov r2=%1; break 0x1000;; mov %0=r8 ;;"
    9.11 -			: "=r" (ret)
    9.12 -			: "r" (hypercall.op),
    9.13 -			"r" (hypercall.arg[0]),
    9.14 -			"r" (hypercall.arg[1]),
    9.15 -			"r" (hypercall.arg[2]),
    9.16 -			"r" (hypercall.arg[3]),
    9.17 -			"r" (hypercall.arg[4])
    9.18 -			: "r14","r15","r16","r17","r18","r2","r8","memory");
    9.19 +		ret = privcmd_hypercall(&hypercall);
    9.20  #endif
    9.21  	}
    9.22  	break;
    10.1 --- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h	Sun Oct 01 19:10:18 2006 -0600
    10.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h	Mon Oct 02 14:03:42 2006 -0600
    10.3 @@ -33,12 +33,13 @@
    10.4  #ifndef __HYPERCALL_H__
    10.5  #define __HYPERCALL_H__
    10.6  
    10.7 -#include <linux/string.h> /* memcpy() */
    10.8 -
    10.9  #ifndef __HYPERVISOR_H__
   10.10  # error "please don't include this file directly"
   10.11  #endif
   10.12  
   10.13 +#include <asm/xen/xcom_hcall.h>
   10.14 +struct xencomm_handle;
   10.15 +
   10.16  /*
   10.17   * Assembler stubs for hyper-calls.
   10.18   */
   10.19 @@ -157,159 +158,107 @@
   10.20  	(type)__res;                                            \
   10.21  })
   10.22  
   10.23 -static inline int
   10.24 -HYPERVISOR_sched_op_compat(
   10.25 -    int cmd, unsigned long arg)
   10.26 -{
   10.27 -	return _hypercall2(int, sched_op_compat, cmd, arg);
   10.28 -}
   10.29  
   10.30  static inline int
   10.31 -HYPERVISOR_sched_op(
   10.32 -	int cmd, void *arg)
   10.33 +xencomm_arch_hypercall_sched_op(int cmd, struct xencomm_handle *arg)
   10.34  {
   10.35  	return _hypercall2(int, sched_op, cmd, arg);
   10.36  }
   10.37  
   10.38  static inline long
   10.39 -HYPERVISOR_set_timer_op(
   10.40 -    u64 timeout)
   10.41 +HYPERVISOR_set_timer_op(u64 timeout)
   10.42  {
   10.43 -    unsigned long timeout_hi = (unsigned long)(timeout>>32);
   10.44 -    unsigned long timeout_lo = (unsigned long)timeout;
   10.45 -    return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
   10.46 +	unsigned long timeout_hi = (unsigned long)(timeout >> 32);
   10.47 +	unsigned long timeout_lo = (unsigned long)timeout;
   10.48 +	return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
   10.49  }
   10.50  
   10.51  static inline int
   10.52 -HYPERVISOR_dom0_op(
   10.53 -    dom0_op_t *dom0_op)
   10.54 +xencomm_arch_hypercall_dom0_op(struct xencomm_handle *op)
   10.55  {
   10.56 -    dom0_op->interface_version = DOM0_INTERFACE_VERSION;
   10.57 -    return _hypercall1(int, dom0_op, dom0_op);
   10.58 +	return _hypercall1(int, dom0_op, op);
   10.59  }
   10.60  
   10.61  static inline int
   10.62 -HYPERVISOR_multicall(
   10.63 -    void *call_list, int nr_calls)
   10.64 +xencomm_arch_hypercall_sysctl(struct xencomm_handle *op)
   10.65  {
   10.66 -    return _hypercall2(int, multicall, call_list, nr_calls);
   10.67 -}
   10.68 -
   10.69 -//XXX xen/ia64 copy_from_guest() is broken.
   10.70 -//    This is a temporal work around until it is fixed.
   10.71 -static inline int
   10.72 -____HYPERVISOR_memory_op(
   10.73 -    unsigned int cmd, void *arg)
   10.74 -{
   10.75 -    return _hypercall2(int, memory_op, cmd, arg);
   10.76 +	return _hypercall1(int, sysctl, op);
   10.77  }
   10.78  
   10.79 -#include <xen/interface/memory.h>
   10.80 -#ifdef CONFIG_VMX_GUEST
   10.81 -# define ia64_xenmem_reservation_op(op, xmr) (0)
   10.82 -#else
   10.83 -int ia64_xenmem_reservation_op(unsigned long op,
   10.84 -		   struct xen_memory_reservation* reservation__);
   10.85 -#endif
   10.86  static inline int
   10.87 -HYPERVISOR_memory_op(
   10.88 -    unsigned int cmd, void *arg)
   10.89 +xencomm_arch_hypercall_domctl(struct xencomm_handle *op)
   10.90  {
   10.91 -    switch (cmd) {
   10.92 -    case XENMEM_increase_reservation:
   10.93 -    case XENMEM_decrease_reservation:
   10.94 -    case XENMEM_populate_physmap:
   10.95 -        return ia64_xenmem_reservation_op(cmd, 
   10.96 -                                          (struct xen_memory_reservation*)arg);
   10.97 -    default:
   10.98 -        return ____HYPERVISOR_memory_op(cmd, arg);
   10.99 -    }
  10.100 -    /* NOTREACHED */
  10.101 +	return _hypercall1(int, domctl, op);
  10.102 +}
  10.103 +
  10.104 +static inline int
  10.105 +xencomm_arch_hypercall_multicall(struct xencomm_handle *call_list,
  10.106 +				 int nr_calls)
  10.107 +{
  10.108 +	return _hypercall2(int, multicall, call_list, nr_calls);
  10.109  }
  10.110  
  10.111  static inline int
  10.112 -HYPERVISOR_event_channel_op(
  10.113 -    int cmd, void *arg)
  10.114 +xencomm_arch_hypercall_memory_op(unsigned int cmd, struct xencomm_handle *arg)
  10.115  {
  10.116 -    int rc = _hypercall2(int, event_channel_op, cmd, arg);
  10.117 -    if (unlikely(rc == -ENOSYS)) {
  10.118 -        struct evtchn_op op;
  10.119 -        op.cmd = cmd;
  10.120 -        memcpy(&op.u, arg, sizeof(op.u));
  10.121 -        rc = _hypercall1(int, event_channel_op_compat, &op);
  10.122 -    }
  10.123 -    return rc;
  10.124 +	return _hypercall2(int, memory_op, cmd, arg);
  10.125  }
  10.126  
  10.127  static inline int
  10.128 -HYPERVISOR_acm_op(
  10.129 -	unsigned int cmd, void *arg)
  10.130 +xencomm_arch_hypercall_event_channel_op(int cmd, struct xencomm_handle *arg)
  10.131  {
  10.132 -    return _hypercall2(int, acm_op, cmd, arg);
  10.133 +	return _hypercall2(int, event_channel_op, cmd, arg);
  10.134  }
  10.135  
  10.136  static inline int
  10.137 -HYPERVISOR_xen_version(
  10.138 -    int cmd, void *arg)
  10.139 +xencomm_arch_hypercall_acm_op(unsigned int cmd, struct xencomm_handle *arg)
  10.140  {
  10.141 -    return _hypercall2(int, xen_version, cmd, arg);
  10.142 +	return _hypercall2(int, acm_op, cmd, arg);
  10.143  }
  10.144  
  10.145  static inline int
  10.146 -HYPERVISOR_console_io(
  10.147 -    int cmd, int count, char *str)
  10.148 +xencomm_arch_hypercall_xen_version(int cmd, struct xencomm_handle *arg)
  10.149  {
  10.150 -    return _hypercall3(int, console_io, cmd, count, str);
  10.151 +	return _hypercall2(int, xen_version, cmd, arg);
  10.152  }
  10.153  
  10.154  static inline int
  10.155 -HYPERVISOR_physdev_op(
  10.156 -    int cmd, void *arg)
  10.157 +xencomm_arch_hypercall_console_io(int cmd, int count,
  10.158 +                                  struct xencomm_handle *str)
  10.159  {
  10.160 -    int rc = _hypercall2(int, physdev_op, cmd, arg);
  10.161 -    if (unlikely(rc == -ENOSYS)) {
  10.162 -        struct physdev_op op;
  10.163 -        op.cmd = cmd;
  10.164 -        memcpy(&op.u, arg, sizeof(op.u));
  10.165 -        rc = _hypercall1(int, physdev_op_compat, &op);
  10.166 -    }
  10.167 -    return rc;
  10.168 +	return _hypercall3(int, console_io, cmd, count, str);
  10.169  }
  10.170  
  10.171 -//XXX __HYPERVISOR_grant_table_op is used for this hypercall constant.
  10.172  static inline int
  10.173 -____HYPERVISOR_grant_table_op(
  10.174 -    unsigned int cmd, void *uop, unsigned int count,
  10.175 -    unsigned long pa1, unsigned long pa2)
  10.176 +xencomm_arch_hypercall_physdev_op(int cmd, struct xencomm_handle *arg)
  10.177  {
  10.178 -    return _hypercall5(int, grant_table_op, cmd, uop, count, pa1, pa2);
  10.179 +	return _hypercall2(int, physdev_op, cmd, arg);
  10.180 +}
  10.181 +
  10.182 +static inline int
  10.183 +xencomm_arch_hypercall_grant_table_op(unsigned int cmd,
  10.184 +                                      struct xencomm_handle *uop,
  10.185 +                                      unsigned int count)
  10.186 +{
  10.187 +	return _hypercall3(int, grant_table_op, cmd, uop, count);
  10.188  }
  10.189  
  10.190  int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
  10.191  
  10.192 +extern int xencomm_arch_hypercall_suspend(struct xencomm_handle *arg);
  10.193 +
  10.194  static inline int
  10.195 -HYPERVISOR_vcpu_op(
  10.196 -	int cmd, int vcpuid, void *extra_args)
  10.197 +xencomm_arch_hypercall_callback_op(int cmd, struct xencomm_handle *arg)
  10.198  {
  10.199 -    return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
  10.200 +	return _hypercall2(int, callback_op, cmd, arg);
  10.201  }
  10.202  
  10.203 -extern int HYPERVISOR_suspend(unsigned long srec);
  10.204 -
  10.205  static inline unsigned long
  10.206 -HYPERVISOR_hvm_op(
  10.207 -	int cmd, void *arg)
  10.208 +xencomm_arch_hypercall_hvm_op(int cmd, void *arg)
  10.209  {
  10.210  	return _hypercall2(unsigned long, hvm_op, cmd, arg);
  10.211  }
  10.212  
  10.213 -static inline int
  10.214 -HYPERVISOR_callback_op(
  10.215 -	int cmd, void *arg)
  10.216 -{
  10.217 -	return _hypercall2(int, callback_op, cmd, arg);
  10.218 -}
  10.219 -
  10.220  extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
  10.221  static inline void exit_idle(void) {}
  10.222  #define do_IRQ(irq, regs) ({			\
  10.223 @@ -420,4 +369,33 @@ HYPERVISOR_add_physmap(unsigned long gpf
  10.224  // for balloon driver
  10.225  #define HYPERVISOR_update_va_mapping(va, new_val, flags) (0)
  10.226  
  10.227 +/* Use xencomm to do hypercalls.  */
  10.228 +#ifdef MODULE
  10.229 +#define HYPERVISOR_sched_op xencomm_mini_hypercall_sched_op
  10.230 +#define HYPERVISOR_event_channel_op xencomm_mini_hypercall_event_channel_op
  10.231 +#define HYPERVISOR_callback_op xencomm_mini_hypercall_callback_op
  10.232 +#define HYPERVISOR_multicall xencomm_mini_hypercall_multicall
  10.233 +#define HYPERVISOR_xen_version xencomm_mini_hypercall_xen_version
  10.234 +#define HYPERVISOR_console_io xencomm_mini_hypercall_console_io
  10.235 +#define HYPERVISOR_physdev_op xencomm_mini_hypercall_physdev_op
  10.236 +#define HYPERVISOR_hvm_op xencomm_mini_hypercall_hvm_op
  10.237 +#ifdef CONFIG_VMX_GUEST
  10.238 +#define HYPERVISOR_memory_op 0
  10.239 +#else
  10.240 +#define HYPERVISOR_memory_op xencomm_mini_hypercall_memory_op
  10.241 +#endif
  10.242 +#else
  10.243 +#define HYPERVISOR_sched_op xencomm_hypercall_sched_op
  10.244 +#define HYPERVISOR_event_channel_op xencomm_hypercall_event_channel_op
  10.245 +#define HYPERVISOR_callback_op xencomm_hypercall_callback_op
  10.246 +#define HYPERVISOR_multicall xencomm_hypercall_multicall
  10.247 +#define HYPERVISOR_xen_version xencomm_hypercall_xen_version
  10.248 +#define HYPERVISOR_console_io xencomm_hypercall_console_io
  10.249 +#define HYPERVISOR_physdev_op xencomm_hypercall_physdev_op
  10.250 +#define HYPERVISOR_hvm_op xencomm_hypercall_hvm_op
  10.251 +#define HYPERVISOR_memory_op xencomm_hypercall_memory_op
  10.252 +#endif
  10.253 +
  10.254 +#define HYPERVISOR_suspend xencomm_hypercall_suspend
  10.255 +
  10.256  #endif /* __HYPERCALL_H__ */
    11.1 --- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h	Sun Oct 01 19:10:18 2006 -0600
    11.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h	Mon Oct 02 14:03:42 2006 -0600
    11.3 @@ -75,9 +75,6 @@ HYPERVISOR_yield(
    11.4  {
    11.5  	int rc = HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
    11.6  
    11.7 -	if (rc == -ENOSYS)
    11.8 -		rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
    11.9 -
   11.10  	return rc;
   11.11  }
   11.12  
   11.13 @@ -87,9 +84,6 @@ HYPERVISOR_block(
   11.14  {
   11.15  	int rc = HYPERVISOR_sched_op(SCHEDOP_block, NULL);
   11.16  
   11.17 -	if (rc == -ENOSYS)
   11.18 -		rc = HYPERVISOR_sched_op_compat(SCHEDOP_block, 0);
   11.19 -
   11.20  	return rc;
   11.21  }
   11.22  
   11.23 @@ -103,9 +97,6 @@ HYPERVISOR_shutdown(
   11.24  
   11.25  	int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
   11.26  
   11.27 -	if (rc == -ENOSYS)
   11.28 -		rc = HYPERVISOR_sched_op_compat(SCHEDOP_shutdown, reason);
   11.29 -
   11.30  	return rc;
   11.31  }
   11.32  
   11.33 @@ -122,8 +113,6 @@ HYPERVISOR_poll(
   11.34  
   11.35  	set_xen_guest_handle(sched_poll.ports, ports);
   11.36  	rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
   11.37 -	if (rc == -ENOSYS)
   11.38 -		rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
   11.39  
   11.40  	return rc;
   11.41  }
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/xen/xcom_hcall.h	Mon Oct 02 14:03:42 2006 -0600
    12.3 @@ -0,0 +1,74 @@
    12.4 +/*
    12.5 + * Copyright (C) 2006 Tristan Gingold <tristan.gingold@bull.net>, Bull SAS
    12.6 + *
    12.7 + * This program is free software; you can redistribute it and/or modify
    12.8 + * it under the terms of the GNU General Public License as published by
    12.9 + * the Free Software Foundation; either version 2 of the License, or
   12.10 + * (at your option) any later version.
   12.11 + * 
   12.12 + * This program is distributed in the hope that it will be useful,
   12.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12.15 + * GNU General Public License for more details.
   12.16 + * 
   12.17 + * You should have received a copy of the GNU General Public License
   12.18 + * along with this program; if not, write to the Free Software
   12.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   12.20 + */
   12.21 +
   12.22 +#ifndef _LINUX_XENCOMM_HCALL_H_
   12.23 +#define _LINUX_XENCOMM_HCALL_H_
   12.24 +
   12.25 +/* These function creates inline descriptor for the parameters and
   12.26 +   calls the corresponding xencomm_arch_hypercall_X.
   12.27 +   Architectures should defines HYPERVISOR_xxx as xencomm_hypercall_xxx unless
   12.28 +   they want to use their own wrapper.  */
   12.29 +extern int xencomm_hypercall_console_io(int cmd, int count, char *str);
   12.30 +
   12.31 +extern int xencomm_hypercall_event_channel_op(int cmd, void *op);
   12.32 +
   12.33 +extern int xencomm_hypercall_xen_version(int cmd, void *arg);
   12.34 +
   12.35 +extern int xencomm_hypercall_physdev_op(int cmd, void *op);
   12.36 +
   12.37 +extern int xencomm_hypercall_grant_table_op(unsigned int cmd, void *op,
   12.38 +                                            unsigned int count);
   12.39 +
   12.40 +extern int xencomm_hypercall_sched_op(int cmd, void *arg);
   12.41 +
   12.42 +extern int xencomm_hypercall_multicall(void *call_list, int nr_calls);
   12.43 +
   12.44 +extern int xencomm_hypercall_callback_op(int cmd, void *arg);
   12.45 +
   12.46 +extern int xencomm_hypercall_memory_op(unsigned int cmd, void *arg);
   12.47 +
   12.48 +extern unsigned long xencomm_hypercall_hvm_op(int cmd, void *arg);
   12.49 +
   12.50 +extern int xencomm_hypercall_suspend(unsigned long srec);
   12.51 +
   12.52 +/* Using mini xencomm.  */
   12.53 +extern int xencomm_mini_hypercall_console_io(int cmd, int count, char *str);
   12.54 +
   12.55 +extern int xencomm_mini_hypercall_event_channel_op(int cmd, void *op);
   12.56 +
   12.57 +extern int xencomm_mini_hypercall_xen_version(int cmd, void *arg);
   12.58 +
   12.59 +extern int xencomm_mini_hypercall_physdev_op(int cmd, void *op);
   12.60 +
   12.61 +extern int xencomm_mini_hypercall_grant_table_op(unsigned int cmd, void *op,
   12.62 +                                                 unsigned int count);
   12.63 +
   12.64 +extern int xencomm_mini_hypercall_sched_op(int cmd, void *arg);
   12.65 +
   12.66 +extern int xencomm_mini_hypercall_multicall(void *call_list, int nr_calls);
   12.67 +
   12.68 +extern int xencomm_mini_hypercall_callback_op(int cmd, void *arg);
   12.69 +
   12.70 +extern int xencomm_mini_hypercall_memory_op(unsigned int cmd, void *arg);
   12.71 +
   12.72 +/* For privcmd.  Locally declare argument type to avoid include storm.
   12.73 +   Type coherency will be checked within privcmd.c  */
   12.74 +struct privcmd_hypercall;
   12.75 +extern int privcmd_hypercall(struct privcmd_hypercall *hypercall);
   12.76 +
   12.77 +#endif /* _LINUX_XENCOMM_HCALL_H_ */
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/xen/xencomm.h	Mon Oct 02 14:03:42 2006 -0600
    13.3 @@ -0,0 +1,57 @@
    13.4 +/*
    13.5 + * Copyright (C) 2006 Hollis Blanchard <hollisb@us.ibm.com>, IBM Corporation
    13.6 + *
    13.7 + * This program is free software; you can redistribute it and/or modify
    13.8 + * it under the terms of the GNU General Public License as published by
    13.9 + * the Free Software Foundation; either version 2 of the License, or
   13.10 + * (at your option) any later version.
   13.11 + * 
   13.12 + * This program is distributed in the hope that it will be useful,
   13.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13.15 + * GNU General Public License for more details.
   13.16 + * 
   13.17 + * You should have received a copy of the GNU General Public License
   13.18 + * along with this program; if not, write to the Free Software
   13.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   13.20 + */
   13.21 +
   13.22 +#ifndef _LINUX_XENCOMM_H_
   13.23 +#define _LINUX_XENCOMM_H_
   13.24 +
   13.25 +#include <xen/interface/xencomm.h>
   13.26 +
   13.27 +#define XENCOMM_MINI_ADDRS 3
   13.28 +struct xencomm_mini {
   13.29 +	struct xencomm_desc _desc;
   13.30 +	uint64_t address[XENCOMM_MINI_ADDRS];
   13.31 +};
   13.32 +
   13.33 +/* To avoid additionnal virt to phys conversion, an opaque structure is
   13.34 +   presented.  */
   13.35 +struct xencomm_handle;
   13.36 +
   13.37 +extern int xencomm_create(void *buffer, unsigned long bytes,
   13.38 +                          struct xencomm_handle **desc, gfp_t type);
   13.39 +extern void xencomm_free(struct xencomm_handle *desc);
   13.40 +
   13.41 +extern int xencomm_create_mini(struct xencomm_mini *area, int *nbr_area,
   13.42 +                               void *buffer, unsigned long bytes,
   13.43 +                               struct xencomm_handle **ret);
   13.44 +
   13.45 +/* Translate virtual address to physical address.  */
   13.46 +extern unsigned long xencomm_vaddr_to_paddr(unsigned long vaddr);
   13.47 +
   13.48 +/* Inline version.  To be used only on linear space (kernel space).  */
   13.49 +static inline struct xencomm_handle *
   13.50 +xencomm_create_inline(void *buffer)
   13.51 +{
   13.52 +	unsigned long paddr;
   13.53 +
   13.54 +	paddr = xencomm_vaddr_to_paddr((unsigned long)buffer);
   13.55 +	return (struct xencomm_handle *)(paddr | XENCOMM_INLINE_FLAG);
   13.56 +}
   13.57 +
   13.58 +#define xen_guest_handle(hnd)  ((hnd).p)
   13.59 +
   13.60 +#endif /* _LINUX_XENCOMM_H_ */
    14.1 --- a/tools/libxc/ia64/xc_ia64_linux_restore.c	Sun Oct 01 19:10:18 2006 -0600
    14.2 +++ b/tools/libxc/ia64/xc_ia64_linux_restore.c	Mon Oct 02 14:03:42 2006 -0600
    14.3 @@ -225,6 +225,9 @@ xc_linux_restore(int xc_handle, int io_f
    14.4          goto out;
    14.5      }
    14.6  
    14.7 +    fprintf(stderr, "ip=%016lx, b0=%016lx\n", ctxt.user_regs.cr_iip,
    14.8 +            ctxt.user_regs.b0);
    14.9 +
   14.10      /* First to initialize.  */
   14.11      domctl.cmd = XEN_DOMCTL_setvcpucontext;
   14.12      domctl.domain = (domid_t)dom;
    15.1 --- a/tools/libxc/ia64/xc_ia64_linux_save.c	Sun Oct 01 19:10:18 2006 -0600
    15.2 +++ b/tools/libxc/ia64/xc_ia64_linux_save.c	Mon Oct 02 14:03:42 2006 -0600
    15.3 @@ -458,6 +458,9 @@ xc_linux_save(int xc_handle, int io_fd, 
    15.4          goto out;
    15.5      }
    15.6  
    15.7 +    fprintf(stderr, "ip=%016lx, b0=%016lx\n", ctxt.user_regs.cr_iip,
    15.8 +            ctxt.user_regs.b0);
    15.9 +
   15.10      mem = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
   15.11                                 PROT_READ|PROT_WRITE, ctxt.privregs_pfn);
   15.12      if (mem == NULL) {
    16.1 --- a/xen/arch/ia64/xen/Makefile	Sun Oct 01 19:10:18 2006 -0600
    16.2 +++ b/xen/arch/ia64/xen/Makefile	Mon Oct 02 14:03:42 2006 -0600
    16.3 @@ -26,5 +26,6 @@ obj-y += xentime.o
    16.4  obj-y += flushd.o
    16.5  obj-y += privop_stat.o
    16.6  obj-y += xenpatch.o
    16.7 +obj-y += xencomm.o
    16.8  
    16.9  obj-$(crash_debug) += gdbstub.o
    17.1 --- a/xen/arch/ia64/xen/domain.c	Sun Oct 01 19:10:18 2006 -0600
    17.2 +++ b/xen/arch/ia64/xen/domain.c	Mon Oct 02 14:03:42 2006 -0600
    17.3 @@ -46,6 +46,7 @@
    17.4  #include <asm/regionreg.h>
    17.5  #include <asm/dom_fw.h>
    17.6  #include <asm/shadow.h>
    17.7 +#include <xen/guest_access.h>
    17.8  
    17.9  unsigned long dom0_size = 512*1024*1024;
   17.10  unsigned long dom0_align = 64*1024*1024;
    18.1 --- a/xen/arch/ia64/xen/faults.c	Sun Oct 01 19:10:18 2006 -0600
    18.2 +++ b/xen/arch/ia64/xen/faults.c	Mon Oct 02 14:03:42 2006 -0600
    18.3 @@ -228,10 +228,10 @@ void ia64_do_page_fault (unsigned long a
    18.4  			// indicate a bad xen pointer
    18.5  			printk("*** xen_handle_domain_access: exception table"
    18.6  			       " lookup failed, iip=0x%lx, addr=0x%lx, spinning...\n",
    18.7 -				iip, address);
    18.8 +			       iip, address);
    18.9  			panic_domain(regs,"*** xen_handle_domain_access: exception table"
   18.10 -			       " lookup failed, iip=0x%lx, addr=0x%lx, spinning...\n",
   18.11 -				iip, address);
   18.12 +				     " lookup failed, iip=0x%lx, addr=0x%lx, spinning...\n",
   18.13 +				     iip, address);
   18.14  		}
   18.15  		return;
   18.16  	}
    19.1 --- a/xen/arch/ia64/xen/fw_emul.c	Sun Oct 01 19:10:18 2006 -0600
    19.2 +++ b/xen/arch/ia64/xen/fw_emul.c	Mon Oct 02 14:03:42 2006 -0600
    19.3 @@ -16,7 +16,6 @@
    19.4   *
    19.5   */
    19.6  #include <xen/config.h>
    19.7 -#include <xen/console.h>
    19.8  #include <asm/system.h>
    19.9  #include <asm/pgalloc.h>
   19.10  
   19.11 @@ -29,6 +28,7 @@
   19.12  #include <asm/vcpu.h>
   19.13  #include <asm/dom_fw.h>
   19.14  #include <asm/uaccess.h>
   19.15 +#include <xen/console.h>
   19.16  
   19.17  extern unsigned long running_on_sim;
   19.18  
    20.1 --- a/xen/arch/ia64/xen/hypercall.c	Sun Oct 01 19:10:18 2006 -0600
    20.2 +++ b/xen/arch/ia64/xen/hypercall.c	Mon Oct 02 14:03:42 2006 -0600
    20.3 @@ -32,7 +32,6 @@
    20.4  #include <xen/event.h>
    20.5  #include <xen/perfc.h>
    20.6  
    20.7 -static long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop);
    20.8  static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg);
    20.9  static long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg);
   20.10  
   20.11 @@ -54,10 +53,10 @@ const hypercall_t ia64_hypercall_table[N
   20.12  	(hypercall_t)do_multicall,
   20.13  	(hypercall_t)do_ni_hypercall,		/* do_update_va_mapping */
   20.14  	(hypercall_t)do_ni_hypercall,		/* do_set_timer_op */  /* 15 */
   20.15 -	(hypercall_t)do_event_channel_op_compat,
   20.16 +	(hypercall_t)do_ni_hypercall,
   20.17  	(hypercall_t)do_xen_version,
   20.18  	(hypercall_t)do_console_io,
   20.19 -	(hypercall_t)do_physdev_op_compat,
   20.20 +	(hypercall_t)do_ni_hypercall,
   20.21  	(hypercall_t)do_grant_table_op,				       /* 20 */
   20.22  	(hypercall_t)do_ni_hypercall,		/* do_vm_assist */
   20.23  	(hypercall_t)do_ni_hypercall,		/* do_update_va_mapping_othe */
   20.24 @@ -108,19 +107,6 @@ static IA64FAULT
   20.25  xen_hypercall (struct pt_regs *regs)
   20.26  {
   20.27  	uint32_t cmd = (uint32_t)regs->r2;
   20.28 -	struct vcpu *v = current;
   20.29 -
   20.30 -	if (cmd == __HYPERVISOR_grant_table_op) {
   20.31 -		XEN_GUEST_HANDLE(void) uop;
   20.32 -
   20.33 -		v->arch.hypercall_param.va = regs->r15;
   20.34 -		v->arch.hypercall_param.pa1 = regs->r17;
   20.35 -		v->arch.hypercall_param.pa2 = regs->r18;
   20.36 -		set_xen_guest_handle(uop, (void *)regs->r15);
   20.37 -		regs->r8 = do_grant_table_op(regs->r14, uop, regs->r16);
   20.38 -		v->arch.hypercall_param.va = 0;
   20.39 -		return IA64_NO_FAULT;
   20.40 -	}
   20.41  
   20.42  	if (cmd < NR_hypercalls) {
   20.43  		perfc_incra(hypercalls, cmd);
   20.44 @@ -133,7 +119,7 @@ xen_hypercall (struct pt_regs *regs)
   20.45  			regs->r19);
   20.46  	} else
   20.47  		regs->r8 = -ENOSYS;
   20.48 -
   20.49 +	
   20.50  	return IA64_NO_FAULT;
   20.51  }
   20.52  
   20.53 @@ -465,28 +451,6 @@ static long do_physdev_op(int cmd, XEN_G
   20.54      return ret;
   20.55  }
   20.56  
   20.57 -/* Legacy hypercall (as of 0x00030202). */
   20.58 -static long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop)
   20.59 -{
   20.60 -    struct physdev_op op;
   20.61 -
   20.62 -    if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
   20.63 -        return -EFAULT;
   20.64 -
   20.65 -    return do_physdev_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void));
   20.66 -}
   20.67 -
   20.68 -/* Legacy hypercall (as of 0x00030202). */
   20.69 -long do_event_channel_op_compat(XEN_GUEST_HANDLE(evtchn_op_t) uop)
   20.70 -{
   20.71 -    struct evtchn_op op;
   20.72 -
   20.73 -    if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
   20.74 -        return -EFAULT;
   20.75 -
   20.76 -    return do_event_channel_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void));
   20.77 -}
   20.78 -
   20.79  static long register_guest_callback(struct callback_register *reg)
   20.80  {
   20.81      long ret = 0;
    21.1 --- a/xen/arch/ia64/xen/mm.c	Sun Oct 01 19:10:18 2006 -0600
    21.2 +++ b/xen/arch/ia64/xen/mm.c	Mon Oct 02 14:03:42 2006 -0600
    21.3 @@ -708,6 +708,22 @@ void *domain_mpa_to_imva(struct domain *
    21.4  }
    21.5  #endif
    21.6  
    21.7 +unsigned long
    21.8 +xencomm_paddr_to_maddr(unsigned long paddr)
    21.9 +{
   21.10 +    struct vcpu *v = current;
   21.11 +    struct domain *d = v->domain;
   21.12 +    u64 pa;
   21.13 +
   21.14 +    pa = ____lookup_domain_mpa(d, paddr);
   21.15 +    if (pa == INVALID_MFN) {
   21.16 +        printf("%s: called with bad memory address: 0x%lx - iip=%lx\n",
   21.17 +               __func__, paddr, vcpu_regs(v)->cr_iip);
   21.18 +        return 0;
   21.19 +    }
   21.20 +    return __va_ul((pa & _PFN_MASK) | (paddr & ~PAGE_MASK));
   21.21 +}
   21.22 +
   21.23  /* Allocate a new page for domain and map it to the specified metaphysical
   21.24     address.  */
   21.25  static struct page_info *
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/xen/arch/ia64/xen/xencomm.c	Mon Oct 02 14:03:42 2006 -0600
    22.3 @@ -0,0 +1,380 @@
    22.4 +/*
    22.5 + * This program is free software; you can redistribute it and/or modify
    22.6 + * it under the terms of the GNU General Public License as published by
    22.7 + * the Free Software Foundation; either version 2 of the License, or
    22.8 + * (at your option) any later version.
    22.9 + *
   22.10 + * This program is distributed in the hope that it will be useful,
   22.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   22.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   22.13 + * GNU General Public License for more details.
   22.14 + *
   22.15 + * You should have received a copy of the GNU General Public License
   22.16 + * along with this program; if not, write to the Free Software
   22.17 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   22.18 + *
   22.19 + * Copyright (C) IBM Corp. 2006
   22.20 + *
   22.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   22.22 + *          Tristan Gingold <tristan.gingold@bull.net>
   22.23 + */
   22.24 +
   22.25 +#include <xen/config.h>
   22.26 +#include <xen/mm.h>
   22.27 +#include <xen/sched.h>
   22.28 +#include <asm/current.h>
   22.29 +#include <asm/guest_access.h>
   22.30 +#include <public/xen.h>
   22.31 +#include <public/xencomm.h>
   22.32 +#include <xen/errno.h>
   22.33 +
   22.34 +#undef DEBUG
   22.35 +#ifdef DEBUG
   22.36 +static int xencomm_debug = 1; /* extremely verbose */
   22.37 +#else
   22.38 +#define xencomm_debug 0
   22.39 +#endif
   22.40 +
   22.41 +static int
   22.42 +xencomm_copy_chunk_from(
   22.43 +    unsigned long to,
   22.44 +    unsigned long paddr,
   22.45 +    unsigned int  len)
   22.46 +{
   22.47 +    unsigned long maddr;
   22.48 +    struct page_info *page;
   22.49 +
   22.50 +    while (1) {
   22.51 +	maddr = xencomm_paddr_to_maddr(paddr);
   22.52 +	if (xencomm_debug > 1)
   22.53 +	    printk("%lx[%d] -> %lx\n", maddr, len, to);
   22.54 +	if (maddr == 0)
   22.55 +	    return -EFAULT;
   22.56 +
   22.57 +	page = virt_to_page(maddr);
   22.58 +	if (get_page(page, current->domain) == 0) {
   22.59 +	    if (page_get_owner(page) != current->domain) {
   22.60 +		/* This page might be a page granted by another domain  */
   22.61 +		panic_domain(NULL, "copy_from_guest from foreign domain\n");
   22.62 +	    }
   22.63 +	    /* Try again.  */
   22.64 +	    continue;
   22.65 +	}
   22.66 +	memcpy((void *)to, (void *)maddr, len);
   22.67 +	put_page(page);
   22.68 +	return 0;
   22.69 +    }
   22.70 +}
   22.71 +
   22.72 +/**
   22.73 + * xencomm_copy_from_guest: Copy a block of data from domain space.
   22.74 + * @to:   Machine address.
   22.75 + * @from: Physical address to a xencomm buffer descriptor.
   22.76 + * @n:    Number of bytes to copy.
   22.77 + * @skip: Number of bytes from the start to skip.
   22.78 + *
   22.79 + * Copy data from domain to hypervisor.
   22.80 + *
   22.81 + * Returns number of bytes that could not be copied.
   22.82 + * On success, this will be zero.
   22.83 + */
   22.84 +unsigned long
   22.85 +xencomm_copy_from_guest(
   22.86 +    void         *to,
   22.87 +    const void   *from,
   22.88 +    unsigned int n,
   22.89 +    unsigned int skip)
   22.90 +{
   22.91 +    struct xencomm_desc *desc;
   22.92 +    unsigned long desc_addr;
   22.93 +    unsigned int from_pos = 0;
   22.94 +    unsigned int to_pos = 0;
   22.95 +    unsigned int i = 0;
   22.96 +
   22.97 +    if (xencomm_debug)
   22.98 +        printf("xencomm_copy_from_guest: from=%lx+%u n=%u\n",
   22.99 +               (unsigned long)from, skip, n);
  22.100 +
  22.101 +    if (XENCOMM_IS_INLINE(from)) {
  22.102 +        unsigned long src_paddr = XENCOMM_INLINE_ADDR(from);
  22.103 +            
  22.104 +        src_paddr += skip;
  22.105 +
  22.106 +        while (n > 0) {
  22.107 +            unsigned int chunksz;
  22.108 +            unsigned int bytes;
  22.109 +	    int res;
  22.110 +            
  22.111 +            chunksz = PAGE_SIZE - (src_paddr % PAGE_SIZE);
  22.112 +            
  22.113 +            bytes = min(chunksz, n);
  22.114 +
  22.115 +            res = xencomm_copy_chunk_from((unsigned long)to, src_paddr, bytes);
  22.116 +	    if (res != 0)
  22.117 +		return -EFAULT;
  22.118 +            src_paddr += bytes;
  22.119 +            to += bytes;
  22.120 +            n -= bytes;
  22.121 +        }
  22.122 +        
  22.123 +        /* Always successful.  */
  22.124 +        return 0;
  22.125 +    }
  22.126 +
  22.127 +    /* first we need to access the descriptor */
  22.128 +    desc_addr = xencomm_paddr_to_maddr((unsigned long)from);
  22.129 +    if (desc_addr == 0)
  22.130 +        return -EFAULT;
  22.131 +
  22.132 +    desc = (struct xencomm_desc *)desc_addr;
  22.133 +    if (desc->magic != XENCOMM_MAGIC) {
  22.134 +        printk("%s: error: %p magic was 0x%x\n",
  22.135 +               __func__, desc, desc->magic);
  22.136 +        return -EFAULT;
  22.137 +    }
  22.138 +
  22.139 +    /* iterate through the descriptor, copying up to a page at a time */
  22.140 +    while ((to_pos < n) && (i < desc->nr_addrs)) {
  22.141 +        unsigned long src_paddr = desc->address[i];
  22.142 +        unsigned int pgoffset;
  22.143 +        unsigned int chunksz;
  22.144 +        unsigned int chunk_skip;
  22.145 +
  22.146 +        if (src_paddr == XENCOMM_INVALID) {
  22.147 +            i++;
  22.148 +            continue;
  22.149 +        }
  22.150 +
  22.151 +        pgoffset = src_paddr % PAGE_SIZE;
  22.152 +        chunksz = PAGE_SIZE - pgoffset;
  22.153 +
  22.154 +        chunk_skip = min(chunksz, skip);
  22.155 +        from_pos += chunk_skip;
  22.156 +        chunksz -= chunk_skip;
  22.157 +        skip -= chunk_skip;
  22.158 +
  22.159 +        if (skip == 0) {
  22.160 +            unsigned int bytes = min(chunksz, n - to_pos);
  22.161 +	    int res;
  22.162 +
  22.163 +            if (xencomm_debug > 1)
  22.164 +                printf ("src_paddr=%lx i=%d, skip=%d\n",
  22.165 +                        src_paddr, i, chunk_skip);
  22.166 +
  22.167 +            res = xencomm_copy_chunk_from((unsigned long)to + to_pos,
  22.168 +                                          src_paddr + chunk_skip, bytes);
  22.169 +            if (res != 0)
  22.170 +                return -EFAULT;
  22.171 +
  22.172 +            from_pos += bytes;
  22.173 +            to_pos += bytes;
  22.174 +        }
  22.175 +
  22.176 +        i++;
  22.177 +    }
  22.178 +
  22.179 +    return n - to_pos;
  22.180 +}
  22.181 +
  22.182 +static int
  22.183 +xencomm_copy_chunk_to(
  22.184 +    unsigned long paddr,
  22.185 +    unsigned long from,
  22.186 +    unsigned int  len)
  22.187 +{
  22.188 +    unsigned long maddr;
  22.189 +    struct page_info *page;
  22.190 +
  22.191 +    while (1) {
  22.192 +	maddr = xencomm_paddr_to_maddr(paddr);
  22.193 +	if (xencomm_debug > 1)
  22.194 +	    printk("%lx[%d] -> %lx\n", from, len, maddr);
  22.195 +	if (maddr == 0)
  22.196 +	    return -EFAULT;
  22.197 +
  22.198 +	page = virt_to_page(maddr);
  22.199 +	if (get_page(page, current->domain) == 0) {
  22.200 +	    if (page_get_owner(page) != current->domain) {
  22.201 +		/* This page might be a page granted by another domain  */
  22.202 +		panic_domain(NULL, "copy_to_guest to foreign domain\n");
  22.203 +	    }
  22.204 +	    /* Try again.  */
  22.205 +	    continue;
  22.206 +	}
  22.207 +	memcpy((void *)maddr, (void *)from, len);
  22.208 +	put_page(page);
  22.209 +	return 0;
  22.210 +    }
  22.211 +}
  22.212 +
  22.213 +/**
  22.214 + * xencomm_copy_to_guest: Copy a block of data to domain space.
  22.215 + * @to:     Physical address to xencomm buffer descriptor.
  22.216 + * @from:   Machine address.
  22.217 + * @n:      Number of bytes to copy.
  22.218 + * @skip: Number of bytes from the start to skip.
  22.219 + *
  22.220 + * Copy data from hypervisor to domain.
  22.221 + *
  22.222 + * Returns number of bytes that could not be copied.
  22.223 + * On success, this will be zero.
  22.224 + */
  22.225 +unsigned long
  22.226 +xencomm_copy_to_guest(
  22.227 +    void         *to,
  22.228 +    const void   *from,
  22.229 +    unsigned int n,
  22.230 +    unsigned int skip)
  22.231 +{
  22.232 +    struct xencomm_desc *desc;
  22.233 +    unsigned long desc_addr;
  22.234 +    unsigned int from_pos = 0;
  22.235 +    unsigned int to_pos = 0;
  22.236 +    unsigned int i = 0;
  22.237 +
  22.238 +    if (xencomm_debug)
  22.239 +        printf ("xencomm_copy_to_guest: to=%lx+%u n=%u\n",
  22.240 +                (unsigned long)to, skip, n);
  22.241 +
  22.242 +    if (XENCOMM_IS_INLINE(to)) {
  22.243 +        unsigned long dest_paddr = XENCOMM_INLINE_ADDR(to);
  22.244 +            
  22.245 +        dest_paddr += skip;
  22.246 +
  22.247 +        while (n > 0) {
  22.248 +            unsigned int chunksz;
  22.249 +            unsigned int bytes;
  22.250 +            int res;
  22.251 +
  22.252 +            chunksz = PAGE_SIZE - (dest_paddr % PAGE_SIZE);
  22.253 +            
  22.254 +            bytes = min(chunksz, n);
  22.255 +
  22.256 +            res = xencomm_copy_chunk_to(dest_paddr, (unsigned long)from, bytes);
  22.257 +            if (res != 0)
  22.258 +                return res;
  22.259 +
  22.260 +            dest_paddr += bytes;
  22.261 +            from += bytes;
  22.262 +            n -= bytes;
  22.263 +        }
  22.264 +
  22.265 +        /* Always successful.  */
  22.266 +        return 0;
  22.267 +    }
  22.268 +
  22.269 +    /* first we need to access the descriptor */
  22.270 +    desc_addr = xencomm_paddr_to_maddr((unsigned long)to);
  22.271 +    if (desc_addr == 0)
  22.272 +        return -EFAULT;
  22.273 +
  22.274 +    desc = (struct xencomm_desc *)desc_addr;
  22.275 +    if (desc->magic != XENCOMM_MAGIC) {
  22.276 +        printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
  22.277 +        return -EFAULT;
  22.278 +    }
  22.279 +
  22.280 +    /* iterate through the descriptor, copying up to a page at a time */
  22.281 +    while ((from_pos < n) && (i < desc->nr_addrs)) {
  22.282 +        unsigned long dest_paddr = desc->address[i];
  22.283 +        unsigned int pgoffset;
  22.284 +        unsigned int chunksz;
  22.285 +        unsigned int chunk_skip;
  22.286 +
  22.287 +        if (dest_paddr == XENCOMM_INVALID) {
  22.288 +            i++;
  22.289 +            continue;
  22.290 +        }
  22.291 +
  22.292 +        pgoffset = dest_paddr % PAGE_SIZE;
  22.293 +        chunksz = PAGE_SIZE - pgoffset;
  22.294 +
  22.295 +        chunk_skip = min(chunksz, skip);
  22.296 +        to_pos += chunk_skip;
  22.297 +        chunksz -= chunk_skip;
  22.298 +        skip -= chunk_skip;
  22.299 +        dest_paddr += chunk_skip;
  22.300 +
  22.301 +        if (skip == 0) {
  22.302 +            unsigned int bytes = min(chunksz, n - from_pos);
  22.303 +            int res;
  22.304 +
  22.305 +            res = xencomm_copy_chunk_to(dest_paddr,
  22.306 +                                        (unsigned long)from + from_pos, bytes);
  22.307 +            if (res != 0)
  22.308 +                return res;
  22.309 +
  22.310 +            from_pos += bytes;
  22.311 +            to_pos += bytes;
  22.312 +        }
  22.313 +
  22.314 +        i++;
  22.315 +    }
  22.316 +    return n - from_pos;
  22.317 +}
  22.318 +
  22.319 +/* Offset page addresses in 'handle' to skip 'bytes' bytes. Set completely
  22.320 + * exhausted pages to XENCOMM_INVALID. */
  22.321 +void *
  22.322 +xencomm_add_offset(
  22.323 +    void         *handle,
  22.324 +    unsigned int bytes)
  22.325 +{
  22.326 +    struct xencomm_desc *desc;
  22.327 +    unsigned long desc_addr;
  22.328 +    int i = 0;
  22.329 +
  22.330 +    if (XENCOMM_IS_INLINE(handle))
  22.331 +        return (void *)((unsigned long)handle + bytes);
  22.332 +
  22.333 +    /* first we need to access the descriptor */
  22.334 +    desc_addr = xencomm_paddr_to_maddr((unsigned long)handle);
  22.335 +    if (desc_addr == 0)
  22.336 +        return NULL;
  22.337 +
  22.338 +    desc = (struct xencomm_desc *)desc_addr;
  22.339 +    if (desc->magic != XENCOMM_MAGIC) {
  22.340 +        printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
  22.341 +        return NULL;
  22.342 +    }
  22.343 +
  22.344 +    /* iterate through the descriptor incrementing addresses */
  22.345 +    while ((bytes > 0) && (i < desc->nr_addrs)) {
  22.346 +        unsigned long dest_paddr = desc->address[i];
  22.347 +        unsigned int pgoffset;
  22.348 +        unsigned int chunksz;
  22.349 +        unsigned int chunk_skip;
  22.350 +
  22.351 +        pgoffset = dest_paddr % PAGE_SIZE;
  22.352 +        chunksz = PAGE_SIZE - pgoffset;
  22.353 +
  22.354 +        chunk_skip = min(chunksz, bytes);
  22.355 +        if (chunk_skip == chunksz) {
  22.356 +            /* exhausted this page */
  22.357 +            desc->address[i] = XENCOMM_INVALID;
  22.358 +        } else {
  22.359 +            desc->address[i] += chunk_skip;
  22.360 +        }
  22.361 +        bytes -= chunk_skip;
  22.362 +    }
  22.363 +    return handle;
  22.364 +}
  22.365 +
  22.366 +int
  22.367 +xencomm_handle_is_null(
  22.368 +   void *ptr)
  22.369 +{
  22.370 +    if (XENCOMM_IS_INLINE(ptr))
  22.371 +        return XENCOMM_INLINE_ADDR(ptr) == 0;
  22.372 +    else {
  22.373 +        struct xencomm_desc *desc;
  22.374 +        unsigned long desc_addr;
  22.375 +
  22.376 +        desc_addr = xencomm_paddr_to_maddr((unsigned long)ptr);
  22.377 +        if (desc_addr == 0)
  22.378 +            return 1;
  22.379 +
  22.380 +        desc = (struct xencomm_desc *)desc_addr;
  22.381 +        return (desc->address[0] == XENCOMM_INVALID);
  22.382 +    }
  22.383 +}
    23.1 --- a/xen/include/asm-ia64/guest_access.h	Sun Oct 01 19:10:18 2006 -0600
    23.2 +++ b/xen/include/asm-ia64/guest_access.h	Mon Oct 02 14:03:42 2006 -0600
    23.3 @@ -1,91 +1,107 @@
    23.4 -/******************************************************************************
    23.5 - * guest_access.h
    23.6 - * 
    23.7 - * Copyright (c) 2006, K A Fraser
    23.8 +/*
    23.9 + * This program is free software; you can redistribute it and/or modify
   23.10 + * it under the terms of the GNU General Public License as published by
   23.11 + * the Free Software Foundation; either version 2 of the License, or
   23.12 + * (at your option) any later version.
   23.13 + *
   23.14 + * This program is distributed in the hope that it will be useful,
   23.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   23.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   23.17 + * GNU General Public License for more details.
   23.18 + *
   23.19 + * You should have received a copy of the GNU General Public License
   23.20 + * along with this program; if not, write to the Free Software
   23.21 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   23.22 + *
   23.23 + * Copyright (C) IBM Corp. 2006
   23.24 + *
   23.25 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   23.26 + *          Tristan Gingold <tristan.gingold@bull.net>
   23.27   */
   23.28  
   23.29 -#ifndef __ASM_IA64_GUEST_ACCESS_H__
   23.30 -#define __ASM_IA64_GUEST_ACCESS_H__
   23.31 +#ifndef __ASM_GUEST_ACCESS_H__
   23.32 +#define __ASM_GUEST_ACCESS_H__
   23.33  
   23.34 -#include <asm/uaccess.h>
   23.35 +extern unsigned long xencomm_copy_to_guest(void *to, const void *from,
   23.36 +        unsigned int len, unsigned int skip); 
   23.37 +extern unsigned long xencomm_copy_from_guest(void *to, const void *from,
   23.38 +        unsigned int len, unsigned int skip); 
   23.39 +extern void *xencomm_add_offset(void *handle, unsigned int bytes);
   23.40 +extern int xencomm_handle_is_null(void *ptr);
   23.41 +
   23.42  
   23.43  /* Is the guest handle a NULL reference? */
   23.44 -#define guest_handle_is_null(hnd)        ((hnd).p == NULL)
   23.45 +#define guest_handle_is_null(hnd)                          \
   23.46 +    ((hnd).p == NULL || xencomm_handle_is_null((hnd).p))
   23.47  
   23.48  /* Offset the given guest handle into the array it refers to. */
   23.49 -#define guest_handle_add_offset(hnd, nr) ((hnd).p += (nr))
   23.50 +#define guest_handle_add_offset(hnd, nr) ({                   \
   23.51 +    const typeof((hnd).p) _ptr = (hnd).p;                     \
   23.52 +    (hnd).p = xencomm_add_offset(_ptr, nr * sizeof(*_ptr));   \
   23.53 +})
   23.54  
   23.55  /* Cast a guest handle to the specified type of handle. */
   23.56 -#define guest_handle_cast(hnd, type) ({         \
   23.57 -    type *_x = (hnd).p;                         \
   23.58 -    (XEN_GUEST_HANDLE(type)) { _x };                \
   23.59 +#define guest_handle_cast(hnd, type) ({   \
   23.60 +    type *_x = (hnd).p;                   \
   23.61 +    XEN_GUEST_HANDLE(type) _y;            \
   23.62 +    set_xen_guest_handle(_y, _x);         \
   23.63 +    _y;                                   \
   23.64  })
   23.65  
   23.66 -#define guest_handle_from_ptr(ptr, type) ((XEN_GUEST_HANDLE(type)) { (type *)ptr })
   23.67 +
   23.68 +/* Since we run in real mode, we can safely access all addresses. That also
   23.69 + * means our __routines are identical to our "normal" routines. */
   23.70 +#define guest_handle_okay(hnd, nr) 1
   23.71  
   23.72  /*
   23.73 - * Copy an array of objects to guest context via a guest handle,
   23.74 - * specifying an offset into the guest array.
   23.75 + * Copy an array of objects to guest context via a guest handle.
   23.76 + * Optionally specify an offset into the guest array.
   23.77   */
   23.78 -#define copy_to_guest_offset(hnd, off, ptr, nr) ({      \
   23.79 -    const typeof(ptr) _x = (hnd).p;                     \
   23.80 -    const typeof(ptr) _y = (ptr);                       \
   23.81 -    copy_to_user(_x+(off), _y, sizeof(*_x)*(nr));       \
   23.82 -})
   23.83 -
   23.84 -/*
   23.85 - * Copy an array of objects from guest context via a guest handle,
   23.86 - * specifying an offset into the guest array.
   23.87 - */
   23.88 -#define copy_from_guest_offset(ptr, hnd, off, nr) ({    \
   23.89 -    const typeof(ptr) _x = (hnd).p;                     \
   23.90 -    const typeof(ptr) _y = (ptr);                       \
   23.91 -    copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));     \
   23.92 -})
   23.93 +#define copy_to_guest_offset(hnd, idx, ptr, nr) \
   23.94 +    __copy_to_guest_offset(hnd, idx, ptr, nr)
   23.95  
   23.96  /* Copy sub-field of a structure to guest context via a guest handle. */
   23.97 -#define copy_field_to_guest(hnd, ptr, field) ({         \
   23.98 -    const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
   23.99 -    const typeof(&(ptr)->field) _y = &(ptr)->field;     \
  23.100 -    copy_to_user(_x, _y, sizeof(*_x));                  \
  23.101 -})
  23.102 -
  23.103 -/* Copy sub-field of a structure from guest context via a guest handle. */
  23.104 -#define copy_field_from_guest(ptr, hnd, field) ({       \
  23.105 -    const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
  23.106 -    const typeof(&(ptr)->field) _y = &(ptr)->field;     \
  23.107 -    copy_from_user(_y, _x, sizeof(*_x));                \
  23.108 -})
  23.109 +#define copy_field_to_guest(hnd, ptr, field) \
  23.110 +    __copy_field_to_guest(hnd, ptr, field)
  23.111  
  23.112  /*
  23.113 - * Pre-validate a guest handle.
  23.114 - * Allows use of faster __copy_* functions.
  23.115 + * Copy an array of objects from guest context via a guest handle.
  23.116 + * Optionally specify an offset into the guest array.
  23.117   */
  23.118 -#define guest_handle_okay(hnd, nr)                      \
  23.119 -    array_access_ok((hnd).p, (nr), sizeof(*(hnd).p))
  23.120 +#define copy_from_guest_offset(ptr, hnd, idx, nr) \
  23.121 +    __copy_from_guest_offset(ptr, hnd, idx, nr)
  23.122  
  23.123 -#define __copy_to_guest_offset(hnd, off, ptr, nr) ({    \
  23.124 -    const typeof(ptr) _x = (hnd).p;                     \
  23.125 -    const typeof(ptr) _y = (ptr);                       \
  23.126 -    __copy_to_user(_x+(off), _y, sizeof(*_x)*(nr));     \
  23.127 +/* Copy sub-field of a structure from guest context via a guest handle. */
  23.128 +#define copy_field_from_guest(ptr, hnd, field) \
  23.129 +    __copy_field_from_guest(ptr, hnd, field)
  23.130 +
  23.131 +#define __copy_to_guest_offset(hnd, idx, ptr, nr) ({                    \
  23.132 +    const typeof(ptr) _d = (hnd).p;                                     \
  23.133 +    const typeof(ptr) _s = (ptr);                                       \
  23.134 +    xencomm_copy_to_guest(_d, _s, sizeof(*_s)*(nr), sizeof(*_s)*(idx)); \
  23.135  })
  23.136  
  23.137 -#define __copy_from_guest_offset(ptr, hnd, off, nr) ({  \
  23.138 -    const typeof(ptr) _x = (hnd).p;                     \
  23.139 -    const typeof(ptr) _y = (ptr);                       \
  23.140 -    __copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));   \
  23.141 +#define __copy_field_to_guest(hnd, ptr, field) ({                   \
  23.142 +    const int _off = offsetof(typeof(*ptr), field);                 \
  23.143 +    const typeof(ptr) _d = (hnd).p;                                 \
  23.144 +    const typeof(&(ptr)->field) _s = &(ptr)->field;                 \
  23.145 +    xencomm_copy_to_guest(_d, _s, sizeof(*_s), _off);               \
  23.146  })
  23.147  
  23.148 -#define __copy_field_to_guest(hnd, ptr, field) ({       \
  23.149 -    const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
  23.150 -    const typeof(&(ptr)->field) _y = &(ptr)->field;     \
  23.151 -    __copy_to_user(_x, _y, sizeof(*_x));                \
  23.152 +#define __copy_from_guest_offset(ptr, hnd, idx, nr) ({                     \
  23.153 +    const typeof(ptr) _s = (hnd).p;                                        \
  23.154 +    const typeof(ptr) _d = (ptr);                                          \
  23.155 +    xencomm_copy_from_guest(_d, _s, sizeof(*_s)*(nr), sizeof(*_s)*(idx));  \
  23.156  })
  23.157  
  23.158 -#define __copy_field_from_guest(ptr, hnd, field) ({     \
  23.159 -    const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
  23.160 -    const typeof(&(ptr)->field) _y = &(ptr)->field;     \
  23.161 -    __copy_from_user(_y, _x, sizeof(*_x));              \
  23.162 +#define __copy_field_from_guest(ptr, hnd, field) ({                 \
  23.163 +    const int _off = offsetof(typeof(*ptr), field);                 \
  23.164 +    const typeof(ptr) _s = (hnd).p;                                 \
  23.165 +    const typeof(&(ptr)->field) _d = &(ptr)->field;                 \
  23.166 +    xencomm_copy_from_guest(_d, _s, sizeof(*_d), _off);             \
  23.167  })
  23.168  
  23.169 -#endif /* __ASM_IA64_GUEST_ACCESS_H__ */
  23.170 +/* Internal use only: returns 0 in case of bad address.  */
  23.171 +extern unsigned long xencomm_paddr_to_maddr(unsigned long paddr);
  23.172 +
  23.173 +#endif /* __ASM_GUEST_ACCESS_H__ */
    24.1 --- a/xen/include/public/arch-ia64.h	Sun Oct 01 19:10:18 2006 -0600
    24.2 +++ b/xen/include/public/arch-ia64.h	Mon Oct 02 14:03:42 2006 -0600
    24.3 @@ -431,6 +431,14 @@ struct xen_ia64_boot_param {
    24.4  #define HYPERPRIVOP_GET_PSR		0x19
    24.5  #define HYPERPRIVOP_MAX			0x19
    24.6  
    24.7 +/* Xencomm macros.  */
    24.8 +#define XENCOMM_INLINE_MASK 0xf800000000000000UL
    24.9 +#define XENCOMM_INLINE_FLAG 0x8000000000000000UL
   24.10 +
   24.11 +#define XENCOMM_IS_INLINE(addr) \
   24.12 +  (((unsigned long)(addr) & XENCOMM_INLINE_MASK) == XENCOMM_INLINE_FLAG)
   24.13 +#define XENCOMM_INLINE_ADDR(addr) \
   24.14 +  ((unsigned long)(addr) & ~XENCOMM_INLINE_MASK)
   24.15  #endif /* __HYPERVISOR_IF_IA64_H__ */
   24.16  
   24.17  /*