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>
This commit is contained in:
parent
deb6001509
commit
a4279e6202
1 changed files with 9 additions and 5 deletions
|
@ -16,7 +16,7 @@
|
||||||
#include <asm/meminit.h>
|
#include <asm/meminit.h>
|
||||||
|
|
||||||
static inline void __iomem *
|
static inline void __iomem *
|
||||||
__ioremap (unsigned long phys_addr)
|
__ioremap_uc(unsigned long phys_addr)
|
||||||
{
|
{
|
||||||
return (void __iomem *) (__IA64_UNCACHED_OFFSET | phys_addr);
|
return (void __iomem *) (__IA64_UNCACHED_OFFSET | phys_addr);
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,11 @@ __ioremap (unsigned long phys_addr)
|
||||||
void __iomem *
|
void __iomem *
|
||||||
early_ioremap (unsigned long phys_addr, unsigned long size)
|
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 *
|
void __iomem *
|
||||||
|
@ -47,7 +51,7 @@ ioremap (unsigned long phys_addr, unsigned long size)
|
||||||
if (attr & EFI_MEMORY_WB)
|
if (attr & EFI_MEMORY_WB)
|
||||||
return (void __iomem *) phys_to_virt(phys_addr);
|
return (void __iomem *) phys_to_virt(phys_addr);
|
||||||
else if (attr & EFI_MEMORY_UC)
|
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
|
* 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 (void __iomem *) (offset + (char __iomem *)addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return __ioremap(phys_addr);
|
return __ioremap_uc(phys_addr);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ioremap);
|
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)
|
if (kern_mem_attribute(phys_addr, size) & EFI_MEMORY_WB)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return __ioremap(phys_addr);
|
return __ioremap_uc(phys_addr);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ioremap_nocache);
|
EXPORT_SYMBOL(ioremap_nocache);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue