From patchwork Mon Jan 24 09:02:13 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Tosatti X-Patchwork-Id: 80113 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 2D3A1B7128 for ; Mon, 24 Jan 2011 20:31:20 +1100 (EST) Received: from localhost ([127.0.0.1]:53216 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PhIlY-00011Q-Jf for incoming@patchwork.ozlabs.org; Mon, 24 Jan 2011 04:31:16 -0500 Received: from [140.186.70.92] (port=37964 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PhIMR-0008Jm-Bm for qemu-devel@nongnu.org; Mon, 24 Jan 2011 04:05:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PhIMN-0007DA-Ma for qemu-devel@nongnu.org; Mon, 24 Jan 2011 04:05:19 -0500 Received: from mx1.redhat.com ([209.132.183.28]:58495) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PhIMN-0007CM-AO for qemu-devel@nongnu.org; Mon, 24 Jan 2011 04:05:15 -0500 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id p0O95Efu018922 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 24 Jan 2011 04:05:14 -0500 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p0O95DHu015415; Mon, 24 Jan 2011 04:05:13 -0500 Received: from amt.cnet (vpn2-9-29.ams2.redhat.com [10.36.9.29]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id p0O95BoP008801; Mon, 24 Jan 2011 04:05:12 -0500 Received: from amt.cnet (localhost.localdomain [127.0.0.1]) by amt.cnet (Postfix) with ESMTP id 4B592652147; Mon, 24 Jan 2011 07:03:19 -0200 (BRST) Received: (from marcelo@localhost) by amt.cnet (8.14.4/8.14.4/Submit) id p0O93Fes028389; Mon, 24 Jan 2011 07:03:15 -0200 From: Marcelo Tosatti To: Anthony Liguori Date: Mon, 24 Jan 2011 07:02:13 -0200 Message-Id: <31ce5e0c49821d92fb30cce2f3055ef33613b287.1295859760.git.mtosatti@redhat.com> In-Reply-To: References: X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: Marcelo Tosatti , qemu-devel@nongnu.org, kvm@vger.kernel.org, Jin Dongming Subject: [Qemu-devel] [PATCH 04/31] Add "broadcast" option for mce command X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Jin Dongming When the following test case is injected with mce command, maybe user could not get the expected result. DATA command cpu bank status mcg_status addr misc (qemu) mce 1 1 0xbd00000000000000 0x05 0x1234 0x8c Expected Result panic type: "Fatal Machine check" That is because each mce command can only inject the given cpu and could not inject mce interrupt to other cpus. So user will get the following result: panic type: "Fatal machine check on current CPU" "broadcast" option is used for injecting dummy data into other cpus. Injecting mce with this option the expected result could be gotten. Usage: Broadcast[on] command broadcast cpu bank status mcg_status addr misc (qemu) mce -b 1 1 0xbd00000000000000 0x05 0x1234 0x8c Broadcast[off] command cpu bank status mcg_status addr misc (qemu) mce 1 1 0xbd00000000000000 0x05 0x1234 0x8c Signed-off-by: Jin Dongming Signed-off-by: Marcelo Tosatti --- cpu-all.h | 3 ++- hmp-commands.hx | 6 +++--- monitor.c | 7 +++++-- target-i386/helper.c | 20 ++++++++++++++++++-- target-i386/kvm.c | 16 ++++++++++++---- target-i386/kvm_x86.h | 5 ++++- 6 files changed, 44 insertions(+), 13 deletions(-) diff --git a/cpu-all.h b/cpu-all.h index 30ae17d..4ce4e83 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -964,6 +964,7 @@ int cpu_memory_rw_debug(CPUState *env, target_ulong addr, uint8_t *buf, int len, int is_write); void cpu_inject_x86_mce(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 broadcast); #endif /* CPU_ALL_H */ diff --git a/hmp-commands.hx b/hmp-commands.hx index 1cea572..d65a41f 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1116,9 +1116,9 @@ ETEXI { .name = "mce", - .args_type = "cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l", - .params = "cpu bank status mcgstatus addr misc", - .help = "inject a MCE on the given CPU", + .args_type = "broadcast:-b,cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l", + .params = "[-b] cpu bank status mcgstatus addr misc", + .help = "inject a MCE on the given CPU [and broadcast to other CPUs with -b option]", .mhandler.cmd = do_inject_mce, }, diff --git a/monitor.c b/monitor.c index d291158..396d5cd 100644 --- a/monitor.c +++ b/monitor.c @@ -2671,12 +2671,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); - for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) + for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) { if (cenv->cpu_index == cpu_index && cenv->mcg_cap) { - cpu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc); + cpu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, + broadcast); break; } + } } #endif diff --git a/target-i386/helper.c b/target-i386/helper.c index 2c94130..2cfb4a4 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1069,18 +1069,34 @@ static void qemu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, } void cpu_inject_x86_mce(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 broadcast) { unsigned bank_num = cenv->mcg_cap & 0xff; + CPUState *env; + int flag = 0; if (bank >= bank_num || !(status & MCI_STATUS_VAL)) { return; } if (kvm_enabled()) { - kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, 0); + if (broadcast) { + flag |= MCE_BROADCAST; + } + + kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, flag); } else { qemu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc); + if (broadcast) { + for (env = first_cpu; env != NULL; env = env->next_cpu) { + if (cenv == env) { + continue; + } + + qemu_inject_x86_mce(env, 1, 0xa000000000000000, 0, 0, 0); + } + } } } #endif /* !CONFIG_USER_ONLY */ diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 4004de7..8b868ad 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -264,11 +264,13 @@ static void kvm_do_inject_x86_mce(void *_data) } } } + +static void kvm_mce_broadcast_rest(CPUState *env); #endif void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, uint64_t mcg_status, uint64_t addr, uint64_t misc, - int abort_on_error) + int flag) { #ifdef KVM_CAP_MCE struct kvm_x86_mce mce = { @@ -288,10 +290,15 @@ void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, return; } + if (flag & MCE_BROADCAST) { + kvm_mce_broadcast_rest(cenv); + } + run_on_cpu(cenv, kvm_do_inject_x86_mce, &data); #else - if (abort_on_error) + if (flag & ABORT_ON_ERROR) { abort(); + } #endif } @@ -1716,7 +1723,8 @@ static void kvm_mce_broadcast_rest(CPUState *env) continue; } kvm_inject_x86_mce(cenv, 1, MCI_STATUS_VAL | MCI_STATUS_UC, - MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0, 1); + MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0, + ABORT_ON_ERROR); } } } @@ -1816,7 +1824,7 @@ int kvm_on_sigbus(int code, void *addr) | 0xc0; kvm_inject_x86_mce(first_cpu, 9, status, MCG_STATUS_MCIP | MCG_STATUS_RIPV, paddr, - (MCM_ADDR_PHYS << 6) | 0xc, 1); + (MCM_ADDR_PHYS << 6) | 0xc, ABORT_ON_ERROR); kvm_mce_broadcast_rest(first_cpu); } else #endif diff --git a/target-i386/kvm_x86.h b/target-i386/kvm_x86.h index 04932cf..9d7b584 100644 --- a/target-i386/kvm_x86.h +++ b/target-i386/kvm_x86.h @@ -15,8 +15,11 @@ #ifndef __KVM_X86_H__ #define __KVM_X86_H__ +#define ABORT_ON_ERROR 0x01 +#define MCE_BROADCAST 0x02 + void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, uint64_t mcg_status, uint64_t addr, uint64_t misc, - int abort_on_error); + int flag); #endif