drivers: remoteproc: ti_k3_m4: use memremap for no-map reserved memory
Replace devm_ioremap_wc() with memremap(MEMREMAP_WB) for no-map reserved-memory regions that have struct page backing. Using ioremap_wc() on a region backed by struct pages violates ARM64 memory aliasing rules by creating conflicting cached and write-combining mappings of the same physical pages. This can cause SIGBUS faults in unrelated userspace processes. Add a devm cleanup action to call memunmap() on the mapped region when the device is released. Signed-off-by: Heinrich Toews <ht@twx-software.de>
This commit is contained in:
@@ -525,6 +525,12 @@ static void k3_m4_rproc_dev_mem_release(void *data)
|
||||
of_reserved_mem_device_release(dev);
|
||||
}
|
||||
|
||||
|
||||
static void k3_m4_rproc_rmem_release(void *data)
|
||||
{
|
||||
memunmap(data);
|
||||
}
|
||||
|
||||
static int k3_m4_reserved_mem_init(struct k3_m4_rproc *kproc)
|
||||
{
|
||||
struct device *dev = kproc->dev;
|
||||
@@ -580,12 +586,23 @@ static int k3_m4_reserved_mem_init(struct k3_m4_rproc *kproc)
|
||||
/* 64-bit address regions currently not supported */
|
||||
kproc->rmem[i].dev_addr = (u32)rmem->base;
|
||||
kproc->rmem[i].size = rmem->size;
|
||||
kproc->rmem[i].cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size);
|
||||
/*
|
||||
* Use memremap(MEMREMAP_WB) instead of ioremap_wc() for no-map
|
||||
* reserved-memory regions that have struct page backing.
|
||||
* ioremap_wc() on a region with struct page violates ARM64 memory
|
||||
* aliasing rules (cached vs. WC mapping of the same physical page)
|
||||
* and causes SIGBUS in unrelated userspace processes.
|
||||
*/
|
||||
kproc->rmem[i].cpu_addr = (__force void __iomem *)memremap(rmem->base, rmem->size, MEMREMAP_WB);
|
||||
if (!kproc->rmem[i].cpu_addr) {
|
||||
dev_err(dev, "failed to map reserved memory#%d at %pa of size %pa\n",
|
||||
i + 1, &rmem->base, &rmem->size);
|
||||
return -ENOMEM;
|
||||
}
|
||||
ret = devm_add_action_or_reset(dev, k3_m4_rproc_rmem_release,
|
||||
(__force void *)kproc->rmem[i].cpu_addr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_dbg(dev, "reserved memory%d: bus addr %pa size 0x%zx va %pK da 0x%x\n",
|
||||
i + 1, &kproc->rmem[i].bus_addr,
|
||||
|
||||
Reference in New Issue
Block a user