ARM: ensure initial page tables are setup for SMP systems
Mapping the same memory using two different attributes (memory type, shareability, cacheability) is unpredictable. During boot, we encounter a situation when we're updating the kernel's page tables which can lead to dirty cache lines existing in the cache which are subsequently missed. This causes stack corruption, and therefore a crash. Therefore, ensure that the shared and cacheability settings matches the configuration that will be used later; this together with the restriction in early_cachepolicy() ensures that we won't create a mismatch during boot. Acked-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
6603a4fd51
commit
4b46d64165
|
@ -117,6 +117,13 @@ static void __init early_cachepolicy(char **p)
|
||||||
}
|
}
|
||||||
if (i == ARRAY_SIZE(cache_policies))
|
if (i == ARRAY_SIZE(cache_policies))
|
||||||
printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n");
|
printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n");
|
||||||
|
/*
|
||||||
|
* This restriction is partly to do with the way we boot; it is
|
||||||
|
* unpredictable to have memory mapped using two different sets of
|
||||||
|
* memory attributes (shared, type, and cache attribs). We can not
|
||||||
|
* change these attributes once the initial assembly has setup the
|
||||||
|
* page tables.
|
||||||
|
*/
|
||||||
if (cpu_architecture() >= CPU_ARCH_ARMv6) {
|
if (cpu_architecture() >= CPU_ARCH_ARMv6) {
|
||||||
printk(KERN_WARNING "Only cachepolicy=writeback supported on ARMv6 and later\n");
|
printk(KERN_WARNING "Only cachepolicy=writeback supported on ARMv6 and later\n");
|
||||||
cachepolicy = CPOLICY_WRITEBACK;
|
cachepolicy = CPOLICY_WRITEBACK;
|
||||||
|
|
|
@ -32,8 +32,10 @@
|
||||||
|
|
||||||
#ifndef CONFIG_SMP
|
#ifndef CONFIG_SMP
|
||||||
#define TTB_FLAGS TTB_RGN_WBWA
|
#define TTB_FLAGS TTB_RGN_WBWA
|
||||||
|
#define PMD_FLAGS PMD_SECT_WB
|
||||||
#else
|
#else
|
||||||
#define TTB_FLAGS TTB_RGN_WBWA|TTB_S
|
#define TTB_FLAGS TTB_RGN_WBWA|TTB_S
|
||||||
|
#define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ENTRY(cpu_v6_proc_init)
|
ENTRY(cpu_v6_proc_init)
|
||||||
|
@ -222,10 +224,9 @@ __v6_proc_info:
|
||||||
.long 0x0007b000
|
.long 0x0007b000
|
||||||
.long 0x0007f000
|
.long 0x0007f000
|
||||||
.long PMD_TYPE_SECT | \
|
.long PMD_TYPE_SECT | \
|
||||||
PMD_SECT_BUFFERABLE | \
|
|
||||||
PMD_SECT_CACHEABLE | \
|
|
||||||
PMD_SECT_AP_WRITE | \
|
PMD_SECT_AP_WRITE | \
|
||||||
PMD_SECT_AP_READ
|
PMD_SECT_AP_READ | \
|
||||||
|
PMD_FLAGS
|
||||||
.long PMD_TYPE_SECT | \
|
.long PMD_TYPE_SECT | \
|
||||||
PMD_SECT_XN | \
|
PMD_SECT_XN | \
|
||||||
PMD_SECT_AP_WRITE | \
|
PMD_SECT_AP_WRITE | \
|
||||||
|
|
|
@ -33,9 +33,11 @@
|
||||||
#ifndef CONFIG_SMP
|
#ifndef CONFIG_SMP
|
||||||
/* PTWs cacheable, inner WB not shareable, outer WB not shareable */
|
/* PTWs cacheable, inner WB not shareable, outer WB not shareable */
|
||||||
#define TTB_FLAGS TTB_IRGN_WB|TTB_RGN_OC_WB
|
#define TTB_FLAGS TTB_IRGN_WB|TTB_RGN_OC_WB
|
||||||
|
#define PMD_FLAGS PMD_SECT_WB
|
||||||
#else
|
#else
|
||||||
/* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
|
/* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
|
||||||
#define TTB_FLAGS TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA
|
#define TTB_FLAGS TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA
|
||||||
|
#define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ENTRY(cpu_v7_proc_init)
|
ENTRY(cpu_v7_proc_init)
|
||||||
|
@ -326,10 +328,9 @@ __v7_proc_info:
|
||||||
.long 0x000f0000 @ Required ID value
|
.long 0x000f0000 @ Required ID value
|
||||||
.long 0x000f0000 @ Mask for ID
|
.long 0x000f0000 @ Mask for ID
|
||||||
.long PMD_TYPE_SECT | \
|
.long PMD_TYPE_SECT | \
|
||||||
PMD_SECT_BUFFERABLE | \
|
|
||||||
PMD_SECT_CACHEABLE | \
|
|
||||||
PMD_SECT_AP_WRITE | \
|
PMD_SECT_AP_WRITE | \
|
||||||
PMD_SECT_AP_READ
|
PMD_SECT_AP_READ | \
|
||||||
|
PMD_FLAGS
|
||||||
.long PMD_TYPE_SECT | \
|
.long PMD_TYPE_SECT | \
|
||||||
PMD_SECT_XN | \
|
PMD_SECT_XN | \
|
||||||
PMD_SECT_AP_WRITE | \
|
PMD_SECT_AP_WRITE | \
|
||||||
|
|
Reference in New Issue