@@ -2412,6 +2412,16 @@ static int vmtrace_output_position(struct vcpu *v, uint64_t *pos)
return v->arch.hvm.vmx.ipt_active;
}
+static int vmtrace_reset(struct vcpu *v)
+{
+ if ( !v->arch.hvm.vmx.ipt_active )
+ return -EINVAL;
+
+ v->arch.msrs->rtit.output_offset = 0;
+ v->arch.msrs->rtit.status = 0;
+ return 0;
+}
+
static struct hvm_function_table __initdata vmx_function_table = {
.name = "VMX",
.cpu_up_prepare = vmx_cpu_up_prepare,
@@ -2471,6 +2481,7 @@ static struct hvm_function_table __initdata vmx_function_table = {
.vmtrace_output_position = vmtrace_output_position,
.vmtrace_set_option = vmtrace_set_option,
.vmtrace_get_option = vmtrace_get_option,
+ .vmtrace_reset = vmtrace_reset,
.tsc_scaling = {
.max_ratio = VMX_TSC_MULTIPLIER_MAX,
},
@@ -1632,6 +1632,8 @@ static int copy_vcpu_settings(struct domain *cd, const struct domain *d)
copy_domain_page(new_vcpu_info_mfn, vcpu_info_mfn);
}
+ hvm_vmtrace_reset(cd_vcpu);
+
/*
* TODO: to support VMs with PV interfaces copy additional
* settings here, such as PV timers.
@@ -1782,6 +1784,7 @@ static int fork(struct domain *cd, struct domain *d)
cd->max_pages = d->max_pages;
*cd->arch.cpuid = *d->arch.cpuid;
*cd->arch.msr = *d->arch.msr;
+ cd->vmtrace_size = d->vmtrace_size;
cd->parent = d;
}
@@ -219,6 +219,7 @@ struct hvm_function_table {
int (*vmtrace_output_position)(struct vcpu *v, uint64_t *pos);
int (*vmtrace_set_option)(struct vcpu *v, uint64_t key, uint64_t value);
int (*vmtrace_get_option)(struct vcpu *v, uint64_t key, uint64_t *value);
+ int (*vmtrace_reset)(struct vcpu *v);
/*
* Parameters and callbacks for hardware-assisted TSC scaling,
@@ -696,6 +697,14 @@ static inline int hvm_vmtrace_get_option(
return -EOPNOTSUPP;
}
+static inline int hvm_vmtrace_reset(struct vcpu *v)
+{
+ if ( hvm_funcs.vmtrace_reset )
+ return hvm_funcs.vmtrace_reset(v);
+
+ return -EOPNOTSUPP;
+}
+
/*
* This must be defined as a macro instead of an inline function,
* because it uses 'struct vcpu' and 'struct domain' which have