Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1259771 > unrolled thread

[for 4.3-final PATCH v2] memremap: fix highmem support

Started byDan Williams <dan.j.williams@intel.com>
First post2015-10-30 21:30 +0100
Last post2015-10-31 07:40 +0100
Articles 2 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [for 4.3-final PATCH v2] memremap: fix highmem support Dan Williams <dan.j.williams@intel.com> - 2015-10-30 21:30 +0100
    Re: [for 4.3-final PATCH v2] memremap: fix highmem support Ard Biesheuvel <ard.biesheuvel@linaro.org> - 2015-10-31 07:40 +0100

#1259771 — [for 4.3-final PATCH v2] memremap: fix highmem support

FromDan Williams <dan.j.williams@intel.com>
Date2015-10-30 21:30 +0100
Subject[for 4.3-final PATCH v2] memremap: fix highmem support
Message-ID<qpotb-1Wd-1@gated-at.bofh.it>
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.wysocki@intel.com>
Reported-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 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 majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1259942

FromArd Biesheuvel <ard.biesheuvel@linaro.org>
Date2015-10-31 07:40 +0100
Message-ID<qpxZw-7SL-1@gated-at.bofh.it>
In reply to#1259771
On 30 October 2015 at 21:19, Dan Williams <dan.j.williams@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.wysocki@intel.com>
> Reported-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>

Acked-by: Ard Biesheuvel <ard.biesheuvel@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 majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web