// SPDX-License-Identifier: GPL-2.0-only
/*
 *	linux/kernel/resource.c
 *
 * Copyright (C) 1999	Linus Torvalds
 * Copyright (C) 1999	Martin Mares <mj@ucw.cz>
 *
 * Arbitrary resource management.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/export.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/pseudo_fs.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/device.h>
#include <linux/pfn.h>
#include <linux/mm.h>
#include <linux/mount.h>
#include <linux/resource_ext.h>
#include <uapi/linux/magic.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <asm/io.h>


struct resource ioport_resource = {
	.name	= "PCI IO",
	.start	= 0,
	.end	= IO_SPACE_LIMIT,
	.flags	= IORESOURCE_IO,
};
EXPORT_SYMBOL(ioport_resource);

struct resource iomem_resource = {
	.name	= "PCI mem",
	.start	= 0,
	.end	= -1,
	.flags	= IORESOURCE_MEM,
};
EXPORT_SYMBOL(iomem_resource);

static DEFINE_RWLOCK(resource_lock);

/*
 * Return the next node of @p in pre-order tree traversal.  If
 * @skip_children is true, skip the descendant nodes of @p in
 * traversal.  If @p is a descendant of @subtree_root, only traverse
 * the subtree under @subtree_root.
 */
static struct resource *next_resource(struct resource *p, bool skip_children,
				      struct resource *subtree_root)
{
	if (!skip_children && p->child)
		return p->child;
	while (!p->sibling && p->parent) {
		p = p->parent;
		if (p == subtree_root)
			return NULL;
	}
	return p->sibling;
}

/*
 * Traverse the resource subtree under @_root in pre-order, excluding
 * @_root itself.
 *
 * NOTE: '__p' is introduced to avoid shadowing '_p' outside of loop.
 * And it is referenced to avoid unused variable warning.
 */
#define for_each_resource(_root, _p, _skip_children) \
	for (typeof(_root) __root = (_root), __p = _p = __root->child;	\
	     __p && _p; _p = next_resource(_p, _skip_children, __root))

#ifdef CONFIG_PROC_FS

enum { MAX_IORES_LEVEL = 5 };

static void *r_start(struct seq_file *m, loff_t *pos)
	__acquires(resource_lock)
{
	struct resource *root = pde_data(file_inode(m->file));
	struct resource *p;
	loff_t l = *pos;

	read_lock(&resource_lock);
	for_each_resource(root, p, false) {
		if (l-- == 0)
			break;
	}

	return p;
}

static void *r_next(struct seq_file *m, void *v, loff_t *pos)
{
	struct resource *p = v;

	(*pos)++;

	return (void *)next_resource(p, false, NULL);
}

static void r_stop(struct seq_file *m, void *v)
	__releases(resource_lock)
{
	read_unlock(&resource_lock);
}

static int r_show(struct seq_file *m, void *v)
{
	struct resource *root = pde_data(file_inode(m->file));
	struct resource *r = v, *p;
	unsigned long long start, end;
	int width = root->end < 0x10000 ? 4 : 8;
	int depth;

	for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent)
		if (p->parent == root)
			break;

	if (file_ns_capable(m->file, &init_user_ns, CAP_SYS_ADMIN)) {
		start = r->start;
		end = r->end;
	} else {
		start = end = 0;
	}

	seq_printf(m, "%*s%0*llx-%0*llx : %s\n",
			depth * 2, "",
			width, start,
			width, end,
			r->name ? r->name : "<BAD>");
	return 0;
}

static const struct seq_operations resource_op = {
	.start	= r_start,
	.next	= r_next,
	.stop	= r_stop,
	.show	= r_show,
};

static int __init ioresources_init(void)
{
	proc_create_seq_data("ioports", 0, NULL, &resource_op,
			&ioport_resource);
	proc_create_seq_data("iomem", 0, NULL, &resource_op, &iomem_resource);
	return 0;
}
__initcall(ioresources_init);

#endif /* CONFIG_PROC_FS */

static void free_resource(struct resource *res)
{
	/**
	 * If the resource was allocated using memblock early during boot
	 * we'll leak it here: we can only return full pages back to the
	 * buddy and trying to be smart and reusing them eventually in
	 * alloc_resource() overcomplicates resource handling.
	 */
	if (res && PageSlab(virt_to_head_page(res)))
		kfree(res);
}

static struct resource *alloc_resource(gfp_t flags)
{
	return kzalloc(sizeof(struct resource), flags);
}

/* Return the conflict entry if you can't request it */
static struct resource * __request_resource(struct resource *root, struct resource *new)
{
	resource_size_t start = new->start;
	resource_size_t end = new->end;
	struct resource *tmp, **p;

	if (end < start)
		return root;
	if (start < root->start)
		return root;
	if (end > root->end)
		return root;
	p = &root->child;
	for (;;) {
		tmp = *p;
		if (!tmp || tmp->start > end) {
			new->sibling = tmp;
			*p = new;
			new->parent = root;
			return NULL;
		}
		p = &tmp->sibling;
		if (tmp->end < start)
			continue;
		return tmp;
	}
}

static int __release_resource(struct resource *old, bool release_child)
{
	struct resource *tmp, **p, *chd;

	p = &old->parent->child;
	for (;;) {
		tmp = *p;
		if (!tmp)
			break;
		if (tmp == old) {
			if (release_child || !(tmp->child)) {
				*p = tmp->sibling;
			} else {
				for (chd = tmp->child;; chd = chd->sibling) {
					chd->parent = tmp->parent;
					if (!(chd->sibling))
						break;
				}
				*p = tmp->child;
				chd->sibling = tmp->sibling;
			}
			old->parent = NULL;
			return 0;
		}
		p = &tmp->sibling;
	}
	return -EINVAL;
}

static void __release_child_resources(struct resource *r)
{
	struct resource *tmp, *p;
	resource_size_t size;

	p = r->child;
	r->child = NULL;
	while (p) {
		tmp = p;
		p = p->sibling;

		tmp->parent = NULL;
		tmp->sibling = NULL;
		__release_child_resources(tmp);

		printk(KERN_DEBUG "release child resource %pR\n", tmp);
		/* need to restore size, and keep flags */
		size = resource_size(tmp);
		tmp->start = 0;
		tmp->end = size - 1;
	}
}

void release_child_resources(struct resource *r)
{
	write_lock(&resource_lock);
	__release_child_resources(r);
	write_unlock(&resource_lock);
}

/**
 * request_resource_conflict - request and reserve an I/O or memory resource
 * @root: root resource descriptor
 * @new: resource descriptor desired by caller
 *
 * Returns 0 for success, conflict resource on error.
 */
struct resource *request_resource_conflict(struct resource *root, struct resource *new)
{
	struct resource *conflict;

	write_lock(&resource_lock);
	conflict = __request_resource(root, new);
	write_unlock(&resource_lock);
	return conflict;
}

/**
 * request_resource - request and reserve an I/O or memory resource
 * @root: root resource descriptor
 * @new: resource descriptor desired by caller
 *
 * Returns 0 for success, negative error code on error.
 */
int request_resource(struct resource *root, struct resource *new)
{
	struct resource *conflict;

	conflict = request_resource_conflict(root, new);
	return conflict ? -EBUSY : 0;
}

EXPORT_SYMBOL(request_resource);

/**
 * release_resource - release a previously reserved resource
 * @old: resource pointer
 */
int release_resource(struct resource *old)
{
	int retval;

	write_lock(&resource_lock);
	retval = __release_resource(old, true);
	write_unlock(&resource_lock);
	return retval;
}

