From patchwork Tue Jul 16 20:30:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Goldschmidt X-Patchwork-Id: 1132940 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ir2/zkZb"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 45pBqd5bZLz9sDB for ; Wed, 17 Jul 2019 06:30:51 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id DDFF8C21EE5; Tue, 16 Jul 2019 20:30:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_MSPIKE_H2, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id DA28BC21CB1; Tue, 16 Jul 2019 20:30:43 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 7DB69C21CB1; Tue, 16 Jul 2019 20:30:42 +0000 (UTC) Received: from mail-wm1-f67.google.com (mail-wm1-f67.google.com [209.85.128.67]) by lists.denx.de (Postfix) with ESMTPS id 2530EC21C4A for ; Tue, 16 Jul 2019 20:30:42 +0000 (UTC) Received: by mail-wm1-f67.google.com with SMTP id p74so19924715wme.4 for ; Tue, 16 Jul 2019 13:30:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=EytaBSMw2RWjp5IoNUjp8VDWbQx0Wwi+aFRxQxDjnHU=; b=ir2/zkZbWHL26Uvaq/AK2Pevt8v/WPPXMFV12IOFs1DeYyx4USId246X8J69TZUyD5 3Pfg63i1+z15J2Fbvti2tIDAYViXaaEKY4Q3kr6Y8N9/QXlCdvOwzQnbtNdgiJEVA2Tm VZzBMm4e22AtTCW2gOFU3G7jrMxrsrXrcqf1YhA5QdawglypNUb3u19/0gtC7S5Q8O8g LvwX5SUXaqAno7qX/lJ6TNSshy89qr7Dqo7QcP8NbjRsPHruJ+9LeO0NeybUA+dFp6Am IS7cMwIQplI3O0AuwKx9wnQT/KYwfFfOhCgfVh0DLt0bSxtOmb/x4PKy3pGi2Gpu/35l /R8Q== 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:mime-version :content-transfer-encoding; bh=EytaBSMw2RWjp5IoNUjp8VDWbQx0Wwi+aFRxQxDjnHU=; b=kT9F1RnZ0CyvcaFiEO9NjViab+Kc6s2j+RNAJnVFzNum5d2Q+l7FCsTecYQ9MTDx4D A4JQHSzU0ZuAU86bKN8OnxbFbBV5/2CYgVeXlJpcp7Eus4GcOxLcVEyYjqZLoSSVhO5z p3EwCODlIAXPV2SNQ6Ki6Y0L2UOK26vZlyoCpQHNV5BD3ZfE+Xx9KHNsTP/Mm1ksqz8c OiP79cUDOA49L0UQQvImd37oglyZP/DzYVStq0VkBT7xKxI396e3k+BDGgYE4c+tGPS7 27nN6cXAAD1JUNxv1u5KkNOPrhp1/wxSypT/n1WqDpvzMua/LdurVDF8RPZtL7hl3KNr s0uA== X-Gm-Message-State: APjAAAUJFalTQA2cX0D6WWYcEzv0f1GiSXzDiu6+A2Stjuw560t+T59r UkXiWsVmqxp7oQOunMdHCHbPDP+S X-Google-Smtp-Source: APXvYqzuJACJpue2Wu+R+X0QeBalh4IkQqVorPtQYPNQJ1ye9xN1gazgnUJxCw7+4bjGh1txEHSqJQ== X-Received: by 2002:a7b:c051:: with SMTP id u17mr31367065wmc.25.1563309041536; Tue, 16 Jul 2019 13:30:41 -0700 (PDT) Received: from ubuntu.home ([2a02:8071:6a3:700:e1af:5c69:a16b:945c]) by smtp.gmail.com with ESMTPSA id j6sm29711524wrx.46.2019.07.16.13.30.40 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Tue, 16 Jul 2019 13:30:40 -0700 (PDT) From: Simon Goldschmidt To: u-boot@lists.denx.de Date: Tue, 16 Jul 2019 22:30:36 +0200 Message-Id: <20190716203036.24430-1-simon.k.r.goldschmidt@gmail.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Cc: Marek Vasut , Tien Fong Chee , Stefan Roese , Jagan Teki Subject: [U-Boot] [PATCH] spl: implement stack usage check X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" This implements a stack usage check in SPL. Many boards start up SPL to run code + data from one common, rather small SRAM. To implement a sophisticated SPL binary size limit on such boards, the stack size (as well as malloc size and global data size) must be subtracted from this SRAM size. However, to do that properly, the stack size first needs to be known. This patch adds a new Kconfig option: - SPL_SYS_REPORT_STACK_F_USAGE: memset(0xaa) the whole area of the stack very early and check stack usage based on this constant later before the stack is switched to DRAM Initializing the stack and checking it is implemented in weak functions, in case a board does not use the stack as saved in gd->start_addr_sp. Signed-off-by: Simon Goldschmidt --- common/init/board_init.c | 20 ++++++++++++++++++++ common/spl/Kconfig | 19 +++++++++++++++++++ common/spl/spl.c | 25 +++++++++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/common/init/board_init.c b/common/init/board_init.c index 526fee35ff..e52106966d 100644 --- a/common/init/board_init.c +++ b/common/init/board_init.c @@ -18,6 +18,23 @@ __weak void arch_setup_gd(struct global_data *gd_ptr) } #endif /* !CONFIG_X86 && !CONFIG_ARM */ +/** + * This function is called after the position of the initial stack is + * determined in gd->start_addr_sp. Boards can override it to set up + * stack-checking markers. + */ +__weak void board_init_f_init_stack_protection(void) +{ +#if CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE) + ulong stack_bottom = gd->start_addr_sp - + CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK); + + /* substact some safety margin (0x20) since stack is in use here */ + memset((void *)stack_bottom, CONFIG_VAL(SYS_STACK_F_CHECK_BYTE), + CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK) - 0x20); +#endif +} + /* * Allocate reserved space for use as 'globals' from 'top' address and * return 'bottom' address of allocated space @@ -126,6 +143,9 @@ void board_init_f_init_reserve(ulong base) /* next alloc will be higher by one 'early malloc arena' size */ base += CONFIG_VAL(SYS_MALLOC_F_LEN); #endif + + if (CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE)) + board_init_f_init_stack_protection(); } /* diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 126931bace..85e1c9158c 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -62,6 +62,25 @@ config SPL_SIZE_LIMIT_PROVIDE_STACK of SRAM available for SPL when the stack required before reolcation uses this SRAM, too. +config SPL_SYS_STACK_F_CHECK_BYTE + hex + default 0xaa + help + Constant used to check the stack + +config SPL_SYS_REPORT_STACK_F_USAGE + depends on SPL_SIZE_LIMIT_PROVIDE_STACK != 0 + bool "Check and report stack usage in SPL before relocation" + help + If this option is enabled, the initial SPL stack is filled with 0xaa + very early, up to the size configured with + SPL_SIZE_LIMIT_PROVIDE_STACK. + Later when SPL is done using this initial stack and switches to a + stack in DRAM, the actually used size of this initial stack is + reported by examining the memory and searching for the lowest + occurrence of non 0xaa bytes. + This default implementation works for stacks growing down only. + menu "PowerPC SPL Boot options" depends on PPC && (SUPPORT_SPL && !SPL_FRAMEWORK) diff --git a/common/spl/spl.c b/common/spl/spl.c index d5e3f680f4..4918e4f320 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -709,6 +709,28 @@ void preloader_console_init(void) } #endif +/** + * This function is called before the stack is changed from initial stack to + * relocated stack. It tries to dump the stack size used + */ +__weak void spl_relocate_stack_check(void) +{ +#if CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE) + ulong init_sp = gd->start_addr_sp; + ulong stack_bottom = init_sp - CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK); + u8 *ptr = (u8 *)stack_bottom; + ulong i; + + for (i = 0; i < CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK); i++) { + if (*ptr != CONFIG_VAL(SYS_STACK_F_CHECK_BYTE)) + break; + ptr++; + } + printf("SPL initial stack usage: %lu bytes\n", + CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK) - i); +#endif +} + /** * spl_relocate_stack_gd() - Relocate stack ready for board_init_r() execution * @@ -733,6 +755,9 @@ ulong spl_relocate_stack_gd(void) gd_t *new_gd; ulong ptr = CONFIG_SPL_STACK_R_ADDR; + if (CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE)) + spl_relocate_stack_check(); + #if defined(CONFIG_SPL_SYS_MALLOC_SIMPLE) && CONFIG_VAL(SYS_MALLOC_F_LEN) if (CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN) { debug("SPL malloc() before relocation used 0x%lx bytes (%ld KB)\n",