From mboxrd@z Thu Jan 1 00:00:00 1970 From: Doug Goldstein Subject: Re: [PATCH v2 03/13] xen/xsplice: Hypervisor implementation of XEN_XSPLICE_op (v7) Date: Sat, 6 Feb 2016 16:35:56 -0600 Message-ID: <56B6754C.2060909@cardoe.com> References: <1452808031-706-1-git-send-email-konrad.wilk@oracle.com> <1452808031-706-4-git-send-email-konrad.wilk@oracle.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============9019995651232065540==" Return-path: Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aSBSY-0002bu-7T for xen-devel@lists.xenproject.org; Sat, 06 Feb 2016 22:36:06 +0000 Received: by mail-yk0-f196.google.com with SMTP id z13so3448632ykd.3 for ; Sat, 06 Feb 2016 14:36:03 -0800 (PST) In-Reply-To: <1452808031-706-4-git-send-email-konrad.wilk@oracle.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Konrad Rzeszutek Wilk , xen-devel@lists.xenproject.org, ross.lagerwall@citrix.com, mpohlack@amazon.com, andrew.cooper3@citrix.com, stefano.stabellini@citrix.com, jbeulich@suse.com, ian.jackson@eu.citrix.com, ian.campbell@citrix.com, wei.liu2@citrix.com, sasha.levin@oracle.com List-Id: xen-devel@lists.xenproject.org This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --===============9019995651232065540== Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="wPDqV9ueC0Cqo1hA86un2L16uimTwSvBJ" This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --wPDqV9ueC0Cqo1hA86un2L16uimTwSvBJ Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable On 1/14/16 3:47 PM, Konrad Rzeszutek Wilk wrote: > The implementation does not actually do any patching. >=20 > 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, replace*1, and unload payloads. >=20 > *1: Which of course in this patch are nops. >=20 > Acked-by: Daniel De Graaf > Signed-off-by: Konrad Rzeszutek Wilk > Signed-off-by: Ross Lagerwall >=20 > --- > v2: Rebased on keyhandler: rework keyhandler infrastructure > v3: Fixed XSM. > v4: Removed REVERTED state. > Split status and error code. > Add REPLACE action. > Separate payload data from the payload structure. > s/XSPLICE_ID_../XSPLICE_NAME_../ > v5: Add xsplice and CONFIG_XSPLICE build toption. > Fix code per Jan's review. > Update the sysctl.h (change bits to enum like) > v6: Rebase on Kconfig changes. > v7: Add missing pad checks. Re-order keyhandler.h to build on ARM. >=20 > Signed-off-by: Konrad Rzeszutek Wilk > --- > tools/flask/policy/policy/modules/xen/xen.te | 1 + > xen/arch/arm/Kconfig | 1 + > xen/arch/x86/Kconfig | 1 + > xen/common/Kconfig | 14 + > xen/common/Makefile | 2 + > xen/common/sysctl.c | 8 + > xen/common/xsplice.c | 386 +++++++++++++++++++= ++++++++ > xen/include/public/sysctl.h | 156 +++++++++++ > xen/include/xen/xsplice.h | 7 + > xen/xsm/flask/hooks.c | 6 + > xen/xsm/flask/policy/access_vectors | 2 + > 11 files changed, 584 insertions(+) > create mode 100644 xen/common/xsplice.c > create mode 100644 xen/include/xen/xsplice.h >=20 > diff --git a/tools/flask/policy/policy/modules/xen/xen.te b/tools/flask= /policy/policy/modules/xen/xen.te > index d35ae22..542c3e1 100644 > --- a/tools/flask/policy/policy/modules/xen/xen.te > +++ b/tools/flask/policy/policy/modules/xen/xen.te > @@ -72,6 +72,7 @@ allow dom0_t xen_t:xen2 { > allow dom0_t xen_t:xen2 { > pmu_ctrl > get_symbol > + xsplice_op > }; > allow dom0_t xen_t:mmu memorymap; > =20 > diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig > index 60e923c..3780949 100644 > --- a/xen/arch/arm/Kconfig > +++ b/xen/arch/arm/Kconfig > @@ -23,6 +23,7 @@ config ARM > select HAS_PASSTHROUGH > select HAS_PDX > select HAS_VIDEO > + select HAS_XSPLICE > =20 > config ARCH_DEFCONFIG > string > diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig > index 4781b34..2b6c832 100644 > --- a/xen/arch/x86/Kconfig > +++ b/xen/arch/x86/Kconfig > @@ -18,6 +18,7 @@ config X86 > select HAS_PCI > select HAS_PDX > select HAS_VGA > + select HAS_XSPLICE > =20 > config ARCH_DEFCONFIG > string > diff --git a/xen/common/Kconfig b/xen/common/Kconfig > index eadfc3b..aaf4053 100644 > --- a/xen/common/Kconfig > +++ b/xen/common/Kconfig > @@ -51,6 +51,9 @@ config HAS_GDBSX > config HAS_IOPORTS > bool > =20 > +config HAS_XSPLICE > + bool > + > # Enable/Disable kexec support > config KEXEC > bool "kexec support" > @@ -97,4 +100,15 @@ config XSM > =20 > If unsure, say N. > =20 > +# Enable/Disable xsplice support > +config XSPLICE > + bool "xsplice support" > + default y > + depends on HAS_XSPLICE > + ---help--- > + Allows a running Xen hypervisor to be patched without rebooting. > + This is primarily used to patch an hypervisor with XSA fixes. > + > + If unsure, say Y. > + > endmenu I'm indifferent on the HAS_XSPLICE, you can drop that if you want to simply stuff. > diff --git a/xen/common/Makefile b/xen/common/Makefile > index 9f8b214..6fdeccf 100644 > --- a/xen/common/Makefile > +++ b/xen/common/Makefile > @@ -71,3 +71,5 @@ subdir-$(coverage) +=3D gcov > =20 > subdir-y +=3D libelf > subdir-$(CONFIG_HAS_DEVICE_TREE) +=3D libfdt > + > +obj-$(CONFIG_XSPLICE) +=3D xsplice.o > diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c > index a3007b8..55e6cfa 100644 > --- a/xen/common/sysctl.c > +++ b/xen/common/sysctl.c > @@ -28,6 +28,7 @@ > #include > #include > #include > +#include > =20 > long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl) > { > @@ -460,6 +461,13 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t= ) u_sysctl) > ret =3D tmem_control(&op->u.tmem_op); > break; > =20 > +#ifdef CONFIG_XSPLICE > + case XEN_SYSCTL_xsplice_op: > + ret =3D xsplice_control(&op->u.xsplice); > + copyback =3D 1; > + break; > +#endif Should the case statement still exist and not just return -ENOSYS? Otherwise we're needlessly going into arch_do_sysctl() just to get the same result. > + > default: > ret =3D arch_do_sysctl(op, u_sysctl); > copyback =3D 0; > diff --git a/xen/common/xsplice.c b/xen/common/xsplice.c > new file mode 100644 > index 0000000..3c6acc3 > --- /dev/null > +++ b/xen/common/xsplice.c > @@ -0,0 +1,386 @@ > +/* > + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserve= d. > + * > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +static DEFINE_SPINLOCK(payload_list_lock); > +static LIST_HEAD(payload_list); > + > +static unsigned int payload_cnt; > +static unsigned int payload_version =3D 1; > + > +struct payload { > + int32_t state; /* One of the XSPLICE_STATE_*= =2E */ > + int32_t rc; /* 0 or -XEN_EXX. */ > + struct list_head list; /* Linked to 'payload_list'. = */ > + char name[XEN_XSPLICE_NAME_SIZE + 1];/* Name of it. */ > +}; > + > +static const char *state2str(int32_t state) > +{ > +#define STATE(x) [XSPLICE_STATE_##x] =3D #x > + static const char *const names[] =3D { > + STATE(LOADED), > + STATE(CHECKED), > + STATE(APPLIED), > + }; > +#undef STATE > + > + if (state >=3D ARRAY_SIZE(names)) > + return "unknown"; > + > + if (state < 0) > + return "-EXX"; > + > + if (!names[state]) > + return "unknown"; > + > + return names[state]; > +} > + > +static void xsplice_printall(unsigned char key) > +{ > + struct payload *data; > + > + spin_lock(&payload_list_lock); > + > + list_for_each_entry ( data, &payload_list, list ) > + printk(" name=3D%s state=3D%s(%d)\n", data->name, > + state2str(data->state), data->state); > + > + spin_unlock(&payload_list_lock); > +} > + > +static int verify_name(xen_xsplice_name_t *name) > +{ > + if ( name->size =3D=3D 0 || name->size > XEN_XSPLICE_NAME_SIZE ) > + return -EINVAL; > + > + if ( name->pad[0] || name->pad[1] || name->pad[2] ) > + return -EINVAL; > + > + if ( !guest_handle_okay(name->name, name->size) ) > + return -EINVAL; > + > + return 0; > +} > + > +static int find_payload(xen_xsplice_name_t *name, bool_t need_lock, > + struct payload **f) > +{ > + struct payload *data; > + XEN_GUEST_HANDLE_PARAM(char) str; > + char n[XEN_XSPLICE_NAME_SIZE + 1] =3D { 0 }; > + int rc =3D -EINVAL; > + > + rc =3D verify_name(name); > + if ( rc ) > + return rc; > + > + str =3D guest_handle_cast(name->name, char); > + if ( copy_from_guest(n, str, name->size) ) > + return -EFAULT; > + > + if ( need_lock ) > + spin_lock(&payload_list_lock); > + > + rc =3D -ENOENT; > + list_for_each_entry ( data, &payload_list, list ) > + { > + if ( !strcmp(data->name, n) ) > + { > + *f =3D data; > + rc =3D 0; > + break; > + } > + } > + > + if ( need_lock ) > + spin_unlock(&payload_list_lock); > + > + return rc; > +} > + > +static int verify_payload(xen_sysctl_xsplice_upload_t *upload) > +{ > + if ( verify_name(&upload->name) ) > + return -EINVAL; > + > + if ( upload->size =3D=3D 0 ) > + return -EINVAL; > + > + if ( !guest_handle_okay(upload->payload, upload->size) ) > + return -EFAULT; > + > + return 0; > +} > + > +/* > + * We MUST be holding the payload_list_lock spinlock. > + */ > +static void free_payload(struct payload *data) > +{ > + list_del(&data->list); > + payload_cnt--; > + payload_version++; > + xfree(data); > +} > + > +static int xsplice_upload(xen_sysctl_xsplice_upload_t *upload) > +{ > + struct payload *data =3D NULL; > + uint8_t *raw_data; > + int rc; > + > + rc =3D verify_payload(upload); > + if ( rc ) > + return rc; > + > + rc =3D find_payload(&upload->name, 1 /* true. */, &data); > + if ( rc =3D=3D 0 /* Found. */ ) > + return -EEXIST; > + > + if ( rc !=3D -ENOENT ) > + return rc; > + > + data =3D xzalloc(struct payload); > + if ( !data ) > + return -ENOMEM; > + > + memset(data, 0, sizeof *data); > + rc =3D -EFAULT; > + if ( copy_from_guest(data->name, upload->name.name, upload->name.s= ize) ) > + goto err_data; > + > + rc =3D -ENOMEM; > + raw_data =3D alloc_xenheap_pages(get_order_from_bytes(upload->size= ), 0); > + if ( !raw_data ) > + goto err_data; > + > + rc =3D -EFAULT; > + if ( copy_from_guest(raw_data, upload->payload, upload->size) ) > + goto err_raw; > + > + data->state =3D XSPLICE_STATE_LOADED; > + data->rc =3D 0; > + INIT_LIST_HEAD(&data->list); > + > + spin_lock(&payload_list_lock); > + list_add_tail(&data->list, &payload_list); > + payload_cnt++; > + payload_version++; > + spin_unlock(&payload_list_lock); > + > + free_xenheap_pages(raw_data, get_order_from_bytes(upload->size)); > + return 0; > + > + err_raw: > + free_xenheap_pages(raw_data, get_order_from_bytes(upload->size)); > + err_data: > + xfree(data); > + return rc; > +} > + > +static int xsplice_get(xen_sysctl_xsplice_summary_t *summary) > +{ > + struct payload *data; > + int rc; > + > + if ( summary->status.state ) > + return -EINVAL; > + > + if ( summary->status.rc !=3D 0 ) > + return -EINVAL; > + > + rc =3D verify_name(&summary->name); > + if ( rc ) > + return rc; > + > + rc =3D find_payload(&summary->name, 1 /* true. */, &data); > + if ( rc ) > + return rc; > + > + summary->status.state =3D data->state; > + summary->status.rc =3D data->rc; > + > + return 0; > +} > + > +static int xsplice_list(xen_sysctl_xsplice_list_t *list) > +{ > + xen_xsplice_status_t status; > + struct payload *data; > + unsigned int idx =3D 0, i =3D 0; > + int rc =3D 0; > + > + if ( list->nr > 1024 ) > + return -E2BIG; > + > + if ( list->pad !=3D 0 ) > + return -EINVAL; > + > + if ( !guest_handle_okay(list->status, sizeof(status) * list->nr) |= | > + !guest_handle_okay(list->name, XEN_XSPLICE_NAME_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 || !list->nr ) > + { > + spin_unlock(&payload_list_lock); > + return -EINVAL; > + } > + > + list_for_each_entry( data, &payload_list, list ) > + { > + uint32_t len; > + > + if ( list->idx > i++ ) > + continue; > + > + status.state =3D data->state; > + status.rc =3D data->rc; > + len =3D strlen(data->name); > + > + /* N.B. 'idx' !=3D 'i'. */ > + if ( __copy_to_guest_offset(list->name, idx * XEN_XSPLICE_NAME= _SIZE, > + data->name, len) || > + __copy_to_guest_offset(list->len, idx, &len, 1) || > + __copy_to_guest_offset(list->status, idx, &status, 1) ) > + { > + rc =3D -EFAULT; > + break; > + } > + idx++; > + if ( hypercall_preempt_check() || (idx + 1 > list->nr) ) > + break; > + } > + list->nr =3D payload_cnt - i; /* Remaining amount. */ > + list->version =3D payload_version; > + spin_unlock(&payload_list_lock); > + > + /* And how many we have processed. */ > + return rc ? : idx; > +} > + > +static int xsplice_action(xen_sysctl_xsplice_action_t *action) > +{ > + struct payload *data; > + int rc; > + > + rc =3D verify_name(&action->name); > + if ( rc ) > + return rc; > + > + spin_lock(&payload_list_lock); > + rc =3D find_payload(&action->name, 0 /* We are holding the lock. *= /, &data); > + if ( rc ) > + goto out; > + > + switch ( action->cmd ) > + { > + case XSPLICE_ACTION_CHECK: > + if ( (data->state =3D=3D XSPLICE_STATE_LOADED) || > + (data->state =3D=3D XSPLICE_STATE_CHECKED) ) > + { > + /* No implementation yet. */ > + data->state =3D XSPLICE_STATE_CHECKED; > + data->rc =3D 0; > + rc =3D 0; > + } > + break; > + case XSPLICE_ACTION_UNLOAD: > + if ( (data->state =3D=3D XSPLICE_STATE_LOADED) || > + (data->state =3D=3D XSPLICE_STATE_CHECKED) ) > + { > + free_payload(data); > + /* No touching 'data' from here on! */ > + rc =3D 0; > + } > + break; > + case XSPLICE_ACTION_REVERT: > + if ( data->state =3D=3D XSPLICE_STATE_APPLIED ) > + { > + /* No implementation yet. */ > + data->state =3D XSPLICE_STATE_CHECKED; > + data->rc =3D 0; > + rc =3D 0; > + } > + break; > + case XSPLICE_ACTION_APPLY: > + if ( (data->state =3D=3D XSPLICE_STATE_CHECKED) ) > + { > + /* No implementation yet. */ > + data->state =3D XSPLICE_STATE_APPLIED; > + data->rc =3D 0; > + rc =3D 0; > + } > + break; > + case XSPLICE_ACTION_REPLACE: > + if ( data->state =3D=3D XSPLICE_STATE_CHECKED ) > + { > + /* No implementation yet. */ > + data->state =3D XSPLICE_STATE_CHECKED; > + data->rc =3D 0; > + rc =3D 0; > + } > + break; > + default: > + rc =3D -EOPNOTSUPP; > + break; > + } > + > + out: > + spin_unlock(&payload_list_lock); > + > + return rc; > +} > + > +int xsplice_control(xen_sysctl_xsplice_op_t *xsplice) > +{ > + int rc; > + > + if ( xsplice->pad !=3D 0 ) > + return -EINVAL; > + > + switch ( xsplice->cmd ) > + { > + case XEN_SYSCTL_XSPLICE_UPLOAD: > + rc =3D xsplice_upload(&xsplice->u.upload); > + break; > + case XEN_SYSCTL_XSPLICE_GET: > + rc =3D xsplice_get(&xsplice->u.get); > + break; > + case XEN_SYSCTL_XSPLICE_LIST: > + rc =3D xsplice_list(&xsplice->u.list); > + break; > + case XEN_SYSCTL_XSPLICE_ACTION: > + rc =3D xsplice_action(&xsplice->u.action); > + break; > + default: > + rc =3D -EOPNOTSUPP; > + break; > + } > + > + return rc; > +} > + > +static int __init xsplice_init(void) > +{ > + register_keyhandler('x', xsplice_printall, "print xsplicing info",= 1); > + return 0; > +} > +__initcall(xsplice_init); > diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h > index 96680eb..0b0b879 100644 > --- a/xen/include/public/sysctl.h > +++ b/xen/include/public/sysctl.h > @@ -766,6 +766,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); > =20 > +/* > + * XEN_SYSCTL_XSPLICE_op > + * > + * Refer to the http://xenbits.xenproject.org/docs/unstable/misc/xspli= ce.html > + * for the design details of this hyprcall. > + */ > + > +/* > + * Structure describing an ELF payload. Uniquely identifies the > + * payload. Should be human readable. > + * Recommended length is upto XEN_XSPLICE_NAME_SIZE. > + */ > +#define XEN_XSPLICE_NAME_SIZE 128 > +struct xen_xsplice_name { > + XEN_GUEST_HANDLE_64(char) name; /* IN: pointer to name. */= > + uint16_t size; /* IN: size of name. May b= e upto > + XEN_XSPLICE_NAME_SIZE. = */ > + uint16_t pad[3]; /* IN: MUST be zero. */ > +}; > +typedef struct xen_xsplice_name xen_xsplice_name_t; > +DEFINE_XEN_GUEST_HANDLE(xen_xsplice_name_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 `name` 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 forma= t` > + * section in the xSplice design document. > + */ > +#define XEN_SYSCTL_XSPLICE_UPLOAD 0 > +struct xen_sysctl_xsplice_upload { > + xen_xsplice_name_t name; /* IN, name of the patch. = */ > + uint64_t size; /* IN, size of the ELF fil= e. */ > + 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 XEN_EXX on failure. This op= eration > + * is synchronous and does not require preemption. > + */ > +#define XEN_SYSCTL_XSPLICE_GET 1 > + > +struct xen_xsplice_status { > +#define XSPLICE_STATE_LOADED 1 > +#define XSPLICE_STATE_CHECKED 2 > +#define XSPLICE_STATE_APPLIED 3 > + int32_t state; /* OUT: XSPLICE_STATE_*. IN: MUST b= e zero. */ > + int32_t rc; /* OUT: 0 if no error, otherwise -X= EN_EXX. */ > + /* 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_name_t name; /* IN, name of the payload= =2E */ > + xen_xsplice_status_t status; /* IN/OUT, state 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 t= o `nr`) > + * of the payloads returned, along with `nr` updated with the number o= f 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= `, > + * `name`, and `len`' are updated at their designed index value (`idx`= ) with > + * the returned value of data. > + * > + * If the hypercall returns E2BIG the `nr` 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 m= ight have > + * added or removed the number of payloads making this information sta= le. It is > + * the responsibility of the toolstack to use the `version` field to c= heck > + * between each invocation. if the version differs it should discard t= he 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 reu= se value. > + If varies between calls= , we are > + * getting stale data. */ > + uint32_t idx; /* IN/OUT: Index into arra= y. */ > + uint32_t nr; /* IN: How many status, id= , and len > + should fill out. > + OUT: How many payloads = left. */ > + uint32_t pad; /* IN: Must be zero. */ > + XEN_GUEST_HANDLE_64(xen_xsplice_status_t) status; /* OUT. Must ha= ve enough > + space allocate for nr o= f them. */ > + XEN_GUEST_HANDLE_64(char) name; /* OUT: Array of ids. Each= member > + MUST XEN_XSPLICE_NAME_S= IZE in size. > + Must have nr of them. *= / > + XEN_GUEST_HANDLE_64(uint32) len; /* OUT: Array of lengths o= f ids. > + Must have nr 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 `na= me` field. > + * The operation request is asynchronous and the status should be retr= ieved > + * by using either XEN_SYSCTL_XSPLICE_GET or XEN_SYSCTL_XSPLICE_LIST h= ypercall. > + */ > +#define XEN_SYSCTL_XSPLICE_ACTION 3 > +struct xen_sysctl_xsplice_action { > + xen_xsplice_name_t name; /* 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 > +#define XSPLICE_ACTION_REPLACE 5 > + uint32_t cmd; /* IN: XSPLICE_ACTION_*. *= / > + uint32_t timeout; /* IN: Zero if no timeout.= */ > + /* Or upper bound of time = (ms) */ > + /* for operation to take. = */ > +}; > +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 > @@ -791,6 +945,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; > @@ -816,6 +971,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..2cb2035 > --- /dev/null > +++ b/xen/include/xen/xsplice.h > @@ -0,0 +1,7 @@ > +#ifndef __XEN_XSPLICE_H__ > +#define __XEN_XSPLICE_H__ > + > +struct xen_sysctl_xsplice_op; > +int xsplice_control(struct xen_sysctl_xsplice_op *); > + > +#endif /* __XEN_XSPLICE_H__ */ > diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c > index 9b7de30..5346dcf 100644 > --- a/xen/xsm/flask/hooks.c > +++ b/xen/xsm/flask/hooks.c > @@ -807,6 +807,12 @@ static int flask_sysctl(int cmd) > case XEN_SYSCTL_tmem_op: > return domain_has_xen(current->domain, XEN__TMEM_CONTROL); > =20 > +#ifdef CONFIG_XSPLICE > + case XEN_SYSCTL_xsplice_op: > + return avc_current_has_perm(SECINITSID_XEN, SECCLASS_XEN2, > + XEN2__XSPLICE_OP, NULL); > +#endif > + > 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 op= eration) > pmu_use > +# XEN_SYSCTL_xsplice_op > + xsplice_op > } > =20 > # Classes domain and domain2 consist of operations that a domain perfo= rms on >=20 --=20 Doug Goldstein --wPDqV9ueC0Cqo1hA86un2L16uimTwSvBJ Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0 iQJ8BAEBCgBmBQJWtnVPXxSAAAAAAC4AKGlzc3Vlci1mcHJAbm90YXRpb25zLm9w ZW5wZ3AuZmlmdGhob3JzZW1hbi5uZXRBNTM5MEQ2RTNFMTkyNzlCNzVDMzIwOTVB MkJDMDNEQzg3RUQxQkQ0AAoJEKK8A9yH7RvUNOIP+wT/KSskVQW41O0y8dO4bnl2 3bacZIzd0FH7G65eJFLpL1auhGdG8u7qPMbbygX7VECHLzEg6ZEiRDmhTXRz9mJh CDTZybHLsAOmibldGqXEuaOig3vYjtsEhhMTTdKzUf5t8lj5qoor6iVeWzWpChYC sn5+pY11sVZ+zje6VJVZTdDzfzlh6IJv0L3Wp9A+c63TTQ303wgP3e4f7UerYl0a tnMz3GrgH1rSGFYd+yXJFsNzYyx69XL/tdNs/5afpf3RrcEdctk8PtRFXVH0ojjV FgvgfwXDNrKcVDLTdL8IfXhJebzgEar/VygJmrqVjbTmya4fjhSIgn90PZpVOABz 2kFgb2K++pUp6BmOm6p2T1gzhtSC80PK/d6XGSuW6uE5lfVZeGnx62uZeKOCA8lW FLa9AExiW4OlrYyauCWpwaw3/3a9aN6rx6ouvYNe/aq6UAn6YLBON/IoOkwHw5GV 58TCg91i6QhcTRrb+pQZpzlNiSdP1GOjztwYSfJMM8JthOqYzncrjyCo3XSf5NsH RlZZ66kbpaKJswahmE7r6keAUhfu3b16LPGk8ZU7HQ5H0ahrTQ0ThcaZSGnVYxXK yrK0pEOSqKDo4+x2IudMX1tkTPezqyxEhfPh/H+gXLMoOvHsDN3QjxUPBRMQaTdO /E1VCB83gXkYySEYO8qh =JzRs -----END PGP SIGNATURE----- --wPDqV9ueC0Cqo1hA86un2L16uimTwSvBJ-- --===============9019995651232065540== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel --===============9019995651232065540==--