提交 a16fc07e 编写于 作者: P Paolo Bonzini

cpus: reorganize signal handling code

Move the KVM "eat signals" code under CONFIG_LINUX, in preparation
for moving it to kvm-all.c; reraise non-MCE SIGBUS immediately,
without passing it to KVM.
Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
上级 20e0ff59
...@@ -922,6 +922,10 @@ static void sigbus_reraise(void) ...@@ -922,6 +922,10 @@ static void sigbus_reraise(void)
static void sigbus_handler(int n, siginfo_t *siginfo, void *ctx) static void sigbus_handler(int n, siginfo_t *siginfo, void *ctx)
{ {
if (siginfo->si_code != BUS_MCEERR_AO && siginfo->si_code != BUS_MCEERR_AR) {
sigbus_reraise();
}
if (kvm_on_sigbus(siginfo->si_code, siginfo->si_addr)) { if (kvm_on_sigbus(siginfo->si_code, siginfo->si_addr)) {
sigbus_reraise(); sigbus_reraise();
} }
...@@ -939,6 +943,30 @@ static void qemu_init_sigbus(void) ...@@ -939,6 +943,30 @@ static void qemu_init_sigbus(void)
prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0); prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0);
} }
static void dummy_signal(int sig)
{
}
static void qemu_kvm_init_cpu_signals(CPUState *cpu)
{
int r;
sigset_t set;
struct sigaction sigact;
memset(&sigact, 0, sizeof(sigact));
sigact.sa_handler = dummy_signal;
sigaction(SIG_IPI, &sigact, NULL);
pthread_sigmask(SIG_BLOCK, NULL, &set);
sigdelset(&set, SIG_IPI);
sigdelset(&set, SIGBUS);
r = kvm_set_signal_mask(cpu, &set);
if (r) {
fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
exit(1);
}
}
static void qemu_kvm_eat_signals(CPUState *cpu) static void qemu_kvm_eat_signals(CPUState *cpu)
{ {
struct timespec ts = { 0, 0 }; struct timespec ts = { 0, 0 };
...@@ -960,6 +988,9 @@ static void qemu_kvm_eat_signals(CPUState *cpu) ...@@ -960,6 +988,9 @@ static void qemu_kvm_eat_signals(CPUState *cpu)
switch (r) { switch (r) {
case SIGBUS: case SIGBUS:
if (siginfo.si_code != BUS_MCEERR_AO && siginfo.si_code != BUS_MCEERR_AR) {
sigbus_reraise();
}
if (kvm_on_sigbus_vcpu(cpu, siginfo.si_code, siginfo.si_addr)) { if (kvm_on_sigbus_vcpu(cpu, siginfo.si_code, siginfo.si_addr)) {
sigbus_reraise(); sigbus_reraise();
} }
...@@ -975,9 +1006,7 @@ static void qemu_kvm_eat_signals(CPUState *cpu) ...@@ -975,9 +1006,7 @@ static void qemu_kvm_eat_signals(CPUState *cpu)
} }
} while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS)); } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
} }
#else /* !CONFIG_LINUX */ #else /* !CONFIG_LINUX */
static void qemu_init_sigbus(void) static void qemu_init_sigbus(void)
{ {
} }
...@@ -985,39 +1014,11 @@ static void qemu_init_sigbus(void) ...@@ -985,39 +1014,11 @@ static void qemu_init_sigbus(void)
static void qemu_kvm_eat_signals(CPUState *cpu) static void qemu_kvm_eat_signals(CPUState *cpu)
{ {
} }
#endif /* !CONFIG_LINUX */
#ifndef _WIN32
static void dummy_signal(int sig)
{
}
static void qemu_kvm_init_cpu_signals(CPUState *cpu)
{
int r;
sigset_t set;
struct sigaction sigact;
memset(&sigact, 0, sizeof(sigact));
sigact.sa_handler = dummy_signal;
sigaction(SIG_IPI, &sigact, NULL);
pthread_sigmask(SIG_BLOCK, NULL, &set);
sigdelset(&set, SIG_IPI);
sigdelset(&set, SIGBUS);
r = kvm_set_signal_mask(cpu, &set);
if (r) {
fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
exit(1);
}
}
#else /* _WIN32 */
static void qemu_kvm_init_cpu_signals(CPUState *cpu) static void qemu_kvm_init_cpu_signals(CPUState *cpu)
{ {
abort();
} }
#endif /* _WIN32 */ #endif /* !CONFIG_LINUX */
static QemuMutex qemu_global_mutex; static QemuMutex qemu_global_mutex;
......
...@@ -284,6 +284,15 @@ void qemu_anon_ram_free(void *ptr, size_t size); ...@@ -284,6 +284,15 @@ void qemu_anon_ram_free(void *ptr, size_t size);
#endif #endif
#if defined(CONFIG_LINUX)
#ifndef BUS_MCEERR_AR
#define BUS_MCEERR_AR 4
#endif
#ifndef BUS_MCEERR_AO
#define BUS_MCEERR_AO 5
#endif
#endif
#if defined(__linux__) && \ #if defined(__linux__) && \
(defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)) (defined(__x86_64__) || defined(__arm__) || defined(__aarch64__))
/* Use 2 MiB alignment so transparent hugepages can be used by KVM. /* Use 2 MiB alignment so transparent hugepages can be used by KVM.
......
...@@ -64,13 +64,6 @@ ...@@ -64,13 +64,6 @@
* 255 kvm_msr_entry structs */ * 255 kvm_msr_entry structs */
#define MSR_BUF_SIZE 4096 #define MSR_BUF_SIZE 4096
#ifndef BUS_MCEERR_AR
#define BUS_MCEERR_AR 4
#endif
#ifndef BUS_MCEERR_AO
#define BUS_MCEERR_AO 5
#endif
const KVMCapabilityInfo kvm_arch_required_capabilities[] = { const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_INFO(SET_TSS_ADDR), KVM_CAP_INFO(SET_TSS_ADDR),
KVM_CAP_INFO(EXT_CPUID), KVM_CAP_INFO(EXT_CPUID),
...@@ -469,9 +462,7 @@ int kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr) ...@@ -469,9 +462,7 @@ int kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr)
ram_addr_t ram_addr; ram_addr_t ram_addr;
hwaddr paddr; hwaddr paddr;
if (code != BUS_MCEERR_AR && code != BUS_MCEERR_AO) { assert(code == BUS_MCEERR_AR || code == BUS_MCEERR_AO);
return 1;
}
/* Because the MCE happened while running the VCPU, KVM could have /* Because the MCE happened while running the VCPU, KVM could have
* injected action required MCEs too. Action optional MCEs should * injected action required MCEs too. Action optional MCEs should
...@@ -504,9 +495,7 @@ int kvm_arch_on_sigbus(int code, void *addr) ...@@ -504,9 +495,7 @@ int kvm_arch_on_sigbus(int code, void *addr)
{ {
X86CPU *cpu = X86_CPU(first_cpu); X86CPU *cpu = X86_CPU(first_cpu);
if (code != BUS_MCEERR_AR && code != BUS_MCEERR_AO) { assert(code == BUS_MCEERR_AR || code == BUS_MCEERR_AO);
return 1;
}
if (code == BUS_MCEERR_AR) { if (code == BUS_MCEERR_AR) {
hardware_memory_error(); hardware_memory_error();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册