EXPORT_SYMBOL(release_resource);

static bool is_type_match(struct resource *p, unsigned long flags, unsigned long desc)
{
	return (p->flags & flags) == flags && (desc == IORES_DESC_NONE || desc == p->desc);
}

/**
 * find_next_iomem_res - Finds the lowest iomem resource that covers part of
 *			 [@start..@end].
 *
 * If a resource is found, returns 0 and @*res is overwritten with the part
 * of the resource that's within [@start..@end]; if none is found, returns
 * -ENODEV.  Returns -EINVAL for invalid parameters.
 *
 * @start:	start address of the resource searched for
 * @end:	end address of same resource
 * @flags:	flags which the resource must have
 * @desc:	descriptor the resource must have
 * @res:	return ptr, if resource found
 *
 * The caller must specify @start, @end, @flags, and @desc
 * (which may be IORES_DESC_NONE).
 */
static int find_next_iomem_res(resource_size_t start, resource_size_t end,
			       unsigned long flags, unsigned long desc,
			       struct resource *res)
{
	/* Skip children until we find a top level range that matches */
	bool skip_children = true;
	struct resource *p;

	if (!res)
		return -EINVAL;

	if (start >= end)
		return -EINVAL;

	read_lock(&resource_lock);

	for_each_resource(&iomem_resource, p, skip_children) {
		/* If we passed the resource we are looking for, stop */
		if (p->start > end) {
			p = NULL;
			break;
		}

		/* Skip until we find a range that matches what we look for */
		if (p->end < start)
			continue;

		/*
		 * We found a top level range that matches what we are looking
		 * for. Time to start checking children too.
		 */
		skip_children = false;

		/* Found a match, break */
		if (is_type_match(p, flags, desc))
			break;
	}

	if (p) {
		/* copy data */
		*res = (struct resource) {
			.start = max(start, p->start),
			.end = min(end, p->end),
			.flags = p->flags,
			.desc = p->desc,
			.parent = p->parent,
		};
	}

	read_unlock(&resource_lock);
	return p ? 0 : -ENODEV;
}

static int __walk_iomem_res_desc(resource_size_t start, resource_size_t end,
				 unsigned long flags, unsigned long desc,
				 void *arg,
				 int (*func)(struct resource *, void *))
{
	struct resource res;
	int ret = -EINVAL;

	while (start < end &&
	       !find_next_iomem_res(start, end, flags, desc, &res)) {
		ret = (*func)(&res, arg);
		if (ret)
			break;

		start = res.end + 1;
	}

	return ret;
}

/**
 * walk_iomem_res_desc - Walks through iomem resources and calls func()
 *			 with matching resource ranges.
 * *
 * @desc: I/O resource descriptor. Use IORES_DESC_NONE to skip @desc check.
 * @flags: I/O resource flags
 * @start: start addr
 * @end: end addr
 * @arg: function argument for the callback @func
 * @func: callback function that is called for each qualifying resource area
 *
 * All the memory ranges which overlap start,end and also match flags and
 * desc are valid candidates.
 *
 * NOTE: For a new descriptor search, define a new IORES_DESC in
 * <linux/ioport.h> and set it in 'desc' of a target resource entry.
 */
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);
}
EXPORT_SYMBOL_GPL(walk_iomem_res_desc);

/*
 * This function calls the @func callback against all memory ranges of type
 * System RAM which are marked as IORESOURCE_SYSTEM_RAM and IORESOUCE_BUSY.
 * Now, this function is only for System RAM, it deals with full ranges and
 * not PFNs. If resources are not PFN-aligned, dealing with PFNs can truncate
 * ranges.
 */
int walk_system_ram_res(u64 start, u64 end, void *arg,
			int (*func)(struct resource *, void *))
{
	unsigned long flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;

	return __walk_iomem_res_desc(start, end, flags, IORES_DESC_NONE, arg,
				     func);
}

/*
 * This function, being a variant of walk_system_ram_res(), calls the @func
 * callback against all memory ranges of type System RAM which are marked as
 * IORESOURCE_SYSTEM_RAM and IORESOUCE_BUSY in reversed order, i.e., from
 * higher to lower.
 */
int walk_system_ram_res_rev(u64 start, u64 end, void *arg,
				int (*func)(struct resource *, void *))
{
	struct resource res, *rams;
	int rams_size = 16, i;
	unsigned long flags;
	int ret = -1;

	/* create a list */
	rams = kvcalloc(rams_size, sizeof(struct resource), GFP_KERNEL);
	if (!rams)
		return ret;

	flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
	i = 0;
	while ((start < end) &&
		(!find_next_iomem_res(start, end, flags, IORES_DESC_NONE, &res))) {
		if (i >= rams_size) {
			/* re-alloc */
			struct resource *rams_new;

			rams_new = kvrealloc(rams, (rams_size + 16) * sizeof(struct resource),
					     GFP_KERNEL);
			if (!rams_new)
				goto out;

			rams = rams_new;
			rams_size += 16;
		}

		rams[i++] = res;
		start = res.end + 1;
	}

	/* go reverse */
	for (i--; i >= 0; i--) {
		ret = (*func)(&rams[i], arg);
		if (ret)
			break;
	}

out:
	kvfree(rams);
	return ret;
}

/*
 * This function calls the @func callback against all memory ranges, which
 * are ranges marked as IORESOURCE_MEM and IORESOUCE_BUSY.
 */
int walk_mem_res(u64 start, u64 end, void *arg,
		 int (*func)(struct resource *, void *))
{
	unsigned long flags = IORESOURCE_MEM | IORESOURCE_BUSY;

	return __walk_iomem_res_desc(start, end, flags, IORES_DESC_NONE, arg,
				     func);
}

/*
 * This function calls the @func callback against all memory ranges of type
 * System RAM which are marked as IORESOURCE_SYSTEM_RAM and IORESOUCE_BUSY.
 * It is to be used only for System RAM.
 */
int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
			  void *arg, int (*func)(unsigned long, unsigned long, void *))
{
	resource_size_t start, end;
	unsigned long flags;
	struct resource res;
	unsigned long pfn, end_pfn;
	int ret = -EINVAL;

	start = (u64) start_pfn << PAGE_SHIFT;
	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)) {
		pfn = PFN_UP(res.start);
		end_pfn = PFN_DOWN(res.end + 1);
		if (end_pfn > pfn)
			ret = (*func)(pfn, end_pfn - pfn, arg);
		if (ret)
			break;
		start = res.end + 1;
	}
	return ret;
}

static int __is_ram(unsigned long pfn, unsigned long nr_pages, void *arg)
{
	return 1;
}

/*
 * This generic page_is_ram() returns true if specified address is
 * registered as System RAM in iomem_resource list.
 */
int __weak page_is_ram(unsigned long pfn)
{
	return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1;
}
EXPORT_SYMBOL_GPL(page_is_ram);

