# 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
|