From: Razvan Cojocaru Date: Tue, 14 Mar 2017 13:30:18 +0000 (+0200) Subject: tools/libxc: Exposed XEN_DOMCTL_getvcpuextstate X-Git-Tag: archive/raspbian/4.11.1-1+rpi1~1^2~66^2~2489 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=6622e7f4c81812c6f14437e501596f496f7e571b;p=xen.git tools/libxc: Exposed XEN_DOMCTL_getvcpuextstate It's useful for an introspection tool to be able to inspect XSAVE states. Xen already has a DOMCTL that can be used for this purpose, but it had no public libxc wrapper. This patch adds xc_vcpu_get_extstate(). Signed-off-by: Razvan Cojocaru Acked-by: Wei Liu --- diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h index a48981abea..b80d150cc5 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -487,6 +487,11 @@ typedef union } start_info_any_t; #endif +typedef struct xc_vcpu_extstate { + uint64_t xfeature_mask; + uint64_t size; + void *buffer; +} xc_vcpu_extstate_t; typedef struct xen_arch_domainconfig xc_domain_configuration_t; int xc_domain_create(xc_interface *xch, uint32_t ssidref, @@ -880,6 +885,24 @@ int xc_vcpu_getcontext(xc_interface *xch, uint32_t vcpu, vcpu_guest_context_any_t *ctxt); +/** + * This function returns information about the XSAVE state of a particular + * vcpu of a domain. If extstate->size and extstate->xfeature_mask are 0, + * the call is considered a query to retrieve them and the buffer is not + * filled. + * + * @parm xch a handle to an open hypervisor interface + * @parm domid the domain to get information from + * @parm vcpu the vcpu number + * @parm extstate a pointer to a structure to store the XSAVE state of the + * domain + * @return 0 on success, negative error code on failure + */ +int xc_vcpu_get_extstate(xc_interface *xch, + uint32_t domid, + uint32_t vcpu, + xc_vcpu_extstate_t *extstate); + typedef xen_domctl_getvcpuinfo_t xc_vcpuinfo_t; int xc_vcpu_getinfo(xc_interface *xch, uint32_t domid, diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index d862e537d9..71e5d939c4 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -555,6 +555,65 @@ int xc_vcpu_getcontext(xc_interface *xch, return rc; } +int xc_vcpu_get_extstate(xc_interface *xch, + uint32_t domid, + uint32_t vcpu, + xc_vcpu_extstate_t *extstate) +{ + int rc; + DECLARE_DOMCTL; + DECLARE_HYPERCALL_BUFFER(void, buffer); + bool get_state; + + if ( !extstate ) + return -EINVAL; + + domctl.cmd = XEN_DOMCTL_getvcpuextstate; + domctl.domain = (domid_t)domid; + domctl.u.vcpuextstate.vcpu = (uint16_t)vcpu; + domctl.u.vcpuextstate.xfeature_mask = extstate->xfeature_mask; + domctl.u.vcpuextstate.size = extstate->size; + + get_state = (extstate->size != 0); + + if ( get_state ) + { + buffer = xc_hypercall_buffer_alloc(xch, buffer, extstate->size); + + if ( !buffer ) + { + PERROR("Unable to allocate memory for vcpu%u's xsave context", + vcpu); + rc = -ENOMEM; + goto out; + } + + set_xen_guest_handle(domctl.u.vcpuextstate.buffer, buffer); + } + + rc = do_domctl(xch, &domctl); + + if ( rc ) + goto out; + + /* A query for the size of buffer to use. */ + if ( !extstate->size && !extstate->xfeature_mask ) + { + extstate->xfeature_mask = domctl.u.vcpuextstate.xfeature_mask; + extstate->size = domctl.u.vcpuextstate.size; + goto out; + } + + if ( get_state ) + memcpy(extstate->buffer, buffer, extstate->size); + +out: + if ( get_state ) + xc_hypercall_buffer_free(xch, buffer); + + return rc; +} + int xc_watchdog(xc_interface *xch, uint32_t id, uint32_t timeout)