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] [PATCH] [RFC] Xencomm patch to fix modules

To: xen-ppc-devel <xen-ppc-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [XenPPC] [PATCH] [RFC] Xencomm patch to fix modules
From: Jerone Young <jyoung5@xxxxxxxxxx>
Date: Wed, 17 Jan 2007 21:20:58 -0600
Delivery-date: Wed, 17 Jan 2007 19:20:47 -0800
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>
Organization: IBM
Reply-to: jyoung5@xxxxxxxxxx
Sender: xen-ppc-devel-bounces@xxxxxxxxxxxxxxxxxxx
I haven't had a chance to fully test this patch. As I have been having
problems with my blade today. But here is the code for review. I'll get
back to the list once it is fully tested.

Signed-off-by: Jerone Young <jyoung5@xxxxxxxxxx>

diff -r e5962db17966 arch/powerpc/platforms/xen/gnttab.c
--- a/arch/powerpc/platforms/xen/gnttab.c       Wed Jan 17 10:25:30 2007 -0600
+++ b/arch/powerpc/platforms/xen/gnttab.c       Tue Jan 16 23:50:28 2007 -0600
@@ -263,8 +263,9 @@ int HYPERVISOR_grant_table_op(unsigned i
                memcpy(&setup, op, sizeof(setup));
                argsize = sizeof(setup);
 
-               frame_list = xencomm_create_inline(
-                       xen_guest_handle(setup.frame_list));
+               frame_list = xencomm_map(
+                       xen_guest_handle(setup.frame_list),
+                       (sizeof(ulong) * setup.nr_frames));
 
                set_xen_guest_handle(setup.frame_list, frame_list);
                memcpy(op, &setup, sizeof(setup));
@@ -286,7 +287,7 @@ int HYPERVISOR_grant_table_op(unsigned i
                return -ENOSYS;
        }
 
-       desc = xencomm_create_inline(op);
+       desc = xencomm_map(op, argsize);
 
        ret = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_grant_table_op), cmd,
                                 desc, count);
diff -r e5962db17966 arch/powerpc/platforms/xen/hcall.c
--- a/arch/powerpc/platforms/xen/hcall.c        Wed Jan 17 10:25:30 2007 -0600
+++ b/arch/powerpc/platforms/xen/hcall.c        Wed Jan 17 00:17:17 2007 -0600
@@ -50,11 +50,16 @@
  * In general, we need a xencomm descriptor to cover the top-level data
  * structure (e.g. the domctl op), plus another for every embedded
pointer to
  * another data structure (i.e. for every GUEST_HANDLE).
+ *
+ * Some hypercalls are made before the memory subsystem is up, so
instead of
+ * calling xencomm_create(), we allocate XENCOMM_MINI_AREA bytes from
the stack
+ * to hold the xencomm descriptor.
  */
 
 int HYPERVISOR_console_io(int cmd, int count, char *str)
 {
-       void *desc = xencomm_create_inline(str);
+
+       void *desc = xencomm_map_early(str, count);
 
        return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_console_io),
                                  cmd, count, desc);
@@ -63,7 +68,8 @@ EXPORT_SYMBOL(HYPERVISOR_console_io);
 
 int HYPERVISOR_event_channel_op(int cmd, void *op)
 {
-       void *desc = xencomm_create_inline(op);
+
+       void *desc = xencomm_map_early(op, sizeof(evtchn_op_t));
 
        return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_event_channel_op),
                                cmd, desc);
@@ -120,8 +126,8 @@ EXPORT_SYMBOL(HYPERVISOR_xen_version);
 
 int HYPERVISOR_xen_version(int cmd, void *arg)
 {
-       if (is_kernel_addr((unsigned long)arg)) {
-               void *desc = xencomm_create_inline(arg);
+       if (is_phys_contiguous((unsigned long)arg)) {
+               void *desc = xencomm_map_early(arg, sizeof(__u64));
                return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_xen_version), 
cmd,
desc);
        }
        return HYPERVISOR_xen_version_userspace(cmd, arg);
@@ -129,7 +135,7 @@ int HYPERVISOR_xen_version(int cmd, void
 
 int HYPERVISOR_physdev_op(int cmd, void *op)
 {
-       void *desc = xencomm_create_inline(op);
+       void *desc = xencomm_map(op, sizeof(physdev_op_t));
 
        return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_physdev_op),
                                cmd, desc);
@@ -139,6 +145,7 @@ int HYPERVISOR_sched_op(int cmd, void *a
 int HYPERVISOR_sched_op(int cmd, void *arg)
 {
        struct xencomm_desc *desc;
+       int argsize = 0;
 
        switch (cmd) {
        case SCHEDOP_yield:
@@ -151,24 +158,29 @@ int HYPERVISOR_sched_op(int cmd, void *a
                evtchn_port_t *ports;
                struct sched_poll sched_poll;
 
+               argsize = sizeof(struct sched_poll);
+
                memcpy(&sched_poll, arg, sizeof(sched_poll));
 
-               ports = xencomm_create_inline(
-                       xen_guest_handle(sched_poll.ports));
+               ports = xencomm_map(
+                       xen_guest_handle(sched_poll.ports),
+                       (sizeof(evtchn_port_t) * sched_poll.nr_ports));
                set_xen_guest_handle(sched_poll.ports, ports);
                memcpy(arg, &sched_poll, sizeof(sched_poll));
-               
+
        }
                break;
        case SCHEDOP_shutdown:
+               argsize = sizeof(struct sched_shutdown);
        case SCHEDOP_remote_shutdown:
+               argsize = sizeof(struct sched_remote_shutdown);
                break;
        default:
                printk(KERN_ERR "%s: unknown sched op %d\n", __func__, cmd);
                return -ENOSYS;
        }
 
-       desc = xencomm_create_inline(arg);
+       desc = xencomm_map(arg, argsize);
 
        return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_sched_op),
                                cmd, desc);