static int __region_intersects(struct resource *parent, resource_size_t start,
			       size_t size, unsigned long flags,
			       unsigned long desc)
{
	int type = 0; int other = 0;
	struct resource *p, *dp;
	struct resource res, o;
	bool covered;

	res = DEFINE_RES(start, size, 0);

	for (p = parent->child; p ; p = p->sibling) {
		if (!resource_intersection(p, &res, &o))
			continue;
		if (is_type_match(p, flags, desc)) {
			type++;
			continue;
		}
		/*
		 * Continue to search in descendant resources as if the
		 * matched descendant resources cover some ranges of 'p'.
		 *
		 * |------------- "CXL Window 0" ------------|
		 * |-- "System RAM" --|
		 *
		 * will behave similar as the following fake resource
		 * tree when searching "System RAM".
		 *
		 * |-- "System RAM" --||-- "CXL Window 0a" --|
		 */
		covered = false;
		for_each_resource(p, dp, false) {
			if (!resource_overlaps(dp, &res))
				continue;
			if (is_type_match(dp, flags, desc)) {
				type++;
				/*
				 * Range from 'o.start' to 'dp->start'
				 * isn't covered by matched resource.
				 */
				if (dp->start > o.start)
					break;
				if (dp->end >= o.end) {
					covered = true;
					break;
				}
				/* Remove covered range */
				o.start = max(o.start, dp->end + 1);
			}
		}
		if (!covered)
			other++;
	}

	if (type == 0)
		return REGION_DISJOINT;

	if (other == 0)
		return REGION_INTERSECTS;

	return REGION_MIXED;
}

/**
 * region_intersects() - determine intersection of region with known resources
 * @start: region start address
 * @size: size of region
 * @flags: flags of resource (in iomem_resource)
 * @desc: descriptor of resource (in iomem_resource) or IORES_DESC_NONE
 *
 * Check if the specified region partially overlaps or fully eclipses a
 * resource identified by @flags and @desc (optional with IORES_DESC_NONE).
 * Return REGION_DISJOINT if the region does not overlap @flags/@desc,
 * return REGION_MIXED if the region overlaps @flags/@desc and another
 * resource, and return REGION_INTERSECTS if the region overlaps @flags/@desc
 * and no other defined resource. Note that REGION_INTERSECTS is also
 * returned in the case when the specified region overlaps RAM and undefined
 * memory holes.
 *
 * region_intersect() is used by memory remapping functions to ensure
 * the user is not remapping RAM and is a vast speed up over walking
 * through the resource table page by page.
 */
int region_intersects(resource_size_t start, size_t size, unsigned long flags,
		      unsigned long desc)
{
	int ret;

	read_lock(&resource_lock);
	ret = __region_intersects(&iomem_resource, start, size, flags, desc);
	read_unlock(&resource_lock);

	return ret;
}
EXPORT_SYMBOL_GPL(region_intersects);

void __weak arch_remove_reservations(struct resource *avail)
{
}

static void resource_clip(struct resource *res, resource_size_t min,
			  resource_size_t max)
{
	if (res->start < min)
		res->start = min;
	if (res->end > max)
		res->end = max;
}

/*
 * Find empty space in the resource tree with the given range and
 * alignment constraints
 */
static int __find_resource_space(struct resource *root, struct resource *old,
				 struct resource *new, resource_size_t size,
				 struct resource_constraint *constraint)
{
	struct resource *this = root->child;
	struct resource tmp = *new, avail, alloc;
	resource_alignf alignf = constraint->alignf;

	tmp.start = root->start;
	/*
	 * Skip past an allocated resource that starts at 0, since the assignment
	 * of this->start - 1 to tmp->end below would cause an underflow.
	 */
	if (this && this->start == root->start) {
		tmp.start = (this == old) ? old->start : this->end + 1;
		this = this->sibling;
	}
	for(;;) {
		if (this)
			tmp.end = (this == old) ?  this->end : this->start - 1;
		else
			tmp.end = root->end;

		if (tmp.end < tmp.start)
			goto next;

		resource_clip(&tmp, constraint->min, constraint->max);
		arch_remove_reservations(&tmp);

		/* Check for overflow after ALIGN() */
		avail.start = ALIGN(tmp.start, constraint->align);
		avail.end = tmp.end;
		avail.flags = new->flags & ~IORESOURCE_UNSET;
		if (avail.start >= tmp.start) {
			alloc.flags = avail.flags;
			if (alignf) {
				alloc.start = alignf(constraint->alignf_data,
						     &avail, size, constraint->align);
			} else {
				alloc.start = avail.start;
			}
			alloc.end = alloc.start + size - 1;
			if (alloc.start <= alloc.end &&
			    resource_contains(&avail, &alloc)) {
				new->start = alloc.start;
				new->end = alloc.end;
				return 0;
			}
		}

next:		if (!this || this->end == root->end)
			break;

		if (this != old)
			tmp.start = this->end + 1;
		this = this->sibling;
	}
	return -EBUSY;
}

/**
 * find_resource_space - Find empty space in the resource tree
 * @root:	Root resource descriptor
 * @new:	Resource descriptor awaiting an empty resource space
 * @size:	The minimum size of the empty space
 * @constraint:	The range and alignment constraints to be met
 *
 * Finds an empty space under @root in the resource tree satisfying range and
 * alignment @constraints.
 *
 * Return:
 * * %0		- if successful, @new members start, end, and flags are altered.
 * * %-EBUSY	- if no empty space was found.
 */
int find_resource_space(struct resource *root, struct resource *new,
			resource_size_t size,
			struct resource_constraint *constraint)
{
	return  __find_resource_space(root, NULL, new, size, constraint);
}
EXPORT_SYMBOL_GPL(find_resource_space);

/**
 * reallocate_resource - allocate a slot in the resource tree given range & alignment.
 *	The resource will be relocated if the new size cannot be reallocated in the
 *	current location.
 *
 * @root: root resource descriptor
 * @old:  resource descriptor desired by caller
 * @newsize: new size of the resource descriptor
 * @constraint: the memory range and alignment constraints to be met.
 */
static int reallocate_resource(struct resource *root, struct resource *old,
			       resource_size_t newsize,
			       struct resource_constraint *constraint)
{
	int err=0;
	struct resource new = *old;
	struct resource *conflict;

	write_lock(&resource_lock);

	if ((err = __find_resource_space(root, old, &new, newsize, constraint)))
		goto out;

	if (resource_contains(&new, old)) {
		old->start = new.start;
		old->end = new.end;
		goto out;
	}

	if (old->child) {
		err = -EBUSY;
		goto out;
	}

	if (resource_contains(old, &new)) {
		old->start = new.start;
		old->end = new.end;
	} else {
		__release_resource(old, true);
		*old = new;
		conflict = __request_resource(root, old);
		BUG_ON(conflict);
	}
out:
	write_unlock(&resource_lock);
	return err;
}


/**
 * allocate_resource - allocate empty slot in the resource tree given range & alignment.
 * 	The resource will be reallocated with a new size if it was already allocated
 * @root: root resource descriptor
 * @new: resource descriptor desired by caller
 * @size: requested resource region size
 * @min: minimum boundary to allocate
 * @max: maximum boundary to allocate
 * @align: alignment requested, in bytes
 * @alignf: alignment function, optional, called if not NULL
 * @alignf_data: arbitrary data to pass to the @alignf function
 */
int allocate_resource(struct resource *root, struct resource *new,
		      resource_size_t size, resource_size_t min,
		      resource_size_t max, resource_size_t align,
		      resource_alignf alignf,
		      void *alignf_data)
{
	int err;
	struct resource_constraint constraint;

	constraint.min = min;
	constraint.max = max;
	constraint.align = align;
	constraint.alignf = alignf;
	constraint.alignf_data = alignf_data;

	if ( new->parent ) {
		/* resource is already allocated, try reallocating with
		   the new constraints */
		return reallocate_resource(root, new, size, &constraint);
	}

	write_lock(&resource_lock);
	err = find_resource_space(root, new, size, &constraint);
	if (err >= 0 && __request_resource(root, new))
		err = -EBUSY;
	write_unlock(&resource_lock);
	return err;
}

