[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] use a share page to transfer the hypercall parameters for vmx guest.
Use a share page to transfer the hypercall parameters for vmx guest. The share page is setuped in event channel pci driver. The point in parameters will traslate to a new value that is against the hypervisor share page virtual address. Signed-off-by: Ke Yu <ke.yu@xxxxxxxxx> Signed-off-by: Xiaofeng Ling <xiaofeng.ling@xxxxxxxxx> Signed-off-by: Arun Sharma <arun.sharma@xxxxxxxxx>b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall-vmx.h | 201 ++++++++++ linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h | 12 2 files changed, 212 insertions(+), 1 deletion(-) diff -r 287d36b46fa3 linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Tue Aug 30 20:36:49 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Fri Sep 2 22:47:27 2005 @@ -31,6 +31,7 @@ #define __HYPERCALL_H__ #include <asm-xen/xen-public/xen.h> + #define _hypercall0(type, name) \ ({ \ @@ -114,12 +115,14 @@ return _hypercall1(int, set_trap_table, table); } +#ifdef CONFIG_XEN static inline int HYPERVISOR_mmu_update( mmu_update_t *req, int count, int *success_count, domid_t domid) { return _hypercall4(int, mmu_update, req, count, success_count, domid); } +#endif static inline int HYPERVISOR_mmuext_op( @@ -261,12 +264,14 @@ new_val.pte_low, pte_hi, flags); } +#ifdef CONFIG_XEN static inline int HYPERVISOR_event_channel_op( void *op) { return _hypercall1(int, event_channel_op, op); } +#endif static inline int HYPERVISOR_xen_version( @@ -288,13 +293,14 @@ { return _hypercall1(int, physdev_op, physdev_op); } - +#ifdef CONFIG_XEN static inline int HYPERVISOR_grant_table_op( unsigned int cmd, void *uop, unsigned int count) { return _hypercall3(int, grant_table_op, cmd, uop, count); } +#endif static inline int HYPERVISOR_update_va_mapping_otherdomain( @@ -375,6 +381,10 @@ return ret; } +#ifndef CONFIG_XEN +#include <asm-xen/asm-i386/hypercall-vmx.h> +#endif + #endif /* __HYPERCALL_H__ */ /* diff -r 287d36b46fa3 linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall-vmx.h --- /dev/null Tue Aug 30 20:36:49 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall-vmx.h Fri Sep 2 22:47:27 2005 @@ -0,0 +1,201 @@ +/****************************************************************************** + * hypercall-vmx.h + * + * Linux-specific hypervisor handling. + * + * Copyright (c) 2002-2004, K A Fraser + * + * This file may be distributed separately from the Linux kernel, or + * incorporated into other software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include <asm-xen/xen-public/event_channel.h> +#include <asm-xen/xen-public/grant_table.h> +extern void* share_addr_guest; +extern void* share_addr_hv; + +/* + * Assembler stubs for hyper-calls. + */ + +static inline int +copy_mmu_update_var( + multicall_entry_t* to, multicall_entry_t* from, + unsigned long offset) +{ +/* copy mmu_update parameter req list and success_count + * do guest->hypervisor address translation at meantime + * args[0] : mmu_update_t* req + * args[1] : int count + * args[2] : int* success_count + */ + unsigned long offset1 = offset; + memcpy( share_addr_guest + offset1, (void*)from->args[0], + sizeof(mmu_update_t) * from->args[1]); + to->args[0] = (unsigned long)(share_addr_hv + offset1); + offset1 += sizeof(mmu_update_t) * from->args[1]; + + if (from->args[2]){ + memcpy( share_addr_guest + offset1, (void*)from->args[2], + sizeof(int)); + to->args[2] = (unsigned long)share_addr_hv + offset1; + offset1 += sizeof(int); + } + return offset1; +} + +static inline void +restore_mmu_update_var ( + multicall_entry_t* to, multicall_entry_t* from +) +{ +/* restore result and success_count */ + + int *to_success_count, *from_success_count; + + to->result = from->result; + if (to->args[2]){ + from_success_count = (int*)(from->args[2] - (unsigned long)share_addr_hv + + share_addr_guest); + to_success_count = (int*) (to->args[2]); + *to_success_count = *from_success_count; + } + return; +} + +static inline int +HYPERVISOR_mmu_update( + mmu_update_t *req, int count, int *success_count, domid_t domid) +{ + int ret; + int * s_success_count; + + BUG_ON (!req); + + /* copy tow parameters (req, success_count) to share page */ + memcpy(share_addr_guest, req, sizeof(*req)*count ); + + if (success_count){ + memcpy ((void*)(share_addr_guest + sizeof(*req)*count), + success_count, sizeof(*success_count)); + s_success_count = (int*)(share_addr_hv + sizeof(*req)*count); + } else { + s_success_count = NULL; + } + + ret = _hypercall4(int, mmu_update, req, share_addr_guest, success_count, domid); + + /* copy return value success_count from share page */ + if (success_count){ + memcpy( success_count, share_addr_guest + sizeof(*req)*count, + sizeof(*success_count) ); + } + + return ret; +} + +static inline int +HYPERVISOR_event_channel_op( + void *op) +{ + int ret; + + BUG_ON(!op); + memcpy (share_addr_guest, op, sizeof (evtchn_op_t) ); + + ret = _hypercall1(int, event_channel_op, share_addr_hv); + + memcpy (op, share_addr_guest, sizeof(evtchn_op_t)) ; + return ret; +} + +static inline int +grant_table_op_size (unsigned int cmd, void *uop) +{ + int size; + switch (cmd) + { + case GNTTABOP_map_grant_ref: + size = sizeof(gnttab_map_grant_ref_t) ; + break; + case GNTTABOP_unmap_grant_ref: + size = sizeof(gnttab_unmap_grant_ref_t) ; + break; + case GNTTABOP_setup_table: + size = sizeof(gnttab_setup_table_t) ; + break; +#if GRANT_DEBUG + case GNTTABOP_dump_table: + size = sizeof(gnttab_dump_table_t ) ; + break; +#endif + case GNTTABOP_donate: + size = sizeof(gnttab_donate_t) ; + break; + default: + size = 0; + } + return size; +} + +static inline int +HYPERVISOR_grant_table_op( + unsigned int cmd, void *uop, unsigned int count) +{ + int ret; + unsigned int size; +#if 0 + gnttab_setup_table_t* t; + gnttab_setup_table_t* ts; + unsigned long * frame_list; +#endif + BUG_ON( !uop ); + + size = grant_table_op_size(cmd, uop) * count; + BUG_ON (size > PAGE_SIZE); + memcpy(share_addr_guest, uop, size * count); + +#if 0 + /* currently, it is not needed */ + if (cmd == GNTTABOP_setup_table ) { + BUG_ON( count!=1 ); + t = (gnttab_setup_table_t*)uop; + ts = (gnttab_setup_table_t*)share_addr_guest; + memcpy (share_addr_guest + size, t->frame_list, + t->nr_frames * sizeof (*(t->frame_list))); + ts->frame_list = (unsigned long*) (share_addr_hv + size); + } +#endif + ret = _hypercall3(int, grant_table_op, cmd, share_addr_hv, count); +#if 0 + if (cmd == GNTTABOP_setup_table){ + frame_list = t->frame_list; + memcpy (t, share_addr_guest, size); + memcpy (frame_list, share_addr_guest + size, + t->nr_frames * sizeof(*(t->frame_list))); + t->frame_list = frame_list; + } else { +#endif + + memcpy (uop, share_addr_guest, size); + + + return ret; +} _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |