WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-ppc-devel

[XenPPC] [xenppc-unstable] [XEN] Move xencomm into generic code and supp

To: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Subject: [XenPPC] [xenppc-unstable] [XEN] Move xencomm into generic code and support "inline" handles.
From: Xen patchbot-xenppc-unstable <patchbot-xenppc-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 12 Sep 2006 17:30:49 +0000
Delivery-date: Tue, 12 Sep 2006 10:33:34 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-ppc-devel-request@lists.xensource.com?subject=help>
List-id: Xen PPC development <xen-ppc-devel.lists.xensource.com>
List-post: <mailto:xen-ppc-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-ppc-devel-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Hollis Blanchard <hollisb@xxxxxxxxxx>
# Node ID b057b940f6ebeec7527c089b5656669025d9a640
# Parent  a79b3252bbe46a13d91586081e7f6be278b07126
[XEN] Move xencomm into generic code and support "inline" handles.
- inline code based on code from Tristan Gingold <tristan.gingold@xxxxxxxx>
- make xencomm_handle_is_null() more thorough (check all addresses)
- delete unused asm-powerpc/uaccess.h
Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx>
---
 xen/include/asm-powerpc/uaccess.h      |   38 ---
 xen/arch/powerpc/usercopy.c            |  214 ----------------------
 xen/common/Makefile                    |    1 
 xen/common/xencomm.c                   |  316 +++++++++++++++++++++++++++++++++
 xen/include/asm-powerpc/guest_access.h |   78 --------
 xen/include/asm-powerpc/mm.h           |   27 --
 xen/include/asm-powerpc/page.h         |   25 ++
 xen/include/public/arch-powerpc.h      |    2 
 xen/include/public/xencomm.h           |    6 
 xen/include/xen/xencomm.h              |  115 ++++++++++++
 10 files changed, 471 insertions(+), 351 deletions(-)

diff -r a79b3252bbe4 -r b057b940f6eb xen/arch/powerpc/usercopy.c
--- a/xen/arch/powerpc/usercopy.c       Fri Sep 08 12:37:27 2006 -0500
+++ b/xen/arch/powerpc/usercopy.c       Tue Sep 12 12:08:04 2006 -0500
@@ -18,23 +18,13 @@
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
  */
 
-#include <xen/config.h>
-#include <xen/mm.h>
 #include <xen/sched.h>
+#include <xen/lib.h>
 #include <asm/current.h>
-#include <asm/uaccess.h>
-#include <public/xen.h>
-#include <public/xencomm.h>
-
-#undef DEBUG
-#ifdef DEBUG
-static int xencomm_debug = 1; /* extremely verbose */
-#else
-#define xencomm_debug 0
-#endif
+#include <asm/page.h>
 
 /* XXX need to return error, not panic, if domain passed a bad pointer */
-static unsigned long paddr_to_maddr(unsigned long paddr)
+unsigned long paddr_to_maddr(unsigned long paddr)
 {
     struct vcpu *v = get_current();
     struct domain *d = v->domain;
@@ -77,201 +67,3 @@ static unsigned long paddr_to_maddr(unsi
 
     return pa;
 }
-
-/**
- * xencomm_copy_from_guest: Copy a block of data from domain space.
- * @to:   Machine address.
- * @from: Physical address to a xencomm buffer descriptor.
- * @n:    Number of bytes to copy.
- * @skip: Number of bytes from the start to skip.
- *
- * Copy data from domain to hypervisor.
- *
- * Returns number of bytes that could not be copied.
- * On success, this will be zero.
- */
-unsigned long
-xencomm_copy_from_guest(void *to, const void *from, unsigned int n,
-        unsigned int skip)
-{
-    struct xencomm_desc *desc;
-    unsigned int from_pos = 0;
-    unsigned int to_pos = 0;
-    unsigned int i = 0;
-
-    /* first we need to access the descriptor */
-    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)from);
-    if (desc == NULL)
-        return n;
-
-    if (desc->magic != XENCOMM_MAGIC) {
-        printk("%s: error: %p magic was 0x%x\n",
-               __func__, desc, desc->magic);
-        return n;
-    }
-
-    /* iterate through the descriptor, copying up to a page at a time */
-    while ((to_pos < n) && (i < desc->nr_addrs)) {
-        unsigned long src_paddr = desc->address[i];
-        unsigned int pgoffset;
-        unsigned int chunksz;
-        unsigned int chunk_skip;
-
-        if (src_paddr == XENCOMM_INVALID) {
-            i++;
-            continue;
-        }
-
-        pgoffset = src_paddr % PAGE_SIZE;
-        chunksz = PAGE_SIZE - pgoffset;
-
-        chunk_skip = min(chunksz, skip);
-        from_pos += chunk_skip;
-        chunksz -= chunk_skip;
-        skip -= chunk_skip;
-
-        if (skip == 0) {
-            unsigned long src_maddr;
-            unsigned long dest = (unsigned long)to + to_pos;
-            unsigned int bytes = min(chunksz, n - to_pos);
-
-            src_maddr = paddr_to_maddr(src_paddr + chunk_skip);
-            if (src_maddr == 0)
-                return n - to_pos;
-
-            if (xencomm_debug)
-                printk("%lx[%d] -> %lx\n", src_maddr, bytes, dest);
-            memcpy((void *)dest, (void *)src_maddr, bytes);
-            from_pos += bytes;
-            to_pos += bytes;
-        }
-
-        i++;
-    }
-
-    return n - to_pos;
-}
-
-/**
- * xencomm_copy_to_guest: Copy a block of data to domain space.
- * @to:     Physical address to xencomm buffer descriptor.
- * @from:   Machine address.
- * @n:      Number of bytes to copy.
- * @skip: Number of bytes from the start to skip.
- *
- * Copy data from hypervisor to domain.
- *
- * Returns number of bytes that could not be copied.
- * On success, this will be zero.
- */
-unsigned long
-xencomm_copy_to_guest(void *to, const void *from, unsigned int n,
-        unsigned int skip)
-{
-    struct xencomm_desc *desc;
-    unsigned int from_pos = 0;
-    unsigned int to_pos = 0;
-    unsigned int i = 0;
-
-    /* first we need to access the descriptor */
-    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)to);
-    if (desc == NULL)
-        return n;
-
-    if (desc->magic != XENCOMM_MAGIC) {
-        printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
-        return n;
-    }
-
-    /* iterate through the descriptor, copying up to a page at a time */
-    while ((from_pos < n) && (i < desc->nr_addrs)) {
-        unsigned long dest_paddr = desc->address[i];
-        unsigned int pgoffset;
-        unsigned int chunksz;
-        unsigned int chunk_skip;
-
-        if (dest_paddr == XENCOMM_INVALID) {
-            i++;
-            continue;
-        }
-
-        pgoffset = dest_paddr % PAGE_SIZE;
-        chunksz = PAGE_SIZE - pgoffset;
-
-        chunk_skip = min(chunksz, skip);
-        to_pos += chunk_skip;
-        chunksz -= chunk_skip;
-        skip -= chunk_skip;
-
-        if (skip == 0) {
-            unsigned long dest_maddr;
-            unsigned long source = (unsigned long)from + from_pos;
-            unsigned int bytes = min(chunksz, n - from_pos);
-
-            dest_maddr = paddr_to_maddr(dest_paddr + chunk_skip);
-            if (dest_maddr == 0)
-                return -1;
-
-            if (xencomm_debug)
-                printk("%lx[%d] -> %lx\n", source, bytes, dest_maddr);
-            memcpy((void *)dest_maddr, (void *)source, bytes);
-            from_pos += bytes;
-            to_pos += bytes;
-        }
-
-        i++;
-    }
-
-    return n - from_pos;
-}
-
-/* Offset page addresses in 'handle' to skip 'bytes' bytes. Set completely
- * exhausted pages to XENCOMM_INVALID. */
-int xencomm_add_offset(void *handle, unsigned int bytes)
-{
-    struct xencomm_desc *desc;
-    int i = 0;
-
-    /* first we need to access the descriptor */
-    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)handle);
-    if (desc == NULL)
-        return -1;
-
-    if (desc->magic != XENCOMM_MAGIC) {
-        printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
-        return -1;
-    }
-
-    /* iterate through the descriptor incrementing addresses */
-    while ((bytes > 0) && (i < desc->nr_addrs)) {
-        unsigned long dest_paddr = desc->address[i];
-        unsigned int pgoffset;
-        unsigned int chunksz;
-        unsigned int chunk_skip;
-
-        pgoffset = dest_paddr % PAGE_SIZE;
-        chunksz = PAGE_SIZE - pgoffset;
-
-        chunk_skip = min(chunksz, bytes);
-        if (chunk_skip == chunksz) {
-            /* exhausted this page */
-            desc->address[i] = XENCOMM_INVALID;
-        } else {
-            desc->address[i] += chunk_skip;
-        }
-        bytes -= chunk_skip;
-    }
-    return 0;
-}
-
-int xencomm_handle_is_null(void *ptr)
-{
-    struct xencomm_desc *desc;
-
-    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)ptr);
-    if (desc == NULL)
-        return 1;
-
-    return (desc->nr_addrs == 0);
-}
-
diff -r a79b3252bbe4 -r b057b940f6eb xen/common/Makefile
--- a/xen/common/Makefile       Fri Sep 08 12:37:27 2006 -0500
+++ b/xen/common/Makefile       Tue Sep 12 12:08:04 2006 -0500
@@ -24,6 +24,7 @@ obj-y += timer.o
 obj-y += timer.o
 obj-y += version.o
 obj-y += vsprintf.o
+obj-y += xencomm.o
 obj-y += xmalloc.o
 
 obj-$(perfc)       += perfc.o
diff -r a79b3252bbe4 -r b057b940f6eb xen/include/asm-powerpc/guest_access.h
--- a/xen/include/asm-powerpc/guest_access.h    Fri Sep 08 12:37:27 2006 -0500
+++ b/xen/include/asm-powerpc/guest_access.h    Tue Sep 12 12:08:04 2006 -0500
@@ -21,82 +21,6 @@
 #ifndef __PPC_GUEST_ACCESS_H__
 #define __PPC_GUEST_ACCESS_H__
 
-extern unsigned long xencomm_copy_to_guest(void *to, const void *from,
-        unsigned int len, unsigned int skip); 
-extern unsigned long xencomm_copy_from_guest(void *to, const void *from,
-        unsigned int len, unsigned int skip); 
-extern int xencomm_add_offset(void *handle, unsigned int bytes);
-extern int xencomm_handle_is_null(void *ptr);
-
-
-/* Is the guest handle a NULL reference? */
-#define guest_handle_is_null(hnd) \
-    ((hnd).p == NULL || xencomm_handle_is_null((hnd).p))
-
-/* Offset the given guest handle into the array it refers to. */
-#define guest_handle_add_offset(hnd, nr) ({         \
-    const typeof((hnd).p) _ptr = (hnd).p;           \
-    xencomm_add_offset(_ptr, nr * sizeof(*_ptr));   \
-})
-
-/* Cast a guest handle to the specified type of handle. */
-#define guest_handle_cast(hnd, type) ({         \
-    type *_x = (hnd).p;                         \
-    XEN_GUEST_HANDLE(type) _y; \
-    set_xen_guest_handle(_y, _x); \
-    _y; \
-})
-
-/* Since we run in real mode, we can safely access all addresses. That also
- * means our __routines are identical to our "normal" routines. */
-#define guest_handle_okay(hnd, nr) 1
-
-/*
- * Copy an array of objects to guest context via a guest handle.
- * Optionally specify an offset into the guest array.
- */
-#define copy_to_guest_offset(hnd, idx, ptr, nr) \
-    __copy_to_guest_offset(hnd, idx, ptr, nr)
-
-/* Copy sub-field of a structure to guest context via a guest handle. */
-#define copy_field_to_guest(hnd, ptr, field) \
-    __copy_field_to_guest(hnd, ptr, field)
-
-/*
- * Copy an array of objects from guest context via a guest handle.
- * Optionally specify an offset into the guest array.
- */
-#define copy_from_guest_offset(ptr, hnd, idx, nr) \
-    __copy_from_guest_offset(ptr, hnd, idx, nr)
-
-/* Copy sub-field of a structure from guest context via a guest handle. */
-#define copy_field_from_guest(ptr, hnd, field) \
-    __copy_field_from_guest(ptr, hnd, field)
-
-#define __copy_to_guest_offset(hnd, idx, ptr, nr) ({                \
-    const typeof(ptr) _x = (hnd).p;                                 \
-    const typeof(ptr) _y = (ptr);                                   \
-    xencomm_copy_to_guest(_x, _y, sizeof(*_x)*(nr), sizeof(*_x)*(idx)); \
-})
-
-#define __copy_field_to_guest(hnd, ptr, field) ({                   \
-    const int _off = offsetof(typeof(*ptr), field);                  \
-    const typeof(&(ptr)->field) _x = &(hnd).p->field;               \
-    const typeof(&(ptr)->field) _y = &(ptr)->field;                 \
-    xencomm_copy_to_guest(_x, _y, sizeof(*_x), sizeof(*_x)*(_off)); \
-})
-
-#define __copy_from_guest_offset(ptr, hnd, idx, nr) ({              \
-    const typeof(ptr) _x = (hnd).p;                                 \
-    const typeof(ptr) _y = (ptr);                                   \
-    xencomm_copy_from_guest(_y, _x, sizeof(*_x)*(nr), sizeof(*_x)*(idx));  \
-})
-
-#define __copy_field_from_guest(ptr, hnd, field) ({                 \
-    const int _off = offsetof(typeof(*ptr), field);                 \
-    const typeof(&(ptr)->field) _x = &(hnd).p->field;               \
-    const typeof(&(ptr)->field) _y = &(ptr)->field;                 \
-    xencomm_copy_to_guest(_y, _x, sizeof(*_x), sizeof(*_x)*(_off)); \
-})
+#include <xen/xencomm.h>
 
 #endif /* __PPC_GUEST_ACCESS_H__ */
