From patchwork Tue Oct 27 18:47:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heinrich Schuchardt X-Patchwork-Id: 1388891 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gmx.de Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=gmx.net header.i=@gmx.net header.a=rsa-sha256 header.s=badeba3b8450 header.b=MYz7hIgg; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CLLMb2c6Dz9sSf for ; Wed, 28 Oct 2020 05:48:59 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 33219824FC; Tue, 27 Oct 2020 19:47:39 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=gmx.de Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; secure) header.d=gmx.net header.i=@gmx.net header.b="MYz7hIgg"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id E45DE823E3; Tue, 27 Oct 2020 19:47:23 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FREEMAIL_FROM,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mout.gmx.net (mout.gmx.net [212.227.17.21]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 5C86582496 for ; Tue, 27 Oct 2020 19:47:18 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=gmx.de Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=xypron.glpk@gmx.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1603824435; bh=lWTJ1nhoS03MCsq2/cE4VRU1V3GL4BqJfMZlM63UxyQ=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=MYz7hIggO+vFfJRSAw3wuzCKoT4WeU9QfvslF4K4yo9ihrri76TIhuhiHwunxPH2m KaJ9AyT1KJdze5Fcya2+PLnI8wD0+w2BOQ5Rk8b9Sgv1EoQpNQ7+lMX7i4eMSpQxVW C2DkSwC6K6H24yfvV3uBgL8AnTAS6GN3NavUKGWs= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from workstation4.fritz.box ([178.202.41.107]) by mail.gmx.com (mrgmx105 [212.227.17.174]) with ESMTPSA (Nemesis) id 1MoO6C-1k0b512obA-00oplr; Tue, 27 Oct 2020 19:47:15 +0100 From: Heinrich Schuchardt To: Simon Glass Cc: Rasmus Villemoes , u-boot@lists.denx.de, Heinrich Schuchardt Subject: [PATCH v2 5/8] sandbox: implement reset Date: Tue, 27 Oct 2020 19:47:01 +0100 Message-Id: <20201027184704.15910-6-xypron.glpk@gmx.de> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201027184704.15910-1-xypron.glpk@gmx.de> References: <20201027184704.15910-1-xypron.glpk@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:mCGgnxYcvBYT6uqB+bIQnl98WZR3TLYQZxhHvjGUtCJ4ku7nsEm DYNE8Znp9mpSD1pdoi0CluNkfikJ1pul12suMa/vIz4vsl7a3odKbSvDMGiwp/uyNBkVVB5 Xe+lrSGip8HjQpMZ06dTN2tjKoTvsrIhZtoFafs05/0Bri89N/JvSNJitmZIRa/ARQdAWNY Etlq0BpJCe3xz+KZ01mLQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:d9s/ZICzoHs=:Kqrs6vORia464k6jGvOokP hTm5bUDFB506KVloPpCQ5TbuBM3fClr+76JDLkZ0HNCRot+cHxUXXfzwNKkeb84Kaht8cQzfr oppcDDJKdUSaTVF5u033xJCgVMsOQpXnwbOaUT9RCyK/1zrdctxt2vDDFUBHIWmAdIw2CWY5m +r6ntqh1zy5SYu8fihMC2TRxO0rkPZZyxNZHf6Yn45D7g5q2lxfxn7A0t71l0zJIbf2NPBgVJ kmegmjXGBcm1XiODUsH8n4iAig+O/L0fAfPU6ck3HRqsDdhhNOQyTuAmRsrhJtryLvj5RGC6N k6ocXm+B98sB/ekl3tPeIg+Z6LDAd7XFFeNf2sNHSxu+ios7h72xyYOeb/oPFufcO9O6LL1yc MwXen1sZluV3DDEp9iWxjHlCktToGruwuw3XLH4117cLjgxdh4cQJ2Sb7GoJsmqs1XJa8Buiu eNp4/iagatkQPQIph7LRXB304Kd7QjMfU+bmO6QEilxfTK1BXhuLSS04fG0/2gkivJdGvzILz i9VD3FzCrQmuh+G1peQGwcS7jWPIAk6zmKWLzoV1w3fey0otWWOeCxsJIE+NKdXEPDE6ZX77U BEQHd0VAvR6Ma/I8P1JgK0I7MyUx15iIlt6z1NR9esfihsQRvFKy7dGb8NYJDQmKf11XFjtWB 4lF0+d2DTBSkbaJBKq0Tv6GTLLEH4MERmh0rHZuwqum5F0kSqGqR1jTakozAhfxRPgt/H1yZp 0wz0o+aBXDkc+v6gMY4xgQ3HDxwWplUQV5t7ziYYEHqYXeU+7Nu7jIZHKZSFhbONbbnrqpJh4 O2iC92opZF2jefl/M2ZgLC+4ONWm9rHS1wbwKGZ0i7DFZicrNCNRFxwc7nPnffBPU41qqm2BS Fo5/Qwrg8zSfaJ02eUXg== X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean Up to now the sandbox would shutdown upon a cold reset request. Instead it should be reset. In our coding we use static variables like LIST_HEAD(efi_obj_list). A reset can occur at any time, e.g. via an UEFI binary calling the reset service. The only safe way to return to an initial state is to relaunch the U-Boot binary. The reset implementation uses a longjmp() to return to the main() function and then relaunches U-Boot using execv(). Signed-off-by: Heinrich Schuchardt --- v2: avoid longjmp() add more comments --- arch/sandbox/cpu/os.c | 6 ++++++ arch/sandbox/cpu/start.c | 26 +++++++++++++++++++++++ arch/sandbox/cpu/state.c | 1 + arch/sandbox/include/asm/u-boot-sandbox.h | 10 +++++++++ drivers/sysreset/sysreset_sandbox.c | 3 +++ include/os.h | 15 +++++++++++++ 6 files changed, 61 insertions(+) -- 2.28.0 diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 7e474d6364..0d8efd83f6 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -822,3 +822,9 @@ void *os_find_text_base(void) return base; } + +void os_relaunch(char *argv[]) +{ + execv(argv[0], argv); + os_exit(1); +} diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index c6a2bbe468..cc47b28d1d 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -19,6 +20,8 @@ DECLARE_GLOBAL_DATA_PTR; +static char **os_argv; + /* Compare two options so that they can be sorted into alphabetical order */ static int h_compare_opt(const void *p1, const void *p2) { @@ -394,12 +397,35 @@ void state_show(struct sandbox_state *state) printf("\n"); } +void sandbox_reset(void) +{ + /* Do this here while it still has an effect */ + os_fd_restore(); + if (state_uninit()) + os_exit(2); + + if (dm_uninit()) + os_exit(2); + + /* Restart U-Boot */ + os_relaunch(os_argv); +} + int main(int argc, char *argv[]) { struct sandbox_state *state; gd_t data; int ret; + /* + * Copy argv[] so that we can pass the arguments in the original + * sequence when resetting the sandbox. + */ + os_argv = calloc(argc + 1, sizeof(char *)); + if (!os_argv) + os_exit(1); + memcpy(os_argv, argv, sizeof(char *) * (argc + 1)); + memset(&data, '\0', sizeof(data)); gd = &data; gd->arch.text_base = os_find_text_base(); diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index 34b6fff7e7..59f37fab0b 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -358,6 +358,7 @@ void state_reset_for_test(struct sandbox_state *state) /* No reset yet, so mark it as such. Always allow power reset */ state->last_sysreset = SYSRESET_COUNT; state->sysreset_allowed[SYSRESET_POWER_OFF] = true; + state->sysreset_allowed[SYSRESET_COLD] = true; state->allow_memio = false; memset(&state->wdt, '\0', sizeof(state->wdt)); diff --git a/arch/sandbox/include/asm/u-boot-sandbox.h b/arch/sandbox/include/asm/u-boot-sandbox.h index 798d003077..73b1897191 100644 --- a/arch/sandbox/include/asm/u-boot-sandbox.h +++ b/arch/sandbox/include/asm/u-boot-sandbox.h @@ -84,6 +84,16 @@ void sandbox_set_enable_pci_map(int enable); */ int sandbox_read_fdt_from_file(void); +/** + * sandbox_reset() - reset sandbox + * + * This functions implements the cold reboot of the sandbox. It relaunches the + * U-Boot binary with the same command line parameters as the original call. + * The PID of the process stays the same. All file descriptors that have not + * been opened with O_CLOEXEC stay open including stdin, stdout, stderr. + */ +void sandbox_reset(void); + /* Exit sandbox (quit U-Boot) */ void sandbox_exit(void); diff --git a/drivers/sysreset/sysreset_sandbox.c b/drivers/sysreset/sysreset_sandbox.c index 69c22a7000..c92132798c 100644 --- a/drivers/sysreset/sysreset_sandbox.c +++ b/drivers/sysreset/sysreset_sandbox.c @@ -56,6 +56,9 @@ static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type) switch (type) { case SYSRESET_COLD: state->last_sysreset = type; + if (!state->sysreset_allowed[type]) + return -EACCES; + sandbox_reset(); break; case SYSRESET_POWER_OFF: state->last_sysreset = type; diff --git a/include/os.h b/include/os.h index 1874ae674f..88dfb71c1a 100644 --- a/include/os.h +++ b/include/os.h @@ -355,4 +355,19 @@ int os_read_file(const char *name, void **bufp, int *sizep); */ void *os_find_text_base(void); +/** + * os_relaunch() - restart the sandbox + * + * This functions is used to implement the cold reboot of the sand box. + * @argv[0] specifies the binary that is started while the calling process + * stops immediately. If the new binary cannot be started, the process is + * terminated and 1 is set as shell return code. + * + * The PID of the process stays the same. All file descriptors that have not + * been opened with O_CLOEXEC stay open including stdin, stdout, stderr. + * + * @argv: NULL terminated list of command line parameters + */ +void os_relaunch(char *argv[]); + #endif