From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jin Dongming Subject: [PATCH 2/3] kvm, x86: kvm_mce_inj_* subroutins for templated error injections Date: Fri, 10 Dec 2010 17:25:06 +0900 Message-ID: <4D01E3E2.1080905@np.css.fujitsu.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit Cc: Andi Kleen , Huang Ying , Hidetoshi Seto , Dean Nelson , KVM list To: Avi Kivity , Marcelo Tosatti Return-path: Received: from fgwmail5.fujitsu.co.jp ([192.51.44.35]:60147 "EHLO fgwmail5.fujitsu.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752521Ab0LJIWn (ORCPT ); Fri, 10 Dec 2010 03:22:43 -0500 Received: from m1.gw.fujitsu.co.jp ([10.0.50.71]) by fgwmail5.fujitsu.co.jp (Fujitsu Gateway) with ESMTP id oBA8MgIc025446 for (envelope-from jin.dongming@np.css.fujitsu.com); Fri, 10 Dec 2010 17:22:42 +0900 Received: from smail (m1 [127.0.0.1]) by outgoing.m1.gw.fujitsu.co.jp (Postfix) with ESMTP id 9A93945DE5B for ; Fri, 10 Dec 2010 17:22:42 +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 81BBE45DE5D for ; Fri, 10 Dec 2010 17:22:42 +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 6763CE38001 for ; Fri, 10 Dec 2010 17:22:42 +0900 (JST) Received: from m005.s.css.fujitsu.com (m005.s.css.fujitsu.com [10.23.4.35]) by s1.gw.fujitsu.co.jp (Postfix) with ESMTP id 34A411DB804B for ; Fri, 10 Dec 2010 17:22:42 +0900 (JST) Sender: kvm-owner@vger.kernel.org List-ID: Refactor codes for maintainability. Signed-off-by: Hidetoshi Seto Signed-off-by: Jin Dongming --- target-i386/kvm.c | 111 ++++++++++++++++++++++++++++++++++------------------- 1 files changed, 71 insertions(+), 40 deletions(-) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index d7aae8b..1f3f369 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1752,44 +1752,75 @@ static void kvm_mce_broadcast_rest(CPUState *env) } } } + +static void kvm_mce_inj_srar_dataload(CPUState *env, target_phys_addr_t paddr) +{ + struct kvm_x86_mce mce = { + .bank = 9, + .status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN + | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S + | MCI_STATUS_AR | 0x134, + .mcg_status = MCG_STATUS_MCIP | MCG_STATUS_EIPV, + .addr = paddr, + .misc = (MCM_ADDR_PHYS << 6) | 0xc, + }; + int r; + + r = kvm_set_mce(env, &mce); + if (r < 0) { + fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno)); + abort(); + } + kvm_mce_broadcast_rest(env); +} + +static void kvm_mce_inj_srao_memscrub(CPUState *env, target_phys_addr_t paddr) +{ + struct kvm_x86_mce mce = { + .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, + }; + int r; + + r = kvm_set_mce(env, &mce); + if (r < 0) { + fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno)); + abort(); + } + kvm_mce_broadcast_rest(env); +} + +static void kvm_mce_inj_srao_memscrub2(CPUState *env, target_phys_addr_t paddr) +{ + uint64_t status; + + status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN + | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S + | 0xc0; + kvm_inject_x86_mce(env, 9, status, + MCG_STATUS_MCIP | MCG_STATUS_RIPV, paddr, + (MCM_ADDR_PHYS << 6) | 0xc, ABORT_ON_ERROR); + + kvm_mce_broadcast_rest(env); +} + #endif int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr) { #if defined(KVM_CAP_MCE) - struct kvm_x86_mce mce = { - .bank = 9, - }; void *vaddr; ram_addr_t ram_addr; target_phys_addr_t paddr; - int r; if ((env->mcg_cap & MCG_SER_P) && addr && (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) { - if (code == BUS_MCEERR_AR) { - /* Fake an Intel architectural Data Load SRAR UCR */ - mce.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN - | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S - | MCI_STATUS_AR | 0x134; - 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 - */ - if (kvm_mce_in_progress(env)) { - return 0; - } - /* 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 - | 0xc0; - mce.misc = (MCM_ADDR_PHYS << 6) | 0xc; - mce.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV; - } vaddr = (void *)addr; if (qemu_ram_addr_from_host(vaddr, &ram_addr) || !kvm_physical_memory_addr_from_ram(env->kvm_state, ram_addr, &paddr)) { @@ -1802,13 +1833,20 @@ int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr) hardware_memory_error(); } } - mce.addr = paddr; - r = kvm_set_mce(env, &mce); - if (r < 0) { - fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno)); - abort(); + + if (code == BUS_MCEERR_AR) { + /* Fake an Intel architectural Data Load SRAR UCR */ + kvm_mce_inj_srar_dataload(env, paddr); + } else { + /* + * If there is an MCE excpetion being processed, ignore + * this SRAO MCE + */ + if (!kvm_mce_in_progress(env)) { + /* Fake an Intel architectural Memory scrubbing UCR */ + kvm_mce_inj_srao_memscrub(env, paddr); + } } - kvm_mce_broadcast_rest(env); } else #endif { @@ -1827,7 +1865,6 @@ int kvm_on_sigbus(int code, void *addr) { #if defined(KVM_CAP_MCE) if ((first_cpu->mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) { - uint64_t status; void *vaddr; ram_addr_t ram_addr; target_phys_addr_t paddr; @@ -1840,13 +1877,7 @@ int kvm_on_sigbus(int code, void *addr) "QEMU itself instead of guest system!: %p\n", addr); return 0; } - status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN - | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S - | 0xc0; - kvm_inject_x86_mce(first_cpu, 9, status, - MCG_STATUS_MCIP | MCG_STATUS_RIPV, paddr, - (MCM_ADDR_PHYS << 6) | 0xc, ABORT_ON_ERROR); - kvm_mce_broadcast_rest(first_cpu); + kvm_mce_inj_srao_memscrub2(first_cpu, paddr); } else #endif { -- 1.7.1.1