From nobody Mon Feb 9 17:25:21 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1487959950552412.12729155417105; Fri, 24 Feb 2017 10:12:30 -0800 (PST) Received: from localhost ([::1]:39092 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1chKM1-0000Wm-9B for importer@patchew.org; Fri, 24 Feb 2017 13:12:29 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36397) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1chJrO-00081J-Kv for qemu-devel@nongnu.org; Fri, 24 Feb 2017 12:40:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1chJrK-0002I4-Kl for qemu-devel@nongnu.org; Fri, 24 Feb 2017 12:40:50 -0500 Received: from mail-wm0-x244.google.com ([2a00:1450:400c:c09::244]:35678) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1chJrK-0002Hj-BM for qemu-devel@nongnu.org; Fri, 24 Feb 2017 12:40:46 -0500 Received: by mail-wm0-x244.google.com with SMTP id u63so4043295wmu.2 for ; Fri, 24 Feb 2017 09:40:46 -0800 (PST) Received: from 640k.lan (94-39-187-56.adsl-ull.clienti.tiscali.it. [94.39.187.56]) by smtp.gmail.com with ESMTPSA id s26sm8814533wra.66.2017.02.24.09.40.44 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Feb 2017 09:40:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:subject:date:message-id:in-reply-to:references; bh=MPKqWeiiXo9VcrYUSNBi1iRTIeM96BYKgld/nw5wu+o=; b=TfV9P+Z5exxDzrVxm/4LpQRkRQ//vUXmp0e6KR+IR4Fdc+ejKweOUw7kXjmwWgtGCb W7q1KWYRGQo8eIklisg/tW9yh9aNHRtBIofJch4j7CcsvoPUl1eyVqjJZwDaJpCy4EsZ wSU/ofIw0WAl2MZ+4ZCoDG7dGsD1MDY4l3US3kywDt3Q5hvuomTmY+vUD4J0y3zQlr5S 0KlZDgkVRFcl50bG1XXBF1tNvGHcZkXnzS6CxpbBoEzLEgARbj4GaJxmEuif8remKsKW TY1/Qsq1jzgxb+T6f80652NIRmm3Y4h0d7wvNKBxl20L82jAa+EwH8AohIkHraCNCBwD qbQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:subject:date:message-id :in-reply-to:references; bh=MPKqWeiiXo9VcrYUSNBi1iRTIeM96BYKgld/nw5wu+o=; b=tseCQKQf4Ph+MMHzES9mGiFfgBFGBmJJsc85xETtBRl0n5wPUxHTWITNsbgaWR3uYr gMurOFeYhp/p4RSZ11LcW/jKaQ34zHRVqFGIy1+G3yFKpGoDylB2PttoKpQe6X5T04pV ZAhEedyPmGueQJBBYVso9f2WRWsOGxqrfuylbZJH7xp22sj+QihZBSK4ezp8OB3OF/W3 Hog8a92/w4jHAZ8ZxnwDF+fN1BJn9UP7AMO1cxSStKCFMSGggJqSyBtbNcWkOR8d3w4A a0HOz96KElcOYHOQmIlFQG6WiiXkmchJEJEkS148hjk33ECsqVVTGQ0H8Lmox+oZC0zY J00w== X-Gm-Message-State: AMke39nsGMTyOX/isWOo4pHo7/wa4J6073Gy1E8b/8LUpX/yzffoFIQSJ2XGc366QPlFYQ== X-Received: by 10.28.9.13 with SMTP id 13mr3593412wmj.37.1487958045092; Fri, 24 Feb 2017 09:40:45 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 24 Feb 2017 18:40:23 +0100 Message-Id: <1487958030-51417-11-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1487958030-51417-1-git-send-email-pbonzini@redhat.com> References: <1487958030-51417-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::244 Subject: [Qemu-devel] [PULL 10/17] KVM: do not use sigtimedwait to catch SIGBUS X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Call kvm_on_sigbus_vcpu asynchronously from the VCPU thread. Information for the SIGBUS can be stored in thread-local variables and processed later in kvm_cpu_exec. Signed-off-by: Paolo Bonzini --- cpus.c | 31 +++++++++++++------------------ include/sysemu/kvm.h | 5 ++++- kvm-all.c | 31 ++++++++++++++++++++++++++++++- target/arm/kvm.c | 5 ----- target/i386/kvm.c | 5 ++--- target/mips/kvm.c | 6 ------ target/ppc/kvm.c | 5 ----- target/s390x/kvm.c | 5 ----- 8 files changed, 49 insertions(+), 44 deletions(-) diff --git a/cpus.c b/cpus.c index e50284f..a2bc916 100644 --- a/cpus.c +++ b/cpus.c @@ -796,8 +796,16 @@ static void sigbus_handler(int n, siginfo_t *siginfo, = void *ctx) sigbus_reraise(); } =20 - if (kvm_on_sigbus(siginfo->si_code, siginfo->si_addr)) { - sigbus_reraise(); + if (current_cpu) { + /* Called asynchronously in VCPU thread. */ + if (kvm_on_sigbus_vcpu(current_cpu, siginfo->si_code, siginfo->si_= addr)) { + sigbus_reraise(); + } + } else { + /* Called synchronously (via signalfd) in main thread. */ + if (kvm_on_sigbus(siginfo->si_code, siginfo->si_addr)) { + sigbus_reraise(); + } } } =20 @@ -828,8 +836,9 @@ static void qemu_kvm_init_cpu_signals(CPUState *cpu) sigaction(SIG_IPI, &sigact, NULL); =20 pthread_sigmask(SIG_BLOCK, NULL, &set); - sigdelset(&set, SIG_IPI); sigdelset(&set, SIGBUS); + pthread_sigmask(SIG_SETMASK, &set, NULL); + sigdelset(&set, SIG_IPI); r =3D kvm_set_signal_mask(cpu, &set); if (r) { fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r)); @@ -847,7 +856,6 @@ static void qemu_kvm_eat_signals(CPUState *cpu) =20 sigemptyset(&waitset); sigaddset(&waitset, SIG_IPI); - sigaddset(&waitset, SIGBUS); =20 do { r =3D sigtimedwait(&waitset, &siginfo, &ts); @@ -856,25 +864,12 @@ static void qemu_kvm_eat_signals(CPUState *cpu) exit(1); } =20 - switch (r) { - case SIGBUS: - if (siginfo.si_code !=3D BUS_MCEERR_AO && siginfo.si_code !=3D= BUS_MCEERR_AR) { - sigbus_reraise(); - } - if (kvm_on_sigbus_vcpu(cpu, siginfo.si_code, siginfo.si_addr))= { - sigbus_reraise(); - } - break; - default: - break; - } - r =3D sigpending(&chkset); if (r =3D=3D -1) { perror("sigpending"); exit(1); } - } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS)= ); + } while (sigismember(&chkset, SIG_IPI)); } #else /* !CONFIG_LINUX */ static void qemu_init_sigbus(void) diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 6ecb61c..a1b019d 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -357,7 +357,10 @@ bool kvm_vcpu_id_is_valid(int vcpu_id); /* Returns VCPU ID to be used on KVM_CREATE_VCPU ioctl() */ unsigned long kvm_arch_vcpu_id(CPUState *cpu); =20 -int kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr); +#ifdef TARGET_I386 +#define KVM_HAVE_MCE_INJECTION 1 +void kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr); +#endif =20 void kvm_arch_init_irq_routing(KVMState *s); =20 diff --git a/kvm-all.c b/kvm-all.c index a433ad3..d3b0487 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1893,6 +1893,10 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu) run_on_cpu(cpu, do_kvm_cpu_synchronize_post_init, RUN_ON_CPU_NULL); } =20 +static __thread void *pending_sigbus_addr; +static __thread int pending_sigbus_code; +static __thread bool have_sigbus_pending; + int kvm_cpu_exec(CPUState *cpu) { struct kvm_run *run =3D cpu->kvm_run; @@ -1930,6 +1934,14 @@ int kvm_cpu_exec(CPUState *cpu) =20 attrs =3D kvm_arch_post_run(cpu, run); =20 + if (unlikely(have_sigbus_pending)) { + qemu_mutex_lock_iothread(); + kvm_arch_on_sigbus_vcpu(cpu, pending_sigbus_code, + pending_sigbus_addr); + have_sigbus_pending =3D false; + qemu_mutex_unlock_iothread(); + } + if (run_ret < 0) { if (run_ret =3D=3D -EINTR || run_ret =3D=3D -EAGAIN) { DPRINTF("io window exit\n"); @@ -2392,13 +2404,27 @@ int kvm_set_signal_mask(CPUState *cpu, const sigset= _t *sigset) return r; } =20 +/* Called asynchronously in VCPU thread. */ int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr) { - return kvm_arch_on_sigbus_vcpu(cpu, code, addr); +#ifdef KVM_HAVE_MCE_INJECTION + if (have_sigbus_pending) { + return 1; + } + have_sigbus_pending =3D true; + pending_sigbus_addr =3D addr; + pending_sigbus_code =3D code; + atomic_set(&cpu->exit_request, 1); + return 0; +#else + return 1; +#endif } =20 +/* Called synchronously (via signalfd) in main thread. */ int kvm_on_sigbus(int code, void *addr) { +#ifdef KVM_HAVE_MCE_INJECTION /* Action required MCE kills the process if SIGBUS is blocked. Because * that's what happens in the I/O thread, where we handle MCE via sign= alfd, * we can only get action optional here. @@ -2406,6 +2432,9 @@ int kvm_on_sigbus(int code, void *addr) assert(code !=3D BUS_MCEERR_AR); kvm_arch_on_sigbus_vcpu(first_cpu, code, addr); return 0; +#else + return 1; +#endif } =20 int kvm_create_device(KVMState *s, uint64_t type, bool test) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 6f2d590..c6d0b3a 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -559,11 +559,6 @@ int kvm_arch_process_async_events(CPUState *cs) return 0; } =20 -int kvm_arch_on_sigbus_vcpu(CPUState *cs, int code, void *addr) -{ - return 1; -} - /* The #ifdef protections are until 32bit headers are imported and can * be removed once both 32 and 64 bit reach feature parity. */ diff --git a/target/i386/kvm.c b/target/i386/kvm.c index 2adf992..7698421 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -455,7 +455,7 @@ static void hardware_memory_error(void) exit(1); } =20 -int kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr) +void kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr) { X86CPU *cpu =3D X86_CPU(c); CPUX86State *env =3D &cpu->env; @@ -475,7 +475,7 @@ int kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void= *addr) kvm_physical_memory_addr_from_host(c->kvm_state, addr, &paddr)= ) { kvm_hwpoison_page_add(ram_addr); kvm_mce_inject(cpu, paddr, code); - return 0; + return; } =20 fprintf(stderr, "Hardware memory error for memory used by " @@ -487,7 +487,6 @@ int kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void= *addr) } =20 /* Hope we are lucky for AO MCE */ - return 0; } =20 static int kvm_inject_mce_oldstyle(X86CPU *cpu) diff --git a/target/mips/kvm.c b/target/mips/kvm.c index 3e686e7..0982e87 100644 --- a/target/mips/kvm.c +++ b/target/mips/kvm.c @@ -180,12 +180,6 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs) return true; } =20 -int kvm_arch_on_sigbus_vcpu(CPUState *cs, int code, void *addr) -{ - DPRINTF("%s\n", __func__); - return 1; -} - void kvm_arch_init_irq_routing(KVMState *s) { } diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 80f2728..3125255 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -2558,11 +2558,6 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cpu) return true; } =20 -int kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr) -{ - return 1; -} - void kvm_arch_init_irq_routing(KVMState *s) { } diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c index 92cf6d4..8b9b211 100644 --- a/target/s390x/kvm.c +++ b/target/s390x/kvm.c @@ -2103,11 +2103,6 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cpu) return true; } =20 -int kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr) -{ - return 1; -} - void kvm_s390_io_interrupt(uint16_t subchannel_id, uint16_t subchannel_nr, uint32_t io_int_parm, uint32_t io_int_word) --=20 1.8.3.1