From patchwork Wed Mar 2 07:56:20 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 602171 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 p227vYwT008450 for ; Wed, 2 Mar 2011 07:57:34 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755710Ab1CBH4v (ORCPT ); Wed, 2 Mar 2011 02:56:51 -0500 Received: from thoth.sbs.de ([192.35.17.2]:34730 "EHLO thoth.sbs.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755613Ab1CBH4r (ORCPT ); Wed, 2 Mar 2011 02:56:47 -0500 Received: from mail1.siemens.de (localhost [127.0.0.1]) by thoth.sbs.de (8.13.6/8.13.6) with ESMTP id p227uYIc028434; Wed, 2 Mar 2011 08:56:34 +0100 Received: from mchn199C.mchp.siemens.de ([146.254.217.97]) by mail1.siemens.de (8.13.6/8.13.6) with ESMTP id p227uKnV031204; Wed, 2 Mar 2011 08:56:33 +0100 From: Jan Kiszka To: Avi Kivity , Marcelo Tosatti Cc: kvm@vger.kernel.org, qemu-devel@nongnu.org, Huang Ying Subject: [PATCH v3 17/17] KVM, MCE, unpoison memory address across reboot Date: Wed, 2 Mar 2011 08:56:20 +0100 Message-Id: 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]); Wed, 02 Mar 2011 07:57:34 +0000 (UTC) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 44e5504..7b7105d 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 *addr) hardware_memory_error(); } } + kvm_hwpoison_page_add(ram_addr); kvm_mce_inject(env, paddr, code); } else #endif /* KVM_CAP_MCE */ @@ -263,6 +297,7 @@ int kvm_arch_on_sigbus(int code, void *addr) "QEMU itself instead of guest system!: %p\n", addr); return 0; } + kvm_hwpoison_page_add(ram_addr); kvm_mce_inject(first_cpu, paddr, code); } else #endif /* KVM_CAP_MCE */ @@ -571,6 +606,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; }