From mboxrd@z Thu Jan 1 00:00:00 1970 From: Hidetoshi Seto Subject: Re: [patch uq/master 7/8] MCE: Relay UCR MCE to guest Date: Wed, 06 Oct 2010 10:10:51 +0900 Message-ID: <4CABCC9B.10101@jp.fujitsu.com> References: <20101004185447.891324545@redhat.com> <20101004185715.167557459@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit Cc: kvm@vger.kernel.org, qemu-devel@nongnu.org, Huang Ying , Dean Nelson To: Marcelo Tosatti Return-path: Received: from fgwmail5.fujitsu.co.jp ([192.51.44.35]:50226 "EHLO fgwmail5.fujitsu.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757762Ab0JFBLs (ORCPT ); Tue, 5 Oct 2010 21:11:48 -0400 Received: from m1.gw.fujitsu.co.jp ([10.0.50.71]) by fgwmail5.fujitsu.co.jp (Fujitsu Gateway) with ESMTP id o961BhPs023986 for (envelope-from seto.hidetoshi@jp.fujitsu.com); Wed, 6 Oct 2010 10:11:43 +0900 Received: from smail (m1 [127.0.0.1]) by outgoing.m1.gw.fujitsu.co.jp (Postfix) with ESMTP id 0BE2845DE52 for ; Wed, 6 Oct 2010 10:11:43 +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 D1AD145DE4D for ; Wed, 6 Oct 2010 10:11: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 B5EC81DB804E for ; Wed, 6 Oct 2010 10:11:42 +0900 (JST) Received: from m105.s.css.fujitsu.com (m105.s.css.fujitsu.com [10.249.87.105]) by s1.gw.fujitsu.co.jp (Postfix) with ESMTP id 5AA3B1DB8053 for ; Wed, 6 Oct 2010 10:11:42 +0900 (JST) In-Reply-To: <20101004185715.167557459@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: (2010/10/05 3:54), Marcelo Tosatti wrote: > Port qemu-kvm's > > commit 4b62fff1101a7ad77553147717a8bd3bf79df7ef > Author: Huang Ying > Date: Mon Sep 21 10:43:25 2009 +0800 > > MCE: Relay UCR MCE to guest > > UCR (uncorrected recovery) MCE is supported in recent Intel CPUs, > where some hardware error such as some memory error can be reported > without PCC (processor context corrupted). To recover from such MCE, > the corresponding memory will be unmapped, and all processes accessing > the memory will be killed via SIGBUS. > > For KVM, if QEMU/KVM is killed, all guest processes will be killed > too. So we relay SIGBUS from host OS to guest system via a UCR MCE > injection. Then guest OS can isolate corresponding memory and kill > necessary guest processes only. SIGBUS sent to main thread (not VCPU > threads) will be broadcast to all VCPU threads as UCR MCE. > > Signed-off-by: Marcelo Tosatti > (snip) > +static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo, > + void *ctx) > +{ > +#if defined(TARGET_I386) > + if (kvm_on_sigbus_vcpu(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr)) > +#endif > + sigbus_reraise(); > +} > + > static void qemu_kvm_eat_signal(CPUState *env, int timeout) > { > struct timespec ts; > int r, e; > siginfo_t siginfo; > sigset_t waitset; > + sigset_t chkset; > > ts.tv_sec = timeout / 1000; > ts.tv_nsec = (timeout % 1000) * 1000000; > > sigemptyset(&waitset); > sigaddset(&waitset, SIG_IPI); > + sigaddset(&waitset, SIGBUS); > > - qemu_mutex_unlock(&qemu_global_mutex); > - r = sigtimedwait(&waitset, &siginfo, &ts); > - e = errno; > - qemu_mutex_lock(&qemu_global_mutex); > + do { > + qemu_mutex_unlock(&qemu_global_mutex); > > - if (r == -1 && !(e == EAGAIN || e == EINTR)) { > - fprintf(stderr, "sigtimedwait: %s\n", strerror(e)); > - exit(1); > - } > + r = sigtimedwait(&waitset, &siginfo, &ts); > + e = errno; > + > + qemu_mutex_lock(&qemu_global_mutex); > + > + if (r == -1 && !(e == EAGAIN || e == EINTR)) { > + fprintf(stderr, "sigtimedwait: %s\n", strerror(e)); > + exit(1); > + } > + > + switch (r) { > + case SIGBUS: > +#ifdef TARGET_I386 > + if (kvm_on_sigbus(env, siginfo.si_code, siginfo.si_addr)) > +#endif > + sigbus_reraise(); > + break; > + default: > + break; > + } > + > + r = sigpending(&chkset); > + if (r == -1) { > + fprintf(stderr, "sigpending: %s\n", strerror(e)); > + exit(1); > + } > + } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS)); > } > > static void qemu_kvm_wait_io_event(CPUState *env) (snip) > Index: qemu/kvm.h > =================================================================== > --- qemu.orig/kvm.h > +++ qemu/kvm.h > @@ -110,6 +110,9 @@ int kvm_arch_init_vcpu(CPUState *env); > > void kvm_arch_reset_vcpu(CPUState *env); > > +int kvm_on_sigbus(CPUState *env, int code, void *addr); > +int kvm_on_sigbus_vcpu(int code, void *addr); > + > struct kvm_guest_debug; > struct kvm_debug_exit_arch; > So kvm_on_sigbus() is called from qemu_kvm_eat_signal() that is called on vcpu thread, while kvm_on_sigbus_vcpu() is called via sigbus_handler that invoked on iothread using signalfd. ... Inverse naming? Thanks, H.Seto