Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d9c9998b authored by Chris Goldsworthy's avatar Chris Goldsworthy
Browse files

of: reserved_mem: Check that memory reserved in device tree is in use



Inside of dma_alloc_attrs(), verify that devices with a reserved memory
region are actually using the region, in order to prevent wastage of
memory.

Change-Id: I56852a761d3253ec2a3a7db0f6501c73983e55c6
Signed-off-by: default avatarChris Goldsworthy <cgoldswo@codeaurora.org>
parent b94e0753
Loading
Loading
Loading
Loading
+10 −0
Original line number Original line Diff line number Diff line
@@ -86,6 +86,16 @@ config OF_RESERVED_MEM
	depends on OF_EARLY_FLATTREE
	depends on OF_EARLY_FLATTREE
	default y if DMA_DECLARE_COHERENT || DMA_CMA
	default y if DMA_DECLARE_COHERENT || DMA_CMA


config OF_RESERVED_MEM_CHECK
	bool "Reserved memory registration check"
	depends on OF_RESERVED_MEM
	help
	  If a device has a reserved memory region and allocates memory
	  through the DMA API, check to see if the device and region have been
	  associated through a call to of_reserved_mem_device_init_by_idx()
	  before performing an allocation. If the association hasn't occurred,
	  WARN_ON.

config OF_RESOLVE
config OF_RESOLVE
	bool
	bool


+45 −0
Original line number Original line Diff line number Diff line
@@ -385,6 +385,51 @@ void of_reserved_mem_device_release(struct device *dev)
}
}
EXPORT_SYMBOL_GPL(of_reserved_mem_device_release);
EXPORT_SYMBOL_GPL(of_reserved_mem_device_release);


#ifdef CONFIG_OF_RESERVED_MEM_CHECK
/**
 * of_reserved_mem_device_is_init() - test if a device's reserved memory
 *				      will be used in DMA allocations
 * @dev: device we want to perform test on
 *
 * Check if a device and its reserved memory region (if it has one) have
 * been associated with one another through a call to
 * of_reserved_mem_device_init_by_idx().
 *
 * Return false if the device has reserved memory and it's not in use, true
 * otherwise.
 */
bool of_reserved_mem_device_is_init(struct device *dev)
{
	struct device_node *mem_dev_node;
	struct rmem_assigned_device *rd;
	bool ret = false;

	if (!dev->of_node)
		return true;

	mem_dev_node = of_parse_phandle(dev->of_node, "memory-region", 0);
	if (!mem_dev_node)
		return true;

	if (!of_device_is_available(mem_dev_node) || !__find_rmem(mem_dev_node))
		goto exit;
	of_node_put(mem_dev_node);

	mutex_lock(&of_rmem_assigned_device_mutex);
	list_for_each_entry(rd, &of_rmem_assigned_device_list, list) {
		if (rd->dev == dev) {
			ret = true;
			break;
		}
	}
	mutex_unlock(&of_rmem_assigned_device_mutex);
	return ret;
exit:
	of_node_put(mem_dev_node);
	return true;
}
#endif /* CONFIG_OF_RESERVED_MEM_CHECK */

/**
/**
 * of_reserved_mem_lookup() - acquire reserved_mem from a device node
 * of_reserved_mem_lookup() - acquire reserved_mem from a device node
 * @np:		node pointer of the desired reserved-memory region
 * @np:		node pointer of the desired reserved-memory region
+9 −0
Original line number Original line Diff line number Diff line
@@ -35,6 +35,15 @@ int of_reserved_mem_device_init_by_idx(struct device *dev,
				       struct device_node *np, int idx);
				       struct device_node *np, int idx);
void of_reserved_mem_device_release(struct device *dev);
void of_reserved_mem_device_release(struct device *dev);


#ifdef CONFIG_OF_RESERVED_MEM_CHECK
bool of_reserved_mem_device_is_init(struct device *dev);
#else /* !CONFIG_OF_RESERVED_MEM_CHECK */
static inline bool of_reserved_mem_device_is_init(struct device *dev)
{
	return true;
}
#endif /* CONFIG_OF_RESERVED_MEM_CHECK */

void fdt_init_reserved_mem(void);
void fdt_init_reserved_mem(void);
void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
			       phys_addr_t base, phys_addr_t size);
			       phys_addr_t base, phys_addr_t size);
+3 −0
Original line number Original line Diff line number Diff line
@@ -12,6 +12,7 @@
#include <linux/export.h>
#include <linux/export.h>
#include <linux/gfp.h>
#include <linux/gfp.h>
#include <linux/of_device.h>
#include <linux/of_device.h>
#include <linux/of_reserved_mem.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/vmalloc.h>


@@ -284,6 +285,8 @@ void *dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle,


	WARN_ON_ONCE(!dev->coherent_dma_mask);
	WARN_ON_ONCE(!dev->coherent_dma_mask);


	WARN_ON(!of_reserved_mem_device_is_init(dev));

	if (dma_alloc_from_dev_coherent(dev, size, dma_handle, &cpu_addr))
	if (dma_alloc_from_dev_coherent(dev, size, dma_handle, &cpu_addr))
		return cpu_addr;
		return cpu_addr;