On 30 October 2015 at 21:19, Dan Williams <dan.j.willi...@intel.com> wrote: > 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 <rafael.j.wyso...@intel.com> > Reported-by: Ard Biesheuvel <ard.biesheu...@linaro.org> > Signed-off-by: Dan Williams <dan.j.willi...@intel.com>
Acked-by: Ard Biesheuvel <ard.biesheu...@linaro.org> This does still leave the issue that we assume that lowmem memory ranges listed as 'System RAM' in /proc/iomem are always covered by the linear mapping. Since the semantics of 'System RAM' are not documented anywhere (as far as I know), this may not be universally true on all architectures. > --- > kernel/memremap.c | 14 ++++++++++++-- > 1 file changed, 12 insertions(+), 2 deletions(-) > > diff --git a/kernel/memremap.c b/kernel/memremap.c > index 72b0c66628b6..9d6b55587eaa 100644 > --- a/kernel/memremap.c > +++ b/kernel/memremap.c > @@ -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 > @@ -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); > } > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/