+static bool hyperv_crash_enable_needed(void *opaque)
+{
+ X86CPU *cpu = opaque;
+ CPUX86State *env = &cpu->env;
+ int i;
+
+ for (i = 0; i < HV_X64_MSR_CRASH_PARAMS; i++) {
+ if (env->msr_hv_crash_params[i]) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static const VMStateDescription vmstate_msr_hyperv_crash = {
+ .name = "cpu/msr_hyperv_crash",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = hyperv_crash_enable_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64_ARRAY(env.msr_hv_crash_params,
+ X86CPU, HV_X64_MSR_CRASH_PARAMS),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static bool hyperv_runtime_enable_needed(void *opaque)
+{
+ X86CPU *cpu = opaque;
+ CPUX86State *env = &cpu->env;
+
+ return env->msr_hv_runtime != 0;
+}
+
+static const VMStateDescription vmstate_msr_hyperv_runtime = {
+ .name = "cpu/msr_hyperv_runtime",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = hyperv_runtime_enable_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(env.msr_hv_runtime, X86CPU),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static bool hyperv_synic_enable_needed(void *opaque)
+{
+ X86CPU *cpu = opaque;
+ CPUX86State *env = &cpu->env;
+ int i;
+
+ if (env->msr_hv_synic_control != 0 ||
+ env->msr_hv_synic_evt_page != 0 ||
+ env->msr_hv_synic_msg_page != 0) {
+ return true;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(env->msr_hv_synic_sint); i++) {
+ if (env->msr_hv_synic_sint[i] != 0) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static const VMStateDescription vmstate_msr_hyperv_synic = {
+ .name = "cpu/msr_hyperv_synic",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = hyperv_synic_enable_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(env.msr_hv_synic_control, X86CPU),
+ VMSTATE_UINT64(env.msr_hv_synic_evt_page, X86CPU),
+ VMSTATE_UINT64(env.msr_hv_synic_msg_page, X86CPU),
+ VMSTATE_UINT64_ARRAY(env.msr_hv_synic_sint, X86CPU,
+ HV_SYNIC_SINT_COUNT),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static bool hyperv_stimer_enable_needed(void *opaque)
+{
+ X86CPU *cpu = opaque;
+ CPUX86State *env = &cpu->env;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(env->msr_hv_stimer_config); i++) {
+ if (env->msr_hv_stimer_config[i] || env->msr_hv_stimer_count[i]) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static const VMStateDescription vmstate_msr_hyperv_stimer = {
+ .name = "cpu/msr_hyperv_stimer",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = hyperv_stimer_enable_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64_ARRAY(env.msr_hv_stimer_config,
+ X86CPU, HV_SYNIC_STIMER_COUNT),
+ VMSTATE_UINT64_ARRAY(env.msr_hv_stimer_count,
+ X86CPU, HV_SYNIC_STIMER_COUNT),
+ VMSTATE_END_OF_LIST()
+ }
+};
+