@@ -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,
@@ -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)
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 <rcojocaru@bitdefender.com> --- tools/libxc/include/xenctrl.h | 23 +++++++++++++++++ tools/libxc/xc_domain.c | 59 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+)