EXPORT_SYMBOL(allocate_resource);

/**
 * lookup_resource - find an existing resource by a resource start address
 * @root: root resource descriptor
 * @start: resource start address
 *
 * Returns a pointer to the resource if found, NULL otherwise
 */
struct resource *lookup_resource(struct resource *root, resource_size_t start)
{
	struct resource *res;

	read_lock(&resource_lock);
	for (res = root->child; res; res = res->sibling) {
		if (res->start == start)
			break;
	}
	read_unlock(&resource_lock);

	return res;
}

/*
 * Insert a resource into the resource tree. If successful, return NULL,
 * otherwise return the conflicting resource (compare to __request_resource())
 */
static struct resource * __insert_resource(struct resource *parent, struct resource *new)
{
	struct resource *first, *next;

	for (;; parent = first) {
		first = __request_resource(parent, new);
		if (!first)
			return first;

		if (first == parent)
			return first;
		if (WARN_ON(first == new))	/* duplicated insertion */
			return first;

		if ((first->start > new->start) || (first->end < new->end))
			break;
		if ((first->start == new->start) && (first->end == new->end))
			break;
	}

	for (next = first; ; next = next->sibling) {
		/* Partial overlap? Bad, and unfixable */
		if (next->start < new->start || next->end > new->end)
			return next;
		if (!next->sibling)
			break;
		if (next->sibling->start > new->end)
			break;
	}

	new->parent = parent;
	new->sibling = next->sibling;
	new->child = first;

	next->sibling = NULL;
	for (next = first; next; next = next->sibling)
		next->parent = new;

	if (parent->child == first) {
		parent->child = new;
	} else {
		next = parent->child;
		while (next->sibling != first)
			next = next->sibling;
		next->sibling = new;
	}
	return NULL;
}

/**
 * insert_resource_conflict - Inserts resource in the resource tree
 * @parent: parent of the new resource
 * @new: new resource to insert
 *
 * Returns 0 on success, conflict resource if the resource can't be inserted.
 *
 * This function is equivalent to request_resource_conflict when no conflict
 * happens. If a conflict happens, and the conflicting resources
 * entirely fit within the range of the new resource, then the new
 * resource is inserted and the conflicting resources become children of
 * the new resource.
 *
 * This function is intended for producers of resources, such as FW modules
 * and bus drivers.
 */
struct resource *insert_resource_conflict(struct resource *parent, struct resource *new)
{
	struct resource *conflict;

	write_lock(&resource_lock);
	conflict = __insert_resource(parent, new);
	write_unlock(&resource_lock);
	return conflict;
}

/**
 * insert_resource - Inserts a resource in the resource tree
 * @parent: parent of the new resource
 * @new: new resource to insert
 *
 * Returns 0 on success, -EBUSY if the resource can't be inserted.
 *
 * This function is intended for producers of resources, such as FW modules
 * and bus drivers.
 */
int insert_resource(struct resource *parent, struct resource *new)
{
	struct resource *conflict;

	conflict = insert_resource_conflict(parent, new);
	return conflict ? -EBUSY : 0;
}
EXPORT_SYMBOL_GPL(insert_resource);

/**
 * insert_resource_expand_to_fit - Insert a resource into the resource tree
 * @root: root resource descriptor
 * @new: new resource to insert
 *
 * Insert a resource into the resource tree, possibly expanding it in order
 * to make it encompass any conflicting resources.
 */
void insert_resource_expand_to_fit(struct resource *root, struct resource *new)
{
	if (new->parent)
		return;

	write_lock(&resource_lock);
	for (;;) {
		struct resource *conflict;

		conflict = __insert_resource(root, new);
		if (!conflict)
			break;
		if (conflict == root)
			break;

		/* Ok, expand resource to cover the conflict, then try again .. */
		if (conflict->start < new->start)
			new->start = conflict->start;
		if (conflict->end > new->end)
			new->end = conflict->end;

		pr_info("Expanded resource %s due to conflict with %s\n", new->name, conflict->name);
	}
	write_unlock(&resource_lock);
}
/*
 * Not for general consumption, only early boot memory map parsing, PCI
 * resource discovery, and late discovery of CXL resources are expected
 * to use this interface. The former are built-in and only the latter,
 * CXL, is a module.
 */
EXPORT_SYMBOL_NS_GPL(insert_resource_expand_to_fit, "CXL");

/**
 * remove_resource - Remove a resource in the resource tree
 * @old: resource to remove
 *
 * Returns 0 on success, -EINVAL if the resource is not valid.
 *
 * This function removes a resource previously inserted by insert_resource()
 * or insert_resource_conflict(), and moves the children (if any) up to
 * where they were before.  insert_resource() and insert_resource_conflict()
 * insert a new resource, and move any conflicting resources down to the
 * children of the new resource.
 *
 * insert_resource(), insert_resource_conflict() and remove_resource() are
 * intended for producers of resources, such as FW modules and bus drivers.
 */
int remove_resource(struct resource *old)
{
	int retval;

	write_lock(&resource_lock);
	retval = __release_resource(old, false);
	write_unlock(&resource_lock);
	return retval;
}
EXPORT_SYMBOL_GPL(remove_resource);

static int __adjust_resource(struct resource *res, resource_size_t start,
				resource_size_t size)
{
	struct resource *tmp, *parent = res->parent;
	resource_size_t end = start + size - 1;
	int result = -EBUSY;

	if (!parent)
		goto skip;

	if ((start < parent->start) || (end > parent->end))
		goto out;

	if (res->sibling && (res->sibling->start <= end))
		goto out;

	tmp = parent->child;
	if (tmp != res) {
		while (tmp->sibling != res)
			tmp = tmp->sibling;
		if (start <= tmp->end)
			goto out;
	}

skip:
	for (tmp = res->child; tmp; tmp = tmp->sibling)
		if ((tmp->start < start) || (tmp->end > end))
			goto out;

	res->start = start;
	res->end = end;
	result = 0;

 out:
	return result;
}

/**
 * adjust_resource - modify a resource's start and size
 * @res: resource to modify
 * @start: new start value
 * @size: new size
 *
 * Given an existing resource, change its start and size to match the
 * arguments.  Returns 0 on success, -EBUSY if it can't fit.
 * Existing children of the resource are assumed to be immutable.
 */
int adjust_resource(struct resource *res, resource_size_t start,
		    resource_size_t size)
{
	int result;

	write_lock(&resource_lock);
	result = __adjust_resource(res, start, size);
	write_unlock(&resource_lock);
	return result;
}
EXPORT_SYMBOL(adjust_resource);

static void __init
__reserve_region_with_split(struct resource *root, resource_size_t start,
			    resource_size_t end, const char *name)
{
	struct resource *parent = root;
	struct resource *conflict;
	struct resource *res = alloc_resource(GFP_ATOMIC);
	struct resource *next_res = NULL;
	int type = resource_type(root);

	if (!res)
		return;

	res->name = name;
	res->start = start;
	res->end = end;
	res->flags = type | IORESOURCE_BUSY;
	res->desc = IORES_DESC_NONE;

	while (1) {

		conflict = __request_resource(parent, res);
		if (!conflict) {
			if (!next_res)
				break;
			res = next_res;
			next_res = NULL;
			continue;
		}

		/* conflict covered whole area */
		if (conflict->start <= res->start &&
				conflict->end >= res->end) {
			free_resource(res);
			WARN_ON(next_res);
			break;
		}

		/* failed, split and try again */
		if (conflict->start > res->start) {
			end = res->end;
			res->end = conflict->start - 1;
			if (conflict->end < end) {
				next_res = alloc_resource(GFP_ATOMIC);
				if (!next_res) {
					free_resource(res);
					break;
				}
				next_res->name = name;
				next_res->start = conflict->end + 1;
				next_res->end = end;
				next_res->flags = type | IORESOURCE_BUSY;
				next_res->desc = IORES_DESC_NONE;
			}
		} else {
			res->start = conflict->end + 1;
		}
	}

}

