From patchwork Tue Feb 1 21:15:58 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 81383 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 B311CB7109 for ; Wed, 2 Feb 2011 08:40:22 +1100 (EST) Received: from localhost ([127.0.0.1]:54977 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PkNw8-0008Eb-Ou for incoming@patchwork.ozlabs.org; Tue, 01 Feb 2011 16:38:56 -0500 Received: from [140.186.70.92] (port=46268 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PkNhA-0000fh-Fb for qemu-devel@nongnu.org; Tue, 01 Feb 2011 16:23:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PkNbO-0003Q4-VJ for qemu-devel@nongnu.org; Tue, 01 Feb 2011 16:17:32 -0500 Received: from fmmailgate03.web.de ([217.72.192.234]:59220) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PkNbN-0003P5-NR for qemu-devel@nongnu.org; Tue, 01 Feb 2011 16:17:30 -0500 Received: from smtp05.web.de ( [172.20.4.166]) by fmmailgate03.web.de (Postfix) with ESMTP id C22C0186EC4D3; Tue, 1 Feb 2011 22:16:14 +0100 (CET) Received: from [88.65.41.52] (helo=localhost.localdomain) by smtp05.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.110 #2) id 1PkNaA-0006FM-01; Tue, 01 Feb 2011 22:16:14 +0100 From: Jan Kiszka To: Avi Kivity , Marcelo Tosatti Date: Tue, 1 Feb 2011 22:15:58 +0100 Message-Id: <9fd62e054de565db850bf0b50402ef883f6c73f8.1296594961.git.jan.kiszka@web.de> X-Mailer: git-send-email 1.7.1 In-Reply-To: References: In-Reply-To: References: X-Sender: jan.kiszka@web.de X-Provags-ID: V01U2FsdGVkX1/eeoC+JRzumynj3xUnQ5GJeK6AOb+HnkOQPFS0 nOpdvMRHyyZofkSuZ1vsOG4mCYAti9pregnQ4EigdrbrjEHaEf /48LOQ+w4= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4-2.6 X-Received-From: 217.72.192.234 Cc: Hidetoshi Seto , Jin Dongming , qemu-devel@nongnu.org, kvm@vger.kernel.org, Huang Ying Subject: [Qemu-devel] [PATCH v2 18/24] kvm: Add MCE signal support for !CONFIG_IOTHREAD 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: Jan Kiszka Currently, we only configure and process MCE-related SIGBUS events if CONFIG_IOTHREAD is enabled. The groundwork is laid, we just need to factor out the required handler registration and system configuration. Signed-off-by: Jan Kiszka CC: Huang Ying CC: Hidetoshi Seto CC: Jin Dongming --- cpus.c | 107 +++++++++++++++++++++++++++++++++++++++------------------------- 1 files changed, 65 insertions(+), 42 deletions(-) diff --git a/cpus.c b/cpus.c index 18caf47..c4c5914 100644 --- a/cpus.c +++ b/cpus.c @@ -34,9 +34,6 @@ #include "cpus.h" #include "compatfd.h" -#ifdef CONFIG_LINUX -#include -#endif #ifdef SIGRTMIN #define SIG_IPI (SIGRTMIN+4) @@ -44,10 +41,24 @@ #define SIG_IPI SIGUSR1 #endif +#ifdef CONFIG_LINUX + +#include + #ifndef PR_MCE_KILL #define PR_MCE_KILL 33 #endif +#ifndef PR_MCE_KILL_SET +#define PR_MCE_KILL_SET 1 +#endif + +#ifndef PR_MCE_KILL_EARLY +#define PR_MCE_KILL_EARLY 1 +#endif + +#endif /* CONFIG_LINUX */ + static CPUState *next_cpu; /***********************************************************/ @@ -166,6 +177,52 @@ static void cpu_debug_handler(CPUState *env) vm_stop(EXCP_DEBUG); } +#ifdef CONFIG_LINUX +static void sigbus_reraise(void) +{ + sigset_t set; + struct sigaction action; + + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_DFL; + if (!sigaction(SIGBUS, &action, NULL)) { + raise(SIGBUS); + sigemptyset(&set); + sigaddset(&set, SIGBUS); + sigprocmask(SIG_UNBLOCK, &set, NULL); + } + perror("Failed to re-raise SIGBUS!\n"); + abort(); +} + +static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo, + void *ctx) +{ + if (kvm_on_sigbus(siginfo->ssi_code, + (void *)(intptr_t)siginfo->ssi_addr)) { + sigbus_reraise(); + } +} + +static void qemu_init_sigbus(void) +{ + struct sigaction action; + + memset(&action, 0, sizeof(action)); + action.sa_flags = SA_SIGINFO; + action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler; + sigaction(SIGBUS, &action, NULL); + + prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0); +} + +#else /* !CONFIG_LINUX */ + +static void qemu_init_sigbus(void) +{ +} +#endif /* !CONFIG_LINUX */ + #ifndef _WIN32 static int io_thread_fd = -1; @@ -288,8 +345,6 @@ static int qemu_signalfd_init(sigset_t mask) return 0; } -static void sigbus_reraise(void); - static void qemu_kvm_eat_signals(CPUState *env) { struct timespec ts = { 0, 0 }; @@ -310,13 +365,11 @@ static void qemu_kvm_eat_signals(CPUState *env) } switch (r) { -#ifdef CONFIG_IOTHREAD case SIGBUS: if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) { sigbus_reraise(); } break; -#endif default: break; } @@ -405,6 +458,7 @@ static sigset_t block_synchronous_signals(void) sigset_t set; sigemptyset(&set); + sigaddset(&set, SIGBUS); if (kvm_enabled()) { /* * We need to process timer signals synchronously to avoid a race @@ -433,6 +487,8 @@ int qemu_init_main_loop(void) #endif cpu_set_debug_excp_handler(cpu_debug_handler); + qemu_init_sigbus(); + return qemu_event_init(); } @@ -565,13 +621,9 @@ static void qemu_tcg_init_cpu_signals(void) pthread_sigmask(SIG_UNBLOCK, &set, NULL); } -static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo, - void *ctx); - static sigset_t block_io_signals(void) { sigset_t set; - struct sigaction action; /* SIGUSR2 used by posix-aio-compat.c */ sigemptyset(&set); @@ -585,12 +637,6 @@ static sigset_t block_io_signals(void) sigaddset(&set, SIGBUS); pthread_sigmask(SIG_BLOCK, &set, NULL); - memset(&action, 0, sizeof(action)); - action.sa_flags = SA_SIGINFO; - action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler; - sigaction(SIGBUS, &action, NULL); - prctl(PR_MCE_KILL, 1, 1, 0, 0); - return set; } @@ -601,6 +647,8 @@ int qemu_init_main_loop(void) cpu_set_debug_excp_handler(cpu_debug_handler); + qemu_init_sigbus(); + blocked_signals = block_io_signals(); ret = qemu_signalfd_init(blocked_signals); @@ -708,31 +756,6 @@ static void qemu_tcg_wait_io_event(void) } } -static void sigbus_reraise(void) -{ - sigset_t set; - struct sigaction action; - - memset(&action, 0, sizeof(action)); - action.sa_handler = SIG_DFL; - if (!sigaction(SIGBUS, &action, NULL)) { - raise(SIGBUS); - sigemptyset(&set); - sigaddset(&set, SIGBUS); - sigprocmask(SIG_UNBLOCK, &set, NULL); - } - perror("Failed to re-raise SIGBUS!\n"); - abort(); -} - -static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo, - void *ctx) -{ - if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr)) { - sigbus_reraise(); - } -} - static void qemu_kvm_wait_io_event(CPUState *env) { while (!cpu_has_work(env))