diff -r a79b3252bbe4 -r b057b940f6eb xen/include/asm-powerpc/mm.h
--- a/xen/include/asm-powerpc/mm.h      Fri Sep 08 12:37:27 2006 -0500
+++ b/xen/include/asm-powerpc/mm.h      Tue Sep 12 12:08:04 2006 -0500
@@ -28,7 +28,7 @@
 #include <asm/misc.h>
 #include <asm/system.h>
 #include <asm/flushtlb.h>
-#include <asm/uaccess.h>
+#include <asm/page.h>
 
 #define memguard_guard_range(_p,_l)    ((void)0)
 #define memguard_unguard_range(_p,_l)    ((void)0)
@@ -234,29 +234,8 @@ extern int update_grant_va_mapping(unsig
                                    struct domain *,
                                    struct vcpu *);
 
-#define INVALID_MFN (~0UL)
-#define PFN_TYPE_NONE 0
-#define PFN_TYPE_RMA 1
-#define PFN_TYPE_LOGICAL 2
-#define PFN_TYPE_IO 3
-#define PFN_TYPE_REMOTE 4
-
-extern ulong pfn2mfn(struct domain *d, ulong pfn, int *type);
-
 /* Arch-specific portion of memory_op hypercall. */
 long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg);
-
-/* XXX implement me? */
-#define set_gpfn_from_mfn(mfn, pfn) do { } while (0)
-/* XXX only used for debug print right now... */
-#define get_gpfn_from_mfn(mfn) (mfn)
-
-static inline unsigned long gmfn_to_mfn(struct domain *d, unsigned long gmfn)
-{
-       return pfn2mfn(d, gmfn, NULL);
-}
-
-#define mfn_to_gmfn(_d, mfn) (mfn)
 
 extern int allocate_rma(struct domain *d, unsigned int order_pages);
 extern uint allocate_extents(struct domain *d, uint nrpages, uint rma_nrpages);
