From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jan Kiszka Subject: [PATCH 15/22] kvm: Add MCE signal support for !CONFIG_IOTHREAD Date: Thu, 27 Jan 2011 14:09:59 +0100 Message-ID: <99d06c0381c7834c80b83669443e26094a3a788b.1296133797.git.jan.kiszka@siemens.com> References: Cc: kvm@vger.kernel.org, qemu-devel@nongnu.org, Huang Ying , Hidetoshi Seto , Jin Dongming To: Avi Kivity , Marcelo Tosatti Return-path: Received: from thoth.sbs.de ([192.35.17.2]:19949 "EHLO thoth.sbs.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753224Ab1A0NKd (ORCPT ); Thu, 27 Jan 2011 08:10:33 -0500 In-Reply-To: In-Reply-To: References: Sender: kvm-owner@vger.kernel.org List-ID: 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 | 106 ++++++++++++++++++++++++++++++++++++++++------------------------ 1 files changed, 66 insertions(+), 40 deletions(-) diff --git a/cpus.c b/cpus.c index 29b1070..bba59e5 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; @@ -248,6 +305,7 @@ static void qemu_kvm_init_cpu_signals(CPUState *env) #ifndef CONFIG_IOTHREAD sigemptyset(&set); sigaddset(&set, SIG_IPI); + sigaddset(&set, SIGBUS); pthread_sigmask(SIG_BLOCK, &set, NULL); #endif @@ -338,13 +396,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; } @@ -408,6 +464,7 @@ int qemu_init_main_loop(void) int ret; sigemptyset(&blocked_signals); + sigaddset(&blocked_signals, SIGBUS); if (kvm_enabled()) { /* * We need to process timer signals synchronously to avoid a race @@ -424,6 +481,8 @@ int qemu_init_main_loop(void) #endif cpu_set_debug_excp_handler(cpu_debug_handler); + qemu_init_sigbus(); + return qemu_event_init(); } @@ -535,13 +594,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); @@ -555,12 +610,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; } @@ -571,6 +620,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); @@ -678,31 +729,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)) -- 1.7.1 From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=49578 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PiRcL-0001dG-Bz for qemu-devel@nongnu.org; Thu, 27 Jan 2011 08:10:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PiRcC-0000nT-A6 for qemu-devel@nongnu.org; Thu, 27 Jan 2011 08:10:29 -0500 Received: from thoth.sbs.de ([192.35.17.2]:19877) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PiRcC-0000nJ-0H for qemu-devel@nongnu.org; Thu, 27 Jan 2011 08:10:20 -0500 From: Jan Kiszka Date: Thu, 27 Jan 2011 14:09:59 +0100 Message-Id: <99d06c0381c7834c80b83669443e26094a3a788b.1296133797.git.jan.kiszka@siemens.com> In-Reply-To: References: In-Reply-To: References: Subject: [Qemu-devel] [PATCH 15/22] kvm: Add MCE signal support for !CONFIG_IOTHREAD List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Avi Kivity , Marcelo Tosatti Cc: Hidetoshi Seto , Jin Dongming , qemu-devel@nongnu.org, kvm@vger.kernel.org, Huang Ying 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 | 106 ++++++++++++++++++++++++++++++++++++++++------------------------ 1 files changed, 66 insertions(+), 40 deletions(-) diff --git a/cpus.c b/cpus.c index 29b1070..bba59e5 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; @@ -248,6 +305,7 @@ static void qemu_kvm_init_cpu_signals(CPUState *env) #ifndef CONFIG_IOTHREAD sigemptyset(&set); sigaddset(&set, SIG_IPI); + sigaddset(&set, SIGBUS); pthread_sigmask(SIG_BLOCK, &set, NULL); #endif @@ -338,13 +396,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; } @@ -408,6 +464,7 @@ int qemu_init_main_loop(void) int ret; sigemptyset(&blocked_signals); + sigaddset(&blocked_signals, SIGBUS); if (kvm_enabled()) { /* * We need to process timer signals synchronously to avoid a race @@ -424,6 +481,8 @@ int qemu_init_main_loop(void) #endif cpu_set_debug_excp_handler(cpu_debug_handler); + qemu_init_sigbus(); + return qemu_event_init(); } @@ -535,13 +594,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); @@ -555,12 +610,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; } @@ -571,6 +620,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); @@ -678,31 +729,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)) -- 1.7.1