void __init
reserve_region_with_split(struct resource *root, resource_size_t start,
			  resource_size_t end, const char *name)
{
	int abort = 0;

	write_lock(&resource_lock);
	if (root->start > start || root->end < end) {
		pr_err("requested range [0x%llx-0x%llx] not in root %pr\n",
		       (unsigned long long)start, (unsigned long long)end,
		       root);
		if (start > root->end || end < root->start)
			abort = 1;
		else {
			if (end > root->end)
				end = root->end;
			if (start < root->start)
				start = root->start;
			pr_err("fixing request to [0x%llx-0x%llx]\n",
			       (unsigned long long)start,
			       (unsigned long long)end);
		}
		dump_stack();
	}
	if (!abort)
		__reserve_region_with_split(root, start, end, name);
	write_unlock(&resource_lock);
}

/**
 * resource_alignment - calculate resource's alignment
 * @res: resource pointer
 *
 * Returns alignment on success, 0 (invalid alignment) on failure.
 */
resource_size_t resource_alignment(struct resource *res)
{
	switch (res->flags & (IORESOURCE_SIZEALIGN | IORESOURCE_STARTALIGN)) {
	case IORESOURCE_SIZEALIGN:
		return resource_size(res);
	case IORESOURCE_STARTALIGN:
		return res->start;
	default:
		return 0;
	}
}

/*
 * This is compatibility stuff for IO resources.
 *
 * Note how this, unlike the above, knows about
 * the IO flag meanings (busy etc).
 *
 * request_region creates a new busy region.
 *
 * release_region releases a matching busy region.
 */

static DECLARE_WAIT_QUEUE_HEAD(muxed_resource_wait);

static struct inode *iomem_inode;

#ifdef CONFIG_IO_STRICT_DEVMEM
static void revoke_iomem(struct resource *res)
{
	/* pairs with smp_store_release() in iomem_init_inode() */
	struct inode *inode = smp_load_acquire(&iomem_inode);

	/*
	 * Check that the initialization has completed. Losing the race
	 * is ok because it means drivers are claiming resources before
	 * the fs_initcall level of init and prevent iomem_get_mapping users
	 * from establishing mappings.
	 */
	if (!inode)
		return;

	/*
	 * The expectation is that the driver has successfully marked
	 * the resource busy by this point, so devmem_is_allowed()
	 * should start returning false, however for performance this
	 * does not iterate the entire resource range.
	 */
	if (devmem_is_allowed(PHYS_PFN(res->start)) &&
	    devmem_is_allowed(PHYS_PFN(res->end))) {
		/*
		 * *cringe* iomem=relaxed says "go ahead, what's the
		 * worst that can happen?"
		 */
		return;
	}

	unmap_mapping_range(inode->i_mapping, res->start, resource_size(res), 1);
}
#else
static void revoke_iomem(struct resource *res) {}
#endif

struct address_space *iomem_get_mapping(void)
{
	/*
	 * This function is only called from file open paths, hence guaranteed
	 * that fs_initcalls have completed and no need to check for NULL. But
	 * since revoke_iomem can be called before the initcall we still need
	 * the barrier to appease checkers.
	 */
	return smp_load_acquire(&iomem_inode)->i_mapping;
}

static int __request_region_locked(struct resource *res, struct resource *parent,
				   resource_size_t start, resource_size_t n,
				   const char *name, int flags)
{
	DECLARE_WAITQUEUE(wait, current);

	res->name = name;
	res->start = start;
	res->end = start + n - 1;

	for (;;) {
		struct resource *conflict;

		res->flags = resource_type(parent) | resource_ext_type(parent);
		res->flags |= IORESOURCE_BUSY | flags;
		res->desc = parent->desc;

		conflict = __request_resource(parent, res);
		if (!conflict)
			break;
		/*
		 * mm/hmm.c reserves physical addresses which then
		 * become unavailable to other users.  Conflicts are
		 * not expected.  Warn to aid debugging if encountered.
		 */
		if (parent == &iomem_resource &&
		    conflict->desc == IORES_DESC_DEVICE_PRIVATE_MEMORY) {
			pr_warn("Unaddressable device %s %pR conflicts with %pR\n",
				conflict->name, conflict, res);
		}
		if (conflict != parent) {
			if (!(conflict->flags & IORESOURCE_BUSY)) {
				parent = conflict;
				continue;
			}
		}
		if (conflict->flags & flags & IORESOURCE_MUXED) {
			add_wait_queue(&muxed_resource_wait, &wait);
			write_unlock(&resource_lock);
			set_current_state(TASK_UNINTERRUPTIBLE);
			schedule();
			remove_wait_queue(&muxed_resource_wait, &wait);
			write_lock(&resource_lock);
			continue;
		}
		/* Uhhuh, that didn't work out.. */
		return -EBUSY;
	}

	return 0;
}

/**
 * __request_region - create a new busy resource region
 * @parent: parent resource descriptor
 * @start: resource start address
 * @n: resource region size
 * @name: reserving caller's ID string
 * @flags: IO resource flags
 */
struct resource *__request_region(struct resource *parent,
				  resource_size_t start, resource_size_t n,
				  const char *name, int flags)
{
	struct resource *res = alloc_resource(GFP_KERNEL);
	int ret;

	if (!res)
		return NULL;

	write_lock(&resource_lock);
	ret = __request_region_locked(res, parent, start, n, name, flags);
	write_unlock(&resource_lock);

	if (ret) {
		free_resource(res);
		return NULL;
	}

	if (parent == &iomem_resource)
		revoke_iomem(res);

	return res;
}
EXPORT_SYMBOL(__request_region);

/**
 * __release_region - release a previously reserved resource region
 * @parent: parent resource descriptor
 * @start: resource start address
 * @n: resource region size
 *
 * The described resource region must match a currently busy region.
 */
void __release_region(struct resource *parent, resource_size_t start,
		      resource_size_t n)
{
	struct resource **p;
	resource_size_t end;

	p = &parent->child;
	end = start + n - 1;

	write_lock(&resource_lock);

	for (;;) {
		struct resource *res = *p;

		if (!res)
			break;
		if (res->start <= start && res->end >= end) {
			if (!(res->flags & IORESOURCE_BUSY)) {
				p = &res->child;
				continue;
			}
			if (res->start != start || res->end != end)
				break;
			*p = res->sibling;
			write_unlock(&resource_lock);
			if (res->flags & IORESOURCE_MUXED)
				wake_up(&muxed_resource_wait);
			free_resource(res);
			return;
		}
		p = &res->sibling;
	}

	write_unlock(&resource_lock);

	pr_warn("Trying to free nonexistent resource <%pa-%pa>\n", &start, &end);
}
EXPORT_SYMBOL(__release_region);

#ifdef CONFIG_MEMORY_HOTREMOVE
static void append_child_to_parent(struct resource *new_parent, struct resource *new_child)
{
	struct resource *child;

	child = new_parent->child;
	if (child) {
		while (child->sibling)
			child = child->sibling;
		child->sibling = new_child;
	} else {
		new_parent->child = new_child;
	}
	new_child->parent = new_parent;
	new_child->sibling = NULL;
}