@@ -265,4 +244,8 @@ extern int steal_page(struct domain *d, 
 extern int steal_page(struct domain *d, struct page_info *page,
                         unsigned int memflags);
 
+/* XXX these just exist until we can stop #including x86 code */
+#define access_ok(addr,size) 1
+#define array_access_ok(addr,count,size) 1
+
 #endif
diff -r a79b3252bbe4 -r b057b940f6eb xen/include/asm-powerpc/page.h
--- a/xen/include/asm-powerpc/page.h    Fri Sep 08 12:37:27 2006 -0500
+++ b/xen/include/asm-powerpc/page.h    Tue Sep 12 12:08:04 2006 -0500
@@ -13,7 +13,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2005
+ * Copyright (C) IBM Corp. 2005, 2006
  *
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
  */
@@ -112,5 +112,28 @@ static inline int get_order_from_pages(u
 #define _PAGE_PAT      0x080UL
 #define _PAGE_PSE      0x080UL
 #define _PAGE_GLOBAL   0x100UL
+
+#define INVALID_MFN (~0UL)
+#define PFN_TYPE_NONE 0
+#define PFN_TYPE_RMA 1
+#define PFN_TYPE_LOGICAL 2
+#define PFN_TYPE_IO 3
+#define PFN_TYPE_REMOTE 4
+
+extern ulong pfn2mfn(struct domain *d, ulong pfn, int *type);
+extern unsigned long paddr_to_maddr(unsigned long paddr);
+
+/* XXX implement me? */
+#define set_gpfn_from_mfn(mfn, pfn) do { } while (0)
+/* XXX only used for debug print right now... */
+#define get_gpfn_from_mfn(mfn) (mfn)
+
+static inline unsigned long gmfn_to_mfn(struct domain *d, unsigned long gmfn)
+{
+       return pfn2mfn(d, gmfn, NULL);
+}
+
+#define mfn_to_gmfn(_d, mfn) (mfn)
+
 #endif  /* ! __ASSEMBLY__ */
 #endif
diff -r a79b3252bbe4 -r b057b940f6eb xen/include/public/arch-powerpc.h
--- a/xen/include/public/arch-powerpc.h Fri Sep 08 12:37:27 2006 -0500
+++ b/xen/include/public/arch-powerpc.h Tue Sep 12 12:08:04 2006 -0500
@@ -72,6 +72,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
 
 #ifndef __ASSEMBLY__
 
+#define XENCOMM_INLINE_FLAG (1UL << 63)
+
 typedef uint64_t xen_ulong_t;
 
 /* User-accessible registers: need to be saved/restored for every nested Xen
diff -r a79b3252bbe4 -r b057b940f6eb xen/include/public/xencomm.h
--- a/xen/include/public/xencomm.h      Fri Sep 08 12:37:27 2006 -0500
+++ b/xen/include/public/xencomm.h      Tue Sep 12 12:08:04 2006 -0500
@@ -1,6 +1,4 @@
 /*
- * Copyright (C) 2006 Hollis Blanchard <hollisb@xxxxxxxxxx>, IBM Corporation
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -14,6 +12,10 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ * Copyright (C) IBM Corp. 2006
+ *
+ * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
  */
 
 #ifndef _XEN_XENCOMM_H_
diff -r a79b3252bbe4 -r b057b940f6eb xen/common/xencomm.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/common/xencomm.c      Tue Sep 12 12:08:04 2006 -0500
@@ -0,0 +1,316 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (C) IBM Corp. 2006
+ *
+ * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
+ *          Tristan Gingold <tristan.gingold@xxxxxxxx>
+ */
+
+#include <xen/config.h>
+#include <xen/mm.h>
+#include <xen/sched.h>
+#include <xen/xencomm.h>
+#include <public/xen.h>
+#include <public/xencomm.h>
+
+
+#undef DEBUG
+#ifdef DEBUG
+static int xencomm_debug = 1; /* extremely verbose */
+#else
+#define xencomm_debug 0
+#endif
+
+static unsigned long
+xencomm_inline_from_guest(void *to, const void *from, unsigned int n,
+        unsigned int skip)
+{
+    unsigned long src_paddr = xencomm_inline_addr(from);
+
+    src_paddr += skip;
+
+    while (n > 0) {
+        unsigned int chunksz;
+        unsigned long src_maddr;
+        unsigned int bytes;
+
+        chunksz = PAGE_SIZE - (src_paddr % PAGE_SIZE);
+
+        bytes = min(chunksz, n);
+
+        src_maddr = paddr_to_maddr(src_paddr);
+        if (xencomm_debug)
+            printk("%lx[%d] -> %lx\n", src_maddr, bytes, (unsigned long)to);
+        memcpy(to, (void *)src_maddr, bytes);
+        src_paddr += bytes;
+        to += bytes;
+        n -= bytes;
+    }
+
+    /* Always successful. */
+    return 0;
+}
+
+/**
+ * xencomm_copy_from_guest: Copy a block of data from domain space.
+ * @to:   Machine address.
+ * @from: Physical address to a xencomm buffer descriptor.
+ * @n:    Number of bytes to copy.
+ * @skip: Number of bytes from the start to skip.
+ *
+ * Copy data from domain to hypervisor.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ */
+unsigned long
+xencomm_copy_from_guest(void *to, const void *from, unsigned int n,
+        unsigned int skip)
+{
+    struct xencomm_desc *desc;
+    unsigned int from_pos = 0;
+    unsigned int to_pos = 0;
+    unsigned int i = 0;
+
+    if (xencomm_is_inline(from))
+        return xencomm_inline_from_guest(to, from, n, skip);
+
+    /* first we need to access the descriptor */
+    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)from);
+    if (desc == NULL)
+        return n;
+
+    if (desc->magic != XENCOMM_MAGIC) {
+        printk("%s: error: %p magic was 0x%x\n",
+               __func__, desc, desc->magic);
+        return n;
+    }
+
+    /* iterate through the descriptor, copying up to a page at a time */
+    while ((to_pos < n) && (i < desc->nr_addrs)) {
+        unsigned long src_paddr = desc->address[i];
+        unsigned int pgoffset;
+        unsigned int chunksz;
+        unsigned int chunk_skip;
+
+        if (src_paddr == XENCOMM_INVALID) {
+            i++;
+            continue;
+        }
+
+        pgoffset = src_paddr % PAGE_SIZE;
+        chunksz = PAGE_SIZE - pgoffset;
+
+        chunk_skip = min(chunksz, skip);
+        from_pos += chunk_skip;
+        chunksz -= chunk_skip;
+        skip -= chunk_skip;
+
+        if (skip == 0) {
+            unsigned long src_maddr;
+            unsigned long dest = (unsigned long)to + to_pos;
+            unsigned int bytes = min(chunksz, n - to_pos);
+
+            src_maddr = paddr_to_maddr(src_paddr + chunk_skip);
+            if (src_maddr == 0)
+                return n - to_pos;
+
+            if (xencomm_debug)
+                printk("%lx[%d] -> %lx\n", src_maddr, bytes, dest);
+            memcpy((void *)dest, (void *)src_maddr, bytes);
+            from_pos += bytes;
+            to_pos += bytes;
+        }
+
+        i++;
+    }
+
+    return n - to_pos;
+}
+
+static unsigned long
+xencomm_inline_to_guest(void *to, const void *from, unsigned int n,
+        unsigned int skip)
+{
+    unsigned long dest_paddr = xencomm_inline_addr(to);
+
+    dest_paddr += skip;
+
+    while (n > 0) {
+        unsigned int chunksz;
+        unsigned long dest_maddr;
+        unsigned int bytes;
+
+        chunksz = PAGE_SIZE - (dest_paddr % PAGE_SIZE);
+
+        bytes = min(chunksz, n);
+
+        dest_maddr = paddr_to_maddr(dest_paddr);
+        if (xencomm_debug)
+            printk("%lx[%d] -> %lx\n", (unsigned long)from, bytes, dest_maddr);
+        memcpy((void *)dest_maddr, (void *)from, bytes);
+        dest_paddr += bytes;
+        from += bytes;
+        n -= bytes;
+    }
+
+    /* Always successful.  */
+    return 0;
+}
+
+/**
+ * xencomm_copy_to_guest: Copy a block of data to domain space.
+ * @to:     Physical address to xencomm buffer descriptor.
+ * @from:   Machine address.
+ * @n:      Number of bytes to copy.
+ * @skip: Number of bytes from the start to skip.
+ *
+ * Copy data from hypervisor to domain.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ */
+unsigned long
+xencomm_copy_to_guest(void *to, const void *from, unsigned int n,
+        unsigned int skip)
+{
+    struct xencomm_desc *desc;
+    unsigned int from_pos = 0;
+    unsigned int to_pos = 0;
+    unsigned int i = 0;
+
+    if (xencomm_is_inline(to))
+        return xencomm_inline_to_guest(to, from, n, skip);
+
+    /* first we need to access the descriptor */
+    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)to);
+    if (desc == NULL)
+        return n;
+
+    if (desc->magic != XENCOMM_MAGIC) {
+        printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
+        return n;
+    }
+
+    /* iterate through the descriptor, copying up to a page at a time */
+    while ((from_pos < n) && (i < desc->nr_addrs)) {
+        unsigned long dest_paddr = desc->address[i];
+        unsigned int pgoffset;
+        unsigned int chunksz;
+        unsigned int chunk_skip;
+
+        if (dest_paddr == XENCOMM_INVALID) {
+            i++;
+            continue;
+        }
+
+        pgoffset = dest_paddr % PAGE_SIZE;
+        chunksz = PAGE_SIZE - pgoffset;
+
+        chunk_skip = min(chunksz, skip);
+        to_pos += chunk_skip;
+        chunksz -= chunk_skip;
+        skip -= chunk_skip;
+
+        if (skip == 0) {
+            unsigned long dest_maddr;
+            unsigned long source = (unsigned long)from + from_pos;
+            unsigned int bytes = min(chunksz, n - from_pos);
+
+            dest_maddr = paddr_to_maddr(dest_paddr + chunk_skip);
+            if (dest_maddr == 0)
+                return -1;
+
+            if (xencomm_debug)
+                printk("%lx[%d] -> %lx\n", source, bytes, dest_maddr);
+            memcpy((void *)dest_maddr, (void *)source, bytes);
+            from_pos += bytes;
+            to_pos += bytes;
+        }
+
+        i++;
+    }
+
+    return n - from_pos;
+}
+
+static int xencomm_inline_add_offset(void **handle, unsigned int bytes)
+{
+    *handle += bytes;
+    return 0;
+}
+
+/* Offset page addresses in 'handle' to skip 'bytes' bytes. Set completely
+ * exhausted pages to XENCOMM_INVALID. */
+int xencomm_add_offset(void **handle, unsigned int bytes)
+{
+    struct xencomm_desc *desc;
+    int i = 0;
+
+    if (xencomm_is_inline(*handle))
+        return xencomm_inline_add_offset(handle, bytes);
+
+    /* first we need to access the descriptor */
+    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)*handle);
+    if (desc == NULL)
+        return -1;
+
+    if (desc->magic != XENCOMM_MAGIC) {
+        printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
+        return -1;
+    }
+
+    /* iterate through the descriptor incrementing addresses */
+    while ((bytes > 0) && (i < desc->nr_addrs)) {
+        unsigned long dest_paddr = desc->address[i];
+        unsigned int pgoffset;
+        unsigned int chunksz;
+        unsigned int chunk_skip;
+
+        pgoffset = dest_paddr % PAGE_SIZE;
+        chunksz = PAGE_SIZE - pgoffset;
+
+        chunk_skip = min(chunksz, bytes);
+        if (chunk_skip == chunksz) {
+            /* exhausted this page */
+            desc->address[i] = XENCOMM_INVALID;
+        } else {
+            desc->address[i] += chunk_skip;
+        }
+        bytes -= chunk_skip;
+    }
+    return 0;
+}
+
+int xencomm_handle_is_null(void *handle)
+{
+    struct xencomm_desc *desc;
+    int i;
+
+    if (xencomm_is_inline(handle))
+        return xencomm_inline_addr(handle) == 0;
+
+    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)handle);
+    if (desc == NULL)
+        return 1;
+
+    for (i = 0; i < desc->nr_addrs; i++)
+        if (desc->address[i] != XENCOMM_INVALID)
+            return 0;
+
+    return 1;
+}
+
diff -r a79b3252bbe4 -r b057b940f6eb xen/include/xen/xencomm.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/xen/xencomm.h Tue Sep 12 12:08:04 2006 -0500
@@ -0,0 +1,115 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (C) IBM Corp. 2006
+ *
+ * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
+ */
+
+#ifndef __XENCOMM_H__
+#define __XENCOMM_H__
+
+#include <public/xen.h>
+
+extern unsigned long xencomm_copy_to_guest(void *to, const void *from,
+        unsigned int len, unsigned int skip); 
+extern unsigned long xencomm_copy_from_guest(void *to, const void *from,
+        unsigned int len, unsigned int skip); 
+extern int xencomm_add_offset(void **handle, unsigned int bytes);
+extern int xencomm_handle_is_null(void *ptr);
+
+
+static inline int xencomm_is_inline(const void *handle)
+{
+    unsigned long addr = (unsigned long)handle;
+    return (addr & XENCOMM_INLINE_FLAG) == XENCOMM_INLINE_FLAG;
+}
+
+static inline unsigned long xencomm_inline_addr(const void *handle)
+{
+       return (unsigned long)handle & ~XENCOMM_INLINE_FLAG;
+}
+
+/* Is the guest handle a NULL reference? */
+#define guest_handle_is_null(hnd) \
+    ((hnd).p == NULL || xencomm_handle_is_null((hnd).p))
+
+/* Offset the given guest handle into the array it refers to. */
+#define guest_handle_add_offset(hnd, nr) ({         \
+    const typeof((hnd).p) _ptr;                     \
+    xencomm_add_offset((void **)&((hnd).p), nr * sizeof(*_ptr));   \
+})
+
+/* Cast a guest handle to the specified type of handle. */
+#define guest_handle_cast(hnd, type) ({         \
+    type *_x = (hnd).p;                         \
+    XEN_GUEST_HANDLE(type) _y; \
+    set_xen_guest_handle(_y, _x); \
+    _y; \
+})
+
+/* Since we run in real mode, we can safely access all addresses. That also
+ * means our __routines are identical to our "normal" routines. */
+#define guest_handle_okay(hnd, nr) 1
+
+/*
+ * Copy an array of objects to guest context via a guest handle.
+ * Optionally specify an offset into the guest array.
+ */
+#define copy_to_guest_offset(hnd, idx, ptr, nr) \
+    __copy_to_guest_offset(hnd, idx, ptr, nr)
+
+/* Copy sub-field of a structure to guest context via a guest handle. */
+#define copy_field_to_guest(hnd, ptr, field) \
+    __copy_field_to_guest(hnd, ptr, field)
+
+/*
+ * Copy an array of objects from guest context via a guest handle.
+ * Optionally specify an offset into the guest array.
+ */
+#define copy_from_guest_offset(ptr, hnd, idx, nr) \
+    __copy_from_guest_offset(ptr, hnd, idx, nr)
+
+/* Copy sub-field of a structure from guest context via a guest handle. */
+#define copy_field_from_guest(ptr, hnd, field) \
+    __copy_field_from_guest(ptr, hnd, field)
+
+#define __copy_to_guest_offset(hnd, idx, ptr, nr) ({                \
+    const typeof(ptr) _x = (hnd).p;                                 \
+    const typeof(ptr) _y = (ptr);                                   \
+    xencomm_copy_to_guest(_x, _y, sizeof(*_x)*(nr), sizeof(*_x)*(idx)); \
+})
+
+#define __copy_field_to_guest(hnd, ptr, field) ({                   \
+    const int _off = offsetof(typeof(*ptr), field);                  \
+    const typeof(&(ptr)->field) _x = &(hnd).p->field;               \
+    const typeof(&(ptr)->field) _y = &(ptr)->field;                 \
+    xencomm_copy_to_guest(_x, _y, sizeof(*_x), sizeof(*_x)*(_off)); \
+})
+
+#define __copy_from_guest_offset(ptr, hnd, idx, nr) ({              \
+    const typeof(ptr) _x = (hnd).p;                                 \
+    const typeof(ptr) _y = (ptr);                                   \
+    xencomm_copy_from_guest(_y, _x, sizeof(*_x)*(nr), sizeof(*_x)*(idx));  \
+})
+
+#define __copy_field_from_guest(ptr, hnd, field) ({                 \
+    const int _off = offsetof(typeof(*ptr), field);                 \
+    const typeof(&(ptr)->field) _x = &(hnd).p->field;               \
+    const typeof(&(ptr)->field) _y = &(ptr)->field;                 \
+    xencomm_copy_to_guest(_y, _x, sizeof(*_x), sizeof(*_x)*(_off)); \
+})
+
+#endif /* __XENCOMM_H__ */
diff -r a79b3252bbe4 -r b057b940f6eb xen/include/asm-powerpc/uaccess.h
--- a/xen/include/asm-powerpc/uaccess.h Fri Sep 08 12:37:27 2006 -0500
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- * Copyright (C) IBM Corp. 2006
- *
- * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
- */
-
-#ifndef __PPC_UACCESS_H__
-#define __PPC_UACCESS_H__
-
-#include <xen/errno.h>
-#include <asm/page.h>
-#include <asm/guest_access.h>
-
-/* since we run in real mode, we can safely access all addresses.
- * XXX well, except IO. should we check for that here? */
-#define access_ok(addr,size) 1
-#define array_access_ok(addr,count,size) 1
-
-#define __copy_to_user copy_to_user
-#define __copy_from_user copy_from_user
-#define copy_to_user(to,from,len) xencomm_copy_to_guest(to,from,len,0)
-#define copy_from_user(to,from,len) xencomm_copy_from_guest(to,from,len,0)
-
-#endif /* __PPC_UACCESS_H__ */

_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [XenPPC] [xenppc-unstable] [XEN] Move xencomm into generic code and support "inline" handles., Xen patchbot-xenppc-unstable <=