* [GIT PULL] memremap fix for 4.3 (v2)
@ 2015-11-01 20:24 ` Williams, Dan J
0 siblings, 0 replies; 6+ messages in thread
From: Williams, Dan J @ 2015-11-01 20:24 UTC (permalink / raw)
To: linux-arm-kernel
Hi Linus, please pull from...
git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm libnvdimm-fixes
...to receive a reworked version of the memremap highmem fix. The
change since v1 is dropping the kmap fallback.
---
The new memremap() api introduced in the 4.3 cycle to unify/replace
ioremap_cache() and ioremap_wt() is mishandling the highmem case. This
patch has received a build success notification from a 0day-kbuild-robot
run and has received an ack from Ard.
The following changes since commit 25cb62b76430a91cc6195f902e61c2cb84ade622:
Linux 4.3-rc5 (2015-10-11 11:09:45 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm libnvdimm-fixes
for you to fetch changes up to 182475b7a2831abf7e6ca83b2aced0bef5dcdfd3:
memremap: fix highmem support (2015-10-26 16:55:56 -0400)
----------------------------------------------------------------
Dan Williams (1):
memremap: fix highmem support
kernel/memremap.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
commit 182475b7a2831abf7e6ca83b2aced0bef5dcdfd3
Author: Dan Williams <dan.j.williams@intel.com>
Date: Mon Oct 26 16:55:56 2015 -0400
memremap: fix highmem support
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>
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
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);
}
^ permalink raw reply related [flat|nested] 6+ messages in thread* [GIT PULL] memremap fix for 4.3 (v2)
@ 2015-11-01 20:24 ` Williams, Dan J
0 siblings, 0 replies; 6+ messages in thread
From: Williams, Dan J @ 2015-11-01 20:24 UTC (permalink / raw)
To: torvalds@linux-foundation.org, akpm@linux-foundation.org
Cc: linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, ard.biesheuvel@linaro.org,
rmk+kernel@arm.linux.org.uk
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 3370 bytes --]
Hi Linus, please pull from...
git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm libnvdimm-fixes
...to receive a reworked version of the memremap highmem fix. The
change since v1 is dropping the kmap fallback.
---
The new memremap() api introduced in the 4.3 cycle to unify/replace
ioremap_cache() and ioremap_wt() is mishandling the highmem case. This
patch has received a build success notification from a 0day-kbuild-robot
run and has received an ack from Ard.
The following changes since commit 25cb62b76430a91cc6195f902e61c2cb84ade622:
Linux 4.3-rc5 (2015-10-11 11:09:45 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm libnvdimm-fixes
for you to fetch changes up to 182475b7a2831abf7e6ca83b2aced0bef5dcdfd3:
memremap: fix highmem support (2015-10-26 16:55:56 -0400)
----------------------------------------------------------------
Dan Williams (1):
memremap: fix highmem support
kernel/memremap.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
commit 182475b7a2831abf7e6ca83b2aced0bef5dcdfd3
Author: Dan Williams <dan.j.williams@intel.com>
Date: Mon Oct 26 16:55:56 2015 -0400
memremap: fix highmem support
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>
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
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);
}
ÿôèº{.nÇ+·®+%Ëÿ±éݶ\x17¥wÿº{.nÇ+·¥{±þG«éÿ{ayº\x1dÊÚë,j\a¢f£¢·hïêÿêçz_è®\x03(éÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?¨èÚ&£ø§~á¶iOæ¬z·vØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?I¥
^ permalink raw reply related [flat|nested] 6+ messages in thread* [GIT PULL] memremap fix for 4.3 (v2)
2015-11-01 20:24 ` Williams, Dan J
@ 2015-11-01 20:36 ` Russell King - ARM Linux
-1 siblings, 0 replies; 6+ messages in thread
From: Russell King - ARM Linux @ 2015-11-01 20:36 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, Nov 01, 2015 at 08:24:25PM +0000, Williams, Dan J wrote:
> 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 */
Right, so a highmem page results in this returning NULL, which will...
> @@ -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);
cause ioremap_cache() to be called. That falls through on ARM to:
__arm_ioremap_pfn_caller()
and we will hit this (as I've mentioned before through explanation
rather than quoting code):
/*
* Don't allow RAM to be mapped - this causes problems with ARMv6+
*/
if (WARN_ON(pfn_valid(pfn)))
return NULL;
--
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [GIT PULL] memremap fix for 4.3 (v2)
@ 2015-11-01 20:36 ` Russell King - ARM Linux
0 siblings, 0 replies; 6+ messages in thread
From: Russell King - ARM Linux @ 2015-11-01 20:36 UTC (permalink / raw)
To: Williams, Dan J
Cc: torvalds@linux-foundation.org, akpm@linux-foundation.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, ard.biesheuvel@linaro.org
On Sun, Nov 01, 2015 at 08:24:25PM +0000, Williams, Dan J wrote:
> 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 */
Right, so a highmem page results in this returning NULL, which will...
> @@ -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);
cause ioremap_cache() to be called. That falls through on ARM to:
__arm_ioremap_pfn_caller()
and we will hit this (as I've mentioned before through explanation
rather than quoting code):
/*
* Don't allow RAM to be mapped - this causes problems with ARMv6+
*/
if (WARN_ON(pfn_valid(pfn)))
return NULL;
--
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply [flat|nested] 6+ messages in thread* [GIT PULL] memremap fix for 4.3 (v2)
2015-11-01 20:36 ` Russell King - ARM Linux
@ 2015-11-01 20:51 ` Dan Williams
-1 siblings, 0 replies; 6+ messages in thread
From: Dan Williams @ 2015-11-01 20:51 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, Nov 1, 2015 at 12:36 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Sun, Nov 01, 2015 at 08:24:25PM +0000, Williams, Dan J wrote:
>> 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 */
>
> Right, so a highmem page results in this returning NULL, which will...
>
>> @@ -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);
>
> cause ioremap_cache() to be called. That falls through on ARM to:
>
> __arm_ioremap_pfn_caller()
>
> and we will hit this (as I've mentioned before through explanation
> rather than quoting code):
>
> /*
> * Don't allow RAM to be mapped - this causes problems with ARMv6+
> */
> if (WARN_ON(pfn_valid(pfn)))
> return NULL;
>
Right, which means the caller is broken and shouldn't be using
memremap, same as misuse of ioremap_cache today.
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [GIT PULL] memremap fix for 4.3 (v2)
@ 2015-11-01 20:51 ` Dan Williams
0 siblings, 0 replies; 6+ messages in thread
From: Dan Williams @ 2015-11-01 20:51 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: torvalds@linux-foundation.org, akpm@linux-foundation.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, ard.biesheuvel@linaro.org
On Sun, Nov 1, 2015 at 12:36 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Sun, Nov 01, 2015 at 08:24:25PM +0000, Williams, Dan J wrote:
>> 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 */
>
> Right, so a highmem page results in this returning NULL, which will...
>
>> @@ -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);
>
> cause ioremap_cache() to be called. That falls through on ARM to:
>
> __arm_ioremap_pfn_caller()
>
> and we will hit this (as I've mentioned before through explanation
> rather than quoting code):
>
> /*
> * Don't allow RAM to be mapped - this causes problems with ARMv6+
> */
> if (WARN_ON(pfn_valid(pfn)))
> return NULL;
>
Right, which means the caller is broken and shouldn't be using
memremap, same as misuse of ioremap_cache today.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-11-01 20:51 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-01 20:24 [GIT PULL] memremap fix for 4.3 (v2) Williams, Dan J
2015-11-01 20:24 ` Williams, Dan J
2015-11-01 20:36 ` Russell King - ARM Linux
2015-11-01 20:36 ` Russell King - ARM Linux
2015-11-01 20:51 ` Dan Williams
2015-11-01 20:51 ` Dan Williams
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.