/*
 * Reparent all child resources that no longer belong to "low" after a split to
 * "high". Note that "high" does not have any children, because "low" is the
 * original resource and "high" is a new resource. Treat "low" as the original
 * resource being split and defer its range adjustment to __adjust_resource().
 */
static void reparent_children_after_split(struct resource *low,
					  struct resource *high,
					  resource_size_t split_addr)
{
	struct resource *child, *next, **p;

	p = &low->child;
	while ((child = *p)) {
		next = child->sibling;
		if (child->start > split_addr) {
			/* unlink child */
			*p = next;
			append_child_to_parent(high, child);
		} else {
			p = &child->sibling;
		}
	}
}

/**
 * release_mem_region_adjustable - release a previously reserved memory region
 * @start: resource start address
 * @size: resource region size
 *
 * This interface is intended for memory hot-delete.  The requested region
 * is released from a currently busy memory resource.  The requested region
 * must either match exactly or fit into a single busy resource entry.  In
 * the latter case, the remaining resource is adjusted accordingly.
 *
 * Note:
 * - Additional release conditions, such as overlapping region, can be
 *   supported after they are confirmed as valid cases.
 * - When a busy memory resource gets split into two entries, its children are
 *   reassigned to the correct parent based on their range. If a child memory
 *   resource overlaps with more than one parent, enhance the logic as needed.
 */
void release_mem_region_adjustable(resource_size_t start, resource_size_t size)
{
	struct resource *parent = &iomem_resource;
	struct resource *new_res = NULL;
	bool alloc_nofail = false;
	struct resource **p;
	struct resource *res;
	resource_size_t end;

	end = start + size - 1;
	if (WARN_ON_ONCE((start < parent->start) || (end > parent->end)))
		return;

	/*
	 * We free up quite a lot of memory on memory hotunplug (esp., memap),
	 * just before releasing the region. This is highly unlikely to
	 * fail - let's play save and make it never fail as the caller cannot
	 * perform any error handling (e.g., trying to re-add memory will fail
	 * similarly).
	 */
retry:
	new_res = alloc_resource(GFP_KERNEL | (alloc_nofail ? __GFP_NOFAIL : 0));

	p = &parent->child;
	write_lock(&resource_lock);

	while ((res = *p)) {
		if (res->start >= end)
			break;

		/* look for the next resource if it does not fit into */
		if (res->start > start || res->end < end) {
			p = &res->sibling;
			continue;
		}

		if (!(res->flags & IORESOURCE_MEM))
			break;

		if (!(res->flags & IORESOURCE_BUSY)) {
			p = &res->child;
			continue;
		}

		/* found the target resource; let's adjust accordingly */
		if (res->start == start && res->end == end) {
			/* free the whole entry */
			*p = res->sibling;
			free_resource(res);
		} else if (res->start == start && res->end != end) {
			/* adjust the start */
			WARN_ON_ONCE(__adjust_resource(res, end + 1,
						       res->end - end));
		} else if (res->start != start && res->end == end) {
			/* adjust the end */
			WARN_ON_ONCE(__adjust_resource(res, res->start,
						       start - res->start));
		} else {
			/* split into two entries - we need a new resource */
			if (!new_res) {
				new_res = alloc_resource(GFP_ATOMIC);
				if (!new_res) {
					alloc_nofail = true;
					write_unlock(&resource_lock);
					goto retry;
				}
			}
			new_res->name = res->name;
			new_res->start = end + 1;
			new_res->end = res->end;
			new_res->flags = res->flags;
			new_res->desc = res->desc;
			new_res->parent = res->parent;
			new_res->sibling = res->sibling;
			new_res->child = NULL;
			reparent_children_after_split(res, new_res, end);

			if (WARN_ON_ONCE(__adjust_resource(res, res->start,
							   start - res->start)))
				break;
			res->sibling = new_res;
			new_res = NULL;
		}

		break;
	}

	write_unlock(&resource_lock);
	free_resource(new_res);
}
#endif	/* CONFIG_MEMORY_HOTREMOVE */

#ifdef CONFIG_MEMORY_HOTPLUG
static bool system_ram_resources_mergeable(struct resource *r1,
					   struct resource *r2)
{
	/* We assume either r1 or r2 is IORESOURCE_SYSRAM_MERGEABLE. */
	return r1->flags == r2->flags && r1->end + 1 == r2->start &&
	       r1->name == r2->name && r1->desc == r2->desc &&
	       !r1->child && !r2->child;
}

/**
 * merge_system_ram_resource - mark the System RAM resource mergeable and try to
 *	merge it with adjacent, mergeable resources
 * @res: resource descriptor
 *
 * This interface is intended for memory hotplug, whereby lots of contiguous
 * system ram resources are added (e.g., via add_memory*()) by a driver, and
 * the actual resource boundaries are not of interest (e.g., it might be
 * relevant for DIMMs). Only resources that are marked mergeable, that have the
 * same parent, and that don't have any children are considered. All mergeable
 * resources must be immutable during the request.
 *
 * Note:
 * - The caller has to make sure that no pointers to resources that are
 *   marked mergeable are used anymore after this call - the resource might
 *   be freed and the pointer might be stale!
 * - release_mem_region_adjustable() will split on demand on memory hotunplug
 */
void merge_system_ram_resource(struct resource *res)
{
	const unsigned long flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
	struct resource *cur;

	if (WARN_ON_ONCE((res->flags & flags) != flags))
		return;

	write_lock(&resource_lock);
	res->flags |= IORESOURCE_SYSRAM_MERGEABLE;

	/* Try to merge with next item in the list. */
	cur = res->sibling;
	if (cur && system_ram_resources_mergeable(res, cur)) {
		res->end = cur->end;
		res->sibling = cur->sibling;
		free_resource(cur);
	}

	/* Try to merge with previous item in the list. */
	cur = res->parent->child;
	while (cur && cur->sibling != res)
		cur = cur->sibling;
	if (cur && system_ram_resources_mergeable(cur, res)) {
		cur->end = res->end;
		cur->sibling = res->sibling;
		free_resource(res);
	}
	write_unlock(&resource_lock);
}
#endif	/* CONFIG_MEMORY_HOTPLUG */

/*
 * Managed region resource
 */
static void devm_resource_release(struct device *dev, void *ptr)
{
	struct resource **r = ptr;

	release_resource(*r);
}

/**
 * devm_request_resource() - request and reserve an I/O or memory resource
 * @dev: device for which to request the resource
 * @root: root of the resource tree from which to request the resource
 * @new: descriptor of the resource to request
 *
 * This is a device-managed version of request_resource(). There is usually
 * no need to release resources requested by this function explicitly since
 * that will be taken care of when the device is unbound from its driver.
 * If for some reason the resource needs to be released explicitly, because
 * of ordering issues for example, drivers must call devm_release_resource()
 * rather than the regular release_resource().
 *
 * When a conflict is detected between any existing resources and the newly
 * requested resource, an error message will be printed.
 *
 * Returns 0 on success or a negative error code on failure.
 */
int devm_request_resource(struct device *dev, struct resource *root,
			  struct resource *new)
{
	struct resource *conflict, **ptr;

	ptr = devres_alloc(devm_resource_release, sizeof(*ptr), GFP_KERNEL);
	if (!ptr)
		return -ENOMEM;

	*ptr = new;

