diff -Nru qemu-2.5+dfsg/debian/changelog qemu-2.5+dfsg/debian/changelog --- qemu-2.5+dfsg/debian/changelog 2018-12-12 10:18:01.000000000 -0200 +++ qemu-2.5+dfsg/debian/changelog 2019-03-01 15:59:01.000000000 -0300 @@ -1,3 +1,12 @@ +qemu (1:2.5+dfsg-5ubuntu10.35) xenial; urgency=medium + + * Fix deadlock when detaching network interface (LP: #1818880) + Fixed by upstream patch: + - d/p/lp-1818880-rcu-disable-atfork.patch: rcu: completely disable + pthread_atfork callbacks as soon as possible + + -- Heitor R. Alves de Siqueira Fri, 01 Mar 2019 15:59:01 -0300 + qemu (1:2.5+dfsg-5ubuntu10.34) xenial; urgency=medium * d/p/ubuntu/lp1807743-linux-user-timerfd.patch: fix define for diff -Nru qemu-2.5+dfsg/debian/patches/lp-1818880-rcu-disable-atfork.patch qemu-2.5+dfsg/debian/patches/lp-1818880-rcu-disable-atfork.patch --- qemu-2.5+dfsg/debian/patches/lp-1818880-rcu-disable-atfork.patch 1969-12-31 21:00:00.000000000 -0300 +++ qemu-2.5+dfsg/debian/patches/lp-1818880-rcu-disable-atfork.patch 2019-03-01 15:59:01.000000000 -0300 @@ -0,0 +1,107 @@ +From 73c6e4013b4cd92d3d531bc22cc29e6036ef42e0 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Wed, 27 Jan 2016 08:49:21 +0100 +Subject: [PATCH 1/1] rcu: completely disable pthread_atfork callbacks as soon as possible + +Because of -daemonize, system mode QEMU sometimes needs to fork() and +keep RCU enabled in the child. However, there is a possible deadlock +with synchronize_rcu: + +- the CPU thread is inside a RCU critical section and wants to take + the BQL in order to do MMIO + +- the monitor thread, which is owning the BQL, calls rcu_init_lock + which tries to take the rcu_sync_lock + +- the call_rcu thread has taken rcu_sync_lock in synchronize_rcu, but + synchronize_rcu needs the CPU thread to end the critical section + before returning. + +This cannot happen for user-mode emulation, because it does not have +a BQL. + +To fix it, assume that system mode QEMU only forks in preparation for +exec (except when daemonizing) and disable pthread_atfork as soon as +the double fork has happened. + +Reported-by: Dr. David Alan Gilbert +Tested-by: Dr. David Alan Gilbert +Signed-off-by: Paolo Bonzini + +Origin: upstream, https://git.qemu.org/?p=qemu.git;a=commit;h=73c6e4013b4c +Bug-Ubuntu: https://bugs.launchpad.net/cloud-archive/+bug/1818880 +--- + include/qemu/rcu.h | 6 ++++++ + util/rcu.c | 20 ++++++++++++++++++++ + vl.c | 1 + + 3 files changed, 27 insertions(+) + +Index: qemu-2.5+dfsg/include/qemu/rcu.h +=================================================================== +--- qemu-2.5+dfsg.orig/include/qemu/rcu.h ++++ qemu-2.5+dfsg/include/qemu/rcu.h +@@ -117,6 +117,12 @@ extern void synchronize_rcu(void); + */ + extern void rcu_register_thread(void); + extern void rcu_unregister_thread(void); ++ ++/* ++ * Support for fork(). fork() support is enabled at startup. ++ */ ++extern void rcu_enable_atfork(void); ++extern void rcu_disable_atfork(void); + extern void rcu_after_fork(void); + + struct rcu_head; +Index: qemu-2.5+dfsg/util/rcu.c +=================================================================== +--- qemu-2.5+dfsg.orig/util/rcu.c ++++ qemu-2.5+dfsg/util/rcu.c +@@ -323,15 +323,35 @@ static void rcu_init_complete(void) + rcu_register_thread(); + } + ++static int atfork_depth = 1; ++ ++void rcu_enable_atfork(void) ++{ ++ atfork_depth++; ++} ++ ++void rcu_disable_atfork(void) ++{ ++ atfork_depth--; ++} ++ + #ifdef CONFIG_POSIX + static void rcu_init_lock(void) + { ++ if (atfork_depth < 1) { ++ return; ++ } ++ + qemu_mutex_lock(&rcu_sync_lock); + qemu_mutex_lock(&rcu_registry_lock); + } + + static void rcu_init_unlock(void) + { ++ if (atfork_depth < 1) { ++ return; ++ } ++ + qemu_mutex_unlock(&rcu_registry_lock); + qemu_mutex_unlock(&rcu_sync_lock); + } +Index: qemu-2.5+dfsg/vl.c +=================================================================== +--- qemu-2.5+dfsg.orig/vl.c ++++ qemu-2.5+dfsg/vl.c +@@ -4046,6 +4046,7 @@ int main(int argc, char **argv, char **e + loc_set_none(); + + os_daemonize(); ++ rcu_disable_atfork(); + + if (qemu_init_main_loop(&main_loop_err)) { + error_report_err(main_loop_err); diff -Nru qemu-2.5+dfsg/debian/patches/series qemu-2.5+dfsg/debian/patches/series --- qemu-2.5+dfsg/debian/patches/series 2018-12-12 10:18:01.000000000 -0200 +++ qemu-2.5+dfsg/debian/patches/series 2019-03-01 15:59:01.000000000 -0300 @@ -250,3 +250,4 @@ CVE-2018-19364-1.patch CVE-2018-19364-2.patch ubuntu/lp1807743-linux-user-timerfd.patch +lp-1818880-rcu-disable-atfork.patch --- -2.17.1 -