From patchwork Fri Dec 14 20:13:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Goldschmidt X-Patchwork-Id: 1013687 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="T+E4vE5m"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 43GhcY4QMyz9s5c for ; Sat, 15 Dec 2018 07:15:25 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 4DBF4C22095; Fri, 14 Dec 2018 20:14:32 +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_DNSWL_BLOCKED, 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 80613C22164; Fri, 14 Dec 2018 20:14:12 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 249C8C22111; Fri, 14 Dec 2018 20:14:10 +0000 (UTC) Received: from mail-wm1-f66.google.com (mail-wm1-f66.google.com [209.85.128.66]) by lists.denx.de (Postfix) with ESMTPS id 8EF5DC21F84 for ; Fri, 14 Dec 2018 20:14:09 +0000 (UTC) Received: by mail-wm1-f66.google.com with SMTP id m1so6826396wml.2 for ; Fri, 14 Dec 2018 12:14:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nc+FV6QaROc3MLPZgOgaawCvz79hmMEv4stNX+RU0TY=; b=T+E4vE5mrKQoJAjTg8wD4gIEwuqEaXMgKmO3z4+35XI3CyVsVE0A+pw7eFywjRXu4K ruLhOVi2USp5eeWuV0gd/+G0GaiFSK3jaWPzxG78epio+eqTb70a9LArxGNxYj9VaXfM EaffO0n/J8AJ2xbeOonwZxzFPPFx9nWGJLua/0wIK+OXEXU27e6G9Y8vRHJoimLnDNNS IqDeHWmXEqhtRyJMqcXw5D6KVyGhSadvNs5n8IjFnPHjiSflNZ6Nm9PWS67L15YFCGwY 7D/+o24AkKluR6vPTA/Ru+i+jZk4xdLVHtKVMv/QK/FaYHic4BAjs++eJghP/pz32NlL s1bg== 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; bh=nc+FV6QaROc3MLPZgOgaawCvz79hmMEv4stNX+RU0TY=; b=GV1X/AV/i1G3xS2EFyE/KdGJeIjuGgod2l07KkJ71/3eDrCQNIdVqlat1MnZI1S3C4 iDn+B+UhxWqALH903HGrrdlQmtJJxAMqvRIgbeN+7wGNBgKot8yIDrxg4HfzAc2rsv64 ofuD9eM6mg2hpezGLtZQQIgX01cTrUVvbIEo35ihq1ruwrgPBYjt+S9jRxiEaUfXFXII gdGJCF+RJHCy0fbjk3yrfiYxP6Y8enqgHAPdGFj2m4Gbr6v3fQGZl58aC8jlhv7xcXgI ykjXrXQ1joomK4vn+eNKBiAGg/5q3EiKKBsU+ACDcaa4rQUdvZbRcWur/5Fxji2ukRDC 6wnw== X-Gm-Message-State: AA+aEWazNnPP+8chNCcHTqY8Bhio48ItpgVK7oeaweLoslYrWj1Gcahk Y+/UMxJAb+PuEixu4sJ7x24= X-Google-Smtp-Source: AFSGD/Up5kdzar/GhbshCwm9KH2EavO7lHENshy+u0c+LKtW0BLMCzQdL/LB//Tw8kx1WVR48rqdOA== X-Received: by 2002:a1c:8791:: with SMTP id j139mr4225378wmd.86.1544818448935; Fri, 14 Dec 2018 12:14:08 -0800 (PST) Received: from ubuntu.home ([2a02:8071:6a3:700:80b1:ba3d:111a:23c5]) by smtp.gmail.com with ESMTPSA id h62sm4299843wmf.11.2018.12.14.12.14.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Dec 2018 12:14:08 -0800 (PST) From: Simon Goldschmidt To: Tom Rini , u-boot@lists.denx.de, Joe Hershberger Date: Fri, 14 Dec 2018 21:13:49 +0100 Message-Id: <20181214201357.26316-2-simon.k.r.goldschmidt@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> References: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> Cc: Heinrich Schuchardt , Andrea Barisani Subject: [U-Boot] [PATCH v6 1/9] test: add test for lib/lmb.c 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Add basic tests for the lmb memory allocation code used to reserve and allocate memory during boot. Signed-off-by: Simon Goldschmidt Reviewed-by: Simon Glass --- Changes in v6: None Changes in v5: - this patch is new in v5 Changes in v4: None Changes in v2: None test/lib/Makefile | 1 + test/lib/lmb.c | 297 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 298 insertions(+) create mode 100644 test/lib/lmb.c diff --git a/test/lib/Makefile b/test/lib/Makefile index ea68fae566..5a636aac74 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -3,3 +3,4 @@ # (C) Copyright 2018 # Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc obj-y += hexdump.o +obj-y += lmb.o diff --git a/test/lib/lmb.c b/test/lib/lmb.c new file mode 100644 index 0000000000..dd7ba14b34 --- /dev/null +++ b/test/lib/lmb.c @@ -0,0 +1,297 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2018 Simon Goldschmidt + */ + +#include +#include +#include +#include + +static int check_lmb(struct unit_test_state *uts, struct lmb *lmb, + phys_addr_t ram_base, phys_size_t ram_size, + unsigned long num_reserved, + phys_addr_t base1, phys_size_t size1, + phys_addr_t base2, phys_size_t size2, + phys_addr_t base3, phys_size_t size3) +{ + ut_asserteq(lmb->memory.cnt, 1); + ut_asserteq(lmb->memory.region[0].base, ram_base); + ut_asserteq(lmb->memory.region[0].size, ram_size); + + ut_asserteq(lmb->reserved.cnt, num_reserved); + if (num_reserved > 0) { + ut_asserteq(lmb->reserved.region[0].base, base1); + ut_asserteq(lmb->reserved.region[0].size, size1); + } + if (num_reserved > 1) { + ut_asserteq(lmb->reserved.region[1].base, base2); + ut_asserteq(lmb->reserved.region[1].size, size2); + } + if (num_reserved > 2) { + ut_asserteq(lmb->reserved.region[2].base, base3); + ut_asserteq(lmb->reserved.region[2].size, size3); + } + return 0; +} + +#define ASSERT_LMB(lmb, ram_base, ram_size, num_reserved, base1, size1, \ + base2, size2, base3, size3) \ + ut_assert(!check_lmb(uts, lmb, ram_base, ram_size, \ + num_reserved, base1, size1, base2, size2, base3, \ + size3)) + +/* + * Test helper function that reserves 64 KiB somewhere in the simulated RAM and + * then does some alloc + free tests. + */ +static int test_multi_alloc(struct unit_test_state *uts, + const phys_addr_t ram, const phys_size_t ram_size, + const phys_addr_t alloc_64k_addr) +{ + const phys_addr_t ram_end = ram + ram_size; + const phys_addr_t alloc_64k_end = alloc_64k_addr + 0x10000; + + struct lmb lmb; + long ret; + phys_addr_t a, a2, b, b2, c, d; + + /* check for overflow */ + ut_assert(ram_end == 0 || ram_end > ram); + ut_assert(alloc_64k_end > alloc_64k_addr); + /* check input addresses + size */ + ut_assert(alloc_64k_addr >= ram + 8); + ut_assert(alloc_64k_end <= ram_end - 8); + + lmb_init(&lmb); + + ret = lmb_add(&lmb, ram, ram_size); + ut_asserteq(ret, 0); + + /* reserve 64KiB somewhere */ + ret = lmb_reserve(&lmb, alloc_64k_addr, 0x10000); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000, + 0, 0, 0, 0); + + /* allocate somewhere, should be at the end of RAM */ + a = lmb_alloc(&lmb, 4, 1); + ut_asserteq(a, ram_end - 4); + ASSERT_LMB(&lmb, ram, ram_size, 2, alloc_64k_addr, 0x10000, + ram_end - 4, 4, 0, 0); + /* alloc below end of reserved region -> below reserved region */ + b = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end); + ut_asserteq(b, alloc_64k_addr - 4); + ASSERT_LMB(&lmb, ram, ram_size, 2, + alloc_64k_addr - 4, 0x10000 + 4, ram_end - 4, 4, 0, 0); + + /* 2nd time */ + c = lmb_alloc(&lmb, 4, 1); + ut_asserteq(c, ram_end - 8); + ASSERT_LMB(&lmb, ram, ram_size, 2, + alloc_64k_addr - 4, 0x10000 + 4, ram_end - 8, 8, 0, 0); + d = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end); + ut_asserteq(d, alloc_64k_addr - 8); + ASSERT_LMB(&lmb, ram, ram_size, 2, + alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0); + + ret = lmb_free(&lmb, a, 4); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 2, + alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0); + /* allocate again to ensure we get the same address */ + a2 = lmb_alloc(&lmb, 4, 1); + ut_asserteq(a, a2); + ASSERT_LMB(&lmb, ram, ram_size, 2, + alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0); + ret = lmb_free(&lmb, a2, 4); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 2, + alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0); + + ret = lmb_free(&lmb, b, 4); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 3, + alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, + ram_end - 8, 4); + /* allocate again to ensure we get the same address */ + b2 = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end); + ut_asserteq(b, b2); + ASSERT_LMB(&lmb, ram, ram_size, 2, + alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0); + ret = lmb_free(&lmb, b2, 4); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 3, + alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, + ram_end - 8, 4); + + ret = lmb_free(&lmb, c, 4); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 2, + alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, 0, 0); + ret = lmb_free(&lmb, d, 4); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000, + 0, 0, 0, 0); + + return 0; +} + +static int test_multi_alloc_512mb(struct unit_test_state *uts, + const phys_addr_t ram) +{ + return test_multi_alloc(uts, ram, 0x20000000, ram + 0x10000000); +} + +/* Create a memory region with one reserved region and allocate */ +static int lib_test_lmb_simple(struct unit_test_state *uts) +{ + /* simulate 512 MiB RAM beginning at 1GiB */ + return test_multi_alloc_512mb(uts, 0x40000000); +} + +DM_TEST(lib_test_lmb_simple, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Simulate 512 MiB RAM, allocate some blocks that fit/don't fit */ +static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram) +{ + const phys_size_t ram_size = 0x20000000; + const phys_size_t big_block_size = 0x10000000; + const phys_addr_t ram_end = ram + ram_size; + const phys_addr_t alloc_64k_addr = ram + 0x10000000; + struct lmb lmb; + long ret; + phys_addr_t a, b; + + /* check for overflow */ + ut_assert(ram_end == 0 || ram_end > ram); + + lmb_init(&lmb); + + ret = lmb_add(&lmb, ram, ram_size); + ut_asserteq(ret, 0); + + /* reserve 64KiB in the middle of RAM */ + ret = lmb_reserve(&lmb, alloc_64k_addr, 0x10000); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000, + 0, 0, 0, 0); + + /* allocate a big block, should be below reserved */ + a = lmb_alloc(&lmb, big_block_size, 1); + ut_asserteq(a, ram); + ASSERT_LMB(&lmb, ram, ram_size, 1, a, + big_block_size + 0x10000, 0, 0, 0, 0); + /* allocate 2nd big block */ + /* This should fail, printing an error */ + b = lmb_alloc(&lmb, big_block_size, 1); + ut_asserteq(b, 0); + ASSERT_LMB(&lmb, ram, ram_size, 1, a, + big_block_size + 0x10000, 0, 0, 0, 0); + + ret = lmb_free(&lmb, a, big_block_size); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000, + 0, 0, 0, 0); + + /* allocate too big block */ + /* This should fail, printing an error */ + a = lmb_alloc(&lmb, ram_size, 1); + ut_asserteq(a, 0); + ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000, + 0, 0, 0, 0); + + return 0; +} + +static int lib_test_lmb_big(struct unit_test_state *uts) +{ + return test_bigblock(uts, 0x40000000); +} + +DM_TEST(lib_test_lmb_big, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Simulate 512 MiB RAM, allocate a block without previous reservation */ +static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram) +{ + const phys_size_t ram_size = 0x20000000; + const phys_addr_t ram_end = ram + ram_size; + struct lmb lmb; + long ret; + phys_addr_t a, b; + + /* check for overflow */ + ut_assert(ram_end == 0 || ram_end > ram); + + lmb_init(&lmb); + + ret = lmb_add(&lmb, ram, ram_size); + ut_asserteq(ret, 0); + + /* allocate a block */ + a = lmb_alloc(&lmb, 4, 1); + ut_assert(a != 0); + /* and free it */ + ret = lmb_free(&lmb, a, 4); + ut_asserteq(ret, 0); + + /* allocate a block with base*/ + b = lmb_alloc_base(&lmb, 4, 1, ram_end); + ut_assert(a == b); + /* and free it */ + ret = lmb_free(&lmb, b, 4); + ut_asserteq(ret, 0); + + return 0; +} + +static int lib_test_lmb_noreserved(struct unit_test_state *uts) +{ + return test_noreserved(uts, 0x40000000); +} + +DM_TEST(lib_test_lmb_noreserved, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* + * Simulate a RAM that starts at 0 and allocate down to address 0, which must + * fail as '0' means failure for the lmb_alloc functions. + */ +static int lib_test_lmb_at_0(struct unit_test_state *uts) +{ + const phys_addr_t ram = 0; + const phys_size_t ram_size = 0x20000000; + struct lmb lmb; + long ret; + phys_addr_t a, b; + + lmb_init(&lmb); + + ret = lmb_add(&lmb, ram, ram_size); + ut_asserteq(ret, 0); + + /* allocate nearly everything */ + a = lmb_alloc(&lmb, ram_size - 4, 1); + ut_asserteq(a, ram + 4); + ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4, + 0, 0, 0, 0); + /* allocate the rest */ + /* This should fail as the allocated address would be 0 */ + b = lmb_alloc(&lmb, 4, 1); + ut_asserteq(b, 0); + /* check that this was an error by checking lmb */ + ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4, + 0, 0, 0, 0); + /* check that this was an error by freeing b */ + ret = lmb_free(&lmb, b, 4); + ut_asserteq(ret, -1); + ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4, + 0, 0, 0, 0); + + ret = lmb_free(&lmb, a, ram_size - 4); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); + + return 0; +} + +DM_TEST(lib_test_lmb_at_0, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); From patchwork Fri Dec 14 20:13:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Goldschmidt X-Patchwork-Id: 1013688 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="ieyet8jE"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 43Ghdr1ZNLz9s47 for ; Sat, 15 Dec 2018 07:16:32 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id C1103C22031; Fri, 14 Dec 2018 20:14:59 +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_DNSWL_BLOCKED, 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 7F731C22111; Fri, 14 Dec 2018 20:14:23 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 4D983C220F0; Fri, 14 Dec 2018 20:14:14 +0000 (UTC) Received: from mail-wm1-f66.google.com (mail-wm1-f66.google.com [209.85.128.66]) by lists.denx.de (Postfix) with ESMTPS id EABCEC220F0 for ; Fri, 14 Dec 2018 20:14:10 +0000 (UTC) Received: by mail-wm1-f66.google.com with SMTP id s14so6834213wmh.1 for ; Fri, 14 Dec 2018 12:14:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=l5imykiJC8eL1VcmJXV/CPIOHMoB82qaKDYuYS7gENY=; b=ieyet8jEaajV20A49qmqeph/to0DrdUxOsNAAd7RqOw6rT3acPDlDf/IjO6Gxx81Li /ylUY2Kh5ulVpElJTRu1B4Li8+GydJwL/kwf6sBatogZX4anjNCywCDIXmYUuoV0VDIt 9R182MgHzglHb/Z/CrRFJwNDd9gWmCeYCEqnWwaz1695gE6OJpQRgcDat7zEHbNzDf9/ W1NtMTggDAnIPIZNGqaZg8JXjSyARumFrbY2XoE5/4rB7Yv8zQTwKklpFVXwvOojisAF FCcXRxKhL197Vn+S8uvQOLIAu3Z8KWFFIOXCZxFQACq1jrdqQfKqn3XINp6hiJr1lNaG IFuQ== 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; bh=l5imykiJC8eL1VcmJXV/CPIOHMoB82qaKDYuYS7gENY=; b=V6UuBtD8gdn7seQTdmSCfqrJey9ohJwDd8FRW8IYz/DQ9gdPZIhpr5bBhW4NvZdTTx giyYBobzCVlzaPqeAdRzu3gcyV/vxTVHwyQgooHjxySKgNg0tXp+SDJg4ds/x9s0ahas aPTbCTQClRvuLsK6r8kpVXjc4uB43MtyHrjOB5DLoAgViNn3TbYBHOA19stqoMD+SoVb +WGmUE/lysh35jOga9eKxcGmnxEF0Ws5QCiYCt6fU0C3MOaG6oMzLxZRRD7f40bkAFWH 0yw7YJpZ5lsdV/gvHbzkbCrOYVfyhgAU83kePzU32WUvgtlea2A5u8R+hMctjmwJ83cJ mEKA== X-Gm-Message-State: AA+aEWZ/etjFtOa1hHdiKlxJeQeEju4AUkD/VJRakrEuqlSV8VP97wx3 A4gif9SESus/MJ3gJ+P3mGo= X-Google-Smtp-Source: AFSGD/UQSWa06QPvk0TVKgw8fEUoLQrock5fQY4Dpebub/RtoTp01BFnsrwkVvOiXNyk4AdglVmh8w== X-Received: by 2002:a1c:770c:: with SMTP id t12mr4387318wmi.101.1544818450540; Fri, 14 Dec 2018 12:14:10 -0800 (PST) Received: from ubuntu.home ([2a02:8071:6a3:700:80b1:ba3d:111a:23c5]) by smtp.gmail.com with ESMTPSA id h62sm4299843wmf.11.2018.12.14.12.14.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Dec 2018 12:14:09 -0800 (PST) From: Simon Goldschmidt To: Tom Rini , u-boot@lists.denx.de, Joe Hershberger Date: Fri, 14 Dec 2018 21:13:50 +0100 Message-Id: <20181214201357.26316-3-simon.k.r.goldschmidt@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> References: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> Cc: Heinrich Schuchardt , Andrea Barisani Subject: [U-Boot] [PATCH v6 2/9] lmb: fix allocation at end of address range 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" The lmb code fails if base + size of RAM overflows to zero. Fix this by calculating end as 'base + size - 1' instead of 'base + size' where appropriate. Added tests to assert this is fixed. Signed-off-by: Simon Goldschmidt --- Changes in v6: None Changes in v5: - this patch is new in v5 Changes in v4: None Changes in v2: None lib/lmb.c | 29 ++++++++++++----------------- test/lib/lmb.c | 29 ++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/lib/lmb.c b/lib/lmb.c index 1705417348..6d3dcf4e09 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -43,7 +43,10 @@ void lmb_dump_all(struct lmb *lmb) static long lmb_addrs_overlap(phys_addr_t base1, phys_size_t size1, phys_addr_t base2, phys_size_t size2) { - return ((base1 < (base2+size2)) && (base2 < (base1+size1))); + const phys_addr_t base1_end = base1 + size1 - 1; + const phys_addr_t base2_end = base2 + size2 - 1; + + return ((base1 <= base2_end) && (base2 <= base1_end)); } static long lmb_addrs_adjacent(phys_addr_t base1, phys_size_t size1, @@ -89,18 +92,9 @@ static void lmb_coalesce_regions(struct lmb_region *rgn, void lmb_init(struct lmb *lmb) { - /* Create a dummy zero size LMB which will get coalesced away later. - * This simplifies the lmb_add() code below... - */ - lmb->memory.region[0].base = 0; - lmb->memory.region[0].size = 0; - lmb->memory.cnt = 1; + lmb->memory.cnt = 0; lmb->memory.size = 0; - - /* Ditto. */ - lmb->reserved.region[0].base = 0; - lmb->reserved.region[0].size = 0; - lmb->reserved.cnt = 1; + lmb->reserved.cnt = 0; lmb->reserved.size = 0; } @@ -110,9 +104,10 @@ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t unsigned long coalesced = 0; long adjacent, i; - if ((rgn->cnt == 1) && (rgn->region[0].size == 0)) { + if (rgn->cnt == 0) { rgn->region[0].base = base; rgn->region[0].size = size; + rgn->cnt = 1; return 0; } @@ -183,7 +178,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size) { struct lmb_region *rgn = &(lmb->reserved); phys_addr_t rgnbegin, rgnend; - phys_addr_t end = base + size; + phys_addr_t end = base + size - 1; int i; rgnbegin = rgnend = 0; /* supress gcc warnings */ @@ -191,7 +186,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size) /* Find the region where (base, size) belongs to */ for (i=0; i < rgn->cnt; i++) { rgnbegin = rgn->region[i].base; - rgnend = rgnbegin + rgn->region[i].size; + rgnend = rgnbegin + rgn->region[i].size - 1; if ((rgnbegin <= base) && (end <= rgnend)) break; @@ -209,7 +204,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size) /* Check to see if region is matching at the front */ if (rgnbegin == base) { - rgn->region[i].base = end; + rgn->region[i].base = end + 1; rgn->region[i].size -= size; return 0; } @@ -225,7 +220,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size) * beginging of the hole and add the region after hole. */ rgn->region[i].size = base - rgn->region[i].base; - return lmb_add_region(rgn, end, rgnend - end); + return lmb_add_region(rgn, end + 1, rgnend - end); } long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size) diff --git a/test/lib/lmb.c b/test/lib/lmb.c index dd7ba14b34..fb7ca45ef1 100644 --- a/test/lib/lmb.c +++ b/test/lib/lmb.c @@ -146,8 +146,15 @@ static int test_multi_alloc_512mb(struct unit_test_state *uts, /* Create a memory region with one reserved region and allocate */ static int lib_test_lmb_simple(struct unit_test_state *uts) { + int ret; + /* simulate 512 MiB RAM beginning at 1GiB */ - return test_multi_alloc_512mb(uts, 0x40000000); + ret = test_multi_alloc_512mb(uts, 0x40000000); + if (ret) + return ret; + + /* simulate 512 MiB RAM beginning at 1.5GiB */ + return test_multi_alloc_512mb(uts, 0xE0000000); } DM_TEST(lib_test_lmb_simple, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); @@ -206,7 +213,15 @@ static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram) static int lib_test_lmb_big(struct unit_test_state *uts) { - return test_bigblock(uts, 0x40000000); + int ret; + + /* simulate 512 MiB RAM beginning at 1GiB */ + ret = test_bigblock(uts, 0x40000000); + if (ret) + return ret; + + /* simulate 512 MiB RAM beginning at 1.5GiB */ + return test_bigblock(uts, 0xE0000000); } DM_TEST(lib_test_lmb_big, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); @@ -247,7 +262,15 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram) static int lib_test_lmb_noreserved(struct unit_test_state *uts) { - return test_noreserved(uts, 0x40000000); + int ret; + + /* simulate 512 MiB RAM beginning at 1GiB */ + ret = test_noreserved(uts, 0x40000000); + if (ret) + return ret; + + /* simulate 512 MiB RAM beginning at 1.5GiB */ + return test_noreserved(uts, 0xE0000000); } DM_TEST(lib_test_lmb_noreserved, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); From patchwork Fri Dec 14 20:13:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Goldschmidt X-Patchwork-Id: 1013691 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="ESjr4bBQ"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 43Ghgg5YXnz9s47 for ; Sat, 15 Dec 2018 07:18:07 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 52DD9C2216B; Fri, 14 Dec 2018 20:15:36 +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_DNSWL_BLOCKED, 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 53740C22158; Fri, 14 Dec 2018 20:14:28 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 778C2C221EB; Fri, 14 Dec 2018 20:14:15 +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 65E3CC2215A for ; Fri, 14 Dec 2018 20:14:12 +0000 (UTC) Received: by mail-wm1-f67.google.com with SMTP id c126so6970353wmh.0 for ; Fri, 14 Dec 2018 12:14:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=eRt5qz/tX6VdiVYy781vKYmSFVuqc1nXimibOViiSbI=; b=ESjr4bBQPIk9SCsCBGoHyJYcuwvptpp6LTKETNp9AklP5UWCYUCC3Fk/Fex2LuUlYm ygkFTsrH5dt0DzbA6/VA7XWCnuyacau/WJekaYD9lTHtvGnxsFI+yOn6VnH/+WunC2xm zpebi8RVuylm2KxHBnFT8729NmW5sFJHK3SHPa1+9EPIH0sjHyCr0sbwKD/FQSSdLzHt ZpK/hSiMdNfCMUjUs7Y2P3FS4OEnh9bJRBJ5Pj4IdhiPzFsOCpFs8fv9C9gbzUTC1eca Ce6L17BmwmaPbBbwKBrnCb7pOAFRjYAoTdYZ2qVNWriCKiWag0BUpAS4Fq1H6t7/6d8o NIhA== 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; bh=eRt5qz/tX6VdiVYy781vKYmSFVuqc1nXimibOViiSbI=; b=WleFHdmXl4m4zo1RF/xoSjXkzVmsfsGd37nC+/jvahJ8/k6VBRrNSub4Bm3eEgWOke 1pyZsh7Dclm647ODY29hUR4BfUtmndUak3XYlghVGf0G3RGzO/HV7PXHn7fp44Qt0xbo nF/MERO6elOuRKpHdT9KmoW+iJ28siG6Ch61XucauKtnk3mcr/bGVwJgzyZRIwSrJX76 YrVFPJXfVq5DmNpKMWfz7HKoS5OL5ZHlMG37aPuOMAm1iLGk3bilplwcsJaKi+Co67qj mhGdEDjrzWIk8iCmhPo5vMnyMymrbr5n2E47h86/etWQ0DLG755CAKI/EoTNokCs/+Qo n3nQ== X-Gm-Message-State: AA+aEWbofnbi72wbmsXFWiBvcAe2MqVtqfzzhOuFIxpHLvZrvnUCMPHh tiMtqDutxgP90FiLjKrcw5U= X-Google-Smtp-Source: AFSGD/U02T/DeagLuiXHd+SUVtp95lF6vI4UBH00CfrMjBGfybBUW5M1xhMssTHy3S5oMWymM0lPDQ== X-Received: by 2002:a1c:87cc:: with SMTP id j195mr4321737wmd.2.1544818451877; Fri, 14 Dec 2018 12:14:11 -0800 (PST) Received: from ubuntu.home ([2a02:8071:6a3:700:80b1:ba3d:111a:23c5]) by smtp.gmail.com with ESMTPSA id h62sm4299843wmf.11.2018.12.14.12.14.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Dec 2018 12:14:10 -0800 (PST) From: Simon Goldschmidt To: Tom Rini , u-boot@lists.denx.de, Joe Hershberger Date: Fri, 14 Dec 2018 21:13:51 +0100 Message-Id: <20181214201357.26316-4-simon.k.r.goldschmidt@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> References: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> Cc: Heinrich Schuchardt , Andrea Barisani Subject: [U-Boot] [PATCH v6 3/9] lib: lmb: reserving overlapping regions should fail 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" lmb_add_region handles overlapping regions wrong: instead of merging or rejecting to add a new reserved region that overlaps an existing one, it just adds the new region. Since internally the same function is used for lmb_alloc, change lmb_add_region to reject overlapping regions. Also, to keep reserved memory correct after 'free', reserved entries created by allocating memory must not set their size to a multiple of alignment but to the original size. This ensures the reserved region is completely removed when the caller calls 'lmb_free', as this one takes the same size as passed to 'lmb_alloc' etc. Add test to assert this. Signed-off-by: Simon Goldschmidt --- Changes in v6: - fix size of allocated regions that need alignment padding Changes in v5: - added a test for this bug Changes in v4: None Changes in v2: None lib/lmb.c | 11 +++--- test/lib/lmb.c | 94 +++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 90 insertions(+), 15 deletions(-) diff --git a/lib/lmb.c b/lib/lmb.c index 6d3dcf4e09..cd297f8202 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -131,6 +131,9 @@ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t rgn->region[i].size += size; coalesced++; break; + } else if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { + /* regions overlap */ + return -1; } } @@ -269,11 +272,6 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) return addr & ~(size - 1); } -static phys_addr_t lmb_align_up(phys_addr_t addr, ulong size) -{ - return (addr + (size - 1)) & ~(size - 1); -} - phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr) { long i, j; @@ -302,8 +300,7 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phy if (j < 0) { /* This area isn't reserved, take it */ if (lmb_add_region(&lmb->reserved, base, - lmb_align_up(size, - align)) < 0) + size) < 0) return 0; return base; } diff --git a/test/lib/lmb.c b/test/lib/lmb.c index fb7ca45ef1..ffa3d53bf1 100644 --- a/test/lib/lmb.c +++ b/test/lib/lmb.c @@ -227,13 +227,16 @@ static int lib_test_lmb_big(struct unit_test_state *uts) DM_TEST(lib_test_lmb_big, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); /* Simulate 512 MiB RAM, allocate a block without previous reservation */ -static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram) +static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram, + const phys_addr_t alloc_size, const ulong align) { const phys_size_t ram_size = 0x20000000; const phys_addr_t ram_end = ram + ram_size; struct lmb lmb; long ret; phys_addr_t a, b; + const phys_addr_t alloc_size_aligned = (alloc_size + align - 1) & + ~(align - 1); /* check for overflow */ ut_assert(ram_end == 0 || ram_end > ram); @@ -242,20 +245,42 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram) ret = lmb_add(&lmb, ram, ram_size); ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); /* allocate a block */ - a = lmb_alloc(&lmb, 4, 1); + a = lmb_alloc(&lmb, alloc_size, align); ut_assert(a != 0); - /* and free it */ - ret = lmb_free(&lmb, a, 4); + ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned, + alloc_size, 0, 0, 0, 0); + /* allocate another block */ + b = lmb_alloc(&lmb, alloc_size, align); + ut_assert(b != 0); + if (alloc_size == alloc_size_aligned) + ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - + (alloc_size_aligned * 2), alloc_size * 2, 0, 0, 0, + 0); + else + ASSERT_LMB(&lmb, ram, ram_size, 2, ram + ram_size - + (alloc_size_aligned * 2), alloc_size, ram + ram_size + - alloc_size_aligned, alloc_size, 0, 0); + /* and free them */ + ret = lmb_free(&lmb, b, alloc_size); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned, + alloc_size, 0, 0, 0, 0); + ret = lmb_free(&lmb, a, alloc_size); ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); /* allocate a block with base*/ - b = lmb_alloc_base(&lmb, 4, 1, ram_end); + b = lmb_alloc_base(&lmb, alloc_size, align, ram_end); ut_assert(a == b); + ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned, + alloc_size, 0, 0, 0, 0); /* and free it */ - ret = lmb_free(&lmb, b, 4); + ret = lmb_free(&lmb, b, alloc_size); ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); return 0; } @@ -265,16 +290,30 @@ static int lib_test_lmb_noreserved(struct unit_test_state *uts) int ret; /* simulate 512 MiB RAM beginning at 1GiB */ - ret = test_noreserved(uts, 0x40000000); + ret = test_noreserved(uts, 0x40000000, 4, 1); if (ret) return ret; /* simulate 512 MiB RAM beginning at 1.5GiB */ - return test_noreserved(uts, 0xE0000000); + return test_noreserved(uts, 0xE0000000, 4, 1); } DM_TEST(lib_test_lmb_noreserved, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); +static int lib_test_lmb_unaligned_size(struct unit_test_state *uts) +{ + int ret; + + /* simulate 512 MiB RAM beginning at 1GiB */ + ret = test_noreserved(uts, 0x40000000, 5, 8); + if (ret) + return ret; + + /* simulate 512 MiB RAM beginning at 1.5GiB */ + return test_noreserved(uts, 0xE0000000, 5, 8); +} + +DM_TEST(lib_test_lmb_unaligned_size, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); /* * Simulate a RAM that starts at 0 and allocate down to address 0, which must * fail as '0' means failure for the lmb_alloc functions. @@ -318,3 +357,42 @@ static int lib_test_lmb_at_0(struct unit_test_state *uts) } DM_TEST(lib_test_lmb_at_0, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Check that calling lmb_reserve with overlapping regions fails. */ +static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) +{ + const phys_addr_t ram = 0x40000000; + const phys_size_t ram_size = 0x20000000; + struct lmb lmb; + long ret; + + lmb_init(&lmb); + + ret = lmb_add(&lmb, ram, ram_size); + ut_asserteq(ret, 0); + + ret = lmb_reserve(&lmb, 0x40010000, 0x10000); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000, + 0, 0, 0, 0); + /* allocate overlapping region should fail */ + ret = lmb_reserve(&lmb, 0x40011000, 0x10000); + ut_asserteq(ret, -1); + ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000, + 0, 0, 0, 0); + /* allocate 3nd region */ + ret = lmb_reserve(&lmb, 0x40030000, 0x10000); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40010000, 0x10000, + 0x40030000, 0x10000, 0, 0); + /* allocate 2nd region */ + ret = lmb_reserve(&lmb, 0x40020000, 0x10000); + ut_assert(ret >= 0); + ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x30000, + 0, 0, 0, 0); + + return 0; +} + +DM_TEST(lib_test_lmb_overlapping_reserve, + DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); From patchwork Fri Dec 14 20:13:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Goldschmidt X-Patchwork-Id: 1013689 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="vMadCgl3"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 43GhfX360Kz9s47 for ; Sat, 15 Dec 2018 07:17:08 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 1AFF1C220F0; Fri, 14 Dec 2018 20:15:18 +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_DNSWL_BLOCKED, 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 5E313C221D5; Fri, 14 Dec 2018 20:14:25 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 44D1BC22153; Fri, 14 Dec 2018 20:14:17 +0000 (UTC) Received: from mail-wm1-f66.google.com (mail-wm1-f66.google.com [209.85.128.66]) by lists.denx.de (Postfix) with ESMTPS id CF195C21FFE for ; Fri, 14 Dec 2018 20:14:13 +0000 (UTC) Received: by mail-wm1-f66.google.com with SMTP id r24so17004821wmh.0 for ; Fri, 14 Dec 2018 12:14:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=baRUnJlmU4RJAXVwz928o5AQoqBpIIQMY3jvOtKKfxo=; b=vMadCgl3oG8xcCGWNSbsahgXBb/sDKxPIzgCOh2tpAWqC/N00187jchKjjC+xfP6yl C9QYGQDYZiyPK7wQSB+Bi0b4v6LtAgu2IDrRByuKSBdoldrEXKCFd1X8qRuxWiDy3I+J XnxEYJMPXkHcjvohkN00rdIh3E9hPEA2f9/UPvWIdyv6Ml3zuYYMKSAJQzv1V29njUJn H/cvlhrjTzOfMBQCrtFe9sCbpa/n29JZbUecrlKmlgotUbkU8geAhJkxNxZfCZYSbB23 0VpwtUCYqG/c+t2qWrjl3XIcwU2v0dVsswHMvVFhx13s5z5BD0LE5EJoq1qPjCMYIm4D 3k8Q== 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; bh=baRUnJlmU4RJAXVwz928o5AQoqBpIIQMY3jvOtKKfxo=; b=clT1903wK83/Qfd8Lmhn+QtWaBLPdLrNTtnCX5zuHtUGKHHee+EgUbJapDOeRldovK 5K4bH4oVyxNQCztGomo1BgQXTjS/3PLIUYq9j4TsQJ/p0XO0Wz40EVJdJ25bMy1cdH8D hUcKRix0J5NWSS81L+LBe80/4+8e6Qg7EQ194arWUZAbryZN/AnS62I0av7pwZ+/12Qc 5A+6fYGNTIKC5WPhwsyJx4pAu4mGjNNnNxRtKHZ0+gYFhcPY2ttOze5qqx3UXgzILAyZ r0xkfDTP0vlU/PbuGTBc41KmS4kJ/itirukdSzmb/zPMv5o7TVDDAsIkfSoPJRpCXRJe 3BJA== X-Gm-Message-State: AA+aEWZevXith7vx1D5ZMw+U8LYZ/J986u9yQbP1+ECJqFJmMOjqfpgp mSgFpUrv/rCO0hU+8/trcFI= X-Google-Smtp-Source: AFSGD/XONL0bAdIUAev30tua6+JV3DfLL7dbspyDO6FY6aMLriBP9GmGhyWnaxvoh9WOVhrB6lrZOA== X-Received: by 2002:a1c:b70a:: with SMTP id h10mr4154178wmf.125.1544818453445; Fri, 14 Dec 2018 12:14:13 -0800 (PST) Received: from ubuntu.home ([2a02:8071:6a3:700:80b1:ba3d:111a:23c5]) by smtp.gmail.com with ESMTPSA id h62sm4299843wmf.11.2018.12.14.12.14.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Dec 2018 12:14:12 -0800 (PST) From: Simon Goldschmidt To: Tom Rini , u-boot@lists.denx.de, Joe Hershberger Date: Fri, 14 Dec 2018 21:13:52 +0100 Message-Id: <20181214201357.26316-5-simon.k.r.goldschmidt@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> References: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> Cc: Alexey Brodkin , Heinrich Schuchardt , Alexander Graf , Miquel Raynal , Andrea Barisani Subject: [U-Boot] [PATCH v6 4/9] fdt: parse "reserved-memory" for memory reservation 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" boot_fdt_add_mem_rsv_regions() adds reserved memory sections to an lmb struct. Currently, it only parses regions described by /memreserve/ entries. Extend this to the more commonly used scheme of the "reserved-memory" node. Signed-off-by: Simon Goldschmidt Reviewed-by: Simon Glass --- Changes in v6: - fix compiling without OF_CONTROL Changes in v5: None Changes in v4: - fixed invalid 'if' statement without braces in boot_fdt_reserve_region Changes in v2: - this patch is new in v2 common/image-fdt.c | 53 +++++++++++++++++++++++++++++++++++++++------- lib/Makefile | 1 + 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/common/image-fdt.c b/common/image-fdt.c index 95748f0ae1..5c0d6db3fe 100644 --- a/common/image-fdt.c +++ b/common/image-fdt.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -67,30 +68,66 @@ static const image_header_t *image_get_fdt(ulong fdt_addr) } #endif +static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr, + uint64_t size) +{ + int ret; + + ret = lmb_reserve(lmb, addr, size); + if (!ret) { + debug(" reserving fdt memory region: addr=%llx size=%llx\n", + (unsigned long long)addr, (unsigned long long)size); + } else { + puts("ERROR: reserving fdt memory region failed "); + printf("(addr=%llx size=%llx)\n", + (unsigned long long)addr, (unsigned long long)size); + } +} + /** - * boot_fdt_add_mem_rsv_regions - Mark the memreserve sections as unusable + * boot_fdt_add_mem_rsv_regions - Mark the memreserve and reserved-memory + * sections as unusable * @lmb: pointer to lmb handle, will be used for memory mgmt * @fdt_blob: pointer to fdt blob base address * - * Adds the memreserve regions in the dtb to the lmb block. Adding the - * memreserve regions prevents u-boot from using them to store the initrd - * or the fdt blob. + * Adds the and reserved-memorymemreserve regions in the dtb to the lmb block. + * Adding the memreserve regions prevents u-boot from using them to store the + * initrd or the fdt blob. */ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) { uint64_t addr, size; - int i, total; + int i, total, ret; + int nodeoffset, subnode; + struct fdt_resource res; if (fdt_check_header(fdt_blob) != 0) return; + /* process memreserve sections */ total = fdt_num_mem_rsv(fdt_blob); for (i = 0; i < total; i++) { if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0) continue; - printf(" reserving fdt memory region: addr=%llx size=%llx\n", - (unsigned long long)addr, (unsigned long long)size); - lmb_reserve(lmb, addr, size); + boot_fdt_reserve_region(lmb, addr, size); + } + + /* process reserved-memory */ + nodeoffset = fdt_subnode_offset(fdt_blob, 0, "reserved-memory"); + if (nodeoffset >= 0) { + subnode = fdt_first_subnode(fdt_blob, nodeoffset); + while (subnode >= 0) { + /* check if this subnode has a reg property */ + ret = fdt_get_resource(fdt_blob, subnode, "reg", 0, + &res); + if (!ret) { + addr = res.start; + size = res.end - res.start + 1; + boot_fdt_reserve_region(lmb, addr, size); + } + + subnode = fdt_next_subnode(fdt_blob, subnode); + } } } diff --git a/lib/Makefile b/lib/Makefile index a6dd928a92..1972fe8cf1 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -30,6 +30,7 @@ obj-y += crc7.o obj-y += crc8.o obj-y += crc16.o obj-$(CONFIG_ERRNO_STR) += errno_str.o +obj-$(CONFIG_FIT) += fdtdec.o obj-$(CONFIG_FIT) += fdtdec_common.o obj-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o obj-$(CONFIG_GZIP_COMPRESSED) += gzip.o From patchwork Fri Dec 14 20:13:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Goldschmidt X-Patchwork-Id: 1013690 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="CMWpDKI3"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 43GhgM0khvz9s47 for ; Sat, 15 Dec 2018 07:17:51 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 9BC0AC220BD; Fri, 14 Dec 2018 20:16:34 +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_DNSWL_BLOCKED, 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 517EAC21DF9; Fri, 14 Dec 2018 20:14:34 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id DC2E3C2215A; Fri, 14 Dec 2018 20:14:18 +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 4D049C22187 for ; Fri, 14 Dec 2018 20:14:15 +0000 (UTC) Received: by mail-wm1-f67.google.com with SMTP id m22so6997539wml.3 for ; Fri, 14 Dec 2018 12:14:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Tud7bCmDbtuX9wbBSIBT9NPrj2NkFW+w+OfbT9HnScQ=; b=CMWpDKI3yxWQ1OA+tOAjVabfrDQNaSrp4lz3IqYZt5msvKXQyv7Cl5Ii82GdRpSAFb b0nUWtJ4dD+hJG+L7fecAC7s4tUai+v6qZzDTAFmxkZ6sckNhM8n3DtAibmYeEfnCYA0 3zUxvCdg//EkcVsZh1ZOq9oIcAbOvFGktW5tDodiI/TLnQxbrWJP3HgVLd4OY4kx7JaE fy/BqSUFkXdjfS4ZyHTW+wZvljJIjI+6gUj/ejlwcygzmtm3N1VMIbJFVVFXt0vU+Fq5 nLgiXvDVQdvoz3xeXH2hDHi9StEYM9OLDAxW8wFRg9IBLk4Za/WD/iENyqrUq1BMqYyq cObA== 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; bh=Tud7bCmDbtuX9wbBSIBT9NPrj2NkFW+w+OfbT9HnScQ=; b=nzlptUpa2yxQzvQBPAer/biU1lWGa08YS7avnE4YIlDXk2MHkMNyTmGMFUGNsLOXAq XL+N+FpJEpyrAyTNV4p0ZnN4R6Q7c7UGvGEHIKIZjA4JvDLancTAEDdNhPsUxyzpidmK WePz1YGGQCqI4eDnCCGVppUu1Ajj95ctsoHwihmR9zcO4yLlRirCvovXizxLkDXLx4o5 a5xyRrIEM6BYqXDePQZjOSxzLPQafmcq2CtNF7F1WwgA01ARTPpbC1XtaP1zW8l08eBf kLtBogwLcB7qqoaS7A8XViEVp7ii6B4yjby0fBMaXmorxfCxTOlFwVy5GGRMWUtf3xSU Ppjg== X-Gm-Message-State: AA+aEWbnx3GBu3WKQB3sxnpDfL6blp30a+io2e90iJwHQhoifSySUe54 xDV9xHFfMiuw0HXhXOQjigY= X-Google-Smtp-Source: AFSGD/U8fmFAtb/LWTAznxY7ldvXCktjWJAqvJ2u889EiHn8nsdMDJS/t3r9LXkxQFT4DVSEc8CxGA== X-Received: by 2002:a1c:1d2:: with SMTP id 201mr4700410wmb.69.1544818454705; Fri, 14 Dec 2018 12:14:14 -0800 (PST) Received: from ubuntu.home ([2a02:8071:6a3:700:80b1:ba3d:111a:23c5]) by smtp.gmail.com with ESMTPSA id h62sm4299843wmf.11.2018.12.14.12.14.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Dec 2018 12:14:13 -0800 (PST) From: Simon Goldschmidt To: Tom Rini , u-boot@lists.denx.de, Joe Hershberger Date: Fri, 14 Dec 2018 21:13:53 +0100 Message-Id: <20181214201357.26316-6-simon.k.r.goldschmidt@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> References: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> Cc: Heinrich Schuchardt , Andrea Barisani Subject: [U-Boot] [PATCH v6 5/9] lib: lmb: extend lmb for checks at load time 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This adds two new functions, lmb_alloc_addr and lmb_get_unreserved_size. lmb_alloc_addr behaves like lmb_alloc, but it tries to allocate a pre-specified address range. Unlike lmb_reserve, this address range must be inside one of the memory ranges that has been set up with lmb_add. lmb_get_unreserved_size returns the number of bytes that can be used up to the next reserved region or the end of valid ram. This can be 0 if the address passed is reserved. Added test for these new functions. Signed-off-by: Simon Goldschmidt --- Changes in v6: None Changes in v5: - fixed lmb_alloc_addr when resulting reserved ranges get combined - added test for these new functions Changes in v4: None Changes in v2: - added lmb_get_unreserved_size() for tftp include/lmb.h | 3 + lib/lmb.c | 53 +++++++++++++ test/lib/lmb.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 258 insertions(+) diff --git a/include/lmb.h b/include/lmb.h index f04d058093..7d7e2a78dc 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -38,6 +38,9 @@ extern phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align phys_addr_t max_addr); extern phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr); +extern phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, + phys_size_t size); +extern phys_size_t lmb_get_unreserved_size(struct lmb *lmb, phys_addr_t addr); extern int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr); extern long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size); diff --git a/lib/lmb.c b/lib/lmb.c index cd297f8202..e380a0a722 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -313,6 +313,59 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phy return 0; } +/* + * Try to allocate a specific address range: must be in defined memory but not + * reserved + */ +phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, phys_size_t size) +{ + long j; + + /* Check if the requested address is in one of the memory regions */ + j = lmb_overlaps_region(&lmb->memory, base, size); + if (j >= 0) { + /* + * Check if the requested end address is in the same memory + * region we found. + */ + if (lmb_addrs_overlap(lmb->memory.region[j].base, + lmb->memory.region[j].size, base + size - + 1, 1)) { + /* ok, reserve the memory */ + if (lmb_reserve(lmb, base, size) >= 0) + return base; + } + } + return 0; +} + +/* Return number of bytes from a given address that are free */ +phys_size_t lmb_get_unreserved_size(struct lmb *lmb, phys_addr_t addr) +{ + int i; + long j; + + /* check if the requested address is in the memory regions */ + j = lmb_overlaps_region(&lmb->memory, addr, 1); + if (j >= 0) { + for (i = 0; i < lmb->reserved.cnt; i++) { + if (addr < lmb->reserved.region[i].base) { + /* first reserved range > requested address */ + return lmb->reserved.region[i].base - addr; + } + if (lmb->reserved.region[i].base + + lmb->reserved.region[i].size > addr) { + /* requested addr is in this reserved range */ + return 0; + } + } + /* if we come here: no reserved ranges above requested addr */ + return lmb->memory.region[lmb->memory.cnt - 1].base + + lmb->memory.region[lmb->memory.cnt - 1].size - addr; + } + return 0; +} + int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr) { int i; diff --git a/test/lib/lmb.c b/test/lib/lmb.c index ffa3d53bf1..f6f4b76dc0 100644 --- a/test/lib/lmb.c +++ b/test/lib/lmb.c @@ -396,3 +396,205 @@ static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) DM_TEST(lib_test_lmb_overlapping_reserve, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* + * Simulate 512 MiB RAM, reserve 3 blocks, allocate addresses in between. + * Expect addresses outside the memory range to fail. + */ +static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) +{ + const phys_size_t ram_size = 0x20000000; + const phys_addr_t ram_end = ram + ram_size; + const phys_size_t alloc_addr_a = ram + 0x8000000; + const phys_size_t alloc_addr_b = ram + 0x8000000 * 2; + const phys_size_t alloc_addr_c = ram + 0x8000000 * 3; + struct lmb lmb; + long ret; + phys_addr_t a, b, c, d, e; + + /* check for overflow */ + ut_assert(ram_end == 0 || ram_end > ram); + + lmb_init(&lmb); + + ret = lmb_add(&lmb, ram, ram_size); + ut_asserteq(ret, 0); + + /* reserve 3 blocks */ + ret = lmb_reserve(&lmb, alloc_addr_a, 0x10000); + ut_asserteq(ret, 0); + ret = lmb_reserve(&lmb, alloc_addr_b, 0x10000); + ut_asserteq(ret, 0); + ret = lmb_reserve(&lmb, alloc_addr_c, 0x10000); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 3, alloc_addr_a, 0x10000, + alloc_addr_b, 0x10000, alloc_addr_c, 0x10000); + + /* allocate blocks */ + a = lmb_alloc_addr(&lmb, ram, alloc_addr_a - ram); + ut_asserteq(a, ram); + ASSERT_LMB(&lmb, ram, ram_size, 3, ram, 0x8010000, + alloc_addr_b, 0x10000, alloc_addr_c, 0x10000); + b = lmb_alloc_addr(&lmb, alloc_addr_a + 0x10000, + alloc_addr_b - alloc_addr_a - 0x10000); + ut_asserteq(b, alloc_addr_a + 0x10000); + ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x10010000, + alloc_addr_c, 0x10000, 0, 0); + c = lmb_alloc_addr(&lmb, alloc_addr_b + 0x10000, + alloc_addr_c - alloc_addr_b - 0x10000); + ut_asserteq(c, alloc_addr_b + 0x10000); + ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000, + 0, 0, 0, 0); + d = lmb_alloc_addr(&lmb, alloc_addr_c + 0x10000, + ram_end - alloc_addr_c - 0x10000); + ut_asserteq(d, alloc_addr_c + 0x10000); + ASSERT_LMB(&lmb, ram, ram_size, 1, ram, ram_size, + 0, 0, 0, 0); + + /* allocating anything else should fail */ + e = lmb_alloc(&lmb, 1, 1); + ut_asserteq(e, 0); + ASSERT_LMB(&lmb, ram, ram_size, 1, ram, ram_size, + 0, 0, 0, 0); + + ret = lmb_free(&lmb, d, ram_end - alloc_addr_c - 0x10000); + ut_asserteq(ret, 0); + + /* allocate at 3 points in free range */ + + d = lmb_alloc_addr(&lmb, ram_end - 4, 4); + ut_asserteq(d, ram_end - 4); + ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x18010000, + d, 4, 0, 0); + ret = lmb_free(&lmb, d, 4); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000, + 0, 0, 0, 0); + + d = lmb_alloc_addr(&lmb, ram_end - 128, 4); + ut_asserteq(d, ram_end - 128); + ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x18010000, + d, 4, 0, 0); + ret = lmb_free(&lmb, d, 4); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000, + 0, 0, 0, 0); + + d = lmb_alloc_addr(&lmb, alloc_addr_c + 0x10000, 4); + ut_asserteq(d, alloc_addr_c + 0x10000); + ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010004, + 0, 0, 0, 0); + ret = lmb_free(&lmb, d, 4); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000, + 0, 0, 0, 0); + + /* allocate at the bottom */ + ret = lmb_free(&lmb, a, alloc_addr_a - ram); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 1, ram + 0x8000000, 0x10010000, + 0, 0, 0, 0); + d = lmb_alloc_addr(&lmb, ram, 4); + ut_asserteq(d, ram); + ASSERT_LMB(&lmb, ram, ram_size, 2, d, 4, + ram + 0x8000000, 0x10010000, 0, 0); + + /* check that allocating outside memory fails */ + if (ram_end != 0) { + ret = lmb_alloc_addr(&lmb, ram_end, 1); + ut_asserteq(ret, 0); + } + if (ram != 0) { + ret = lmb_alloc_addr(&lmb, ram - 1, 1); + ut_asserteq(ret, 0); + } + + return 0; +} + +static int lib_test_lmb_alloc_addr(struct unit_test_state *uts) +{ + int ret; + + /* simulate 512 MiB RAM beginning at 1GiB */ + ret = test_alloc_addr(uts, 0x40000000); + if (ret) + return ret; + + /* simulate 512 MiB RAM beginning at 1.5GiB */ + return test_alloc_addr(uts, 0xE0000000); +} + +DM_TEST(lib_test_lmb_alloc_addr, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Simulate 512 MiB RAM, reserve 3 blocks, check addresses in between */ +static int test_get_unreserved_size(struct unit_test_state *uts, + const phys_addr_t ram) +{ + const phys_size_t ram_size = 0x20000000; + const phys_addr_t ram_end = ram + ram_size; + const phys_size_t alloc_addr_a = ram + 0x8000000; + const phys_size_t alloc_addr_b = ram + 0x8000000 * 2; + const phys_size_t alloc_addr_c = ram + 0x8000000 * 3; + struct lmb lmb; + long ret; + phys_size_t s; + + /* check for overflow */ + ut_assert(ram_end == 0 || ram_end > ram); + + lmb_init(&lmb); + + ret = lmb_add(&lmb, ram, ram_size); + ut_asserteq(ret, 0); + + /* reserve 3 blocks */ + ret = lmb_reserve(&lmb, alloc_addr_a, 0x10000); + ut_asserteq(ret, 0); + ret = lmb_reserve(&lmb, alloc_addr_b, 0x10000); + ut_asserteq(ret, 0); + ret = lmb_reserve(&lmb, alloc_addr_c, 0x10000); + ut_asserteq(ret, 0); + ASSERT_LMB(&lmb, ram, ram_size, 3, alloc_addr_a, 0x10000, + alloc_addr_b, 0x10000, alloc_addr_c, 0x10000); + + /* check addresses in between blocks */ + s = lmb_get_unreserved_size(&lmb, ram); + ut_asserteq(s, alloc_addr_a - ram); + s = lmb_get_unreserved_size(&lmb, ram + 0x10000); + ut_asserteq(s, alloc_addr_a - ram - 0x10000); + s = lmb_get_unreserved_size(&lmb, alloc_addr_a - 4); + ut_asserteq(s, 4); + + s = lmb_get_unreserved_size(&lmb, alloc_addr_a + 0x10000); + ut_asserteq(s, alloc_addr_b - alloc_addr_a - 0x10000); + s = lmb_get_unreserved_size(&lmb, alloc_addr_a + 0x20000); + ut_asserteq(s, alloc_addr_b - alloc_addr_a - 0x20000); + s = lmb_get_unreserved_size(&lmb, alloc_addr_b - 4); + ut_asserteq(s, 4); + + s = lmb_get_unreserved_size(&lmb, alloc_addr_c + 0x10000); + ut_asserteq(s, ram_end - alloc_addr_c - 0x10000); + s = lmb_get_unreserved_size(&lmb, alloc_addr_c + 0x20000); + ut_asserteq(s, ram_end - alloc_addr_c - 0x20000); + s = lmb_get_unreserved_size(&lmb, ram_end - 4); + ut_asserteq(s, 4); + + return 0; +} + +static int lib_test_lmb_get_unreserved_size(struct unit_test_state *uts) +{ + int ret; + + /* simulate 512 MiB RAM beginning at 1GiB */ + ret = test_get_unreserved_size(uts, 0x40000000); + if (ret) + return ret; + + /* simulate 512 MiB RAM beginning at 1.5GiB */ + return test_get_unreserved_size(uts, 0xE0000000); +} + +DM_TEST(lib_test_lmb_get_unreserved_size, + DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); From patchwork Fri Dec 14 20:13:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Goldschmidt X-Patchwork-Id: 1013692 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="MInFy52w"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 43Ghhc05k6z9s47 for ; Sat, 15 Dec 2018 07:18:55 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id A8066C22031; Fri, 14 Dec 2018 20:17:17 +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_DNSWL_BLOCKED, 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 24FA5C221F9; Fri, 14 Dec 2018 20:14:49 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 7E8DAC221F9; Fri, 14 Dec 2018 20:14:20 +0000 (UTC) Received: from mail-wr1-f68.google.com (mail-wr1-f68.google.com [209.85.221.68]) by lists.denx.de (Postfix) with ESMTPS id 6BD78C221BA for ; Fri, 14 Dec 2018 20:14:16 +0000 (UTC) Received: by mail-wr1-f68.google.com with SMTP id x10so6600147wrs.8 for ; Fri, 14 Dec 2018 12:14:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=O5nrStCoM9dChZW6Cw+8dlod8jTspjACxyJpE1Xs8es=; b=MInFy52witwUlavHoHpF3OKJ6R1wmSUlQz7S82/dI3+VNlKgdRkFh7EJxE2sOh8ryA rCILTDaPGbk/j9d3ePBe8figmmlKm0dRsJTRIJ7ugrtXMsgYmixuaG1/yVtX3+BTnNl8 fqsjjHUJMrH1tgjyX8H97b3+m1UnEGkZyON/8mLQiFlk28SX0J3dF8gK1MBLdSUOknA3 uqdUEMgcWEUZbFW1tgxie3b72B5QTmSvOz1KgDipV7IZxZToSPVdMTVuBUg0HX6wBtJC /oQXEMs/19Z3w+bomvaeBME5LrwLGkuyNbZ21Yg55GywwYYXphgZLrWCg94pwRmkr2/6 0KQw== 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; bh=O5nrStCoM9dChZW6Cw+8dlod8jTspjACxyJpE1Xs8es=; b=Yn+uVxmMvrEiDJPeXH/61L4vF7l/4hMwnt+yuqZiGy7HYO4zYlEp6d96Ayt0k4g/9D Xyn62qUwW80EqWMc6zAgTFBIHiLP3czkfThiAnH6BE5/4RGvmfmMH9WqK/wKx/7UnsW4 ELGuk3DWvp+K1BBedsxVsqV8F84Gs0X08Er7YaH11oYI57hsEwdJcuugCQMCSBAsR6pT rlcXpk2CIx4S8d2KgF5ZwRvZtKur80X/xZ2XVMOtbPQ6UM3t9WU5AbUA2GCv4IbbDUfd e7Le3UmxlYFIZu0Ox+0pi8VlPt6pyvZKor4C150GvIRPvs0dcLAy9Jyti+uzqydDSstw CpYw== X-Gm-Message-State: AA+aEWZjdgcJgorDteRTqWWw3l0cXT0zd5XI5mJsj8lQ+oVyLpUqJj5f hrFbx2AxqgskG/QZ0hQqgQc= X-Google-Smtp-Source: AFSGD/X0NoTG4wdG1te6zYpmmar6ZzyVB5ydk5RkK/7MRIpeYOcpNJ65DGafzdTaLlX5j+vKf35ZNA== X-Received: by 2002:a5d:5443:: with SMTP id w3mr3457655wrv.4.1544818455996; Fri, 14 Dec 2018 12:14:15 -0800 (PST) Received: from ubuntu.home ([2a02:8071:6a3:700:80b1:ba3d:111a:23c5]) by smtp.gmail.com with ESMTPSA id h62sm4299843wmf.11.2018.12.14.12.14.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Dec 2018 12:14:15 -0800 (PST) From: Simon Goldschmidt To: Tom Rini , u-boot@lists.denx.de, Joe Hershberger Date: Fri, 14 Dec 2018 21:13:54 +0100 Message-Id: <20181214201357.26316-7-simon.k.r.goldschmidt@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> References: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> Cc: Heinrich Schuchardt , Alexander Graf , Andrea Barisani Subject: [U-Boot] [PATCH v6 6/9] fs: prevent overwriting reserved memory 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This fixes CVE-2018-18440 ("insufficient boundary checks in filesystem image load") by using lmb to check the load size of a file against reserved memory addresses. Signed-off-by: Simon Goldschmidt Reviewed-by: Simon Glass --- Changes in v6: - fixed NULL pointer access in 'fdt_blob' passed to 'boot_fdt_add_mem_rsv_regions' Changes in v5: None Changes in v4: None Changes in v2: None fs/fs.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++--- include/lmb.h | 2 ++ lib/lmb.c | 13 ++++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/fs/fs.c b/fs/fs.c index cb265174e2..400aa921a7 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -429,13 +429,57 @@ int fs_size(const char *filename, loff_t *size) return ret; } -int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len, - loff_t *actread) +#ifdef CONFIG_LMB +/* Check if a file may be read to the given address */ +static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset, + loff_t len, struct fstype_info *info) +{ + struct lmb lmb; + int ret; + loff_t size; + loff_t read_len; + + /* get the actual size of the file */ + ret = info->size(filename, &size); + if (ret) + return ret; + if (offset >= size) { + /* offset >= EOF, no bytes will be written */ + return 0; + } + read_len = size - offset; + + /* limit to 'len' if it is smaller */ + if (len && len < read_len) + read_len = len; + + lmb_init_and_reserve(&lmb, gd->bd->bi_dram[0].start, + gd->bd->bi_dram[0].size, (void *)gd->fdt_blob); + lmb_dump_all(&lmb); + + if (lmb_alloc_addr(&lmb, addr, read_len) == addr) + return 0; + + printf("** Reading file would overwrite reserved memory **\n"); + return -1; +} +#endif + +static int _fs_read(const char *filename, ulong addr, loff_t offset, loff_t len, + int do_lmb_check, loff_t *actread) { struct fstype_info *info = fs_get_info(fs_type); void *buf; int ret; +#ifdef CONFIG_LMB + if (do_lmb_check) { + ret = fs_read_lmb_check(filename, addr, offset, len, info); + if (ret) + return ret; + } +#endif + /* * We don't actually know how many bytes are being read, since len==0 * means read the whole file. @@ -452,6 +496,12 @@ int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len, return ret; } +int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len, + loff_t *actread) +{ + return _fs_read(filename, addr, offset, len, 0, actread); +} + int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len, loff_t *actwrite) { @@ -622,7 +672,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], pos = 0; time = get_timer(0); - ret = fs_read(filename, addr, pos, bytes, &len_read); + ret = _fs_read(filename, addr, pos, bytes, 1, &len_read); time = get_timer(time); if (ret < 0) return 1; diff --git a/include/lmb.h b/include/lmb.h index 7d7e2a78dc..62da85e716 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -31,6 +31,8 @@ struct lmb { extern struct lmb lmb; extern void lmb_init(struct lmb *lmb); +extern void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base, + phys_size_t size, void *fdt_blob); extern long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size); extern long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size); extern phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align); diff --git a/lib/lmb.c b/lib/lmb.c index e380a0a722..3407705fa7 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -98,6 +98,19 @@ void lmb_init(struct lmb *lmb) lmb->reserved.size = 0; } +/* Initialize the struct, add memory and call arch/board reserve functions */ +void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size, + void *fdt_blob) +{ + lmb_init(lmb); + lmb_add(lmb, base, size); + arch_lmb_reserve(lmb); + board_lmb_reserve(lmb); + + if (IMAGE_ENABLE_OF_LIBFDT && fdt_blob) + boot_fdt_add_mem_rsv_regions(lmb, fdt_blob); +} + /* This routine called with relocation disabled. */ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t size) { From patchwork Fri Dec 14 20:13:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Goldschmidt X-Patchwork-Id: 1013694 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="AD4BDayK"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 43Ghjf22QPz9s5c for ; Sat, 15 Dec 2018 07:19:50 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id B8458C22089; Fri, 14 Dec 2018 20:15:58 +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_DNSWL_BLOCKED, 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 290A1C22209; Fri, 14 Dec 2018 20:14:30 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 3B2C4C22149; Fri, 14 Dec 2018 20:14:21 +0000 (UTC) Received: from mail-wr1-f66.google.com (mail-wr1-f66.google.com [209.85.221.66]) by lists.denx.de (Postfix) with ESMTPS id 97840C21FFE for ; Fri, 14 Dec 2018 20:14:17 +0000 (UTC) Received: by mail-wr1-f66.google.com with SMTP id v13so6604718wrw.5 for ; Fri, 14 Dec 2018 12:14:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=j+ihmg1v/juP4dqjG8kCUYyzjHmYlcbZb0Oz+M2t9tA=; b=AD4BDayK3MS+AkwRarBImL3lhsCH+ewwHm0zOoPtoGsyDEAgeP0Ys7lJ3gE4iz5XF8 VTdMlGPM9RN/C26CBAceRmHNgacVA4XYp8ZYv0KNnmnTXMVs3W6VC9XZ5w8OIBZbb+UG ITyMTpElhJucH4SM1RaEVSz3HMqsZpMHq3EzuFL2Ue91a3AfzQA+hVAJmduG4ouWVf2f 48ZzTUH9e3FK/GXn2si025YAw7V2n3KoFoB4P+6eAVmFCMKy4djnA93SE33pos0aNX72 wT1apzX94S3ewZrezsOb3lBdM1cgnspHIUKfruoAQqClOjx5tuYTuLfNCvT+WtLn1sDC ShfA== 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; bh=j+ihmg1v/juP4dqjG8kCUYyzjHmYlcbZb0Oz+M2t9tA=; b=YHbURF6PVtGWlarKpkKdvE3ALu+SR7hDuomuDoMUFRAShth+QFqzS9/D7g7kTlutw0 mT0+gPMpV9xJIg3Cfcjnfjc2Yal63pkGv6r6sdt4CxITR4uRkzAFDM30c/inTgfwBwkT Ug8OOOCX+o3ti8u/ABwkyLHprlpQkpTAnopQB4k5CpRY622eWupIjPktGbTf6v4vFKSx k8IAD1Oal+FlDAlXttZ1Azmbdp3tMyUJMvwwA1aTXX52CkQkPaL1vlx05Fq42RBVEakX LaKNunbcarDJsYhoxNBes3WTaDQh769abPf1cH5w82AwW+hcGMAxcxsa82r04picYA1/ 9dHA== X-Gm-Message-State: AA+aEWZpEB0x1Z3JqD+iSZojIHmxM6Keezwu1K8pPEEkQP8MWYY1D/88 6j5baHekfxvtZ8prxKkPmAE= X-Google-Smtp-Source: AFSGD/XX4D+SDShi9C6kowSN0EpNmNpugn+FodX+q3c0oUgc5gR7KjFwWgmRcOJleqAFU5oGbzCAJQ== X-Received: by 2002:adf:dbcb:: with SMTP id e11mr3877178wrj.58.1544818457272; Fri, 14 Dec 2018 12:14:17 -0800 (PST) Received: from ubuntu.home ([2a02:8071:6a3:700:80b1:ba3d:111a:23c5]) by smtp.gmail.com with ESMTPSA id h62sm4299843wmf.11.2018.12.14.12.14.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Dec 2018 12:14:16 -0800 (PST) From: Simon Goldschmidt To: Tom Rini , u-boot@lists.denx.de, Joe Hershberger Date: Fri, 14 Dec 2018 21:13:55 +0100 Message-Id: <20181214201357.26316-8-simon.k.r.goldschmidt@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> References: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> Cc: Heinrich Schuchardt , Alexander Graf , Andrea Barisani Subject: [U-Boot] [PATCH v6 7/9] bootm: use new common function lmb_init_and_reserve 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This reduces duplicate code only. Signed-off-by: Simon Goldschmidt Reviewed-by: Simon Glass --- Changes in v6: None Changes in v5: None Changes in v4: None Changes in v2: None common/bootm.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/common/bootm.c b/common/bootm.c index 8bf84ebcb7..31e4f0f794 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -56,15 +56,11 @@ static void boot_start_lmb(bootm_headers_t *images) ulong mem_start; phys_size_t mem_size; - lmb_init(&images->lmb); - mem_start = env_get_bootm_low(); mem_size = env_get_bootm_size(); - lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size); - - arch_lmb_reserve(&images->lmb); - board_lmb_reserve(&images->lmb); + lmb_init_and_reserve(&images->lmb, (phys_addr_t)mem_start, mem_size, + NULL); } #else #define lmb_reserve(lmb, base, size) From patchwork Fri Dec 14 20:13:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Goldschmidt X-Patchwork-Id: 1013695 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="J7OME3JN"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 43GhkB2tZHz9s5c for ; Sat, 15 Dec 2018 07:20:18 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 0F5E2C22159; Fri, 14 Dec 2018 20:17:01 +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_DNSWL_BLOCKED, 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 4F991C2220A; Fri, 14 Dec 2018 20:14:48 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 22AA3C22185; Fri, 14 Dec 2018 20:14:22 +0000 (UTC) Received: from mail-wr1-f66.google.com (mail-wr1-f66.google.com [209.85.221.66]) by lists.denx.de (Postfix) with ESMTPS id 9F25CC221D1 for ; Fri, 14 Dec 2018 20:14:18 +0000 (UTC) Received: by mail-wr1-f66.google.com with SMTP id p4so6597441wrt.7 for ; Fri, 14 Dec 2018 12:14:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=fPB4VzH4b1TTPh0CPG0qfAK4NoksM8o7d7KeDg6fSXA=; b=J7OME3JNZWaB06tjt/AkSRiB0xhGMzlx7XJZHnwi4jQCyhaNAPpqdkra/8A6/8EYTj nR6J1G/hZxaBLyhGZfMOJWEA5deI+W5JZObfFLb/YKSvMiBa/GDxkXceYRLquAjTHM9v y3P71hScdopV9KEhp9kD1QiV94+lvDiS8DSRD99BrD0z8DoSidbID8f9o8MH94KMy4lO 4Ws7xVHv5FT56Vmz2uCi5belY9GrrAg7+xHpnITgLh4suY+jylOHM7RVyGPOynop9BTI LlWwPswbP+2hh70LUoUGf3ZiukukY5FTPRyzXs/kgDaVTCi/GI7Y2jyt2MrUYzYb5LUy WfZQ== 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; bh=fPB4VzH4b1TTPh0CPG0qfAK4NoksM8o7d7KeDg6fSXA=; b=Md8CwHuqW3Hbb9gfJ5uop9KdEUhp+dRaQbZIZU7HrpPtzsLKWciY76byppG1eshRO6 5dmaCiZFRqfltXT42jOI/Es7BFO8cefJcythI1bdtczDrZfWhH1jDFIKbMQbtjgPtzql 9QUOn7MgmIMBBBDrTX6d5YISvIFdsL39/tdsEe6TuK9m4FlQlgddrIXkT+2JJRrouZeT IxXvLb2QxyPCRrdqCs3Dv6IcL+B9WNuKOsTr3TB37ZlpeorvyC/KMMZ80XrgtTgmBVT0 qK/pCw/sslk6ij1S7MurePmfBDbI/+Jbex2ImMSBss31cK5Gi/ayZb5gbvgq/Wg9YCq3 S7dQ== X-Gm-Message-State: AA+aEWYaNTyd9Laqbq18Uh9P85N/9gLJ+nE2ehY/Thcq5TWAEoU3yyLB 4qMfxtb+/O7T31hbwTEDhYE= X-Google-Smtp-Source: AFSGD/UK7vcmWP9F2Mm1rqoh8c2qmMcxsqSyUth1d7anUkgMkndfWv4jylrpWAx2rQ7AbkxtVTIKaw== X-Received: by 2002:a5d:4f10:: with SMTP id c16mr3823732wru.177.1544818458368; Fri, 14 Dec 2018 12:14:18 -0800 (PST) Received: from ubuntu.home ([2a02:8071:6a3:700:80b1:ba3d:111a:23c5]) by smtp.gmail.com with ESMTPSA id h62sm4299843wmf.11.2018.12.14.12.14.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Dec 2018 12:14:17 -0800 (PST) From: Simon Goldschmidt To: Tom Rini , u-boot@lists.denx.de, Joe Hershberger Date: Fri, 14 Dec 2018 21:13:56 +0100 Message-Id: <20181214201357.26316-9-simon.k.r.goldschmidt@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> References: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> Cc: Heinrich Schuchardt , Andrea Barisani Subject: [U-Boot] [PATCH v6 8/9] lmb: remove unused extern declaration 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" lmb.h includes an extern declaration of "struct lmb lmb;" which is not used anywhere, so remove it. Signed-off-by: Simon Goldschmidt --- Changes in v6: None Changes in v5: None Changes in v4: None Changes in v2: - this patch is new in v2 include/lmb.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/lmb.h b/include/lmb.h index 62da85e716..1bb003e35e 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -28,8 +28,6 @@ struct lmb { struct lmb_region reserved; }; -extern struct lmb lmb; - extern void lmb_init(struct lmb *lmb); extern void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size, void *fdt_blob); From patchwork Fri Dec 14 20:13:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Goldschmidt X-Patchwork-Id: 1013696 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="Mc4riAUJ"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 43GhkD2nYpz9s5c for ; Sat, 15 Dec 2018 07:20:20 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 25B97C2214F; Fri, 14 Dec 2018 20:16:15 +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_DNSWL_BLOCKED, 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 49F9DC2211E; Fri, 14 Dec 2018 20:14:33 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 433A7C2204B; Fri, 14 Dec 2018 20:14:23 +0000 (UTC) Received: from mail-wr1-f67.google.com (mail-wr1-f67.google.com [209.85.221.67]) by lists.denx.de (Postfix) with ESMTPS id D3898C221E7 for ; Fri, 14 Dec 2018 20:14:19 +0000 (UTC) Received: by mail-wr1-f67.google.com with SMTP id q18so6601346wrx.9 for ; Fri, 14 Dec 2018 12:14:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=W99xjx2hmoJlqybu68X4WssZew8+O5++gjP/9SK6Vic=; b=Mc4riAUJxut4OmjhqObgEcoHbWxbrPlJld+BWi2K2xQRe2aevJ5Oors16Of5hALH0A lqqPHZWgpDHFzZ8vwj6ETuHuRHI8K5bDYbvRV04OIzHcdFBAEJa6Zltm1xirqv1GLSok ottb2LiP7gFPTOV0imXJsCPZWQnConyFNsh350YLTbzW5Nr3gTlxossRQg17IZMhcXiB Kim8pzMQe6Dca5W+RVvbxj1BwZtcsIkL56LbQ8tBx1ojib2OOAboxUcdkZvvd6eactYk 50a3VauwJ0JPEwGVMAwzmQ3fAT21A7BOl+I+dFdDIA1iVBBDMervyKrkxhyQtDPL1Bhq 2Ugw== 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; bh=W99xjx2hmoJlqybu68X4WssZew8+O5++gjP/9SK6Vic=; b=mDE9Wn0+SlbU33uegP+yfURCskY1k3QlI8SlqdoX7yO8XCMvbJkT8Ig95/DiObPCPL XDDS3t3JN6Q9E4xO9SnkXl6VfVs1nrMKcCtNiIvSZTaIBmxytCXvcQDUxpQYH3mvWtCo eXm9HIdbMW6ZsVdDLD33m5nLnA1t6S0Pn39/YJt7nh4PNBFE7bIHFZpk7LK5YbAqC7TB buxgu2ScsU0Gll6V8/lXGCLI9ayvL+76ihIdkwvT5tb3fchRL7FOEv5zZ5QYHDEdqswo EEQhN0wCIWdqMkRZMPvUvEIB8ju7xKDWpL+orMo36GJHJRlxcgS6Jow4A6S6CU2d0V0o Bjkw== X-Gm-Message-State: AA+aEWaaZBc07JtYiWRK0PrQncqTpOrWO71EY35BR5O2WvBCU23SlR9M jTQycQWvlp5J3MrXwmrZF4A= X-Google-Smtp-Source: AFSGD/VfzKlaNkzuFB1KzZZiQ7oMQTMYwIy3ppPMHPD0cdNtNnR7Whl920Dg0+vo0zcwR7hl7rHESQ== X-Received: by 2002:adf:9d85:: with SMTP id p5mr3517195wre.41.1544818459503; Fri, 14 Dec 2018 12:14:19 -0800 (PST) Received: from ubuntu.home ([2a02:8071:6a3:700:80b1:ba3d:111a:23c5]) by smtp.gmail.com with ESMTPSA id h62sm4299843wmf.11.2018.12.14.12.14.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Dec 2018 12:14:18 -0800 (PST) From: Simon Goldschmidt To: Tom Rini , u-boot@lists.denx.de, Joe Hershberger Date: Fri, 14 Dec 2018 21:13:57 +0100 Message-Id: <20181214201357.26316-10-simon.k.r.goldschmidt@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> References: <20181214201357.26316-1-simon.k.r.goldschmidt@gmail.com> Cc: Heinrich Schuchardt , Andrea Barisani Subject: [U-Boot] [PATCH v6 9/9] tftp: prevent overwriting reserved memory 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This fixes CVE-2018-18439 ("insufficient boundary checks in network image boot") by using lmb to check for a valid range to store received blocks. Signed-off-by: Simon Goldschmidt --- Changes in v6: None Changes in v5: None Changes in v4: - this was patch 8, is now patch 7 - lines changed because v3 patch 7 got removed and MCAST_TFTP still exists Changes in v2: - this patch is new in v2 net/tftp.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/net/tftp.c b/net/tftp.c index 68ffd81414..d31364166e 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -17,6 +17,8 @@ #include #endif +DECLARE_GLOBAL_DATA_PTR; + /* Well known TFTP port # */ #define WELL_KNOWN_PORT 69 /* Millisecs to timeout for lost pkt */ @@ -81,6 +83,8 @@ static ulong tftp_block_wrap; /* memory offset due to wrapping */ static ulong tftp_block_wrap_offset; static int tftp_state; +static ulong tftp_load_addr; +static ulong tftp_load_size; #ifdef CONFIG_TFTP_TSIZE /* The file size reported by the server */ static int tftp_tsize; @@ -164,10 +168,11 @@ static void mcast_cleanup(void) #endif /* CONFIG_MCAST_TFTP */ -static inline void store_block(int block, uchar *src, unsigned len) +static inline int store_block(int block, uchar *src, unsigned int len) { ulong offset = block * tftp_block_size + tftp_block_wrap_offset; ulong newsize = offset + len; + ulong store_addr = tftp_load_addr + offset; #ifdef CONFIG_SYS_DIRECT_FLASH_TFTP int i, rc = 0; @@ -175,24 +180,30 @@ static inline void store_block(int block, uchar *src, unsigned len) /* start address in flash? */ if (flash_info[i].flash_id == FLASH_UNKNOWN) continue; - if (load_addr + offset >= flash_info[i].start[0]) { + if (store_addr >= flash_info[i].start[0]) { rc = 1; break; } } if (rc) { /* Flash is destination for this packet */ - rc = flash_write((char *)src, (ulong)(load_addr+offset), len); + rc = flash_write((char *)src, store_addr, len); if (rc) { flash_perror(rc); - net_set_state(NETLOOP_FAIL); - return; + return rc; } } else #endif /* CONFIG_SYS_DIRECT_FLASH_TFTP */ { - void *ptr = map_sysmem(load_addr + offset, len); + void *ptr; + if (store_addr < tftp_load_addr || + store_addr + len > tftp_load_addr + tftp_load_size) { + puts("\nTFTP error: "); + puts("trying to overwrite reserved memory...\n"); + return -1; + } + ptr = map_sysmem(store_addr, len); memcpy(ptr, src, len); unmap_sysmem(ptr); } @@ -203,6 +214,8 @@ static inline void store_block(int block, uchar *src, unsigned len) if (net_boot_file_size < newsize) net_boot_file_size = newsize; + + return 0; } /* Clear our state ready for a new transfer */ @@ -606,7 +619,11 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip, timeout_count_max = tftp_timeout_count_max; net_set_timeout_handler(timeout_ms, tftp_timeout_handler); - store_block(tftp_cur_block - 1, pkt + 2, len); + if (store_block(tftp_cur_block - 1, pkt + 2, len)) { + eth_halt(); + net_set_state(NETLOOP_FAIL); + break; + } /* * Acknowledge the block just received, which will prompt @@ -695,6 +712,24 @@ static void tftp_timeout_handler(void) } } +/* Initialize tftp_load_addr and tftp_load_size from load_addr and lmb */ +static int tftp_init_load_addr(void) +{ + struct lmb lmb; + phys_size_t max_size; + + tftp_load_addr = load_addr; + + lmb_init_and_reserve(&lmb, gd->bd->bi_dram[0].start, + gd->bd->bi_dram[0].size, (void *)gd->fdt_blob); + + max_size = lmb_get_unreserved_size(&lmb, tftp_load_addr); + if (!max_size) + return -1; + + tftp_load_size = max_size; + return 0; +} void tftp_start(enum proto_t protocol) { @@ -791,7 +826,14 @@ void tftp_start(enum proto_t protocol) } else #endif { - printf("Load address: 0x%lx\n", load_addr); + if (tftp_init_load_addr()) { + eth_halt(); + net_set_state(NETLOOP_FAIL); + puts("\nTFTP error: "); + puts("trying to overwrite reserved memory...\n"); + return; + } + printf("Load address: 0x%lx\n", tftp_load_addr); puts("Loading: *\b"); tftp_state = STATE_SEND_RRQ; #ifdef CONFIG_CMD_BOOTEFI @@ -842,9 +884,15 @@ void tftp_start_server(void) { tftp_filename[0] = 0; + if (tftp_init_load_addr()) { + eth_halt(); + net_set_state(NETLOOP_FAIL); + puts("\nTFTP error: trying to overwrite reserved memory...\n"); + return; + } printf("Using %s device\n", eth_get_name()); printf("Listening for TFTP transfer on %pI4\n", &net_ip); - printf("Load address: 0x%lx\n", load_addr); + printf("Load address: 0x%lx\n", tftp_load_addr); puts("Loading: *\b");