From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jin Dongming Subject: [PATCH 11/11] kvm, x86: broadcast mce depending on the cpu version Date: Thu, 14 Oct 2010 17:55:28 +0900 Message-ID: <4CB6C580.1090804@np.css.fujitsu.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit Cc: Dean Nelson , Marcelo Tosatti , Avi Kivity , Huang Ying , Hidetoshi Seto , "qemu-devel@nongnu.org" To: KVM list Return-path: Received: from fgwmail7.fujitsu.co.jp ([192.51.44.37]:41548 "EHLO fgwmail7.fujitsu.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753060Ab0JNIyC (ORCPT ); Thu, 14 Oct 2010 04:54:02 -0400 Received: from m1.gw.fujitsu.co.jp ([10.0.50.71]) by fgwmail7.fujitsu.co.jp (Fujitsu Gateway) with ESMTP id o9E8s16C002555 for (envelope-from jin.dongming@np.css.fujitsu.com); Thu, 14 Oct 2010 17:54:01 +0900 Received: from smail (m1 [127.0.0.1]) by outgoing.m1.gw.fujitsu.co.jp (Postfix) with ESMTP id 8484745DE52 for ; Thu, 14 Oct 2010 17:54:01 +0900 (JST) Received: from s1.gw.fujitsu.co.jp (s1.gw.fujitsu.co.jp [10.0.50.91]) by m1.gw.fujitsu.co.jp (Postfix) with ESMTP id 5A73545DE50 for ; Thu, 14 Oct 2010 17:54:01 +0900 (JST) Received: from s1.gw.fujitsu.co.jp (localhost.localdomain [127.0.0.1]) by s1.gw.fujitsu.co.jp (Postfix) with ESMTP id 364D71DB8049 for ; Thu, 14 Oct 2010 17:54:01 +0900 (JST) Received: from m004.s.css.fujitsu.com (m004.s.css.fujitsu.com [10.23.4.34]) by s1.gw.fujitsu.co.jp (Postfix) with ESMTP id D609B1DB8046 for ; Thu, 14 Oct 2010 17:54:00 +0900 (JST) Sender: kvm-owner@vger.kernel.org List-ID: There is no reason why SRAO event received by the main thread is the only one that being broadcasted. According to the x86 ASDM vol.3A 15.10.4.1, MCE signal is broadcast on processor version 06H_EH or later. This change is required to handle SRAR in the guest. Signed-off-by: Hidetoshi Seto Tested-by: Jin Dongming --- qemu-kvm.c | 63 +++++++++++++++++++++++++++++------------------------------ 1 files changed, 31 insertions(+), 32 deletions(-) diff --git a/qemu-kvm.c b/qemu-kvm.c index d2b2459..846f0b6 100644 --- a/qemu-kvm.c +++ b/qemu-kvm.c @@ -1149,6 +1149,34 @@ static int kvm_mce_in_progress(CPUState *env) return !!(msr_mcg_status.data & MCG_STATUS_MCIP); } +static void kvm_mce_inj_broadcast(CPUState *env, struct kvm_x86_mce *mce) +{ + struct kvm_x86_mce mce_sub = { + .bank = 1, + .status = MCI_STATUS_VAL | MCI_STATUS_UC, + .mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV, + .addr = 0, + .misc = 0, + }; + CPUState *cenv; + int family, model, cpuver = env->cpuid_version; + + family = (cpuver >> 8) & 0xf; + model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0xf); + + kvm_inject_x86_mce_on(env, mce, 1); + + /* Broadcast MCA signal for processor version 06H_EH and above */ + if ((family == 6 && model >= 14) || family > 6) { + for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) { + if (cenv == env) { + continue; + } + kvm_inject_x86_mce_on(cenv, &mce_sub, 1); + } + } +} + static void kvm_do_set_mce(CPUState *env, struct kvm_x86_mce *mce, int abort_on_error) { @@ -1175,7 +1203,7 @@ static void kvm_mce_inj_srar_dataload(CPUState *env, target_phys_addr_t paddr) .misc = (MCM_ADDR_PHYS << 6) | 0xc, }; - kvm_do_set_mce(env, &mce, 1); + kvm_mce_inj_broadcast(env, &mce); } static void kvm_mce_inj_srao_memscrub(CPUState *env, target_phys_addr_t paddr) @@ -1190,32 +1218,7 @@ static void kvm_mce_inj_srao_memscrub(CPUState *env, target_phys_addr_t paddr) .misc = (MCM_ADDR_PHYS << 6) | 0xc, }; - kvm_do_set_mce(env, &mce, 1); -} - -static void kvm_mce_inj_srao_broadcast(target_phys_addr_t paddr) -{ - struct kvm_x86_mce mce_srao_memscrub = { - .bank = 9, - .status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN - | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S - | 0xc0, - .mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV, - .addr = paddr, - .misc = (MCM_ADDR_PHYS << 6) | 0xc, - }; - struct kvm_x86_mce mce_dummy = { - .bank = 1, - .status = MCI_STATUS_VAL | MCI_STATUS_UC, - .mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV, - .addr = 0, - .misc = 0, - }; - CPUState *cenv; - - kvm_inject_x86_mce_on(first_cpu, &mce_srao_memscrub, 1); - for (cenv = first_cpu->next_cpu; cenv != NULL; cenv = cenv->next_cpu) - kvm_inject_x86_mce_on(cenv, &mce_dummy, 1); + kvm_mce_inj_broadcast(env, &mce); } #endif @@ -1255,11 +1258,7 @@ static void kvm_handle_sigbus(CPUState *env, int code, void *vaddr) kvm_mce_inj_srar_dataload(target_env, paddr); } else { /* Fake an Intel architectural Memory scrubbing UCR */ - if (env) { - kvm_mce_inj_srao_memscrub(target_env, paddr); - } else { - kvm_mce_inj_srao_broadcast(paddr); - } + kvm_mce_inj_srao_memscrub(target_env, paddr); } return; } -- 1.7.1.1