From patchwork Tue Feb 15 08:23:37 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 558041 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 p1F8O8cq015500 for ; Tue, 15 Feb 2011 08:24:09 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754245Ab1BOIX5 (ORCPT ); Tue, 15 Feb 2011 03:23:57 -0500 Received: from goliath.siemens.de ([192.35.17.28]:22295 "EHLO goliath.siemens.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754201Ab1BOIXy (ORCPT ); Tue, 15 Feb 2011 03:23:54 -0500 Received: from mail1.siemens.de (localhost [127.0.0.1]) by goliath.siemens.de (8.13.6/8.13.6) with ESMTP id p1F8NdJv011897; Tue, 15 Feb 2011 09:23:39 +0100 Received: from mchn199C.mchp.siemens.de ([139.25.246.60]) by mail1.siemens.de (8.13.6/8.13.6) with ESMTP id p1F8Nb0x027686; Tue, 15 Feb 2011 09:23:39 +0100 From: Jan Kiszka To: Avi Kivity , Marcelo Tosatti Cc: kvm@vger.kernel.org, qemu-devel@nongnu.org, Huang Ying Subject: [PATCH 13/13] KVM, MCE, unpoison memory address across reboot Date: Tue, 15 Feb 2011 09:23:37 +0100 Message-Id: <9edbfeecbb577d7db970e0a21d7e5444e331184f.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:09 +0000 (UTC) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 8eda78b..45e366a 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -173,7 +173,40 @@ static int get_para_features(CPUState *env) } #endif /* CONFIG_KVM_PARA */ +typedef struct HWPoisonPage { + ram_addr_t ram_addr; + QLIST_ENTRY(HWPoisonPage) list; +} HWPoisonPage; + +static QLIST_HEAD(, HWPoisonPage) hwpoison_page_list = + QLIST_HEAD_INITIALIZER(hwpoison_page_list); + +static void kvm_unpoison_all(void *param) +{ + HWPoisonPage *page, *next_page; + + QLIST_FOREACH_SAFE(page, &hwpoison_page_list, list, next_page) { + QLIST_REMOVE(page, list); + qemu_ram_remap(page->ram_addr, TARGET_PAGE_SIZE); + qemu_free(page); + } +} + #ifdef KVM_CAP_MCE +static void kvm_hwpoison_page_add(ram_addr_t ram_addr) +{ + HWPoisonPage *page; + + QLIST_FOREACH(page, &hwpoison_page_list, list) { + if (page->ram_addr == ram_addr) { + return; + } + } + page = qemu_malloc(sizeof(HWPoisonPage)); + page->ram_addr = ram_addr; + QLIST_INSERT_HEAD(&hwpoison_page_list, page, list); +} + static int kvm_get_mce_cap_supported(KVMState *s, uint64_t *mce_cap, int *max_banks) { @@ -233,6 +266,7 @@ int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *hvaddr) hardware_memory_error(); } } + kvm_hwpoison_page_add(ram_addr); kvm_mce_inject(env, gpaddr, code); } else #endif /* KVM_CAP_MCE */ @@ -263,6 +297,7 @@ int kvm_arch_on_sigbus(int code, void *hvaddr) "QEMU itself instead of guest system!: %p\n", hvaddr); return 0; } + kvm_hwpoison_page_add(ram_addr); kvm_mce_inject(first_cpu, gpaddr, code); } else #endif /* KVM_CAP_MCE */ @@ -577,6 +612,7 @@ int kvm_arch_init(KVMState *s) fprintf(stderr, "e820_add_entry() table is full\n"); return ret; } + qemu_register_reset(kvm_unpoison_all, NULL); return 0; }