[PATCH 6/9] libxc: add hypercall buffer arrays
David Vrabel
david.vrabel at citrix.com
Wed Nov 6 09:49:43 EST 2013
From: David Vrabel <david.vrabel at citrix.com>
Hypercall buffer arrays are used when a hypercall takes a variable
length array of buffers.
Signed-off-by: David Vrabel <david.vrabel at citrix.com>
Acked-by: Ian Campbell <ian.campbell at citrix.com>
Reviewed-by: Daniel Kiper <daniel.kiper at oracle.com>
Tested-by: Daniel Kiper <daniel.kiper at oracle.com>
Reviewed-by: Andrew Cooper <andrew.cooper3 at citrix.com>
---
tools/libxc/xc_hcall_buf.c | 73 ++++++++++++++++++++++++++++++++++++++++++++
tools/libxc/xenctrl.h | 27 ++++++++++++++++
2 files changed, 100 insertions(+), 0 deletions(-)
diff --git a/tools/libxc/xc_hcall_buf.c b/tools/libxc/xc_hcall_buf.c
index c354677..e762a93 100644
--- a/tools/libxc/xc_hcall_buf.c
+++ b/tools/libxc/xc_hcall_buf.c
@@ -228,6 +228,79 @@ void xc__hypercall_bounce_post(xc_interface *xch, xc_hypercall_buffer_t *b)
xc__hypercall_buffer_free(xch, b);
}
+struct xc_hypercall_buffer_array {
+ unsigned max_bufs;
+ xc_hypercall_buffer_t *bufs;
+};
+
+xc_hypercall_buffer_array_t *xc_hypercall_buffer_array_create(xc_interface *xch,
+ unsigned n)
+{
+ xc_hypercall_buffer_array_t *array;
+ xc_hypercall_buffer_t *bufs = NULL;
+
+ array = malloc(sizeof(*array));
+ if ( array == NULL )
+ goto error;
+
+ bufs = calloc(n, sizeof(*bufs));
+ if ( bufs == NULL )
+ goto error;
+
+ array->max_bufs = n;
+ array->bufs = bufs;
+
+ return array;
+
+error:
+ free(bufs);
+ free(array);
+ return NULL;
+}
+
+void *xc__hypercall_buffer_array_alloc(xc_interface *xch,
+ xc_hypercall_buffer_array_t *array,
+ unsigned index,
+ xc_hypercall_buffer_t *hbuf,
+ size_t size)
+{
+ void *buf;
+
+ if ( index >= array->max_bufs || array->bufs[index].hbuf )
+ abort();
+
+ buf = xc__hypercall_buffer_alloc(xch, hbuf, size);
+ if ( buf )
+ array->bufs[index] = *hbuf;
+ return buf;
+}
+
+void *xc__hypercall_buffer_array_get(xc_interface *xch,
+ xc_hypercall_buffer_array_t *array,
+ unsigned index,
+ xc_hypercall_buffer_t *hbuf)
+{
+ if ( index >= array->max_bufs || array->bufs[index].hbuf == NULL )
+ abort();
+
+ *hbuf = array->bufs[index];
+ return array->bufs[index].hbuf;
+}
+
+void xc_hypercall_buffer_array_destroy(xc_interface *xc,
+ xc_hypercall_buffer_array_t *array)
+{
+ unsigned i;
+
+ if ( array == NULL )
+ return;
+
+ for (i = 0; i < array->max_bufs; i++ )
+ xc__hypercall_buffer_free(xc, &array->bufs[i]);
+ free(array->bufs);
+ free(array);
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index 8cf3f3b..a7e8c31 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -321,6 +321,33 @@ void xc__hypercall_buffer_free_pages(xc_interface *xch, xc_hypercall_buffer_t *b
#define xc_hypercall_buffer_free_pages(_xch, _name, _nr) xc__hypercall_buffer_free_pages(_xch, HYPERCALL_BUFFER(_name), _nr)
/*
+ * Array of hypercall buffers.
+ *
+ * Create an array with xc_hypercall_buffer_array_create() and
+ * populate it by declaring one hypercall buffer in a loop and
+ * allocating the buffer with xc_hypercall_buffer_array_alloc().
+ *
+ * To access a previously allocated buffers, declare a new hypercall
+ * buffer and call xc_hypercall_buffer_array_get().
+ *
+ * Destroy the array with xc_hypercall_buffer_array_destroy() to free
+ * the array and all its alocated hypercall buffers.
+ */
+struct xc_hypercall_buffer_array;
+typedef struct xc_hypercall_buffer_array xc_hypercall_buffer_array_t;
+
+xc_hypercall_buffer_array_t *xc_hypercall_buffer_array_create(xc_interface *xch, unsigned n);
+void *xc__hypercall_buffer_array_alloc(xc_interface *xch, xc_hypercall_buffer_array_t *array,
+ unsigned index, xc_hypercall_buffer_t *hbuf, size_t size);
+#define xc_hypercall_buffer_array_alloc(_xch, _array, _index, _name, _size) \
+ xc__hypercall_buffer_array_alloc(_xch, _array, _index, HYPERCALL_BUFFER(_name), _size)
+void *xc__hypercall_buffer_array_get(xc_interface *xch, xc_hypercall_buffer_array_t *array,
+ unsigned index, xc_hypercall_buffer_t *hbuf);
+#define xc_hypercall_buffer_array_get(_xch, _array, _index, _name, _size) \
+ xc__hypercall_buffer_array_get(_xch, _array, _index, HYPERCALL_BUFFER(_name))
+void xc_hypercall_buffer_array_destroy(xc_interface *xc, xc_hypercall_buffer_array_t *array);
+
+/*
* CPUMAP handling
*/
typedef uint8_t *xc_cpumap_t;
--
1.7.2.5
More information about the kexec
mailing list