From patchwork Tue Dec 17 12:14:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 181871 Delivered-To: patch@linaro.org Received: by 2002:a92:3001:0:0:0:0:0 with SMTP id x1csp5664728ile; Tue, 17 Dec 2019 04:16:40 -0800 (PST) X-Google-Smtp-Source: APXvYqxJb8VYY4GLth2Yrf7A6MeQucjGNznJwqPf/okI/niKCrNDb8RPgRfZFt/3dEY6Lt+2I0sD X-Received: by 2002:aed:2f01:: with SMTP id l1mr4024896qtd.391.1576585000583; Tue, 17 Dec 2019 04:16:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1576585000; cv=none; d=google.com; s=arc-20160816; b=GXQrEL1mjknO9TVcmAGc5Hh8fmUYgREhjwBzDU3UCcCaYMPQvR3I7WedWiqP6MaKtb 3uQFPnj3Ip30euVOr7Ytv5pDrucalhoW3a3BiK/jghP01SRdv3mBGR08Eobpz8stZ/xc 05hu9XnZMnA7P/XIeh9tFpy2tGdiSNpF0hp1BHyUsMawW+Yl80Urx7sOQswUayYnknpe qeJbtn9suFpXa4sQeDKegNFmTareydjasJ5ocKHnUpRnV0Sxa3sxY1FiW7L+0JK0vSzZ v0lTNmeafgoKYF6+iZIx6gHqipyqLANCtH91OnJEr226FzyJ9/OIxQr4JiOUntrdAh58 RqEA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=LvGv/oA29v3zt0SGusdkh9CXABD727Mt4qfYOd5YuqE=; b=OkbXpGWs2ukRsHafTO9rysqA9azcS9ZzPN22KTpK0rSojU/U+7mZo/D7KKUNSl0oo9 tJ5zvweYHcVgFqqnO16cb/kOgsLSF9aPxx/yGxRsKXX4yv8ciA2MTWkmjDdISR8SGThW 6fUvvy9AAMc1cEqhLPqMaD/dKPBEtWaSAPbqnkdy1VNifaid5cRDslri8JgXkd40tPDR zVZ5e/2aO98VLlMSZ9Mc/E0WttxVqUGInbmnoTOBAUJZ8TMm9BfLYpgOQoN5A6lHTvxz cubtJ+0Uvg/fgBI4WIfWsrAEYDs/aj8lIcxB+LTFbpxJJlheAC05fFDJwFWWtMjHUJgd kMgw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=cCgrlnva; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id l202si11938680qke.241.2019.12.17.04.16.40 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 17 Dec 2019 04:16:40 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=cCgrlnva; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:39674 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ihBmK-0007RW-3Y for patch@linaro.org; Tue, 17 Dec 2019 07:16:40 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:39577) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ihBki-0005so-AW for qemu-devel@nongnu.org; Tue, 17 Dec 2019 07:15:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ihBkg-0001Vy-OI for qemu-devel@nongnu.org; Tue, 17 Dec 2019 07:15:00 -0500 Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:40020) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ihBkg-0001VB-Gr for qemu-devel@nongnu.org; Tue, 17 Dec 2019 07:14:58 -0500 Received: by mail-wm1-x344.google.com with SMTP id t14so2875426wmi.5 for ; Tue, 17 Dec 2019 04:14:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=LvGv/oA29v3zt0SGusdkh9CXABD727Mt4qfYOd5YuqE=; b=cCgrlnva6/4AFedL+p7UWTQL4gS+7t/xWsC1mTFh/FVwlzFp3dzNDNdd0vwTFZeGI0 w140mzPNWiLN/n9iuw3w+z2xHJxoe6Jrvbj8KGR0WeXGjMXM4I6i1za1waxxon5e06tk mLGY/uaexDKUYNuyjzffCsDVra0hPWo6EO7zXkww0rFP1lFMK9RuzLNXJJZ8wFwOwMCI 94vfHoDBKQawByKQh0P2lc24ixba35LYBctaxtTdsQqiPA8Xnds1TidKKa3jphftmcvg T2frAKwS0jjSD4YbJQ5Pm9HiDtkZxeJPpROoPDijh3ELY+f/gLcf83wDW7U5VpaKlIFr WEjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LvGv/oA29v3zt0SGusdkh9CXABD727Mt4qfYOd5YuqE=; b=jAQwf5XJRBXmvJfqw1s5LA5SLt7dtTn8P/S3w5A+sH+YY4vth70L9au35hivwfJwqq SIcia8jGZqX0yCdrKyKYN82PfPI/CvAYEx6gy0SA4yRS4fkEWIWj2n/eGMaNClgQu8We niR7ztVnUNWHnMf7097CdW6gbNve7axVnqSWIb9WA++asQhg3DgQZjh7AK9gKfCVEnMD kD1unDT70CP8vXN5pYSr0a+FanmXsR7fnJ2nNFx5YwrVzOLJcuWQUZzIEq9ki/Dzetza 54aRB4oLhNMZQF2Bm6ZAuyp0KlscdnKpkftbY6FWeaPeW3/YzuXbbWgLRAj67qecL60+ I1wQ== X-Gm-Message-State: APjAAAVdDIxkmzv37yOa12EH+UT9mgLGu+JO9cE95+j5IZ/QVrar07Ht uDCXbE0CeIAcdwZytCocWXqYEA== X-Received: by 2002:a7b:cf18:: with SMTP id l24mr4838878wmg.95.1576584896241; Tue, 17 Dec 2019 04:14:56 -0800 (PST) Received: from zen.linaroharston ([51.148.130.216]) by smtp.gmail.com with ESMTPSA id u22sm26484597wru.30.2019.12.17.04.14.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 17 Dec 2019 04:14:54 -0800 (PST) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 22B6F1FF87; Tue, 17 Dec 2019 12:14:54 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: qemu-devel@nongnu.org Subject: [RFC PATCH] semihosting: suspend recieving CPU when blocked (HACK, WIP) Date: Tue, 17 Dec 2019 12:14:43 +0000 Message-Id: <20191217121443.14757-1-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <77dd4863-6301-b17d-529c-451d491d4794@redhat.com> References: <77dd4863-6301-b17d-529c-451d491d4794@redhat.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::344 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: pbonzini@redhat.com, keithp@keithp.com, =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Sleeping in the semihosting code is problematic as we deadlock the whole system. This includes issuing a "quit" via the HMP or presumably if gdbserver got involved. What we really want is to return to the main loop and gt woken up when there is data to process. We can then re-execute the instruction which will succeed this time. [AJB: So this at least solves the hang of not being able to quit system emulation while blocked. However there are two things we still need to ensure: - the PC has not advanced until completion so we can redo the instruction - we actually wake up the CPU in console_read In my testcase console_read never seems to get called. I've tried with both an external pipe loopback and using the ringbuf: qemu-system-aarch64 -M virt --display none -cpu cortex-a57 -kernel systest-a64-with-console.axf -semihosting-config enable=on,chardev=sh0 -serial mon:stdio -chardev ringbuf,logfile=foo,id=sh0 ] Signed-off-by: Alex Bennée --- include/exec/cpu-all.h | 1 + hw/semihosting/console.c | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 17 deletions(-) -- 2.20.1 diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index e96781a4559..093d7a76edd 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -31,6 +31,7 @@ #define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */ #define EXCP_YIELD 0x10004 /* cpu wants to yield timeslice to another */ #define EXCP_ATOMIC 0x10005 /* stop-the-world and emulate atomic */ +#define EXCP_BLOCKED 0x10006 /* cpu is blocked (semihosting) */ /* some important defines: * diff --git a/hw/semihosting/console.c b/hw/semihosting/console.c index 4db68d62270..bda457a0608 100644 --- a/hw/semihosting/console.c +++ b/hw/semihosting/console.c @@ -20,6 +20,7 @@ #include "hw/semihosting/semihost.h" #include "hw/semihosting/console.h" #include "exec/gdbstub.h" +#include "exec/exec-all.h" #include "qemu/log.h" #include "chardev/char.h" #include @@ -109,50 +110,49 @@ void qemu_semihosting_console_outc(CPUArchState *env, target_ulong addr) typedef struct SemihostingConsole { CharBackend backend; - pthread_mutex_t mutex; - pthread_cond_t cond; + CPUState *sleeping_cpu; bool got; Fifo8 fifo; } SemihostingConsole; -static SemihostingConsole console = { - .mutex = PTHREAD_MUTEX_INITIALIZER, - .cond = PTHREAD_COND_INITIALIZER -}; +static SemihostingConsole console; static int console_can_read(void *opaque) { SemihostingConsole *c = opaque; int ret; - pthread_mutex_lock(&c->mutex); + g_assert(qemu_mutex_iothread_locked()); ret = (int) fifo8_num_free(&c->fifo); - pthread_mutex_unlock(&c->mutex); return ret; } static void console_read(void *opaque, const uint8_t *buf, int size) { SemihostingConsole *c = opaque; - pthread_mutex_lock(&c->mutex); + g_assert(qemu_mutex_iothread_locked()); while (size-- && !fifo8_is_full(&c->fifo)) { fifo8_push(&c->fifo, *buf++); } - pthread_cond_broadcast(&c->cond); - pthread_mutex_unlock(&c->mutex); + if (c->sleeping_cpu) { + cpu_resume(c->sleeping_cpu); + } } target_ulong qemu_semihosting_console_inc(CPUArchState *env) { uint8_t ch; SemihostingConsole *c = &console; - qemu_mutex_unlock_iothread(); - pthread_mutex_lock(&c->mutex); - while (fifo8_is_empty(&c->fifo)) { - pthread_cond_wait(&c->cond, &c->mutex); + g_assert(qemu_mutex_iothread_locked()); + g_assert(current_cpu); + if (fifo8_is_empty(&c->fifo)) { + c->sleeping_cpu = current_cpu; + c->sleeping_cpu->stop = true; + c->sleeping_cpu->exception_index = EXCP_BLOCKED; + cpu_loop_exit(c->sleeping_cpu); + /* never returns */ } + c->sleeping_cpu = NULL; ch = fifo8_pop(&c->fifo); - pthread_mutex_unlock(&c->mutex); - qemu_mutex_lock_iothread(); return (target_ulong) ch; }