	conflict = request_resource_conflict(root, new);
	if (conflict) {
		dev_err(dev, "resource collision: %pR conflicts with %s %pR\n",
			new, conflict->name, conflict);
		devres_free(ptr);
		return -EBUSY;
	}

	devres_add(dev, ptr);
	return 0;
}
EXPORT_SYMBOL(devm_request_resource);

static int devm_resource_match(struct device *dev, void *res, void *data)
{
	struct resource **ptr = res;

	return *ptr == data;
}

/**
 * devm_release_resource() - release a previously requested resource
 * @dev: device for which to release the resource
 * @new: descriptor of the resource to release
 *
 * Releases a resource previously requested using devm_request_resource().
 */
void devm_release_resource(struct device *dev, struct resource *new)
{
	WARN_ON(devres_release(dev, devm_resource_release, devm_resource_match,
			       new));
}
EXPORT_SYMBOL(devm_release_resource);

struct region_devres {
	struct resource *parent;
	resource_size_t start;
	resource_size_t n;
};

static void devm_region_release(struct device *dev, void *res)
{
	struct region_devres *this = res;

	__release_region(this->parent, this->start, this->n);
}

static int devm_region_match(struct device *dev, void *res, void *match_data)
{
	struct region_devres *this = res, *match = match_data;

	return this->parent == match->parent &&
		this->start == match->start && this->n == match->n;
}

struct resource *
__devm_request_region(struct device *dev, struct resource *parent,
		      resource_size_t start, resource_size_t n, const char *name)
{
	struct region_devres *dr = NULL;
	struct resource *res;

	dr = devres_alloc(devm_region_release, sizeof(struct region_devres),
			  GFP_KERNEL);
	if (!dr)
		return NULL;

	dr->parent = parent;
	dr->start = start;
	dr->n = n;

	res = __request_region(parent, start, n, name, 0);
	if (res)
		devres_add(dev, dr);
	else
		devres_free(dr);

	return res;
}
EXPORT_SYMBOL(__devm_request_region);

void __devm_release_region(struct device *dev, struct resource *parent,
			   resource_size_t start, resource_size_t n)
{
	struct region_devres match_data = { parent, start, n };

	WARN_ON(devres_release(dev, devm_region_release, devm_region_match,
			       &match_data));
}
EXPORT_SYMBOL(__devm_release_region);

/*
 * Reserve I/O ports or memory based on "reserve=" kernel parameter.
 */
#define MAXRESERVE 4
static int __init reserve_setup(char *str)
{
	static int reserved;
	static struct resource reserve[MAXRESERVE];

	for (;;) {
		unsigned int io_start, io_num;
		int x = reserved;
		struct resource *parent;

		if (get_option(&str, &io_start) != 2)
			break;
		if (get_option(&str, &io_num) == 0)
			break;
		if (x < MAXRESERVE) {
			struct resource *res = reserve + x;

			/*
			 * If the region starts below 0x10000, we assume it's
			 * I/O port space; otherwise assume it's memory.
			 */
			if (io_start < 0x10000) {
				*res = DEFINE_RES_IO_NAMED(io_start, io_num, "reserved");
				parent = &ioport_resource;
			} else {
				*res = DEFINE_RES_MEM_NAMED(io_start, io_num, "reserved");
				parent = &iomem_resource;
			}
			res->flags |= IORESOURCE_BUSY;
			if (request_resource(parent, res) == 0)
				reserved = x+1;
		}
	}
	return 1;
}
__setup("reserve=", reserve_setup);

/*
 * Check if the requested addr and size spans more than any slot in the
 * iomem resource tree.
 */
int iomem_map_sanity_check(resource_size_t addr, unsigned long size)
{
	resource_size_t end = addr + size - 1;
	struct resource *p;
	int err = 0;

	read_lock(&resource_lock);
	for_each_resource(&iomem_resource, p, false) {
		/*
		 * We can probably skip the resources without
		 * IORESOURCE_IO attribute?
		 */
		if (p->start > end)
			continue;
		if (p->end < addr)
			continue;
		if (PFN_DOWN(p->start) <= PFN_DOWN(addr) &&
		    PFN_DOWN(p->end) >= PFN_DOWN(end))
			continue;
		/*
		 * if a resource is "BUSY", it's not a hardware resource
		 * but a driver mapping of such a resource; we don't want
		 * to warn for those; some drivers legitimately map only
		 * partial hardware resources. (example: vesafb)
		 */
		if (p->flags & IORESOURCE_BUSY)
			continue;

		pr_warn("resource sanity check: requesting [mem %pa-%pa], which spans more than %s %pR\n",
			&addr, &end, p->name, p);
		err = -1;
		break;
	}
	read_unlock(&resource_lock);

	return err;
}

#ifdef CONFIG_STRICT_DEVMEM
static int strict_iomem_checks = 1;
#else
static int strict_iomem_checks;
#endif

/*
 * Check if an address is exclusive to the kernel and must not be mapped to
 * user space, for example, via /dev/mem.
 *
 * Returns true if exclusive to the kernel, otherwise returns false.
 */
bool resource_is_exclusive(struct resource *root, u64 addr, resource_size_t size)
{
	const unsigned int exclusive_system_ram = IORESOURCE_SYSTEM_RAM |
						  IORESOURCE_EXCLUSIVE;
	bool skip_children = false, err = false;
	struct resource *p;

	read_lock(&resource_lock);
	for_each_resource(root, p, skip_children) {
		if (p->start >= addr + size)
			break;
		if (p->end < addr) {
			skip_children = true;
			continue;
		}
		skip_children = false;

		/*
		 * IORESOURCE_SYSTEM_RAM resources are exclusive if
		 * IORESOURCE_EXCLUSIVE is set, even if they
		 * are not busy and even if "iomem=relaxed" is set. The
		 * responsible driver dynamically adds/removes system RAM within
		 * such an area and uncontrolled access is dangerous.
		 */
		if ((p->flags & exclusive_system_ram) == exclusive_system_ram) {
			err = true;
			break;
		}

		/*
		 * A resource is exclusive if IORESOURCE_EXCLUSIVE is set
		 * or CONFIG_IO_STRICT_DEVMEM is enabled and the
		 * resource is busy.
		 */
		if (!strict_iomem_checks || !(p->flags & IORESOURCE_BUSY))
			continue;
		if (IS_ENABLED(CONFIG_IO_STRICT_DEVMEM)
				|| p->flags & IORESOURCE_EXCLUSIVE) {
			err = true;
			break;
		}
	}
	read_unlock(&resource_lock);

	return err;
}

bool iomem_is_exclusive(u64 addr)
{
	return resource_is_exclusive(&iomem_resource, addr & PAGE_MASK,
				     PAGE_SIZE);
}

struct resource_entry *resource_list_create_entry(struct resource *res,
						  size_t extra_size)
{
	struct resource_entry *entry;

	entry = kzalloc(sizeof(*entry) + extra_size, GFP_KERNEL);
	if (entry) {
		INIT_LIST_HEAD(&entry->node);
		entry->res = res ? res : &entry->__res;
	}

	return entry;
}
EXPORT_SYMBOL(resource_list_create_entry);

void resource_list_free(struct list_head *head)
{
	struct resource_entry *entry, *tmp;

	list_for_each_entry_safe(entry, tmp, head, node)
		resource_list_destroy_entry(entry);
}
EXPORT_SYMBOL(resource_list_free);

#ifdef CONFIG_GET_FREE_REGION
#define GFR_DESCENDING		(1UL << 0)
#define GFR_REQUEST_REGION	(1UL << 1)
#ifdef PA_SECTION_SHIFT
#define GFR_DEFAULT_ALIGN	(1UL << PA_SECTION_SHIFT)
#else
#define GFR_DEFAULT_ALIGN	PAGE_SIZE
#endif

