From patchwork Fri Mar 18 11:55:36 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Paramonov X-Patchwork-Id: 87518 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 0FD25B6FDE for ; Fri, 18 Mar 2011 22:57:59 +1100 (EST) Received: from localhost ([127.0.0.1]:33388 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q0YJQ-0002uy-Rh for incoming@patchwork.ozlabs.org; Fri, 18 Mar 2011 07:57:48 -0400 Received: from [140.186.70.92] (port=38656 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q0YIb-0002iH-Kb for qemu-devel@nongnu.org; Fri, 18 Mar 2011 07:56:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q0YIa-0002EB-1d for qemu-devel@nongnu.org; Fri, 18 Mar 2011 07:56:57 -0400 Received: from mail-fx0-f45.google.com ([209.85.161.45]:63180) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q0YIZ-0002Dt-MD for qemu-devel@nongnu.org; Fri, 18 Mar 2011 07:56:55 -0400 Received: by fxm2 with SMTP id 2so3996289fxm.4 for ; Fri, 18 Mar 2011 04:56:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:message-id:date:from:user-agent:mime-version:to :subject:content-type:content-transfer-encoding; bh=XGQGCCxBdMOK3Ja+o1IKtm82jLiycPP9pUvJCb1poNs=; b=XY1M/Dc1MNlOyTovgl83+5wDod8XD/LBwRtioHSqqimS9TZNTuHFqDCXRKxN/IYYPj 5fSKPFJYi0nhD6znAhfpTJMYkUpGn2rVzSMsv9TXA2MV8ykCPXK9E8vpLJ1gteE5R7cr wEygx7FpGZiMjbbPBu2C6qHAZhgy9+XGhC0qg= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject :content-type:content-transfer-encoding; b=iybFa2n3gzn6kTsKIjM1g7T9GkX9kejYIxVokJZ/kmcxhcDP2Y0pZAmEGTZpl/+CXI bpMQJUuj/vhJHn1n/hap3aZFenZzW/VaQb+5eM/gR2cA+P74kxpyqGIMnp16VJL1mZIS oYI6eRYjw+7eC1Wc+q2NohpGR4lwwRv9bHBT8= Received: by 10.223.106.76 with SMTP id w12mr1151399fao.104.1300449412725; Fri, 18 Mar 2011 04:56:52 -0700 (PDT) Received: from [10.0.0.33] ([80.90.125.218]) by mx.google.com with ESMTPS id k5sm1152687faa.39.2011.03.18.04.56.50 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 18 Mar 2011 04:56:51 -0700 (PDT) Message-ID: <4D834838.7040507@gmail.com> Date: Fri, 18 Mar 2011 14:55:36 +0300 From: Alexander Paramonov User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.14) Gecko/20110223 Thunderbird/3.1.8 MIME-Version: 1.0 To: qemu-devel@nongnu.org X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.161.45 Subject: [Qemu-devel] QEMU patch for non-NPTL mode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Hello! We use QEMU to run ARM-compiled soft on PC Linux OS. Our soft is linked with uClibc library in non-NPTL mode. So there are some problems in running multi-threaded applications under QEMU: 1. Both uClibc and gLibc use 32 and 33 signals and conflict. 2. Signals processing was not thread-safe. Here's a patch which makes our soft working fine. Perhaps, you would find something useful and apply it in yout further QEMU versions. Alexander, Terminal Technologies, Russia. #endif diff -ruN qemu_orig/linux-user/qemu.h qemu_patched/linux-user/qemu.h --- qemu_orig/linux-user/qemu.h 2011-02-16 17:44:05.000000000 +0300 +++ qemu_patched/linux-user/qemu.h 2011-03-17 19:16:13.000000000 +0300 @@ -80,6 +80,7 @@ struct sigqueue { struct sigqueue *next; target_siginfo_t info; + pid_t pid; }; struct emulated_sigtable { diff -ruN qemu_orig/linux-user/signal.c qemu_patched/linux-user/signal.c --- qemu_orig/linux-user/signal.c 2011-02-16 17:44:05.000000000 +0300 +++ qemu_patched/linux-user/signal.c 2011-03-18 14:29:57.991141322 +0300 @@ -314,6 +314,8 @@ for(i = 1; i < _NSIG; i++) { if (host_to_target_signal_table[i] == 0) host_to_target_signal_table[i] = i; + if (i >= SIGRTMIN && i <= SIGRTMAX) + host_to_target_signal_table[i] = __SIGRTMIN + (i - SIGRTMIN); } for(i = 1; i < _NSIG; i++) { j = host_to_target_signal_table[i]; @@ -473,6 +475,7 @@ *pq = q; q->info = *info; q->next = NULL; + q->pid = getpid(); k->pending = 1; /* signal that a new signal is pending */ ts->signal_pending = 1; @@ -4896,21 +4899,34 @@ target_sigset_t target_old_set; struct emulated_sigtable *k; struct target_sigaction *sa; - struct sigqueue *q; - TaskState *ts = cpu_env->opaque; + struct sigqueue *q, *q_prev; + TaskState *ts = thread_env->opaque; if (!ts->signal_pending) return; - /* FIXME: This is not threadsafe. */ k = ts->sigtab; + int signal_pending = 0; for(sig = 1; sig <= TARGET_NSIG; sig++) { if (k->pending) - goto handle_signal; + { + q = k->first; + q_prev = NULL; + while (q) + { + if (q->pid == getpid()) + goto handle_signal; + else + signal_pending = 1; + q_prev = q; + q = q->next; + } + } k++; } + /* if no signal is pending, just return */ - ts->signal_pending = 0; + ts->signal_pending = signal_pending; return; handle_signal: @@ -4918,10 +4934,19 @@ fprintf(stderr, "qemu: process signal %d\n", sig); #endif /* dequeue signal */ - q = k->first; - k->first = q->next; - if (!k->first) - k->pending = 0; + if (q_prev == k->first) + { + q = k->first; + k->first = q->next; + if (!k->first) + { + k->pending = 0; + } + } + else if (q_prev) + q_prev->next = q->next; + else + k->pending = 0; sig = gdb_handlesig (cpu_env, sig); if (!sig) { diff -ruN qemu_orig/linux-user/syscall.c qemu_patched/linux-user/syscall.c --- qemu_orig/linux-user/syscall.c 2011-02-16 17:44:05.000000000 +0300 +++ qemu_patched/linux-user/syscall.c 2011-03-18 14:32:47.107641348 +0300 @@ -88,6 +88,7 @@ #endif #include #include +#include #include "linux_loop.h" #include "cpu-uname.h" @@ -3827,6 +3828,12 @@ #ifdef __ia64__ ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env); #else + unsigned int clone_sig = flags & CSIGNAL; + if (clone_sig >= __SIGRTMIN && clone_sig <= __SIGRTMIN+2) + { + flags &= ~CSIGNAL; + flags |= SIGRTMIN + (clone_sig - __SIGRTMIN); + } ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); #endif