@@ -979,11 +979,33 @@ void kvm_arch_load_regs(CPUState *env, i
set_msr_entry(&msrs[n++], MSR_KVM_SYSTEM_TIME, env->system_time_msr);
set_msr_entry(&msrs[n++], MSR_KVM_WALL_CLOCK, env->wall_clock_msr);
}
+#ifdef KVM_CAP_MCE
+ if (env->mcg_cap && level == KVM_PUT_RESET_STATE) {
+ /*
+ * MCG_STATUS should reset to 0 after reset, while other MCE
+ * registers should be unchanged
+ */
+ set_msr_entry(&msrs[n++], MSR_MCG_STATUS, 0);
+ }
+#endif
rc = kvm_set_msrs(env, msrs, n);
if (rc == -1)
perror("kvm_set_msrs FAILED");
+#ifdef KVM_CAP_MCE
+ if (env->mcg_cap && level == KVM_PUT_FULL_STATE) {
+ n = 0;
+ set_msr_entry(&msrs[n++], MSR_MCG_STATUS, env->mcg_status);
+ set_msr_entry(&msrs[n++], MSR_MCG_CTL, env->mcg_ctl);
+ for (i = 0; i < (env->mcg_cap & 0xff); i++)
+ set_msr_entry(&msrs[n++], MSR_MC0_CTL + i, env->mce_banks[i]);
+ rc = kvm_set_msrs(env, msrs, n);
+ if (rc == -1)
+ perror("kvm_set_msrs FAILED");
+ }
+#endif
+
if (level >= KVM_PUT_RESET_STATE) {
kvm_arch_load_mpstate(env);
kvm_load_lapic(env);
@@ -1155,6 +1177,27 @@ void kvm_arch_save_regs(CPUState *env)
return;
}
}
+
+#ifdef KVM_CAP_MCE
+ if (env->mcg_cap) {
+ msrs[0].index = MSR_MCG_STATUS;
+ msrs[1].index = MSR_MCG_CTL;
+ n = (env->mcg_cap & 0xff) * 4;
+ for (i = 0; i < n; i++)
+ msrs[2 + i].index = MSR_MC0_CTL + i;
+
+ rc = kvm_get_msrs(env, msrs, n + 2);
+ if (rc == -1)
+ perror("kvm_get_msrs FAILED");
+ else {
+ env->mcg_status = msrs[0].data;
+ env->mcg_ctl = msrs[1].data;
+ for (i = 0; i < n; i++)
+ env->mce_banks[i] = msrs[2 + i].data;
+ }
+ }
+#endif
+
kvm_arch_save_mpstate(env);
kvm_save_lapic(env);
kvm_get_vcpu_events(env);