From: Alexander Graf <agraf@suse.de>
To: "qemu-devel@nongnu.org Developers" <qemu-devel@nongnu.org>
Cc: Peter Maydell <peter.maydell@linaro.org>,
Fabio Erculiani <lxnay@sabayon.org>,
Riku Voipio <riku.voipio@iki.fi>
Subject: [Qemu-devel] [PATCH] linux-user: fix segfault deadlock
Date: Fri, 13 Jan 2012 16:46:05 +0100 [thread overview]
Message-ID: <1326469565-7736-1-git-send-email-agraf@suse.de> (raw)
When entering the guest we take a lock to ensure that nobody else messes
with our TB chaining while we're doing it. If we get a segfault inside that
code, we manage to work on, but will not unlock the lock.
This patch forces unlocking of that lock in the segv handler. I'm not sure
this is the right approach though. Maybe we should rather make sure we don't
segfault in the code? I would greatly appreciate someone more intelligible
than me to look at this :).
Example code to trigger this is at: http://csgraf.de/tmp/conftest.c
Reported-by: Fabio Erculiani <lxnay@sabayon.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
qemu-lock.h | 10 ++++++++++
user-exec.c | 4 ++++
2 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/qemu-lock.h b/qemu-lock.h
index a72edda..e460e12 100644
--- a/qemu-lock.h
+++ b/qemu-lock.h
@@ -24,6 +24,12 @@
#include <pthread.h>
#define spin_lock pthread_mutex_lock
#define spin_unlock pthread_mutex_unlock
+static inline void spin_unlock_safe(pthread_mutex_t *lock)
+{
+ /* unlocking an unlocked mutex results in undefined behavior */
+ pthread_mutex_trylock(lock);
+ pthread_mutex_unlock(lock);
+}
#define spinlock_t pthread_mutex_t
#define SPIN_LOCK_UNLOCKED PTHREAD_MUTEX_INITIALIZER
@@ -46,4 +52,8 @@ static inline void spin_unlock(spinlock_t *lock)
{
}
+static inline void spin_unlock_safe(spinlock_t *lock)
+{
+}
+
#endif
diff --git a/user-exec.c b/user-exec.c
index abf6885..2826bd1 100644
--- a/user-exec.c
+++ b/user-exec.c
@@ -96,6 +96,10 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
pc, address, is_write, *(unsigned long *)old_set);
#endif
+
+ /* Maybe we're still holding the TB fiddling lock? */
+ spin_unlock_safe(&tb_lock);
+
/* XXX: locking issue */
if (is_write && page_unprotect(h2g(address), pc, puc)) {
return 1;
--
1.6.0.2
next reply other threads:[~2012-01-13 16:13 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-13 15:46 Alexander Graf [this message]
2012-01-13 16:16 ` [Qemu-devel] [PATCH] linux-user: fix segfault deadlock Peter Maydell
2012-01-13 16:21 ` Alexander Graf
2012-01-15 18:14 ` Fabio Erculiani
2012-02-21 16:11 ` Peter Maydell
2012-02-21 16:19 ` Alexander Graf
2012-02-21 16:21 ` Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1326469565-7736-1-git-send-email-agraf@suse.de \
--to=agraf@suse.de \
--cc=lxnay@sabayon.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=riku.voipio@iki.fi \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).