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] [linux-ppc-2.6] [XEN] xencomm fixes for various runtime situati

To: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Subject: [XenPPC] [linux-ppc-2.6] [XEN] xencomm fixes for various runtime situations
From: Xen patchbot-linux-ppc-2.6 <patchbot-linux-ppc-2.6@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 06 Feb 2007 22:30:54 +0000
Delivery-date: Wed, 07 Feb 2007 04:10:56 -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>
Reply-to: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-ppc-devel-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
# Node ID 5eca8383a521939f0d74e68eaddb049c5057742a
# Parent  ab3b5849331da89e578ae0813021376d66b7f333
[XEN] xencomm fixes for various runtime situations

This patch makes xencomm safe for all allocations scenarios including:
 - too early to use allocator
 - in IRQ
 - Recognize when inline can be used
 - vmalloc()
 - Automatic use of the xencomm_mini when the number of pages is small.

Signed-off-by: Jerone Young <jyoung5@xxxxxxxxxx>
Signed-off-by: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
---
 arch/powerpc/platforms/xen/gnttab.c |   21 ++
 arch/powerpc/platforms/xen/hcall.c  |  283 ++++++++++++++++++++++--------------
 arch/powerpc/platforms/xen/setup.c  |    2 
 drivers/xen/core/xencomm.c          |   73 ++++++++-
 include/xen/xencomm.h               |   20 ++
 5 files changed, 280 insertions(+), 119 deletions(-)

diff -r ab3b5849331d -r 5eca8383a521 arch/powerpc/platforms/xen/gnttab.c
--- a/arch/powerpc/platforms/xen/gnttab.c       Sun Jan 21 08:36:53 2007 -0500
+++ b/arch/powerpc/platforms/xen/gnttab.c       Tue Feb 06 16:21:30 2007 -0500
@@ -244,8 +244,8 @@ static void gnttab_post_map_grant_ref(
 
 int HYPERVISOR_grant_table_op(unsigned int cmd, void *op, unsigned int count)
 {
-       void *desc;
-       void *frame_list;
+       void *desc = NULL;
+       void *frame_list = NULL;
        int argsize;
        int ret;
 
@@ -263,8 +263,13 @@ 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(*xen_guest_handle(setup.frame_list)) 
+                       * setup.nr_frames));
+
+               if (frame_list == NULL)
+                       return -ENOMEM;
 
                set_xen_guest_handle(setup.frame_list, frame_list);
                memcpy(op, &setup, sizeof(setup));
@@ -286,12 +291,18 @@ int HYPERVISOR_grant_table_op(unsigned i
                return -ENOSYS;
        }
 
-       desc = xencomm_create_inline(op);
+       desc = xencomm_map_no_alloc(op, argsize);
+
+       if (desc == NULL)
+               return -ENOSPC;
 
        ret = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_grant_table_op), cmd,
                                 desc, count);
        if (cmd == GNTTABOP_map_grant_ref)
                gnttab_post_map_grant_ref(op, count);
+
+       xencomm_free(frame_list);
+       xencomm_free(desc);
 
        return ret;
 }
diff -r ab3b5849331d -r 5eca8383a521 arch/powerpc/platforms/xen/hcall.c
--- a/arch/powerpc/platforms/xen/hcall.c        Sun Jan 21 08:36:53 2007 -0500
+++ b/arch/powerpc/platforms/xen/hcall.c        Tue Feb 06 16:21:30 2007 -0500
@@ -54,25 +54,43 @@
 
 int HYPERVISOR_console_io(int cmd, int count, char *str)
 {
-       void *desc = xencomm_create_inline(str);
-
-       return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_console_io),
+       int rc;
+
+       void *desc = xencomm_map_no_alloc(str, count); 
+
+       if (desc == NULL)
+               return -EINVAL;
+
+       rc = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_console_io),
                                  cmd, count, desc);
+
+       xencomm_free(desc);
+
+       return rc;
 }
 EXPORT_SYMBOL(HYPERVISOR_console_io);
 
 int HYPERVISOR_event_channel_op(int cmd, void *op)
 {
-       void *desc = xencomm_create_inline(op);
-
-       return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_event_channel_op),
+       int rc;
+
+       void *desc = xencomm_map_no_alloc(op, sizeof(evtchn_op_t));
+       if (desc == NULL)
+               return -EINVAL;
+
+       rc = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_event_channel_op),
                                cmd, desc);
+
+       xencomm_free(desc);
+       
+       return rc;
+
 }
 EXPORT_SYMBOL(HYPERVISOR_event_channel_op);
 
