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>
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>
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 /*