aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiu, Jinsong <jinsong.liu@intel.com>2012-09-26 12:13:38 +0200
committerLiu, Jinsong <jinsong.liu@intel.com>2012-09-26 12:13:38 +0200
commite35cd2cce4fe119ef63913f3eb7443b7f5b57d75 (patch)
tree6b6956fee5f6016a488a44efe54d00bb97d8c470
parent6e0336351ed95e2f72e396b3e1d055a8f5663542 (diff)
downloadxen-e35cd2cce4fe119ef63913f3eb7443b7f5b57d75.tar.gz
xen-e35cd2cce4fe119ef63913f3eb7443b7f5b57d75.tar.bz2
xen-e35cd2cce4fe119ef63913f3eb7443b7f5b57d75.zip
x86: Save/restore TSC adjust during HVM guest migration
Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com> Committed-by: Jan Beulich <jbeulich@suse.com>
-rw-r--r--tools/misc/xen-hvmctx.c8
-rw-r--r--xen/arch/x86/hvm/hvm.c40
-rw-r--r--xen/include/public/arch-x86/hvm/save.h8
3 files changed, 55 insertions, 1 deletions
diff --git a/tools/misc/xen-hvmctx.c b/tools/misc/xen-hvmctx.c
index edcebec00a..5a69245713 100644
--- a/tools/misc/xen-hvmctx.c
+++ b/tools/misc/xen-hvmctx.c
@@ -392,6 +392,13 @@ static void dump_vmce_vcpu(void)
printf(" VMCE_VCPU: bank1 mci_ctl2 %" PRIx64 "\n", p.mci_ctl2_bank1);
}
+static void dump_tsc_adjust(void)
+{
+ HVM_SAVE_TYPE(TSC_ADJUST) p;
+ READ(p);
+ printf(" TSC_ADJUST: tsc_adjust %" PRIx64 "\n", p.tsc_adjust);
+}
+
int main(int argc, char **argv)
{
int entry, domid;
@@ -459,6 +466,7 @@ int main(int argc, char **argv)
case HVM_SAVE_CODE(VIRIDIAN_DOMAIN): dump_viridian_domain(); break;
case HVM_SAVE_CODE(VIRIDIAN_VCPU): dump_viridian_vcpu(); break;
case HVM_SAVE_CODE(VMCE_VCPU): dump_vmce_vcpu(); break;
+ case HVM_SAVE_CODE(TSC_ADJUST): dump_tsc_adjust(); break;
case HVM_SAVE_CODE(END): break;
default:
printf(" ** Don't understand type %u: skipping\n",
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 52ba47ca28..3571916965 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -603,6 +603,46 @@ void hvm_domain_destroy(struct domain *d)
hvm_destroy_cacheattr_region_list(d);
}
+static int hvm_save_tsc_adjust(struct domain *d, hvm_domain_context_t *h)
+{
+ struct vcpu *v;
+ struct hvm_tsc_adjust ctxt;
+ int err = 0;
+
+ for_each_vcpu ( d, v )
+ {
+ ctxt.tsc_adjust = v->arch.hvm_vcpu.msr_tsc_adjust;
+ err = hvm_save_entry(TSC_ADJUST, v->vcpu_id, h, &ctxt);
+ if ( err )
+ break;
+ }
+
+ return err;
+}
+
+static int hvm_load_tsc_adjust(struct domain *d, hvm_domain_context_t *h)
+{
+ unsigned int vcpuid = hvm_load_instance(h);
+ struct vcpu *v;
+ struct hvm_tsc_adjust ctxt;
+
+ if ( vcpuid >= d->max_vcpus || (v = d->vcpu[vcpuid]) == NULL )
+ {
+ dprintk(XENLOG_G_ERR, "HVM restore: dom%d has no vcpu%u\n",
+ d->domain_id, vcpuid);
+ return -EINVAL;
+ }
+
+ if ( hvm_load_entry(TSC_ADJUST, h, &ctxt) != 0 )
+ return -EINVAL;
+
+ v->arch.hvm_vcpu.msr_tsc_adjust = ctxt.tsc_adjust;
+ return 0;
+}
+
+HVM_REGISTER_SAVE_RESTORE(TSC_ADJUST, hvm_save_tsc_adjust,
+ hvm_load_tsc_adjust, 1, HVMSR_PER_VCPU);
+
static int hvm_save_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
{
struct vcpu *v;
diff --git a/xen/include/public/arch-x86/hvm/save.h b/xen/include/public/arch-x86/hvm/save.h
index 8475edbac2..a82a5ee421 100644
--- a/xen/include/public/arch-x86/hvm/save.h
+++ b/xen/include/public/arch-x86/hvm/save.h
@@ -583,9 +583,15 @@ struct hvm_vmce_vcpu {
DECLARE_HVM_SAVE_TYPE(VMCE_VCPU, 18, struct hvm_vmce_vcpu);
+struct hvm_tsc_adjust {
+ uint64_t tsc_adjust;
+};
+
+DECLARE_HVM_SAVE_TYPE(TSC_ADJUST, 19, struct hvm_tsc_adjust);
+
/*
* Largest type-code in use
*/
-#define HVM_SAVE_CODE_MAX 18
+#define HVM_SAVE_CODE_MAX 19
#endif /* __XEN_PUBLIC_HVM_SAVE_X86_H__ */