-int HYPERVISOR_xen_version_userspace(int cmd, void *arg)
-{
-       struct xencomm_desc *desc;
+int HYPERVISOR_xen_version(int cmd, void *arg)
+{
+       void *desc;
        const unsigned long hcall = __HYPERVISOR_xen_version;
        int argsize;
        int rc;
@@ -97,7 +115,10 @@ int HYPERVISOR_xen_version_userspace(int
                argsize = sizeof(xen_platform_parameters_t);
                break;
        case XENVER_pagesize:
-               argsize = (arg == NULL) ? 0 : sizeof(void *);
+               if (arg == NULL)
+                       argsize = 0;
+               else
+                       argsize = sizeof(void *);
                break;
        case XENVER_get_features:
                argsize = sizeof(xen_feature_info_t);
@@ -107,38 +128,41 @@ int HYPERVISOR_xen_version_userspace(int
                return -ENOSYS;
        }
 
-       rc = xencomm_create(arg, argsize, &desc, GFP_KERNEL);
-       if (rc)
-               return rc;
-
-       rc = plpar_hcall_norets(XEN_MARK(hcall), cmd, xencomm_pa(desc));
-
-       xencomm_free(desc);
+       /* desc could be NULL in the case of XENVER_pagesize with NULL arg */
+       desc = xencomm_map(arg, argsize);
+
+       rc = plpar_hcall_norets(XEN_MARK(hcall), cmd, desc);
+
+       xencomm_free(desc);     
+
        return rc;
 }
 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);
-               return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_xen_version), 
cmd, desc);
-       }
-       return HYPERVISOR_xen_version_userspace(cmd, arg);
-}
 
 int HYPERVISOR_physdev_op(int cmd, void *op)
 {
-       void *desc = xencomm_create_inline(op);
-
-       return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_physdev_op),
+       void *desc = xencomm_map_no_alloc(op, sizeof(physdev_op_t)); 
+       int rc;
+
+       if (desc == NULL)
+               return -EINVAL;
+
+       rc = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_physdev_op),
                                cmd, desc);
+
+       xencomm_free(desc);
+
+       return rc;
 }
 EXPORT_SYMBOL(HYPERVISOR_physdev_op);
 
 int HYPERVISOR_sched_op(int cmd, void *arg)
 {
-       struct xencomm_desc *desc;
+       int argsize = 0;
+       int rc;
+       void *desc;
+       evtchn_port_t *ports = NULL;
 
        switch (cmd) {
        case SCHEDOP_yield:
@@ -148,30 +172,46 @@ int HYPERVISOR_sched_op(int cmd, void *a
                break;
 
        case SCHEDOP_poll: {
-               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));
+
+               if (ports == NULL)
+                       return -ENOMEM;
+
                set_xen_guest_handle(sched_poll.ports, ports);
                memcpy(arg, &sched_poll, sizeof(sched_poll));
                
        }
                break;
        case SCHEDOP_shutdown:
+               argsize = sizeof(struct sched_shutdown);
+               break;
        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);
-
-       return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_sched_op),
+       desc = xencomm_map_no_alloc(arg, argsize); 
+
+       if (desc == NULL)
+               return -EINVAL;
+
+       rc = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_sched_op),
                                cmd, desc);
+
+       xencomm_free(ports);
+
+       return rc;
 }
 EXPORT_SYMBOL(HYPERVISOR_sched_op);
 
