From patchwork Thu Feb 13 13:11:01 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 864824 Delivered-To: patch@linaro.org Received: by 2002:a5d:47a6:0:b0:38f:210b:807b with SMTP id 6csp415953wrb; Thu, 13 Feb 2025 05:11:43 -0800 (PST) X-Forwarded-Encrypted: i=2; AJvYcCWcxPSuGJn96Kb918Q6G/1rnzO35f6FaFrRIIWahzkfhN5j618vo4HA3/GsWLFWod1EBgbHgg==@linaro.org X-Google-Smtp-Source: AGHT+IHURkFgvO6o3PoamfH7Ylf7T7i2JJtJXK9Iat3IdDjq7k4PkL2THFI0hk/4uzCkaPJej05g X-Received: by 2002:a05:6000:1a8b:b0:38d:d8b2:cf14 with SMTP id ffacd0b85a97d-38dea28cffemr6749330f8f.30.1739452303379; Thu, 13 Feb 2025 05:11:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1739452303; cv=none; d=google.com; s=arc-20240605; b=WsxsLStC2oACPoWicGUYBzFe8hr8xFTTUVuc5m7UfyboIrOaKjbpB88CRtNM4kTnqJ xeMgt3ShI3nIR7kzoN///SqTnCgjgYs2Vbi768gaXhkaLSVKHqH6F09mZrWwtQ8T7SaL gTqJpX7AiM9+0ixUibDgg+jBzZ/YJDd82BbvwgD9oJ6+gpOd1Rendkfgg/yE4WAw8x8z KFl7iLysYSIvBvV0ZN4vp0vGc4TU7DSAuWrVq5EUvJEcu3h9JST2bmZXXIhvUKTFu8ok DGT3OFY0+z9Xac7DCpvEtjcJCmAhCkVdy5uoY/rdqgH8qs5VXziPWtPDgagnStPJ9LXQ IeSQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from; bh=h9uR4GsbgrGeSYDg/CsobnX8QhSRKKKzC7cT+Zwf9q8=; fh=2HGKihHUAicyV3F+aHiaoPpwvqWA0zlC04Ew6QaQoEg=; b=TX1IH1Qhj28+lq+KiyW8KZNQohUNQsS+vVQKHpRGksd6diraFiJh9kzrsl7LeRWDWa /ozxCu0dx2/AuxclnPBCXG8oGjVQgjXV/jbyJa98Ybk4rfekWYUD6ORBkVyr/7aDiRuV z/TpVfy/+UkbQp0Ini8rAE73Cd1Gg1/5VVSTFlPoNkpzVJrIn9cBXTAS3n1+I7WM4PZZ SRSb4ktM0hWI5kkfsW7SGnkM6mQiPkju0szRHfK0gjccdF3W6bRq+8FAvcm4RUIfylG+ eBiE56GJuYZC+UBeKt8qWliNylnBxpY0ReoDvw2QR2ejP3Na+7rHnOZ5bvAxv2V8ZIH4 7Ewg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id ffacd0b85a97d-38f25a2967bsi1399100f8f.728.2025.02.13.05.11.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Feb 2025 05:11:43 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 8D8D380ECC; Thu, 13 Feb 2025 14:11:39 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 2C2BE806FE; Thu, 13 Feb 2025 14:11:38 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE,SPF_SOFTFAIL autolearn=no autolearn_force=no version=3.4.2 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by phobos.denx.de (Postfix) with ESMTP id D4D9C80E94 for ; Thu, 13 Feb 2025 14:11:35 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sughosh.ganu@linaro.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 03E5016F3; Thu, 13 Feb 2025 05:11:56 -0800 (PST) Received: from a079122.blr.arm.com (a079122.arm.com [10.162.17.48]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A6FCE3F58B; Thu, 13 Feb 2025 05:11:32 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Ilias Apalodimas , Simon Glass , Tom Rini , Quentin Schulz , Udit Kumar , Heinrich Schuchardt , Sughosh Ganu Subject: [PATCH 1/4] lmb: check if a region can be reserved by lmb_reserve() Date: Thu, 13 Feb 2025 18:41:01 +0530 Message-Id: <20250213131104.186663-2-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250213131104.186663-1-sughosh.ganu@linaro.org> References: <20250213131104.186663-1-sughosh.ganu@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean The logic used in lmb_alloc() takes into consideration the existing reserved regions, and ensures that the allocated region does not overlap with any existing allocated regions. The lmb_reserve() function is not doing any such checks -- the requested region might overlap with an existing region. This also shows up with lmb_alloc_addr() as this function ends up calling lmb_reserve(). Add a function which checks if the region requested is overlapping with an existing reserved region, and allow for the reservation to happen only if both the regions have LMB_NONE flag, which allows re-requesting of the region. In any other scenario of an overlap, have lmb_reserve() return -EEXIST, implying that the requested region is already reserved. Also add corresponding test cases which checks for overlapping reservation requests made through lmb_reserve() and lmb_alloc_addr(). Signed-off-by: Sughosh Ganu --- lib/lmb.c | 23 ++++++++++++ test/lib/lmb.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 122 insertions(+), 1 deletion(-) diff --git a/lib/lmb.c b/lib/lmb.c index 7ca44591e1d..aeaf120f57d 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -595,6 +595,26 @@ static __maybe_unused void lmb_reserve_common_spl(void) } } +static bool lmb_can_reserve_region(phys_addr_t base, phys_size_t size, + u32 flags) +{ + uint i; + struct lmb_region *lmb_reserved = lmb.used_mem.data; + + for (i = 0; i < lmb.used_mem.count; i++) { + u32 rgnflags = lmb_reserved[i].flags; + phys_addr_t rgnbase = lmb_reserved[i].base; + phys_size_t rgnsize = lmb_reserved[i].size; + + if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { + if (flags != LMB_NONE || flags != rgnflags) + return false; + } + } + + return true; +} + void lmb_add_memory(void) { int i; @@ -667,6 +687,9 @@ long lmb_reserve(phys_addr_t base, phys_size_t size, u32 flags) long ret = 0; struct alist *lmb_rgn_lst = &lmb.used_mem; + if (!lmb_can_reserve_region(base, size, flags)) + return -EEXIST; + ret = lmb_add_region_flags(lmb_rgn_lst, base, size, flags); if (ret) return ret; diff --git a/test/lib/lmb.c b/test/lib/lmb.c index fcb5f1af532..6b995c976dd 100644 --- a/test/lib/lmb.c +++ b/test/lib/lmb.c @@ -499,6 +499,32 @@ static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40000000, 0x40000, 0, 0, 0, 0); + /* try to allocate overlapping region with a different flag, should fail */ + ret = lmb_reserve(0x40008000, 0x1000, LMB_NOOVERWRITE); + ut_asserteq(ret, -EEXIST); + + /* allocate another region at 0x40050000 with a different flag */ + ret = lmb_reserve(0x40050000, 0x10000, LMB_NOOVERWRITE); + ut_asserteq(ret, 0); + ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, 0x40000000, 0x40000, + 0x40050000, 0x10000, 0, 0); + + /* + * try to allocate a region adjacent to region 1 overlapping the 2nd region, + * should fail + */ + ret = lmb_reserve(0x40040000, 0x20000, LMB_NONE); + ut_asserteq(ret, -EEXIST); + + /* + * try to allocate a region between the two regions, but without an overlap, + * should succeed. this added region coalesces with the region 1 + */ + ret = lmb_reserve(0x40040000, 0x10000, LMB_NONE); + ut_asserteq(ret, 0); + ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, 0x40000000, 0x50000, + 0x40050000, 0x10000, 0, 0); + lmb_pop(&store); return 0; @@ -549,6 +575,78 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) ret = lmb_free(alloc_addr_a, 0x1000); ut_asserteq(ret, 0); + /* + * Add two regions with different flags, region1 and region2 with + * a gap between them. + * Try adding another region, adjacent to region 1 and overlapping + * region 2. Should fail. + */ + a = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NONE); + ut_asserteq(a, alloc_addr_a); + + b = lmb_alloc_addr(alloc_addr_a + 0x4000, 0x1000, LMB_NOOVERWRITE); + ut_asserteq(b, alloc_addr_a + 0x4000); + ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, a, 0x1000, + b, 0x1000, 0, 0); + + c = lmb_alloc_addr(alloc_addr_a + 0x1000, 0x5000, LMB_NONE); + ut_asserteq(c, 0); + ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, a, 0x1000, + b, 0x1000, 0, 0); + + ret = lmb_free(a, 0x1000); + ut_asserteq(ret, 0); + ret = lmb_free(b, 0x1000); + ut_asserteq(ret, 0); + + + /* + * Add two regions with same flags(LMB_NONE), region1 and region2 + * with a gap between them. + * Try adding another region, adjacent to region 1 and overlapping + * region 2. Should succeed. All regions should coalesce into a + * single region. + */ + a = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NONE); + ut_asserteq(a, alloc_addr_a); + + b = lmb_alloc_addr(alloc_addr_a + 0x4000, 0x1000, LMB_NONE); + ut_asserteq(b, alloc_addr_a + 0x4000); + ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, a, 0x1000, + b, 0x1000, 0, 0); + + c = lmb_alloc_addr(alloc_addr_a + 0x1000, 0x5000, LMB_NONE); + ut_asserteq(c, alloc_addr_a + 0x1000); + ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, a, 0x6000, + 0, 0, 0, 0); + + ret = lmb_free(a, 0x6000); + ut_asserteq(ret, 0); + + /* + * Add two regions with same flags(LMB_NOOVERWRITE), region1 and + * region2 with a gap between them. + * Try adding another region, adjacent to region 1 and overlapping + * region 2. Should fail. + */ + a = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NOOVERWRITE); + ut_asserteq(a, alloc_addr_a); + + b = lmb_alloc_addr(alloc_addr_a + 0x4000, 0x1000, LMB_NOOVERWRITE); + ut_asserteq(b, alloc_addr_a + 0x4000); + ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, a, 0x1000, + b, 0x1000, 0, 0); + + c = lmb_alloc_addr(alloc_addr_a + 0x1000, 0x5000, LMB_NOOVERWRITE); + ut_asserteq(c, 0); + ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, a, 0x1000, + b, 0x1000, 0, 0); + + ret = lmb_free(a, 0x1000); + ut_asserteq(ret, 0); + ret = lmb_free(b, 0x1000); + ut_asserteq(ret, 0); + /* reserve 3 blocks */ ret = lmb_reserve(alloc_addr_a, 0x10000, LMB_NONE); ut_asserteq(ret, 0); @@ -760,7 +858,7 @@ static int lib_test_lmb_flags(struct unit_test_state *uts) /* reserve again, new flag */ ret = lmb_reserve(0x40010000, 0x10000, LMB_NONE); - ut_asserteq(ret, -1); + ut_asserteq(ret, -EEXIST); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40010000, 0x10000, 0, 0, 0, 0);