static resource_size_t gfr_start(struct resource *base, resource_size_t size,
				 resource_size_t align, unsigned long flags)
{
	if (flags & GFR_DESCENDING) {
		resource_size_t end;

		end = min_t(resource_size_t, base->end, DIRECT_MAP_PHYSMEM_END);
		return end - size + 1;
	}

	return ALIGN(max(base->start, align), align);
}

static bool gfr_continue(struct resource *base, resource_size_t addr,
			 resource_size_t size, unsigned long flags)
{
	if (flags & GFR_DESCENDING)
		return addr > size && addr >= base->start;
	/*
	 * In the ascend case be careful that the last increment by
	 * @size did not wrap 0.
	 */
	return addr > addr - size &&
	       addr <= min_t(resource_size_t, base->end, DIRECT_MAP_PHYSMEM_END);
}

static resource_size_t gfr_next(resource_size_t addr, resource_size_t size,
				unsigned long flags)
{
	if (flags & GFR_DESCENDING)
		return addr - size;
	return addr + size;
}

static void remove_free_mem_region(void *_res)
{
	struct resource *res = _res;

	if (res->parent)
		remove_resource(res);
	free_resource(res);
}

static struct resource *
get_free_mem_region(struct device *dev, struct resource *base,
		    resource_size_t size, const unsigned long align,
		    const char *name, const unsigned long desc,
		    const unsigned long flags)
{
	resource_size_t addr;
	struct resource *res;
	struct region_devres *dr = NULL;

	size = ALIGN(size, align);

	res = alloc_resource(GFP_KERNEL);
	if (!res)
		return ERR_PTR(-ENOMEM);

	if (dev && (flags & GFR_REQUEST_REGION)) {
		dr = devres_alloc(devm_region_release,
				sizeof(struct region_devres), GFP_KERNEL);
		if (!dr) {
			free_resource(res);
			return ERR_PTR(-ENOMEM);
		}
	} else if (dev) {
		if (devm_add_action_or_reset(dev, remove_free_mem_region, res))
			return ERR_PTR(-ENOMEM);
	}

	write_lock(&resource_lock);
	for (addr = gfr_start(base, size, align, flags);
	     gfr_continue(base, addr, align, flags);
	     addr = gfr_next(addr, align, flags)) {
		if (__region_intersects(base, addr, size, 0, IORES_DESC_NONE) !=
		    REGION_DISJOINT)
			continue;

		if (flags & GFR_REQUEST_REGION) {
			if (__request_region_locked(res, &iomem_resource, addr,
						    size, name, 0))
				break;

			if (dev) {
				dr->parent = &iomem_resource;
				dr->start = addr;
				dr->n = size;
				devres_add(dev, dr);
			}

			res->desc = desc;
			write_unlock(&resource_lock);


			/*
			 * A driver is claiming this region so revoke any
			 * mappings.
			 */
			revoke_iomem(res);
		} else {
			*res = DEFINE_RES_NAMED_DESC(addr, size, name, IORESOURCE_MEM, desc);

			/*
			 * Only succeed if the resource hosts an exclusive
			 * range after the insert
			 */
			if (__insert_resource(base, res) || res->child)
				break;

			write_unlock(&resource_lock);
		}

		return res;
	}
	write_unlock(&resource_lock);

	if (flags & GFR_REQUEST_REGION) {
		free_resource(res);
		devres_free(dr);
	} else if (dev)
		devm_release_action(dev, remove_free_mem_region, res);

	return ERR_PTR(-ERANGE);
}

/**
 * devm_request_free_mem_region - find free region for device private memory
 *
 * @dev: device struct to bind the resource to
 * @size: size in bytes of the device memory to add
 * @base: resource tree to look in
 *
 * This function tries to find an empty range of physical address big enough to
 * contain the new resource, so that it can later be hotplugged as ZONE_DEVICE
 * memory, which in turn allocates struct pages.
 */
struct resource *devm_request_free_mem_region(struct device *dev,
		struct resource *base, unsigned long size)
{
	unsigned long flags = GFR_DESCENDING | GFR_REQUEST_REGION;

	return get_free_mem_region(dev, base, size, GFR_DEFAULT_ALIGN,
				   dev_name(dev),
				   IORES_DESC_DEVICE_PRIVATE_MEMORY, flags);
}
EXPORT_SYMBOL_GPL(devm_request_free_mem_region);

struct resource *request_free_mem_region(struct resource *base,
		unsigned long size, const char *name)
{
	unsigned long flags = GFR_DESCENDING | GFR_REQUEST_REGION;

	return get_free_mem_region(NULL, base, size, GFR_DEFAULT_ALIGN, name,
				   IORES_DESC_DEVICE_PRIVATE_MEMORY, flags);
}
EXPORT_SYMBOL_GPL(request_free_mem_region);

/**
 * alloc_free_mem_region - find a free region relative to @base
 * @base: resource that will parent the new resource
 * @size: size in bytes of memory to allocate from @base
 * @align: alignment requirements for the allocation
 * @name: resource name
 *
 * Buses like CXL, that can dynamically instantiate new memory regions,
 * need a method to allocate physical address space for those regions.
 * Allocate and insert a new resource to cover a free, unclaimed by a
 * descendant of @base, range in the span of @base.
 */
struct resource *alloc_free_mem_region(struct resource *base,
				       unsigned long size, unsigned long align,
				       const char *name)
{
	/* Default of ascending direction and insert resource */
	unsigned long flags = 0;

	return get_free_mem_region(NULL, base, size, align, name,
				   IORES_DESC_NONE, flags);
}
EXPORT_SYMBOL_GPL(alloc_free_mem_region);
#endif /* CONFIG_GET_FREE_REGION */

static int __init strict_iomem(char *str)
{
	if (strstr(str, "relaxed"))
		strict_iomem_checks = 0;
	if (strstr(str, "strict"))
		strict_iomem_checks = 1;
	return 1;
}

static int iomem_fs_init_fs_context(struct fs_context *fc)
{
	return init_pseudo(fc, DEVMEM_MAGIC) ? 0 : -ENOMEM;
}

static struct file_system_type iomem_fs_type = {
	.name		= "iomem",
	.owner		= THIS_MODULE,
	.init_fs_context = iomem_fs_init_fs_context,
	.kill_sb	= kill_anon_super,
};

static int __init iomem_init_inode(void)
{
	static struct vfsmount *iomem_vfs_mount;
	static int iomem_fs_cnt;
	struct inode *inode;
	int rc;

	rc = simple_pin_fs(&iomem_fs_type, &iomem_vfs_mount, &iomem_fs_cnt);
	if (rc < 0) {
		pr_err("Cannot mount iomem pseudo filesystem: %d\n", rc);
		return rc;
	}

	inode = alloc_anon_inode(iomem_vfs_mount->mnt_sb);
	if (IS_ERR(inode)) {
		rc = PTR_ERR(inode);
		pr_err("Cannot allocate inode for iomem: %d\n", rc);
		simple_release_fs(&iomem_vfs_mount, &iomem_fs_cnt);
		return rc;
	}

	/*
	 * Publish iomem revocation inode initialized.
	 * Pairs with smp_load_acquire() in revoke_iomem().
	 */
	smp_store_release(&iomem_inode, inode);

	return 0;
}

fs_initcall(iomem_init_inode);

__setup("iomem=", strict_iomem);
