From patchwork Tue Feb 15 08:23:29 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 558111 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p1F8OJ5m015630 for ; Tue, 15 Feb 2011 08:24:38 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754425Ab1BOIYL (ORCPT ); Tue, 15 Feb 2011 03:24:11 -0500 Received: from thoth.sbs.de ([192.35.17.2]:20847 "EHLO thoth.sbs.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754254Ab1BOIX6 (ORCPT ); Tue, 15 Feb 2011 03:23:58 -0500 Received: from mail1.siemens.de (localhost [127.0.0.1]) by thoth.sbs.de (8.13.6/8.13.6) with ESMTP id p1F8NcFt015051; Tue, 15 Feb 2011 09:23:38 +0100 Received: from mchn199C.mchp.siemens.de ([139.25.246.60]) by mail1.siemens.de (8.13.6/8.13.6) with ESMTP id p1F8Nb0p027686; Tue, 15 Feb 2011 09:23:38 +0100 From: Jan Kiszka To: Avi Kivity , Marcelo Tosatti Cc: kvm@vger.kernel.org, qemu-devel@nongnu.org, Huang Ying , Hidetoshi Seto , Jin Dongming Subject: [PATCH 05/13] x86: Optionally avoid injecting AO MCEs while others are pending Date: Tue, 15 Feb 2011 09:23:29 +0100 Message-Id: <7bf2a899a44100e18837b15ed23551f26fc8e7c7.1297758211.git.jan.kiszka@siemens.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: References: In-Reply-To: References: Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Tue, 15 Feb 2011 08:24:38 +0000 (UTC) diff --git a/monitor.c b/monitor.c index 662df7c..ae20927 100644 --- a/monitor.c +++ b/monitor.c @@ -2709,12 +2709,15 @@ static void do_inject_mce(Monitor *mon, const QDict *qdict) uint64_t mcg_status = qdict_get_int(qdict, "mcg_status"); uint64_t addr = qdict_get_int(qdict, "addr"); uint64_t misc = qdict_get_int(qdict, "misc"); - int broadcast = qdict_get_try_bool(qdict, "broadcast", 0); + int flags = MCE_INJECT_UNCOND_AO; + if (qdict_get_try_bool(qdict, "broadcast", 0)) { + flags |= MCE_INJECT_BROADCAST; + } for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) { if (cenv->cpu_index == cpu_index) { cpu_x86_inject_mce(mon, cenv, bank, status, mcg_status, addr, misc, - broadcast); + flags); break; } } diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 486af1d..d0eae75 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -987,8 +987,11 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, void do_cpu_init(CPUState *env); void do_cpu_sipi(CPUState *env); +#define MCE_INJECT_BROADCAST 1 +#define MCE_INJECT_UNCOND_AO 2 + void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank, uint64_t status, uint64_t mcg_status, uint64_t addr, - uint64_t misc, int broadcast); + uint64_t misc, int flags); #endif /* CPU_I386_H */ diff --git a/target-i386/helper.c b/target-i386/helper.c index 462d332..e3ef40c 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1069,11 +1069,20 @@ static void breakpoint_handler(CPUState *env) static void qemu_inject_x86_mce(Monitor *mon, CPUState *cenv, int bank, uint64_t status, - uint64_t mcg_status, uint64_t addr, uint64_t misc) + uint64_t mcg_status, uint64_t addr, uint64_t misc, + int flags) { uint64_t mcg_cap = cenv->mcg_cap; uint64_t *banks = cenv->mce_banks + 4 * bank; + /* + * If there is an MCE exception being processed, ignore this SRAO MCE + * unless unconditional injection was requested. + */ + if (!(flags & MCE_INJECT_UNCOND_AO) && !(status & MCI_STATUS_AR) + && (cenv->mcg_status & MCG_STATUS_MCIP)) { + return; + } if (status & MCI_STATUS_UC) { /* * if MSR_MCG_CTL is not all 1s, the uncorrected error @@ -1127,7 +1136,7 @@ qemu_inject_x86_mce(Monitor *mon, CPUState *cenv, int bank, uint64_t status, void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank, uint64_t status, uint64_t mcg_status, uint64_t addr, - uint64_t misc, int broadcast) + uint64_t misc, int flags) { unsigned bank_num = cenv->mcg_cap & 0xff; CPUState *env; @@ -1145,27 +1154,30 @@ void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank, monitor_printf(mon, "Invalid MCE status code\n"); return; } - if (broadcast && !cpu_x86_support_mca_broadcast(cenv)) { + if ((flags & MCE_INJECT_BROADCAST) + && !cpu_x86_support_mca_broadcast(cenv)) { monitor_printf(mon, "Guest CPU does not support MCA broadcast\n"); return; } if (kvm_enabled()) { - if (broadcast) { + if (flags & MCE_INJECT_BROADCAST) { flag |= MCE_BROADCAST; } kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, flag); } else { - qemu_inject_x86_mce(mon, cenv, bank, status, mcg_status, addr, misc); - if (broadcast) { + qemu_inject_x86_mce(mon, cenv, bank, status, mcg_status, addr, misc, + flags); + if (flags & MCE_INJECT_BROADCAST) { for (env = first_cpu; env != NULL; env = env->next_cpu) { if (cenv == env) { continue; } qemu_inject_x86_mce(mon, env, 1, MCI_STATUS_VAL | MCI_STATUS_UC, - MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0); + MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0, + flags); } } }