mirror of
https://github.com/xen-project/xen.git
synced 2026-10-30 03:00:05 +01:00
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 <rcojocaru@bitdefender.com> Acked-by: Wei Liu <wei.liu2@citrix.com>
This commit is contained in:
1 parent
3e5f1a63b5
commit
6622e7f4c8
2 files changed
+82
No files matched your search
@@ -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)
|
||||
|
||||