@@ -322,6 +322,48 @@ void arch_get_domain_info(const struct domain *d,
info->arch_config.emulation_flags = d->arch.emulation_flags;
}
+static int do_vmtrace_op(struct domain *d, struct xen_domctl_vmtrace_op *op,
+ XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
+{
+ int rc;
+ struct vcpu *v;
+
+ if ( !vmtrace_supported )
+ return -EOPNOTSUPP;
+
+ if ( !is_hvm_domain(d) )
+ return -EOPNOTSUPP;
+
+ if ( op->vcpu >= d->max_vcpus )
+ return -EINVAL;
+
+ v = domain_vcpu(d, op->vcpu);
+ rc = 0;
+
+ switch ( op->cmd )
+ {
+ case XEN_DOMCTL_vmtrace_pt_enable:
+ case XEN_DOMCTL_vmtrace_pt_disable:
+ vcpu_pause(v);
+ spin_lock(&d->vmtrace_lock);
+
+ rc = vmtrace_control_pt(v, op->cmd == XEN_DOMCTL_vmtrace_pt_enable);
+
+ spin_unlock(&d->vmtrace_lock);
+ vcpu_unpause(v);
+ break;
+
+ case XEN_DOMCTL_vmtrace_pt_get_offset:
+ rc = vmtrace_get_pt_offset(v, &op->offset);
+ break;
+
+ default:
+ rc = -EOPNOTSUPP;
+ }
+
+ return rc;
+}
+
#define MAX_IOPORTS 0x10000
long arch_do_domctl(
@@ -337,6 +379,12 @@ long arch_do_domctl(
switch ( domctl->cmd )
{
+ case XEN_DOMCTL_vmtrace_op:
+ ret = do_vmtrace_op(d, &domctl->u.vmtrace_op, u_domctl);
+ if ( !ret )
+ copyback = true;
+ break;
+
case XEN_DOMCTL_shadow_op:
ret = paging_domctl(d, &domctl->u.shadow_op, u_domctl, 0);
if ( ret == -ERESTART )
@@ -1136,6 +1136,28 @@ struct xen_domctl_vuart_op {
*/
};
+/* XEN_DOMCTL_vmtrace_op: Perform VM tracing related operation */
+#if defined(__XEN__) || defined(__XEN_TOOLS__)
+
+struct xen_domctl_vmtrace_op {
+ /* IN variable */
+ uint32_t cmd;
+/* Enable/disable external vmtrace for given domain */
+#define XEN_DOMCTL_vmtrace_pt_enable 1
+#define XEN_DOMCTL_vmtrace_pt_disable 2
+#define XEN_DOMCTL_vmtrace_pt_get_offset 3
+ domid_t domain;
+ uint32_t vcpu;
+ uint64_aligned_t size;
+
+ /* OUT variable */
+ uint64_aligned_t offset;
+};
+typedef struct xen_domctl_vmtrace_op xen_domctl_vmtrace_op_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_vmtrace_op_t);
+
+#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
+
struct xen_domctl {
uint32_t cmd;
#define XEN_DOMCTL_createdomain 1
@@ -1217,6 +1239,7 @@ struct xen_domctl {
#define XEN_DOMCTL_vuart_op 81
#define XEN_DOMCTL_get_cpu_policy 82
#define XEN_DOMCTL_set_cpu_policy 83
+#define XEN_DOMCTL_vmtrace_op 84
#define XEN_DOMCTL_gdbsx_guestmemio 1000
#define XEN_DOMCTL_gdbsx_pausevcpu 1001
#define XEN_DOMCTL_gdbsx_unpausevcpu 1002
@@ -1277,6 +1300,9 @@ struct xen_domctl {
struct xen_domctl_monitor_op monitor_op;
struct xen_domctl_psr_alloc psr_alloc;
struct xen_domctl_vuart_op vuart_op;
+#if defined(__XEN__) || defined(__XEN_TOOLS__)
+ struct xen_domctl_vmtrace_op vmtrace_op;
+#endif
uint8_t pad[128];
} u;
};