@@ -233,8 +273,8 @@ static int xenppc_privcmd_domctl(privcmd
 {
        xen_domctl_t kern_op;
        xen_domctl_t __user *user_op = (xen_domctl_t __user *)hypercall->arg[0];
-       struct xencomm_desc *op_desc;
-       struct xencomm_desc *desc = NULL;
+       void *op_desc;
+       void *desc = NULL;
        int ret = 0;
 
        if (copy_from_user(&kern_op, user_op, sizeof(xen_domctl_t)))
@@ -246,9 +286,9 @@ static int xenppc_privcmd_domctl(privcmd
                return -EACCES;
        }
 
-       ret = xencomm_create(&kern_op, sizeof(xen_domctl_t), &op_desc, 
GFP_KERNEL);
-       if (ret)
-               return ret;
+       op_desc = xencomm_map(&kern_op, sizeof(xen_domctl_t));
+       if (op_desc == NULL)
+               return -ENOMEM;
 
        switch (kern_op.cmd) {
        case XEN_DOMCTL_createdomain:
@@ -258,52 +298,71 @@ static int xenppc_privcmd_domctl(privcmd
        case XEN_DOMCTL_getdomaininfo:
                break;
        case XEN_DOMCTL_getmemlist:
-               ret = xencomm_create(
+               desc = xencomm_map(
                        xen_guest_handle(kern_op.u.getmemlist.buffer),
-                       kern_op.u.getmemlist.max_pfns * sizeof(unsigned long),
-                       &desc, GFP_KERNEL);
+                       kern_op.u.getmemlist.max_pfns * sizeof(unsigned long));
+
+               if (desc == NULL)
+                       ret = -ENOMEM;
+
                set_xen_guest_handle(kern_op.u.getmemlist.buffer,
-                                    xencomm_pa(desc));
+                                    desc);
                break;
        case XEN_DOMCTL_getpageframeinfo:
                break;
        case XEN_DOMCTL_getpageframeinfo2:
-               ret = xencomm_create(
+               desc = xencomm_map(
                        xen_guest_handle(kern_op.u.getpageframeinfo2.array),
-                       kern_op.u.getpageframeinfo2.num,
-                       &desc, GFP_KERNEL);
+                       kern_op.u.getpageframeinfo2.num);
+               
+               if (desc == NULL)
+                       ret = -ENOMEM;
+
                set_xen_guest_handle(kern_op.u.getpageframeinfo2.array,
-                                    xencomm_pa(desc));
+                                    desc);
                break;
        case XEN_DOMCTL_shadow_op:
-               ret = xencomm_create(
-                       xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap),
-                       kern_op.u.shadow_op.pages * sizeof(unsigned long),
-                       &desc, GFP_KERNEL);
-               set_xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap,
-                                    xencomm_pa(desc));
+
+               if (xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap))
+               {
+                       desc = xencomm_map(
+                               
xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap),
+                               kern_op.u.shadow_op.pages * sizeof(unsigned 
long));
+       
+                       if (desc == NULL)
+                               ret = -ENOMEM;
+
+                       set_xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap,
+                                        desc);
+               }
                break;
        case XEN_DOMCTL_max_mem:
                break;
        case XEN_DOMCTL_setvcpucontext:
        case XEN_DOMCTL_getvcpucontext:
-               ret = xencomm_create(
+               desc = xencomm_map(
                        xen_guest_handle(kern_op.u.vcpucontext.ctxt),
-                       sizeof(vcpu_guest_context_t),
-                       &desc, GFP_KERNEL);
+                       sizeof(vcpu_guest_context_t));
+
+               if (desc == NULL)
+                       ret = -ENOMEM;
+
                set_xen_guest_handle(kern_op.u.vcpucontext.ctxt,
-                                    xencomm_pa(desc));
+                                    desc);
                break;
        case XEN_DOMCTL_getvcpuinfo:
                break;
        case XEN_DOMCTL_setvcpuaffinity:
        case XEN_DOMCTL_getvcpuaffinity:
-               ret = xencomm_create(
+               desc = xencomm_map(
                        xen_guest_handle(kern_op.u.vcpuaffinity.cpumap.bitmap),
-                       (kern_op.u.vcpuaffinity.cpumap.nr_cpus + 7) / 8,
-                       &desc, GFP_KERNEL);
+                       (kern_op.u.vcpuaffinity.cpumap.nr_cpus + 7) / 8);
+               
+               if (desc == NULL)
+                       ret = -ENOMEM;
+               
                set_xen_guest_handle(kern_op.u.vcpuaffinity.cpumap.bitmap,
-                                    xencomm_pa(desc));
+                                    desc);
                break;
        case XEN_DOMCTL_max_vcpus:
        case XEN_DOMCTL_scheduler_op:
