* Add savevm/loadvm support for MCE
@ 2010-02-26 3:20 Huang Ying
2010-02-26 8:43 ` Jan Kiszka
0 siblings, 1 reply; 2+ messages in thread
From: Huang Ying @ 2010-02-26 3:20 UTC (permalink / raw)
To: Avi Kivity, Anthony Liguori, Andi Kleen; +Cc: kvm
MCE registers are saved/load into/from CPUState in
kvm_arch_save/load_regs. Because all MCE registers except for
MCG_STATUS should be preserved, MCE registers are saved before
kvm_arch_load_regs in kvm_arch_cpu_reset. To simulate the MCG_STATUS
clearing upon reset, env->mcg_status is set to 0 after saving.
Signed-off-by: Huang Ying <ying.huang@intel.com>
---
qemu-kvm-x86.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -803,6 +803,27 @@ static void get_seg(SegmentCache *lhs, c
| (rhs->avl * DESC_AVL_MASK);
}
+static void kvm_load_mce_regs(CPUState *env)
+{
+#ifdef KVM_CAP_MCE
+ struct kvm_msr_entry msrs[100];
+ int rc, n, i;
+
+ if (!env->mcg_cap)
+ return;
+
+ 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) * 4; 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
+}
+
void kvm_arch_load_regs(CPUState *env)
{
struct kvm_regs regs;
@@ -922,6 +943,8 @@ void kvm_arch_load_regs(CPUState *env)
if (rc == -1)
perror("kvm_set_msrs FAILED");
+ kvm_load_mce_regs(env);
+
/*
* Kernels before 2.6.33 (which correlates with !kvm_has_vcpu_events())
* overwrote flags.TF injected via SET_GUEST_DEBUG while updating GP regs.
@@ -991,6 +1014,33 @@ void kvm_arch_load_mpstate(CPUState *env
#endif
}
+static void kvm_save_mce_regs(CPUState *env)
+{
+#ifdef KVM_CAP_MCE
+ struct kvm_msr_entry msrs[100];
+ int rc, n, i;
+
+ if (!env->mcg_cap)
+ return;
+
+ 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_set_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
+}
+
void kvm_arch_save_regs(CPUState *env)
{
struct kvm_regs regs;
@@ -1148,6 +1198,7 @@ void kvm_arch_save_regs(CPUState *env)
}
}
kvm_arch_save_mpstate(env);
+ kvm_save_mce_regs(env);
}
static void do_cpuid_ent(struct kvm_cpuid_entry2 *e, uint32_t function,
@@ -1385,6 +1436,9 @@ void kvm_arch_push_nmi(void *opaque)
void kvm_arch_cpu_reset(CPUState *env)
{
kvm_arch_reset_vcpu(env);
+ /* MCE registers except MCG_STATUS should be unchanged across reset */
+ kvm_save_mce_regs(env);
+ env->mcg_status = 0;
kvm_arch_load_regs(env);
kvm_put_vcpu_events(env);
if (!cpu_is_bsp(env)) {
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: Add savevm/loadvm support for MCE
2010-02-26 3:20 Add savevm/loadvm support for MCE Huang Ying
@ 2010-02-26 8:43 ` Jan Kiszka
0 siblings, 0 replies; 2+ messages in thread
From: Jan Kiszka @ 2010-02-26 8:43 UTC (permalink / raw)
To: Huang Ying; +Cc: Avi Kivity, Anthony Liguori, Andi Kleen, kvm
Huang Ying wrote:
> MCE registers are saved/load into/from CPUState in
> kvm_arch_save/load_regs. Because all MCE registers except for
> MCG_STATUS should be preserved, MCE registers are saved before
> kvm_arch_load_regs in kvm_arch_cpu_reset. To simulate the MCG_STATUS
> clearing upon reset, env->mcg_status is set to 0 after saving.
That should be solved differently on top of [1]: Write back
MSR_MCG_STATUS on KVM_PUT_RESET_STATE, write all MCE MSRs on
KVM_PUT_FULL_STATE. Then you can also unfold kvm_load/save_mce_regs to
avoid duplicating its infrastructure (becomes even more obvious when
looking at kvm_get/put/_msrs in upstream).
>
> Signed-off-by: Huang Ying <ying.huang@intel.com>
>
> ---
> qemu-kvm-x86.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 54 insertions(+)
>
> --- a/qemu-kvm-x86.c
> +++ b/qemu-kvm-x86.c
> @@ -803,6 +803,27 @@ static void get_seg(SegmentCache *lhs, c
> | (rhs->avl * DESC_AVL_MASK);
> }
>
> +static void kvm_load_mce_regs(CPUState *env)
> +{
> +#ifdef KVM_CAP_MCE
> + struct kvm_msr_entry msrs[100];
> + int rc, n, i;
> +
> + if (!env->mcg_cap)
> + return;
> +
> + 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) * 4; 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
> +}
> +
> void kvm_arch_load_regs(CPUState *env)
> {
> struct kvm_regs regs;
> @@ -922,6 +943,8 @@ void kvm_arch_load_regs(CPUState *env)
> if (rc == -1)
> perror("kvm_set_msrs FAILED");
>
> + kvm_load_mce_regs(env);
> +
> /*
> * Kernels before 2.6.33 (which correlates with !kvm_has_vcpu_events())
> * overwrote flags.TF injected via SET_GUEST_DEBUG while updating GP regs.
> @@ -991,6 +1014,33 @@ void kvm_arch_load_mpstate(CPUState *env
> #endif
> }
>
> +static void kvm_save_mce_regs(CPUState *env)
> +{
> +#ifdef KVM_CAP_MCE
> + struct kvm_msr_entry msrs[100];
> + int rc, n, i;
> +
> + if (!env->mcg_cap)
> + return;
> +
> + 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_set_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
> +}
> +
> void kvm_arch_save_regs(CPUState *env)
> {
> struct kvm_regs regs;
> @@ -1148,6 +1198,7 @@ void kvm_arch_save_regs(CPUState *env)
> }
> }
> kvm_arch_save_mpstate(env);
> + kvm_save_mce_regs(env);
> }
>
> static void do_cpuid_ent(struct kvm_cpuid_entry2 *e, uint32_t function,
> @@ -1385,6 +1436,9 @@ void kvm_arch_push_nmi(void *opaque)
> void kvm_arch_cpu_reset(CPUState *env)
> {
> kvm_arch_reset_vcpu(env);
> + /* MCE registers except MCG_STATUS should be unchanged across reset */
> + kvm_save_mce_regs(env);
> + env->mcg_status = 0;
> kvm_arch_load_regs(env);
> kvm_put_vcpu_events(env);
> if (!cpu_is_bsp(env)) {
>
>
Jan
[1] http://thread.gmane.org/gmane.comp.emulators.kvm.devel/47411
--
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-02-26 8:44 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-26 3:20 Add savevm/loadvm support for MCE Huang Ying
2010-02-26 8:43 ` Jan Kiszka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox