From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: xen-devel@lists.xenproject.org, msw@amazon.com,
aliguori@amazon.com, amesserl@rackspace.com,
rick.harris@rackspace.com, paul.voccio@rackspace.com,
steven.wilson@rackspace.com, major.hayden@rackspace.com,
josh.kearney@rackspace.com, jinsong.liu@alibaba-inc.com,
xiantao.zxt@alibaba-inc.com, boris.ostrovsky@oracle.com,
daniel.kiper@oracle.com, elena.ufimtseva@oracle.com,
bob.liu@oracle.com, lars.kurth@citrix.com, hanweidong@huawei.com,
peter.huangpeng@huawei.com, fanhenglong@huawei.com,
liuyingdong@huawei.com, john.liuqiming@huawei.com,
jbeulich@suse.com, andrew.cooper3@citrix.com,
mpohlack@amazon.com, ian.campbell@citrix.com
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Subject: [PATCH v1 2/5] xen/xsplice: Hypervisor implementation of XEN_XSPLICE_op
Date: Wed, 16 Sep 2015 17:01:13 -0400 [thread overview]
Message-ID: <1442437276-2620-3-git-send-email-konrad.wilk@oracle.com> (raw)
In-Reply-To: <1442437276-2620-1-git-send-email-konrad.wilk@oracle.com>
The implementation does not actually do any patching.
It just adds the framework for doing the hypercalls,
keeping track of ELF payloads, and the basic operations:
- query which payloads exist,
- query for specific payloads,
- check*1, apply*1, and unload payloads.
*1: Which of course in this patch are nops.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
xen/common/Makefile | 1 +
xen/common/keyhandler.c | 8 +-
xen/common/sysctl.c | 6 +
xen/common/xsplice.c | 442 ++++++++++++++++++++++++++++++++++++
xen/include/public/sysctl.h | 156 +++++++++++++
xen/include/xen/xsplice.h | 9 +
xen/xsm/flask/hooks.c | 3 +
xen/xsm/flask/policy/access_vectors | 2 +
8 files changed, 626 insertions(+), 1 deletion(-)
create mode 100644 xen/common/xsplice.c
create mode 100644 xen/include/xen/xsplice.h
diff --git a/xen/common/Makefile b/xen/common/Makefile
index 1726fac..7d53234 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -55,6 +55,7 @@ obj-y += vmap.o
obj-y += vsprintf.o
obj-y += wait.o
obj-y += xmalloc_tlsf.o
+obj-y += xsplice.o
obj-bin-$(CONFIG_X86) += $(foreach n,decompress bunzip2 unxz unlzma unlzo unlz4 earlycpio,$(n).init.o)
diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c
index 5d21e48..1d4574a 100644
--- a/xen/common/keyhandler.c
+++ b/xen/common/keyhandler.c
@@ -18,6 +18,7 @@
#include <xen/mm.h>
#include <xen/watchdog.h>
#include <xen/init.h>
+#include <xen/xsplice.h>
#include <asm/debugger.h>
#include <asm/div64.h>
@@ -455,6 +456,11 @@ static struct keyhandler spinlock_reset_keyhandler = {
.desc = "reset lock profile info"
};
#endif
+static struct keyhandler xsplice_printall_keyhandler = {
+ .diagnostic = 1,
+ .u.fn = xsplice_printall,
+ .desc = "print splicing information"
+};
static void run_all_nonirq_keyhandlers(unsigned long unused)
{
@@ -567,7 +573,7 @@ void __init initialize_keytable(void)
register_keyhandler('l', &spinlock_printall_keyhandler);
register_keyhandler('L', &spinlock_reset_keyhandler);
#endif
-
+ register_keyhandler('x', &xsplice_printall_keyhandler);
}
/*
diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c
index 85e853f..517d684 100644
--- a/xen/common/sysctl.c
+++ b/xen/common/sysctl.c
@@ -28,6 +28,7 @@
#include <xsm/xsm.h>
#include <xen/pmstat.h>
#include <xen/gcov.h>
+#include <xen/xsplice.h>
long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
{
@@ -460,6 +461,11 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
ret = tmem_control(&op->u.tmem_op);
break;
+ case XEN_SYSCTL_xsplice_op:
+ ret = xsplice_control(&op->u.xsplice);
+ copyback = 1;
+ break;
+
default:
ret = arch_do_sysctl(op, u_sysctl);
copyback = 0;
diff --git a/xen/common/xsplice.c b/xen/common/xsplice.c
new file mode 100644
index 0000000..d330efe
--- /dev/null
+++ b/xen/common/xsplice.c
@@ -0,0 +1,442 @@
+/*
+ * xSplice - Copyright Oracle Corp. Inc 2015.
+ *
+ * Author: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+ */
+
+#include <xen/smp.h>
+#include <xen/keyhandler.h>
+#include <xen/spinlock.h>
+#include <xen/mm.h>
+#include <xen/list.h>
+#include <xen/guest_access.h>
+#include <xen/stdbool.h>
+#include <xen/sched.h>
+#include <xen/lib.h>
+#include <xen/xsplice.h>
+#include <public/sysctl.h>
+
+#include <asm/event.h>
+
+static DEFINE_SPINLOCK(payload_list_lock);
+static LIST_HEAD(payload_list);
+
+static unsigned int payload_cnt;
+static unsigned int payload_version = 1;
+
+struct payload {
+ char *id; /* Name of it. Past this structure. */
+ ssize_t id_len; /* Length of the name. */
+
+ uint8_t *raw; /* Pointer to Elf file. Past 'id'*/
+ ssize_t raw_len; /* Size of 'raw'. */
+
+ int32_t status; /* XSPLICE_STATUS_* or Exx type value. */
+ int32_t old_status; /* XSPLICE_STATUS_* or Exx type value. */
+
+ struct spinlock cmd_lock; /* Lock against the action. */
+ uint32_t cmd; /* Action request. XSPLICE_ACTION_* */
+
+ /* Boring things below: */
+ struct list_head list; /* Linked to 'payload_list'. */
+ ssize_t len; /* This structure + raw_len + id_len + 1. */
+
+ struct tasklet tasklet;
+};
+
+static const char *status2str(int64_t status)
+{
+#define STATUS(x) [XSPLICE_STATUS_##x] = #x
+ static const char *const names[] = {
+ STATUS(LOADED),
+ STATUS(PROGRESS),
+ STATUS(CHECKED),
+ STATUS(APPLIED),
+ STATUS(REVERTED),
+ };
+#undef STATUS
+
+ if (status >= ARRAY_SIZE(names))
+ return "unknown";
+
+ if (status < 0)
+ return "-EXX";
+
+ if (!names[status])
+ return "unknown";
+
+ return names[status];
+}
+
+void xsplice_printall(unsigned char key)
+{
+ struct payload *data;
+
+ spin_lock(&payload_list_lock);
+
+ list_for_each_entry ( data, &payload_list, list )
+ {
+ printk(" id=%s status=%s(%d,old=%d): \n", data->id,
+ status2str(data->status), data->status, data->old_status);
+ }
+ spin_unlock(&payload_list_lock);
+}
+
+static int verify_id(xen_xsplice_id_t *id)
+{
+ if ( id->size == 0 || id->size > XEN_XSPLICE_ID_SIZE )
+ return -EINVAL;
+
+ if ( id->_pad != 0 )
+ return -EINVAL;
+
+ if ( !guest_handle_okay(id->name, id->size) )
+ return -EINVAL;
+
+ return 0;
+}
+
+int find_payload(xen_xsplice_id_t *id, bool_t need_lock, struct payload **f)
+{
+ struct payload *data;
+ XEN_GUEST_HANDLE_PARAM(char) str;
+ char name[XEN_XSPLICE_ID_SIZE]; /* 128 bytes on stack. Perhaps kzalloc? */
+ int rc = -EINVAL;
+
+ rc = verify_id(id);
+ if ( rc )
+ return rc;
+
+ str = guest_handle_cast(id->name, char);
+ if ( copy_from_guest(name, str, id->size) )
+ return -EFAULT;
+
+ if ( need_lock )
+ spin_lock(&payload_list_lock);
+
+ rc = -ENOENT;
+ list_for_each_entry ( data, &payload_list, list )
+ {
+ if ( !strncmp(data->id, name, data->id_len) )
+ {
+ *f = data;
+ rc = 0;
+ break;
+ }
+ }
+
+ if ( need_lock )
+ spin_unlock(&payload_list_lock);
+
+ return rc;
+}
+
+
+static int verify_payload(xen_sysctl_xsplice_upload_t *upload)
+{
+ if ( verify_id(&upload->id) )
+ return -EINVAL;
+
+ if ( upload->size == 0 )
+ return -EINVAL;
+
+ if ( !guest_handle_okay(upload->payload, upload->size) )
+ return -EFAULT;
+
+ return 0;
+}
+
+/*
+ * We MUST be holding the spinlock.
+ */
+static void __free_payload(struct payload *data)
+{
+ list_del(&data->list);
+ payload_cnt --;
+ payload_version ++;
+ tasklet_kill(&data->tasklet);
+ free_xenheap_pages(data, get_order_from_bytes(data->len));
+}
+
+static void xsplice_tasklet(unsigned long _data)
+{
+ struct payload *data = (struct payload *)_data;
+
+ spin_lock(&data->cmd_lock);
+ switch ( data->cmd ) {
+ case XSPLICE_ACTION_CHECK:
+ /* TODO: Do the operation here. */
+ data->status = XSPLICE_STATUS_CHECKED;
+ break;
+ case XSPLICE_ACTION_APPLY:
+ /* TODO: Well, do the work :-) */
+ data->status = XSPLICE_STATUS_APPLIED;
+ break;
+ case XSPLICE_ACTION_REVERT:
+ /* TODO: Well, do the work :-) */
+ data->status = XSPLICE_STATUS_REVERTED;
+ break;
+ default:
+ data->status = -EINVAL;
+ }
+ spin_unlock(&data->cmd_lock);
+}
+
+static int xsplice_upload(xen_sysctl_xsplice_upload_t *upload)
+{
+ struct payload *data = NULL;
+ int rc;
+ ssize_t len;
+
+ rc = verify_payload(upload);
+ if ( rc )
+ return rc;
+
+ rc = find_payload(&upload->id, true, &data);
+ if ( rc == 0 /* Found. */ )
+ return -EEXIST;
+
+ if ( rc != -ENOENT )
+ return rc;
+
+ /*
+ * Compute the size of the structures which need to be verified.
+ * The 1 is for the extra \0 in case name does not have it.
+ */
+ len = sizeof(*data) + upload->id.size + 1 + upload->size;
+ data = alloc_xenheap_pages(get_order_from_bytes(len), 0);
+ if ( !data )
+ return -ENOMEM;
+
+ memset(data, 0, len);
+ data->len = len;
+
+ /* At the end of structure we put the name. */
+ data->id = (char *)data + sizeof(*data);
+ data->id_len = upload->id.size;
+ /* And after the name + \0 we stick the raw ELF data. */
+ data->raw = (uint8_t *)data + sizeof(*data) + data->id_len + 1;
+ data->raw_len = upload->size;
+
+ rc = -EFAULT;
+ if ( copy_from_guest(data->raw, upload->payload, upload->size) )
+ goto err_out;
+
+ if ( copy_from_guest(data->id, upload->id.name, upload->id.size) )
+ goto err_out;
+
+ data->status = XSPLICE_STATUS_LOADED;
+ INIT_LIST_HEAD(&data->list);
+ spin_lock_init(&data->cmd_lock);
+ data->cmd = 0;
+ tasklet_init(&data->tasklet, xsplice_tasklet, (unsigned long)data);
+
+ spin_lock(&payload_list_lock);
+ list_add_tail(&data->list, &payload_list);
+ payload_cnt ++;
+ payload_version ++;
+ spin_unlock(&payload_list_lock);
+
+ return 0;
+
+ err_out:
+ free_xenheap_pages(data, get_order_from_bytes(len));
+ return rc;
+}
+
+static int xsplice_get(xen_sysctl_xsplice_summary_t *summary)
+{
+ struct payload *data;
+ int rc;
+
+ if ( summary->status.status )
+ return -EINVAL;
+
+ if ( summary->status._pad != 0 )
+ return -EINVAL;
+
+ rc = verify_id(&summary->id );
+ if ( rc )
+ return rc;
+
+ rc = find_payload(&summary->id, true, &data);
+ if ( rc )
+ return rc;
+
+ summary->status.status = data->status;
+
+ return 0;
+}
+
+static int xsplice_list(xen_sysctl_xsplice_list_t *list)
+{
+ xen_xsplice_status_t status;
+ struct payload *data;
+ unsigned int idx = 0, i = 0;
+ int rc = 0;
+ unsigned int ver = payload_version;
+
+ // TODO: Increase to a 64 or other value. Leave 4 for debug.
+ if ( list->nr > 4 )
+ return -E2BIG;
+
+ if ( list->_pad != 0 )
+ return -EINVAL;
+
+ if ( guest_handle_is_null(list->status) ||
+ guest_handle_is_null(list->id) ||
+ guest_handle_is_null(list->len) )
+ return -EINVAL;
+
+ if ( !guest_handle_okay(list->status, sizeof(status) * list->nr) ||
+ !guest_handle_okay(list->id, XEN_XSPLICE_ID_SIZE * list->nr) ||
+ !guest_handle_okay(list->len, sizeof(uint32_t) * list->nr) )
+ return -EINVAL;
+
+ spin_lock(&payload_list_lock);
+ if ( list->idx > payload_cnt )
+ {
+ spin_unlock(&payload_list_lock);
+ return -EINVAL;
+ }
+
+ status._pad = 0; /* No stack leaking. */
+ list_for_each_entry( data, &payload_list, list )
+ {
+ uint32_t len;
+
+ if ( list->idx > i++ )
+ continue;
+
+ status.status = data->status;
+ len = data->id_len;
+
+ /* N.B. 'idx' != 'i'. */
+ if ( copy_to_guest_offset(list->id, idx * XEN_XSPLICE_ID_SIZE,
+ data->id, len) ||
+ copy_to_guest_offset(list->len, idx, &len, 1) ||
+ copy_to_guest_offset(list->status, idx, &status, 1) )
+ {
+ rc = -EFAULT;
+ break;
+ }
+ idx ++;
+ if ( hypercall_preempt_check() || (idx + 1 > list->nr) )
+ {
+ break;
+ }
+ }
+ list->nr = payload_cnt - i; /* Remaining amount. */
+ spin_unlock(&payload_list_lock);
+ list->version = ver;
+
+ /* And how many we have processed. */
+ return rc ? rc : idx;
+}
+
+static int xsplice_action(xen_sysctl_xsplice_action_t *action)
+{
+ struct payload *data;
+ int rc;
+
+ if ( action->_pad != 0 )
+ return -EINVAL;
+
+ rc = verify_id(&action->id);
+ if ( rc )
+ return rc;
+
+ spin_lock(&payload_list_lock);
+ rc = find_payload(&action->id, false /* we are holding the lock. */, &data);
+ if ( rc )
+ goto out;
+
+ if ( action->cmd != XSPLICE_ACTION_UNLOAD )
+ spin_lock(&data->cmd_lock);
+
+ switch ( action->cmd )
+ {
+ case XSPLICE_ACTION_CHECK:
+ if ( ( data->status == XSPLICE_STATUS_LOADED ) )
+ {
+ data->old_status = data->status;
+ data->status = XSPLICE_STATUS_PROGRESS;
+ data->cmd = action->cmd;
+ tasklet_schedule(&data->tasklet);
+ rc = 0;
+ } else if ( data->status == XSPLICE_STATUS_CHECKED )
+ {
+ rc = 0;
+ }
+ break;
+ case XSPLICE_ACTION_UNLOAD:
+ if ( ( data->status == XSPLICE_STATUS_REVERTED ) ||
+ ( data->status == XSPLICE_STATUS_LOADED ) ||
+ ( data->status == XSPLICE_STATUS_CHECKED ) )
+ {
+ __free_payload(data);
+ /* No touching 'data' from here on! */
+ rc = 0;
+ }
+ break;
+ case XSPLICE_ACTION_REVERT:
+ if ( data->status == XSPLICE_STATUS_APPLIED )
+ {
+ data->old_status = data->status;
+ data->status = XSPLICE_STATUS_PROGRESS;
+ data->cmd = action->cmd;
+ rc = 0;
+ /* TODO: Tasklet is not good for this. We need a different vehicle. */
+ tasklet_schedule(&data->tasklet);
+ }
+ break;
+ case XSPLICE_ACTION_APPLY:
+ if ( ( data->status == XSPLICE_STATUS_CHECKED ) ||
+ ( data->status == XSPLICE_STATUS_REVERTED ))
+ {
+ data->old_status = data->status;
+ data->status = XSPLICE_STATUS_PROGRESS;
+ data->cmd = action->cmd;
+ rc = 0;
+ /* TODO: Tasklet is not good for this. We need a different vehicle. */
+ tasklet_schedule(&data->tasklet);
+ }
+ break;
+ default:
+ rc = -ENOSYS;
+ break;
+ }
+
+ if ( action->cmd != XSPLICE_ACTION_UNLOAD )
+ spin_unlock(&data->cmd_lock);
+ out:
+ spin_unlock(&payload_list_lock);
+
+ return rc;
+}
+
+int xsplice_control(xen_sysctl_xsplice_op_t *xsplice)
+{
+ int rc;
+
+ switch ( xsplice->cmd )
+ {
+ case XEN_SYSCTL_XSPLICE_UPLOAD:
+ rc = xsplice_upload(&xsplice->u.upload);
+ break;
+ case XEN_SYSCTL_XSPLICE_GET:
+ rc = xsplice_get(&xsplice->u.get);
+ break;
+ case XEN_SYSCTL_XSPLICE_LIST:
+ rc = xsplice_list(&xsplice->u.list);
+ break;
+ case XEN_SYSCTL_XSPLICE_ACTION:
+ rc = xsplice_action(&xsplice->u.action);
+ break;
+ default:
+ rc = -ENOSYS;
+ break;
+ }
+
+ return rc;
+}
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index 0cacacc..08952de 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -764,6 +764,160 @@ struct xen_sysctl_tmem_op {
typedef struct xen_sysctl_tmem_op xen_sysctl_tmem_op_t;
DEFINE_XEN_GUEST_HANDLE(xen_sysctl_tmem_op_t);
+/*
+ * XEN_SYSCTL_XSPLICE_op
+ *
+ * Refer to the docs/misc/xsplice.markdown for the design details
+ * of this hypercall.
+ */
+
+/*
+ * Structure describing an ELF payload. Uniquely identifies the
+ * payload. Should be human readable.
+ * Recommended length is XEN_XSPLICE_ID_SIZE.
+ */
+#define XEN_XSPLICE_ID_SIZE 128
+struct xen_xsplice_id {
+ XEN_GUEST_HANDLE_64(char) name; /* IN, pointer to name. */
+ uint32_t size; /* IN, size of name. May be upto
+ XEN_XSPLICE_ID_SIZE. */
+ uint32_t _pad;
+};
+typedef struct xen_xsplice_id xen_xsplice_id_t;
+DEFINE_XEN_GUEST_HANDLE(xen_xsplice_id_t);
+
+/*
+ * Upload a payload to the hypervisor. The payload is verified
+ * against basic checks and if there are any issues the proper return code
+ * will be returned. The payload is not applied at this time - that is
+ * controlled by XEN_SYSCTL_XSPLICE_ACTION.
+ *
+ * The return value is zero if the payload was succesfully uploaded.
+ * Otherwise an EXX return value is provided. Duplicate `id` are not supported.
+ * The payload at this point is verified against the basic checks.
+ *
+ * The `payload` is the ELF payload as mentioned in the `Payload format`
+ * section in the xSplice design document.
+ */
+#define XEN_SYSCTL_XSPLICE_UPLOAD 0
+struct xen_sysctl_xsplice_upload {
+ xen_xsplice_id_t id; /* IN, name of the patch. */
+ uint64_t size; /* IN, size of the ELF file. */
+ XEN_GUEST_HANDLE_64(uint8) payload; /* IN, the ELF file. */
+};
+typedef struct xen_sysctl_xsplice_upload xen_sysctl_xsplice_upload_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_xsplice_upload_t);
+
+/*
+ * Retrieve an status of an specific payload.
+ *
+ * Upon completion the `struct xen_xsplice_status` is updated.
+ *
+ * The return value is zero on success and EXX on failure. This operation
+ * is synchronous and does not require preemption.
+ */
+#define XEN_SYSCTL_XSPLICE_GET 1
+
+struct xen_xsplice_status {
+#define XSPLICE_STATUS_LOADED 0x01
+#define XSPLICE_STATUS_PROGRESS 0x02
+#define XSPLICE_STATUS_CHECKED 0x04
+#define XSPLICE_STATUS_APPLIED 0x08
+#define XSPLICE_STATUS_REVERTED 0x10
+ /* Any negative value is an error. The error would be in -EXX format. */
+ int32_t status; /* OUT, On IN has to be zero. */
+ uint32_t _pad; /* IN, Must be zero. */
+};
+typedef struct xen_xsplice_status xen_xsplice_status_t;
+DEFINE_XEN_GUEST_HANDLE(xen_xsplice_status_t);
+
+struct xen_sysctl_xsplice_summary {
+ xen_xsplice_id_t id; /* IN, name of the payload. */
+ xen_xsplice_status_t status; /* IN/OUT, status of it. */
+};
+typedef struct xen_sysctl_xsplice_summary xen_sysctl_xsplice_summary_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_xsplice_summary_t);
+
+/*
+ * Retrieve an array of abbreviated status and names of payloads that are
+ * loaded in the hypervisor.
+ *
+ * If the hypercall returns an positive number, it is the number (up to `nr`)
+ * of the payloads returned, along with `nr` updated with the number of remaining
+ * payloads, `version` updated (it may be the same across hypercalls. If it
+ * varies the data is stale and further calls could fail). The `status`,
+ * `id`, and `len`' are updated at their designed index value (`idx`) with
+ * the returned value of data.
+ *
+ * If the hypercall returns E2BIG the `count` is too big and should be
+ * lowered.
+ *
+ * This operation can be preempted by the hypercall returning EAGAIN.
+ * Retry.
+ *
+ * Note that due to the asynchronous nature of hypercalls the domain might have
+ * added or removed the number of payloads making this information stale. It is
+ * the responsibility of the toolstack to use the `version` field to check
+ * between each invocation. if the version differs it should discard the stale
+ * data and start from scratch. It is OK for the toolstack to use the new
+ * `version` field.
+ */
+#define XEN_SYSCTL_XSPLICE_LIST 2
+struct xen_sysctl_xsplice_list {
+ uint32_t version; /* IN/OUT: Initially *MUST* be zero.
+ On subsequent calls reuse value.
+ If varies between calls, we are
+ * getting stale data. */
+ uint32_t idx; /* IN/OUT: Index into array. */
+ uint32_t nr; /* IN: How many status, id, and len
+ should populate.
+ OUT: How many payloads left. */
+ uint32_t _pad; /* IN: Must be zero. */
+ XEN_GUEST_HANDLE_64(xen_xsplice_status_t) status; /* OUT. Must have enough
+ space allocate for n of them. */
+ XEN_GUEST_HANDLE_64(char) id; /* OUT: Array of ids. Each member
+ MUST XEN_XSPLICE_ID_SIZE in size.
+ Must have n of them. */
+ XEN_GUEST_HANDLE_64(uint32) len; /* OUT: Array of lengths of ids.
+ Must have n of them. */
+};
+typedef struct xen_sysctl_xsplice_list xen_sysctl_xsplice_list_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_xsplice_list_t);
+
+/*
+ * Perform an operation on the payload structure referenced by the `id` field.
+ * The operation request is asynchronous and the status should be retrieved
+ * by using either XEN_SYSCTL_XSPLICE_GET or XEN_SYSCTL_XSPLICE_LIST hypercall.
+ * If the operation fails more details on the operation can be retrieved via
+ * XEN_SYSCTL_XSPLICE_INFO hypercall.
+ */
+#define XEN_SYSCTL_XSPLICE_ACTION 3
+struct xen_sysctl_xsplice_action {
+ xen_xsplice_id_t id; /* IN, name of the patch. */
+#define XSPLICE_ACTION_CHECK 1
+#define XSPLICE_ACTION_UNLOAD 2
+#define XSPLICE_ACTION_REVERT 3
+#define XSPLICE_ACTION_APPLY 4
+ uint32_t cmd; /* IN: XSPLICE_ACTION_*. */
+ uint32_t _pad; /* IN: Always zero. */
+ uint64_aligned_t time; /* IN: Zero if no timeout. */
+};
+typedef struct xen_sysctl_xsplice_action xen_sysctl_xsplice_action_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_xsplice_action_t);
+
+struct xen_sysctl_xsplice_op {
+ uint32_t cmd; /* IN: XEN_SYSCTL_XSPLICE_* */
+ uint32_t _pad; /* IN: Always zero. */
+ union {
+ xen_sysctl_xsplice_upload_t upload;
+ xen_sysctl_xsplice_list_t list;
+ xen_sysctl_xsplice_summary_t get;
+ xen_sysctl_xsplice_action_t action;
+ } u;
+};
+typedef struct xen_sysctl_xsplice_op xen_sysctl_xsplice_op_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_xsplice_op_t);
+
struct xen_sysctl {
uint32_t cmd;
#define XEN_SYSCTL_readconsole 1
@@ -789,6 +943,7 @@ struct xen_sysctl {
#define XEN_SYSCTL_pcitopoinfo 22
#define XEN_SYSCTL_psr_cat_op 23
#define XEN_SYSCTL_tmem_op 24
+#define XEN_SYSCTL_xsplice_op 25
uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
union {
struct xen_sysctl_readconsole readconsole;
@@ -814,6 +969,7 @@ struct xen_sysctl {
struct xen_sysctl_psr_cmt_op psr_cmt_op;
struct xen_sysctl_psr_cat_op psr_cat_op;
struct xen_sysctl_tmem_op tmem_op;
+ struct xen_sysctl_xsplice_op xsplice;
uint8_t pad[128];
} u;
};
diff --git a/xen/include/xen/xsplice.h b/xen/include/xen/xsplice.h
new file mode 100644
index 0000000..41e28da
--- /dev/null
+++ b/xen/include/xen/xsplice.h
@@ -0,0 +1,9 @@
+#ifndef __XEN_XSPLICE_H__
+#define __XEN_XSPLICE_H__
+
+struct xen_sysctl_xsplice_op;
+int xsplice_control(struct xen_sysctl_xsplice_op *);
+
+extern void xsplice_printall(unsigned char key);
+
+#endif /* __XEN_XSPLICE_H__ */
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 4180f3b..053f083 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -807,6 +807,9 @@ static int flask_sysctl(int cmd)
case XEN_SYSCTL_tmem_op:
return domain_has_xen(current->domain, XEN__TMEM_CONTROL);
+ case XEN_SYSCTL_xsplice_op:
+ return domain_has_xen(current->domain, XEN2__XSPLICE_OP);
+
default:
printk("flask_sysctl: Unknown op %d\n", cmd);
return -EPERM;
diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors
index effb59f..5f08d05 100644
--- a/xen/xsm/flask/policy/access_vectors
+++ b/xen/xsm/flask/policy/access_vectors
@@ -93,6 +93,8 @@ class xen2
pmu_ctrl
# PMU use (domains, including unprivileged ones, will be using this operation)
pmu_use
+# XEN_SYSCTL_xsplice_op
+ xsplice_op
}
# Classes domain and domain2 consist of operations that a domain performs on
--
2.1.0
next prev parent reply other threads:[~2015-09-16 21:01 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-16 21:01 [PATCH v1] xSplice initial foundation patches Konrad Rzeszutek Wilk
2015-09-16 21:01 ` [PATCH v1 1/5] xsplice: Design document Konrad Rzeszutek Wilk
2015-10-05 10:02 ` Jan Beulich
2015-10-05 10:28 ` Ross Lagerwall
2015-10-12 11:44 ` xsplice-build prototype (was [PATCH v1 1/5] xsplice: Design document.) Ross Lagerwall
2015-10-12 13:06 ` Konrad Rzeszutek Wilk
2015-10-12 14:20 ` Konrad Rzeszutek Wilk
2015-10-06 12:57 ` [PATCH v1 1/5] xsplice: Design document Ross Lagerwall
2015-10-27 8:08 ` Martin Pohlack
2015-10-27 8:45 ` Ross Lagerwall
2015-10-06 15:26 ` Jan Beulich
2015-10-26 12:01 ` Martin Pohlack
2015-10-26 12:10 ` Jan Beulich
2015-10-26 13:21 ` Ross Lagerwall
2015-10-26 13:55 ` Konrad Rzeszutek Wilk
2015-09-16 21:01 ` Konrad Rzeszutek Wilk [this message]
2015-10-02 15:06 ` [PATCH v1 2/5] xen/xsplice: Hypervisor implementation of XEN_XSPLICE_op Jan Beulich
2015-09-16 21:01 ` [PATCH v1 3/5] libxc: Implementation of XEN_XSPLICE_op in libxc Konrad Rzeszutek Wilk
2015-09-16 21:01 ` [PATCH v1 4/5] xen-xsplice: Tool to manipulate xsplice payloads Konrad Rzeszutek Wilk
2015-09-16 21:01 ` [PATCH v1 5/5] xsplice: Use ld-embedded build-ids Konrad Rzeszutek Wilk
2015-09-16 21:41 ` Andrew Cooper
2015-09-16 21:59 ` Konrad Rzeszutek Wilk
2015-09-16 22:31 ` Andrew Cooper
2015-09-17 6:41 ` Martin Pohlack
2015-09-17 9:35 ` Andrew Cooper
2015-09-17 18:45 ` Is: Make XENVER_* use XSM, seperate the different ops in smaller security domains. Was:Re: " Konrad Rzeszutek Wilk
2015-09-18 11:40 ` Andrew Cooper
2015-09-22 13:22 ` Konrad Rzeszutek Wilk
2015-09-22 13:33 ` Andrew Cooper
2015-09-22 13:45 ` Konrad Rzeszutek Wilk
2015-09-22 16:28 ` Daniel De Graaf
2015-09-22 16:28 ` Daniel De Graaf
2015-09-25 20:18 ` Konrad Rzeszutek Wilk
2015-10-02 15:13 ` Jan Beulich
2015-10-02 14:48 ` [PATCH v1] xSplice initial foundation patches Konrad Rzeszutek Wilk
2015-10-09 12:46 ` Konrad Rzeszutek Wilk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1442437276-2620-3-git-send-email-konrad.wilk@oracle.com \
--to=konrad.wilk@oracle.com \
--cc=aliguori@amazon.com \
--cc=amesserl@rackspace.com \
--cc=andrew.cooper3@citrix.com \
--cc=bob.liu@oracle.com \
--cc=boris.ostrovsky@oracle.com \
--cc=daniel.kiper@oracle.com \
--cc=elena.ufimtseva@oracle.com \
--cc=fanhenglong@huawei.com \
--cc=hanweidong@huawei.com \
--cc=ian.campbell@citrix.com \
--cc=jbeulich@suse.com \
--cc=jinsong.liu@alibaba-inc.com \
--cc=john.liuqiming@huawei.com \
--cc=josh.kearney@rackspace.com \
--cc=lars.kurth@citrix.com \
--cc=liuyingdong@huawei.com \
--cc=major.hayden@rackspace.com \
--cc=mpohlack@amazon.com \
--cc=msw@amazon.com \
--cc=paul.voccio@rackspace.com \
--cc=peter.huangpeng@huawei.com \
--cc=rick.harris@rackspace.com \
--cc=steven.wilson@rackspace.com \
--cc=xen-devel@lists.xenproject.org \
--cc=xiantao.zxt@alibaba-inc.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).