diff -r e5962db17966 drivers/xen/core/xencomm.c
--- a/drivers/xen/core/xencomm.c        Wed Jan 17 10:25:30 2007 -0600
+++ b/drivers/xen/core/xencomm.c        Wed Jan 17 01:42:11 2007 -0600
@@ -123,9 +123,87 @@ void *xencomm_create_inline(void *ptr)
 {
        unsigned long paddr;
 
-       BUG_ON(!is_kernel_addr((unsigned long)ptr));
-
        paddr = (unsigned long)xencomm_pa(ptr);
        BUG_ON(paddr & XENCOMM_INLINE_FLAG);
        return (void *)(paddr | XENCOMM_INLINE_FLAG);
 }
+
+/* "mini" routines, for stack-based communications: */
+static void *xencomm_alloc_mini(void *area, int arealen)
+{
+       unsigned long base = (unsigned long)area;
+       unsigned int left_in_page;
+
+       left_in_page = PAGE_SIZE - base % PAGE_SIZE;
+
+       /* we probably fit right at the front of area */
+       if (left_in_page >= sizeof(struct xencomm_mini)) {
+               return area;
+       }
+
+       /* if not, see if area is big enough to advance to the next page */
+       if ((arealen - left_in_page) >= sizeof(struct xencomm_mini))
+               return (void *)(base + left_in_page);
+
+       /* area was too small */
+       return NULL;
+}
+
+int xencomm_create_mini(void *area, int arealen, void *buffer,
+               unsigned long bytes, struct xencomm_desc **ret)
+{
+       struct xencomm_desc *desc;
+       int rc;
+       
+       desc = xencomm_alloc_mini(area, arealen);
+       if (!desc)
+               return -ENOMEM;
+       desc->nr_addrs = XENCOMM_MINI_ADDRS;
+
+       rc = xencomm_init(desc, buffer, bytes);
+       if (rc)
+               return rc;
+
+       *ret = desc;
+       return 0;
+}
+
+void *xencomm_map(void *ptr, unsigned long bytes)
+{
+       int rc;
+       struct xencomm_desc *desc;
+
+       if (is_phys_contiguous((unsigned long)ptr))
+               return xencomm_create_inline(ptr);
+       
+       rc =  xencomm_create(ptr, bytes, &desc, GFP_KERNEL);
+
+       if (rc)
+               return NULL;
+       
+       return xencomm_pa(desc); 
+}
+
+void *__xencomm_map_early(void *ptr, unsigned long bytes, 
+                       char *xc_area)
+{
+       int rc;
+       struct xencomm_desc *desc;
+
+       if (is_phys_contiguous((unsigned long)ptr))
+               return xencomm_create_inline(ptr);
+
+       rc = xencomm_create_mini(xc_area, XENCOMM_MINI_AREA,ptr, bytes,
+                               &desc);
+
+       if (rc)
+               return NULL;
+       
+       return (void*)__pa(desc);
+}
+
+/* check if is physically contiguous memory */
+int is_phys_contiguous(unsigned long addr)
+{
+       return (addr < VMALLOC_START) || (addr >= VMALLOC_END);
+}
diff -r e5962db17966 include/xen/xencomm.h
--- a/include/xen/xencomm.h     Wed Jan 17 10:25:30 2007 -0600
+++ b/include/xen/xencomm.h     Wed Jan 17 01:38:30 2007 -0600
@@ -23,10 +23,27 @@
 
 #include <xen/interface/xencomm.h>
 
+#define XENCOMM_MINI_ADDRS 3
+struct xencomm_mini {
+       struct xencomm_desc _desc;
+       uint64_t address[XENCOMM_MINI_ADDRS];
+};
+#define XENCOMM_MINI_AREA (sizeof(struct xencomm_mini) * 2)
+
 extern int xencomm_create(void *buffer, unsigned long bytes,
                          struct xencomm_desc **desc, gfp_t type);
 extern void xencomm_free(struct xencomm_desc *desc);
 extern void *xencomm_create_inline(void *ptr);
+extern int xencomm_create_mini(void *area, int arealen, void *buffer,
+                       unsigned long bytes, struct xencomm_desc **ret);
+extern void *xencomm_map(void *ptr, unsigned long bytes);
+extern void *__xencomm_map_early(void *ptr, unsigned long bytes, 
+                               char *xc_area);
+extern int is_phys_contiguous(unsigned long addr);
+
+#define xencomm_map_early(ptr, bytes) \
+       ({char xc_area[XENCOMM_MINI_AREA];\
+        __xencomm_map_early(ptr, bytes, xc_area);})
 
 /* provided by architecture code: */
 extern unsigned long xencomm_vtop(unsigned long vaddr);



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