@@ -325,7 +384,7 @@ static int xenppc_privcmd_domctl(privcmd
        if (ret)
                goto out; /* error mapping the nested pointer */
 
-       ret = plpar_hcall_norets(XEN_MARK(hypercall->op), xencomm_pa(op_desc));
+       ret = plpar_hcall_norets(XEN_MARK(hypercall->op),op_desc);
 
        if (copy_to_user(user_op, &kern_op, sizeof(xen_domctl_t)))
                ret = -EFAULT;
@@ -341,7 +400,7 @@ static int xenppc_privcmd_sysctl(privcmd
        xen_sysctl_t kern_op;
        xen_sysctl_t __user *user_op = (xen_sysctl_t __user *)hypercall->arg[0];
        struct xencomm_desc *op_desc;
-       struct xencomm_desc *desc = NULL;
+       void *desc = NULL;
        int ret = 0;
 
        if (copy_from_user(&kern_op, user_op, sizeof(xen_sysctl_t)))
@@ -353,18 +412,22 @@ static int xenppc_privcmd_sysctl(privcmd
                return -EACCES;
        }
 
-       ret = xencomm_create(&kern_op, sizeof(xen_sysctl_t), &op_desc, 
GFP_KERNEL);
-       if (ret)
-               return ret;
+       op_desc = xencomm_map(&kern_op, sizeof(xen_sysctl_t));
+
+       if (op_desc == NULL)
+               return -ENOMEM;
 
        switch (kern_op.cmd) {
        case XEN_SYSCTL_readconsole:
-               ret = xencomm_create(
+               desc = xencomm_map(
                        xen_guest_handle(kern_op.u.readconsole.buffer),
-                       kern_op.u.readconsole.count,
-                       &desc, GFP_KERNEL);
+                       kern_op.u.readconsole.count);
+
+               if (desc == NULL)
+                       ret = -ENOMEM;
+       
                set_xen_guest_handle(kern_op.u.readconsole.buffer,
-                                    xencomm_pa(desc));
+                                    desc);
                break;
        case XEN_SYSCTL_tbuf_op:
        case XEN_SYSCTL_physinfo:
@@ -376,13 +439,16 @@ static int xenppc_privcmd_sysctl(privcmd
                printk(KERN_ERR "%s: unknown sysctl cmd %d\n", __func__, 
kern_op.cmd);
                return -ENOSYS;
        case XEN_SYSCTL_getdomaininfolist:
-               ret = xencomm_create(
+               desc = xencomm_map(
                        xen_guest_handle(kern_op.u.getdomaininfolist.buffer),
                        kern_op.u.getdomaininfolist.max_domains *
-                                       sizeof(xen_domctl_getdomaininfo_t),
-                       &desc, GFP_KERNEL);
+                                       sizeof(xen_domctl_getdomaininfo_t));
+
+               if (desc == NULL)
+                       ret = -ENOMEM;
+
                set_xen_guest_handle(kern_op.u.getdomaininfolist.buffer,
-                                    xencomm_pa(desc));
+                                    desc);
                break;
        default:
                printk(KERN_ERR "%s: unknown sysctl cmd %d\n", __func__, 
kern_op.cmd);
@@ -392,7 +458,7 @@ static int xenppc_privcmd_sysctl(privcmd
        if (ret)
                goto out; /* error mapping the nested pointer */
 
-       ret = plpar_hcall_norets(XEN_MARK(hypercall->op), xencomm_pa(op_desc));
+       ret = plpar_hcall_norets(XEN_MARK(hypercall->op), op_desc);
 
        if (copy_to_user(user_op, &kern_op, sizeof(xen_sysctl_t)))
                ret = -EFAULT;
@@ -408,8 +474,8 @@ static int xenppc_privcmd_platform_op(pr
        xen_platform_op_t kern_op;
        xen_platform_op_t __user *user_op =
                        (xen_platform_op_t __user *)hypercall->arg[0];
-       struct xencomm_desc *op_desc;
-       struct xencomm_desc *desc = NULL;
+       void *op_desc;
+       void *desc = NULL;
        int ret = 0;
 
        if (copy_from_user(&kern_op, user_op, sizeof(xen_platform_op_t)))
@@ -421,10 +487,10 @@ static int xenppc_privcmd_platform_op(pr
                return -EACCES;
        }
 
-       ret = xencomm_create(&kern_op, sizeof(xen_platform_op_t), &op_desc,
-                       GFP_KERNEL);
-       if (ret)
-               return ret;
+       op_desc = xencomm_map(&kern_op, sizeof(xen_platform_op_t));
+
+       if (op_desc == NULL)
+               return -ENOMEM;
 
        switch (kern_op.cmd) {
        case XENPF_settime:
@@ -443,7 +509,7 @@ static int xenppc_privcmd_platform_op(pr
        if (ret)
                goto out; /* error mapping the nested pointer */
 
-       ret = plpar_hcall_norets(XEN_MARK(hypercall->op), xencomm_pa(op_desc));
+       ret = plpar_hcall_norets(XEN_MARK(hypercall->op), op_desc);
 
        if (copy_to_user(user_op, &kern_op, sizeof(xen_platform_op_t)))
                ret = -EFAULT;
@@ -457,37 +523,38 @@ int HYPERVISOR_memory_op(unsigned int cm
 int HYPERVISOR_memory_op(unsigned int cmd, void *arg)
 {
        int ret;
-       struct xencomm_desc *op_desc;
+       void *op_desc;
        xen_memory_reservation_t *mop;
 
 
        mop = (xen_memory_reservation_t *)arg;
-       ret = xencomm_create(mop, sizeof(xen_memory_reservation_t),
-                            &op_desc, GFP_KERNEL);
-       if (ret)
-               return ret;
+
+       op_desc = xencomm_map(mop, sizeof(xen_memory_reservation_t));
+
+       if (op_desc == NULL)
+               return -ENOMEM;
 
        switch (cmd) {
        case XENMEM_increase_reservation:
        case XENMEM_decrease_reservation:
        {
-               struct xencomm_desc *desc = NULL;
+               void *desc = NULL;
 
                if (xen_guest_handle(mop->extent_start)) {
-                       ret = xencomm_create(
+                       desc = xencomm_map(
                                xen_guest_handle(mop->extent_start),
                                mop->nr_extents *
-                               sizeof(*xen_guest_handle(mop->extent_start)),
-                               &desc, GFP_KERNEL);
-                       if (ret)
-                               return ret;
+                               sizeof(*xen_guest_handle(mop->extent_start)));
+
+                       if (desc == NULL)
+                               return -ENOMEM;
 
                        set_xen_guest_handle(mop->extent_start,
-                                            xencomm_pa(desc));
+                                            desc);
                }
 
                ret = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_memory_op),
-                                        cmd, xencomm_pa(op_desc));
+                                       cmd, op_desc);
 
                xencomm_free(desc);
        }
@@ -556,12 +623,13 @@ static int xenppc_privcmd_event_channel_
                return -EINVAL;
        }
 
-       ret = xencomm_create((void *)hypercall->arg[1], argsize, &desc, 
GFP_KERNEL);
-       if (ret)
-               return ret;
+       desc = xencomm_map((void *)hypercall->arg[1], argsize);
+
+       if (desc == NULL)
+               return -ENOMEM;
 
        ret = plpar_hcall_norets(XEN_MARK(hypercall->op), hypercall->arg[0],
-                       xencomm_pa(desc));
+                               desc);
 
        xencomm_free(desc);
        return ret;
@@ -604,6 +672,7 @@ int HYPERVISOR_vcpu_op(int cmd, int vcpu
        int argsize;
        const unsigned long hcall = __HYPERVISOR_vcpu_op;
        void *desc;
+       int rc;
 
        switch (cmd) {
        case  VCPUOP_initialise:
@@ -622,8 +691,14 @@ int HYPERVISOR_vcpu_op(int cmd, int vcpu
                return -ENOSYS;
        }
 
-       desc = xencomm_create_inline(extra_args);
-       (void)argsize;
-       return plpar_hcall_norets(XEN_MARK(hcall), cmd, vcpuid, desc);
-}
+       desc = xencomm_map_no_alloc(extra_args, argsize);
        
+       if (desc == NULL)
+               return -EINVAL;
+       
+       rc = plpar_hcall_norets(XEN_MARK(hcall), cmd, vcpuid, desc);
+
+       xencomm_free(desc);
+
+       return rc;
+}
diff -r ab3b5849331d -r 5eca8383a521 arch/powerpc/platforms/xen/setup.c
--- a/arch/powerpc/platforms/xen/setup.c        Sun Jan 21 08:36:53 2007 -0500
+++ b/arch/powerpc/platforms/xen/setup.c        Tue Feb 06 16:21:30 2007 -0500
@@ -33,6 +33,7 @@ EXPORT_SYMBOL(HYPERVISOR_shared_info);
 
 /* Raw start-of-day parameters from the hypervisor. */
 start_info_t *xen_start_info;
+EXPORT_SYMBOL(xen_start_info);
 
 extern struct machdep_calls mach_maple_md;
 extern void maple_pci_init(void);
@@ -150,6 +151,7 @@ int is_running_on_xen(void)
 {
        return running_on_xen;
 }
+EXPORT_SYMBOL(is_running_on_xen);
 
 static void xen_power_save(void)
 {
diff -r ab3b5849331d -r 5eca8383a521 drivers/xen/core/xencomm.c
--- a/drivers/xen/core/xencomm.c        Sun Jan 21 08:36:53 2007 -0500
+++ b/drivers/xen/core/xencomm.c        Tue Feb 06 16:21:30 2007 -0500
@@ -80,13 +80,13 @@ static struct xencomm_desc *xencomm_allo
        return desc;
 }
 
-void xencomm_free(struct xencomm_desc *desc)
+void xencomm_free(void *desc)
 {
-       if (desc)
-               free_page((unsigned long)desc);
+       if (desc && !((ulong)desc & XENCOMM_INLINE_FLAG))
+               free_page((unsigned long)__va(desc));
 }
 
-int xencomm_create(void *buffer, unsigned long bytes, struct xencomm_desc 
**ret, gfp_t gfp_mask)
+static int xencomm_create(void *buffer, unsigned long bytes, struct 
xencomm_desc **ret, gfp_t gfp_mask)
 {
        struct xencomm_desc *desc;
        int rc;
@@ -119,13 +119,74 @@ int xencomm_create(void *buffer, unsigne
        return 0;
 }
 
-void *xencomm_create_inline(void *ptr)
+/* check if memory address is within VMALLOC region  */
+static int is_phys_contiguous(unsigned long addr)
+{
+       if (!is_kernel_addr(addr))
+               return 0;
+
+       return (addr < VMALLOC_START) || (addr >= VMALLOC_END);
+}
+
+static void *xencomm_create_inline(void *ptr)
 {
        unsigned long paddr;
 
-       BUG_ON(!is_kernel_addr((unsigned long)ptr));
+       BUG_ON(!is_phys_contiguous((unsigned long)ptr));
 
        paddr = (unsigned long)xencomm_pa(ptr);
        BUG_ON(paddr & XENCOMM_INLINE_FLAG);
        return (void *)(paddr | XENCOMM_INLINE_FLAG);
 }
+
+/* "mini" routine, for stack-based communications: */
+static int xencomm_create_mini(void *buffer,
+       unsigned long bytes, struct xencomm_mini *xc_desc,
+       struct xencomm_desc **ret)
+{
+       int rc = 0;
+       struct xencomm_desc *desc;
+
+       desc = (void *)xc_desc; 
+
+       desc->nr_addrs = XENCOMM_MINI_ADDRS;
+
+       if (!(rc = xencomm_init(desc, buffer, bytes)))
+               *ret = desc;
+
+       return rc;
+}
+
+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 || desc == NULL)
+               return NULL;
+
+       return (void *)__pa(desc);
+}
+
+void *__xencomm_map_no_alloc(void *ptr, unsigned long bytes, 
+                       struct xencomm_mini *xc_desc)
+{
+       int rc;
+       struct xencomm_desc *desc = NULL;
+
+       if (is_phys_contiguous((unsigned long)ptr))
+               return xencomm_create_inline(ptr);
+
+       rc = xencomm_create_mini(ptr, bytes, xc_desc,
+                               &desc);
+
+       if (rc)
+               return NULL;
+ 
+       return (void *)__pa(desc);
+}
diff -r ab3b5849331d -r 5eca8383a521 include/xen/xencomm.h
--- a/include/xen/xencomm.h     Sun Jan 21 08:36:53 2007 -0500
+++ b/include/xen/xencomm.h     Tue Feb 06 16:21:30 2007 -0500
@@ -16,6 +16,7 @@
  * Copyright (C) IBM Corp. 2006
  *
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
+ *          Jerone Young <jyoung5@xxxxxxxxxx>
  */
 
 #ifndef _LINUX_XENCOMM_H_
@@ -23,10 +24,21 @@
 
 #include <xen/interface/xencomm.h>
 
-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);
+#define XENCOMM_MINI_ADDRS 3
+struct xencomm_mini {
+       struct xencomm_desc _desc;
+       uint64_t address[XENCOMM_MINI_ADDRS];
+};
+
+extern void xencomm_free(void *desc);
+extern void *xencomm_map(void *ptr, unsigned long bytes);
+extern void *__xencomm_map_no_alloc(void *ptr, unsigned long bytes, 
+                               struct xencomm_mini *xc_area);
+
+#define xencomm_map_no_alloc(ptr, bytes) \
+       ({struct xencomm_mini xc_desc\
+               __attribute__((__aligned__(sizeof(struct xencomm_mini))));\
+               __xencomm_map_no_alloc(ptr, bytes, &xc_desc);})
 
 /* 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

<Prev in Thread] Current Thread [Next in Thread>
  • [XenPPC] [linux-ppc-2.6] [XEN] xencomm fixes for various runtime situations, Xen patchbot-linux-ppc-2 . 6 <=