diff options
Diffstat (limited to 'cpus.c')
-rw-r--r-- | cpus.c | 63 |
1 files changed, 32 insertions, 31 deletions
@@ -922,6 +922,10 @@ static void sigbus_reraise(void) 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)) { sigbus_reraise(); } @@ -939,6 +943,30 @@ static void qemu_init_sigbus(void) 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) { struct timespec ts = { 0, 0 }; @@ -960,6 +988,9 @@ static void qemu_kvm_eat_signals(CPUState *cpu) switch (r) { 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)) { sigbus_reraise(); } @@ -975,9 +1006,7 @@ static void qemu_kvm_eat_signals(CPUState *cpu) } } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS)); } - #else /* !CONFIG_LINUX */ - static void qemu_init_sigbus(void) { } @@ -985,39 +1014,11 @@ static void qemu_init_sigbus(void) 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) { - abort(); } -#endif /* _WIN32 */ +#endif /* !CONFIG_LINUX */ static QemuMutex qemu_global_mutex; |