Skip to content

Commit

Permalink
memremap: fix highmem support
Browse files Browse the repository at this point in the history
Currently memremap checks if the range is "System RAM" and returns the
kernel linear address.  This is broken for highmem platforms where a
range may be "System RAM", but is not part of the kernel linear mapping.
Fallback to ioremap_cache() in these cases, to let the arch code attempt
to handle it.

Note that ARM ioremap will WARN when attempting to remap ram, and in
that case the caller needs to be fixed.  For this reason, existing
ioremap_cache() usages for ARM are already trained to avoid attempts to
remap ram.

The impact of this bug is low for now since the pmem driver is the only
user of memremap(), but this is important to fix before more conversions
to memremap arrive in 4.4.

Cc: Rafael J. Wysocki <[email protected]>
Reported-by: Ard Biesheuvel <[email protected]>
Acked-by: Ard Biesheuvel <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
  • Loading branch information
djbw committed Oct 26, 2015
1 parent 25cb62b commit 182475b
Showing 1 changed file with 12 additions and 2 deletions.
14 changes: 12 additions & 2 deletions kernel/memremap.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ __weak void __iomem *ioremap_cache(resource_size_t offset, unsigned long size)
}
#endif

static void *try_ram_remap(resource_size_t offset, size_t size)
{
struct page *page = pfn_to_page(offset >> PAGE_SHIFT);

/* In the simple case just return the existing linear address */
if (!PageHighMem(page))
return __va(offset);
return NULL; /* fallback to ioremap_cache */
}

/**
* memremap() - remap an iomem_resource as cacheable memory
* @offset: iomem resource start address
Expand Down Expand Up @@ -66,8 +76,8 @@ void *memremap(resource_size_t offset, size_t size, unsigned long flags)
* the requested range is potentially in "System RAM"
*/
if (is_ram == REGION_INTERSECTS)
addr = __va(offset);
else
addr = try_ram_remap(offset, size);
if (!addr)
addr = ioremap_cache(offset, size);
}

Expand Down

0 comments on commit 182475b

Please sign in to comment.