From: Marc Zyngier <maz@kernel.org>
To: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Cc: Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>, Ard Biesheuvel <ardb@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
James Morse <james.morse@arm.com>,
Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
Hanjun Guo <guohanjun@huawei.com>,
Sudeep Holla <sudeep.holla@arm.com>,
Eric Biederman <ebiederm@xmission.com>,
Bhupesh SHARMA <bhupesh.sharma@linaro.org>,
AKASHI Takahiro <takahiro.akashi@linaro.org>,
Dave Young <dyoung@redhat.com>,
Andrew Morton <akpm@linux-foundation.org>,
Moritz Fischer <mdf@kernel.org>,
kernel-team@android.com
Subject: [PATCH v2 3/5] kernel/resource: Allow find_next_iomem_res() to exclude overlapping child resources
Date: Mon, 31 May 2021 10:57:18 +0100 [thread overview]
Message-ID: <20210531095720.77469-4-maz@kernel.org> (raw)
In-Reply-To: <20210531095720.77469-1-maz@kernel.org>
find_next_iomem_res() returns the first resource that matches the
input parameters (range, flags, desc). It however ignores any
sub-resource that may invalidate the usefulness of such resource.
Allow find_next_iomem_res() to filter out such sub-resources and
wire it into the callers. As nobody is interested in this type
of filtering yet, there shouldn't be any functional change.
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
kernel/resource.c | 67 ++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 58 insertions(+), 9 deletions(-)
diff --git a/kernel/resource.c b/kernel/resource.c
index ca9f5198a01f..0e4d2ca763cd 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -318,6 +318,42 @@ int release_resource(struct resource *old)
EXPORT_SYMBOL(release_resource);
+static int exclude_overlapping_child_res(struct resource *res,
+ struct resource *child)
+{
+ struct resource cursor = *res;
+
+ for (; child; child = child->sibling) {
+ if (!resource_overlaps(&cursor, child))
+ continue;
+
+ if (cursor.start < child->start) {
+ *res = (struct resource) {
+ .start = cursor.start,
+ .end = child->start - 1,
+ .flags = res->flags,
+ .desc = res->desc,
+ .parent = res->parent,
+ };
+
+ return 0;
+ }
+
+ /*
+ * This may result in a resource with a negative size
+ * at the very end of the loop.
+ */
+ cursor.start = child->end + 1;
+ }
+
+ if (cursor.start <= cursor.end) {
+ *res = cursor;
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
/**
* find_next_iomem_res - Finds the lowest iomem resource that covers part of
* [@start..@end].
@@ -330,6 +366,7 @@ EXPORT_SYMBOL(release_resource);
* @end: end address of same resource
* @flags: flags which the resource must have
* @desc: descriptor the resource must have
+ * @exclude_child_res: exclude parts of resource that have overlapping children
* @res: return ptr, if resource found
*
* The caller must specify @start, @end, @flags, and @desc
@@ -337,7 +374,7 @@ EXPORT_SYMBOL(release_resource);
*/
static int find_next_iomem_res(resource_size_t start, resource_size_t end,
unsigned long flags, unsigned long desc,
- struct resource *res)
+ bool exclude_child_res, struct resource *res)
{
struct resource *p;
@@ -348,7 +385,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end,
return -EINVAL;
read_lock(&resource_lock);
-
+again:
for (p = iomem_resource.child; p; p = next_resource(p)) {
/* If we passed the resource we are looking for, stop */
if (p->start > end) {
@@ -378,6 +415,15 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end,
.desc = p->desc,
.parent = p->parent,
};
+
+ if (exclude_child_res &&
+ exclude_overlapping_child_res(res, p->child)) {
+ start = res->end + 1;
+ if (start >= end)
+ p = NULL;
+ else
+ goto again;
+ }
}
read_unlock(&resource_lock);
@@ -386,6 +432,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end,
static int __walk_iomem_res_desc(resource_size_t start, resource_size_t end,
unsigned long flags, unsigned long desc,
+ bool exclude_child_res,
void *arg,
int (*func)(struct resource *, void *))
{
@@ -393,7 +440,8 @@ static int __walk_iomem_res_desc(resource_size_t start, resource_size_t end,
int ret = -EINVAL;
while (start < end &&
- !find_next_iomem_res(start, end, flags, desc, &res)) {
+ !find_next_iomem_res(start, end, flags, desc,
+ exclude_child_res, &res)) {
ret = (*func)(&res, arg);
if (ret)
break;
@@ -424,7 +472,7 @@ static int __walk_iomem_res_desc(resource_size_t start, resource_size_t end,
int walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start,
u64 end, void *arg, int (*func)(struct resource *, void *))
{
- return __walk_iomem_res_desc(start, end, flags, desc, arg, func);
+ return __walk_iomem_res_desc(start, end, flags, desc, false, arg, func);
}
EXPORT_SYMBOL_GPL(walk_iomem_res_desc);
@@ -440,8 +488,8 @@ int walk_system_ram_res(u64 start, u64 end, void *arg,
{
unsigned long flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
- return __walk_iomem_res_desc(start, end, flags, IORES_DESC_NONE, arg,
- func);
+ return __walk_iomem_res_desc(start, end, flags, IORES_DESC_NONE,
+ false, arg, func);
}
/*
@@ -453,8 +501,8 @@ int walk_mem_res(u64 start, u64 end, void *arg,
{
unsigned long flags = IORESOURCE_MEM | IORESOURCE_BUSY;
- return __walk_iomem_res_desc(start, end, flags, IORES_DESC_NONE, arg,
- func);
+ return __walk_iomem_res_desc(start, end, flags, IORES_DESC_NONE,
+ false, arg, func);
}
/*
@@ -475,7 +523,8 @@ int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
end = ((u64)(start_pfn + nr_pages) << PAGE_SHIFT) - 1;
flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
while (start < end &&
- !find_next_iomem_res(start, end, flags, IORES_DESC_NONE, &res)) {
+ !find_next_iomem_res(start, end, flags, IORES_DESC_NONE,
+ false, &res)) {
pfn = PFN_UP(res.start);
end_pfn = PFN_DOWN(res.end + 1);
if (end_pfn > pfn)
--
2.30.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2021-05-31 10:00 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-31 9:57 [PATCH v2 0/5] arm64: Make kexec_file_load honor iomem reservations Marc Zyngier
2021-05-31 9:57 ` [PATCH v2 1/5] arm64: kexec_file: Forbid non-crash kernels Marc Zyngier
2021-05-31 19:37 ` Ard Biesheuvel
2021-06-01 8:36 ` Marc Zyngier
2021-06-04 16:20 ` James Morse
2021-05-31 9:57 ` [PATCH v2 2/5] kexec_file: Make locate_mem_hole_callback global Marc Zyngier
2021-05-31 9:57 ` Marc Zyngier [this message]
2021-05-31 9:57 ` [PATCH v2 4/5] kernel/resource: Introduce walk_system_ram_excluding_child_res() Marc Zyngier
2021-05-31 9:57 ` [PATCH v2 5/5] arm64: kexec_image: Restore full kexec functionnality Marc Zyngier
2021-05-31 19:36 ` [PATCH v2 0/5] arm64: Make kexec_file_load honor iomem reservations Ard Biesheuvel
2021-06-04 16:20 ` James Morse
2021-06-09 22:39 ` Moritz Fischer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210531095720.77469-4-maz@kernel.org \
--to=maz@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=ardb@kernel.org \
--cc=bhupesh.sharma@linaro.org \
--cc=catalin.marinas@arm.com \
--cc=dyoung@redhat.com \
--cc=ebiederm@xmission.com \
--cc=guohanjun@huawei.com \
--cc=james.morse@arm.com \
--cc=kernel-team@android.com \
--cc=kexec@lists.infradead.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lorenzo.pieralisi@arm.com \
--cc=mark.rutland@arm.com \
--cc=mdf@kernel.org \
--cc=sudeep.holla@arm.com \
--cc=takahiro.akashi@linaro.org \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).