summaryrefslogtreecommitdiffstats
path: root/arch/ia64/mm
diff options
context:
space:
mode:
authorLi, Zhen-Hua <zhen-hual@hp.com>2013-03-18 10:45:43 +0800
committerTony Luck <tony.luck@intel.com>2013-03-19 16:14:52 -0700
commita4279e6202bbd08ac6038234571ac639c98879cf (patch)
treecd3e2a755a22304e695494115484a15fdb038d05 /arch/ia64/mm
parentdeb60015096102f9842b631dcad98a05001268e9 (diff)
downloadlinux-a4279e6202bbd08ac6038234571ac639c98879cf.tar.gz
linux-a4279e6202bbd08ac6038234571ac639c98879cf.tar.xz
Add WB/UC check for early_ioremap
On ia64 system, the function early_ioremap returned an uncached memory reference without checking whether this was consistent with existing mappings. This causes efi error and the kernel failed during boot. Add a check to test whether memory has EFI_MEMORY_WB set. Use the function kern_mem_attribute() in early_iomap() function to provide appropriate cacheable or uncacheable mapped address. See the document Documentation/ia64/aliasing.txt for more details. Signed-off-by: Li, Zhen-Hua <zhen-hual@hp.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/mm')
-rw-r--r--arch/ia64/mm/ioremap.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c
index 3dccdd8eb275..43964cde6214 100644
--- a/arch/ia64/mm/ioremap.c
+++ b/arch/ia64/mm/ioremap.c
@@ -16,7 +16,7 @@
#include <asm/meminit.h>
static inline void __iomem *
-__ioremap (unsigned long phys_addr)
+__ioremap_uc(unsigned long phys_addr)
{
return (void __iomem *) (__IA64_UNCACHED_OFFSET | phys_addr);
}
@@ -24,7 +24,11 @@ __ioremap (unsigned long phys_addr)
void __iomem *
early_ioremap (unsigned long phys_addr, unsigned long size)
{
- return __ioremap(phys_addr);
+ u64 attr;
+ attr = kern_mem_attribute(phys_addr, size);
+ if (attr & EFI_MEMORY_WB)
+ return (void __iomem *) phys_to_virt(phys_addr);
+ return __ioremap_uc(phys_addr);
}
void __iomem *
@@ -47,7 +51,7 @@ ioremap (unsigned long phys_addr, unsigned long size)
if (attr & EFI_MEMORY_WB)
return (void __iomem *) phys_to_virt(phys_addr);
else if (attr & EFI_MEMORY_UC)
- return __ioremap(phys_addr);
+ return __ioremap_uc(phys_addr);
/*
* Some chipsets don't support UC access to memory. If
@@ -93,7 +97,7 @@ ioremap (unsigned long phys_addr, unsigned long size)
return (void __iomem *) (offset + (char __iomem *)addr);
}
- return __ioremap(phys_addr);
+ return __ioremap_uc(phys_addr);
}
EXPORT_SYMBOL(ioremap);
@@ -103,7 +107,7 @@ ioremap_nocache (unsigned long phys_addr, unsigned long size)
if (kern_mem_attribute(phys_addr, size) & EFI_MEMORY_WB)
return NULL;
- return __ioremap(phys_addr);
+ return __ioremap_uc(phys_addr);
}
EXPORT_SYMBOL(ioremap_nocache);