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
|