From patchwork Mon Jan 25 15:41:51 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 101124 Delivered-To: patch@linaro.org Received: by 10.112.130.2 with SMTP id oa2csp1432690lbb; Mon, 25 Jan 2016 07:43:54 -0800 (PST) X-Received: by 10.66.140.14 with SMTP id rc14mr26969344pab.65.1453736634279; Mon, 25 Jan 2016 07:43:54 -0800 (PST) Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id g62si34378665pfg.92.2016.01.25.07.43.54 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Jan 2016 07:43:54 -0800 (PST) Received-SPF: pass (google.com: domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) client-ip=2001:1868:205::9; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) smtp.mailfrom=linux-mtd-bounces+patch=linaro.org@lists.infradead.org Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aNjIv-0000WD-Tw; Mon, 25 Jan 2016 15:43:45 +0000 Received: from mout.kundenserver.de ([212.227.126.135]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aNjIV-0008P3-TL; Mon, 25 Jan 2016 15:43:23 +0000 Received: from wuerfel.lan. ([78.42.132.4]) by mrelayeu.kundenserver.de (mreue002) with ESMTPA (Nemesis) id 0M8WB9-1aAL910fbv-00wFpl; Mon, 25 Jan 2016 16:42:56 +0100 From: Arnd Bergmann To: David Woodhouse , Brian Norris Subject: [PATCH] mtd: avoid stack overflow in MTD CFI code Date: Mon, 25 Jan 2016 16:41:51 +0100 Message-Id: <1453736525-1959191-3-git-send-email-arnd@arndb.de> X-Mailer: git-send-email 2.7.0 X-Provags-ID: V03:K0:0hHX4rdMZusBvEhlcJf2EC11ZiAQ/rOFor7z6mEQ9oeIp2j2zrL rSV6XEoXhzcEwXQyanwmoK2KzdLIMfkYI1mZe6gX9SE8Eo6YrZ9fs2u6jDlsBuxSxwQ1LvP q5mK7jzIIsf5dsCWMQQd2n0qFxzWWYueRI3xFz1llc00RTb+MF6Efvefo/uZ7gvX2bXruno Elygxsfc61z39mZae7DCQ== X-UI-Out-Filterresults: notjunk:1; V01:K0:60YWHoHhj4I=:++vYE2gWXwFLriH/rVwCDY 7IMLiSTSVDDbjswVwr2PaD88yG2P4oMsNonSqzOEmExx6ZxYXl49VzoqcITFMn5e+A6qf0jND UDGyuQVjmf7ajMyW+Quoksk7BdT2x7ofcme2T1OhewrpMLITKGwhR9JhsxIiV23vFdNI4mZH+ rz1h3nl8stnEZO/Ex/oIXGrux5hxxNy1Y9EqDR+cHPYUX2VBeTsUnYb+5nx3KBWCD2EOPlMR/ Av2U5pOLbj5buLCi1xkdo6HB/tdiRLGYM48YjPnN876+b6OrZuicFBLX/8jBvMPXSu2jKQGog aJvvWTjr/7UuNrbPpkNMNlJ6aPXrnygy5pjRPLOORR27GviKuvP57y4xowhZx6vA6ClnttpgH VBtBsjB3/tZCuekJQJzM+WDQNCHpW8zp4dJ0W7EFvUj0XpYNe8j7o24mWU/3D+jRej0dw2+tp GOiT/LB5+K0BQ/huoPtABWpBK9Xexoy6fi9bbQ5CnexzU8AeyNjSiGJF7kje8MmlndeQLONIg XpEgTN8bSB0JoMYmcs9d8gEtudhhidy8ERG5hzJ/bONE8dAlKUxgeGVeTuch0VeDKBtUfkN3h EK2gFiJbcxazuylxHWg3DoiC9SeCblISM5f99xo9/YAs60kLmkrO2qbAT8QX5nlnQxx4gzJHk Iq3Y/9Li4h08d5dAUcsocDLvEi9FROtUXxx/8/V8XDYx/C0vTS6t73yS38iv8q4g6dRs= X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160125_074320_677111_2FC56862 X-CRM114-Status: GOOD ( 12.61 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [212.227.126.135 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [212.227.126.135 listed in wl.mailspike.net] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-mtd@lists.infradead.org, Arnd Bergmann , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+patch=linaro.org@lists.infradead.org When map_word gets too large, we use a lot of kernel stack, and for MTD_MAP_BANK_WIDTH_32, this means we use more than the recommended 1024 bytes in a number of functions: drivers/mtd/chips/cfi_cmdset_0020.c: In function 'cfi_staa_write_buffers': drivers/mtd/chips/cfi_cmdset_0020.c:651:1: warning: the frame size of 1336 bytes is larger than 1024 bytes [-Wframe-larger-than=] drivers/mtd/chips/cfi_cmdset_0020.c: In function 'cfi_staa_erase_varsize': drivers/mtd/chips/cfi_cmdset_0020.c:972:1: warning: the frame size of 1208 bytes is larger than 1024 bytes [-Wframe-larger-than=] drivers/mtd/chips/cfi_cmdset_0001.c: In function 'do_write_buffer': drivers/mtd/chips/cfi_cmdset_0001.c:1835:1: warning: the frame size of 1240 bytes is larger than 1024 bytes [-Wframe-larger-than=] This can be avoided if all operations on the map word are done indirectly and the stack gets reused between the calls. We can mostly achieve this by selecting MTD_COMPLEX_MAPPINGS whenever MTD_MAP_BANK_WIDTH_32 is set, but for the case that no other bank width is enabled, we also need to use a non-constant map_bankwidth() to convince the compiler to use less stack. Signed-off-by: Arnd Bergmann --- drivers/mtd/chips/Kconfig | 1 + include/linux/mtd/map.h | 19 +++++++------------ 2 files changed, 8 insertions(+), 12 deletions(-) -- 2.7.0 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig index 3b3dabce58de..b24be7d75c9c 100644 --- a/drivers/mtd/chips/Kconfig +++ b/drivers/mtd/chips/Kconfig @@ -115,6 +115,7 @@ config MTD_MAP_BANK_WIDTH_16 config MTD_MAP_BANK_WIDTH_32 bool "Support 256-bit buswidth" if MTD_CFI_GEOMETRY + select MTD_COMPLEX_MAPPINGS default n help If you wish to support CFI devices on a physical bus which is diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h index 58f3ba709ade..e20fcf678155 100644 --- a/include/linux/mtd/map.h +++ b/include/linux/mtd/map.h @@ -122,18 +122,13 @@ #endif #ifdef CONFIG_MTD_MAP_BANK_WIDTH_32 -# ifdef map_bankwidth -# undef map_bankwidth -# define map_bankwidth(map) ((map)->bankwidth) -# undef map_bankwidth_is_large -# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8) -# undef map_words -# define map_words(map) map_calc_words(map) -# else -# define map_bankwidth(map) 32 -# define map_bankwidth_is_large(map) (1) -# define map_words(map) map_calc_words(map) -# endif +/* always use indirect access for 256-bit to preserve kernel stack */ +# undef map_bankwidth +# define map_bankwidth(map) ((map)->bankwidth) +# undef map_bankwidth_is_large +# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8) +# undef map_words +# define map_words(map) map_calc_words(map) #define map_bankwidth_is_32(map) (map_bankwidth(map) == 32) #undef MAX_MAP_BANKWIDTH #define MAX_MAP_BANKWIDTH 32