From patchwork Tue Apr 27 07:10:49 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Ying" X-Patchwork-Id: 95284 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o3R7Asxl000838 for ; Tue, 27 Apr 2010 07:10:54 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752093Ab0D0HKv (ORCPT ); Tue, 27 Apr 2010 03:10:51 -0400 Received: from mga01.intel.com ([192.55.52.88]:21005 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751396Ab0D0HKv (ORCPT ); Tue, 27 Apr 2010 03:10:51 -0400 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP; 27 Apr 2010 00:09:10 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.52,278,1270450800"; d="scan'208";a="561833441" Received: from yhuang-dev.sh.intel.com (HELO [10.239.13.156]) ([10.239.13.156]) by fmsmga002.fm.intel.com with ESMTP; 27 Apr 2010 00:10:20 -0700 Subject: [PATCH] Ignore SRAO MCE if another MCE is being processed From: Huang Ying To: Avi Kivity Cc: Andi Kleen , "kvm@vger.kernel.org" Date: Tue, 27 Apr 2010 15:10:49 +0800 Message-ID: <1272352249.24125.19.camel@yhuang-dev.sh.intel.com> Mime-Version: 1.0 X-Mailer: Evolution 2.28.3 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.3 (demeter.kernel.org [140.211.167.41]); Tue, 27 Apr 2010 07:10:55 +0000 (UTC) --- a/qemu-kvm.c +++ b/qemu-kvm.c @@ -1610,6 +1610,19 @@ static void flush_queued_work(CPUState * pthread_cond_broadcast(&qemu_work_cond); } +static int kvm_mce_in_exception(CPUState *env) +{ + struct kvm_msr_entry msr_mcg_status = { + .index = MSR_MCG_STATUS, + }; + int r; + + r = kvm_get_msrs(env, &msr_mcg_status, 1); + if (r == -1 || r == 0) + return -1; + return !!(msr_mcg_status.data & MCG_STATUS_MCIP); +} + static void kvm_on_sigbus(CPUState *env, siginfo_t *siginfo) { #if defined(KVM_CAP_MCE) && defined(TARGET_I386) @@ -1630,6 +1643,15 @@ static void kvm_on_sigbus(CPUState *env, mce.misc = (MCM_ADDR_PHYS << 6) | 0xc; mce.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_EIPV; } else { + /* + * If there is an MCE excpetion being processed, ignore + * this SRAO MCE + */ + r = kvm_mce_in_exception(env); + if (r == -1) + fprintf(stderr, "Failed to get MCE status\n"); + else if (r) + return; /* Fake an Intel architectural Memory scrubbing UCR */ mce.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S @@ -2475,6 +2497,12 @@ static void kvm_do_inject_x86_mce(void * struct kvm_x86_mce_data *data = _data; int r; + /* If there is an MCE excpetion being processed, ignore this SRAO MCE */ + r = kvm_mce_in_exception(data->env); + if (r == -1) + fprintf(stderr, "Failed to get MCE status\n"); + else if (r && !(data->mce->status & MCI_STATUS_AR)) + return; r = kvm_set_mce(data->env, data->mce); if (r < 0) { perror("kvm_set_mce FAILED");