diff options
| author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-11-01 12:44:24 -0500 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-11-02 11:59:59 -0500 |
| commit | 4b46d6416548fb6a0940dfd9911fd895eb6247b3 (patch) | |
| tree | c2a890342019c9df5e6187ad185a28208b786341 | |
| parent | 6603a4fd5195a004dec5f9568e38ff76bae630c1 (diff) | |
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>
| -rw-r--r-- | arch/arm/mm/mmu.c | 7 | ||||
| -rw-r--r-- | arch/arm/mm/proc-v6.S | 7 | ||||
| -rw-r--r-- | arch/arm/mm/proc-v7.S | 7 |
3 files changed, 15 insertions, 6 deletions
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 02243eeccf50..ea67be0223ac 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
| @@ -117,6 +117,13 @@ static void __init early_cachepolicy(char **p) | |||
| 117 | } | 117 | } |
| 118 | if (i == ARRAY_SIZE(cache_policies)) | 118 | if (i == ARRAY_SIZE(cache_policies)) |
| 119 | printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n"); | 119 | printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n"); |
| 120 | /* | ||
| 121 | * This restriction is partly to do with the way we boot; it is | ||
| 122 | * unpredictable to have memory mapped using two different sets of | ||
| 123 | * memory attributes (shared, type, and cache attribs). We can not | ||
| 124 | * change these attributes once the initial assembly has setup the | ||
| 125 | * page tables. | ||
| 126 | */ | ||
| 120 | if (cpu_architecture() >= CPU_ARCH_ARMv6) { | 127 | if (cpu_architecture() >= CPU_ARCH_ARMv6) { |
| 121 | printk(KERN_WARNING "Only cachepolicy=writeback supported on ARMv6 and later\n"); | 128 | printk(KERN_WARNING "Only cachepolicy=writeback supported on ARMv6 and later\n"); |
| 122 | cachepolicy = CPOLICY_WRITEBACK; | 129 | cachepolicy = CPOLICY_WRITEBACK; |
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 194737d60a22..70f75d2e3ead 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S | |||
| @@ -32,8 +32,10 @@ | |||
| 32 | 32 | ||
| 33 | #ifndef CONFIG_SMP | 33 | #ifndef CONFIG_SMP |
| 34 | #define TTB_FLAGS TTB_RGN_WBWA | 34 | #define TTB_FLAGS TTB_RGN_WBWA |
| 35 | #define PMD_FLAGS PMD_SECT_WB | ||
| 35 | #else | 36 | #else |
| 36 | #define TTB_FLAGS TTB_RGN_WBWA|TTB_S | 37 | #define TTB_FLAGS TTB_RGN_WBWA|TTB_S |
| 38 | #define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S | ||
| 37 | #endif | 39 | #endif |
| 38 | 40 | ||
| 39 | ENTRY(cpu_v6_proc_init) | 41 | ENTRY(cpu_v6_proc_init) |
| @@ -222,10 +224,9 @@ __v6_proc_info: | |||
| 222 | .long 0x0007b000 | 224 | .long 0x0007b000 |
| 223 | .long 0x0007f000 | 225 | .long 0x0007f000 |
| 224 | .long PMD_TYPE_SECT | \ | 226 | .long PMD_TYPE_SECT | \ |
| 225 | PMD_SECT_BUFFERABLE | \ | ||
| 226 | PMD_SECT_CACHEABLE | \ | ||
| 227 | PMD_SECT_AP_WRITE | \ | 227 | PMD_SECT_AP_WRITE | \ |
| 228 | PMD_SECT_AP_READ | 228 | PMD_SECT_AP_READ | \ |
| 229 | PMD_FLAGS | ||
| 229 | .long PMD_TYPE_SECT | \ | 230 | .long PMD_TYPE_SECT | \ |
| 230 | PMD_SECT_XN | \ | 231 | PMD_SECT_XN | \ |
| 231 | PMD_SECT_AP_WRITE | \ | 232 | PMD_SECT_AP_WRITE | \ |
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 23ebcf6eab9f..eeeed01ee44a 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
| @@ -33,9 +33,11 @@ | |||
| 33 | #ifndef CONFIG_SMP | 33 | #ifndef CONFIG_SMP |
| 34 | /* PTWs cacheable, inner WB not shareable, outer WB not shareable */ | 34 | /* PTWs cacheable, inner WB not shareable, outer WB not shareable */ |
| 35 | #define TTB_FLAGS TTB_IRGN_WB|TTB_RGN_OC_WB | 35 | #define TTB_FLAGS TTB_IRGN_WB|TTB_RGN_OC_WB |
| 36 | #define PMD_FLAGS PMD_SECT_WB | ||
| 36 | #else | 37 | #else |
| 37 | /* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */ | 38 | /* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */ |
| 38 | #define TTB_FLAGS TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA | 39 | #define TTB_FLAGS TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA |
| 40 | #define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S | ||
| 39 | #endif | 41 | #endif |
| 40 | 42 | ||
| 41 | ENTRY(cpu_v7_proc_init) | 43 | ENTRY(cpu_v7_proc_init) |
| @@ -326,10 +328,9 @@ __v7_proc_info: | |||
| 326 | .long 0x000f0000 @ Required ID value | 328 | .long 0x000f0000 @ Required ID value |
| 327 | .long 0x000f0000 @ Mask for ID | 329 | .long 0x000f0000 @ Mask for ID |
| 328 | .long PMD_TYPE_SECT | \ | 330 | .long PMD_TYPE_SECT | \ |
| 329 | PMD_SECT_BUFFERABLE | \ | ||
| 330 | PMD_SECT_CACHEABLE | \ | ||
| 331 | PMD_SECT_AP_WRITE | \ | 331 | PMD_SECT_AP_WRITE | \ |
| 332 | PMD_SECT_AP_READ | 332 | PMD_SECT_AP_READ | \ |
| 333 | PMD_FLAGS | ||
| 333 | .long PMD_TYPE_SECT | \ | 334 | .long PMD_TYPE_SECT | \ |
| 334 | PMD_SECT_XN | \ | 335 | PMD_SECT_XN | \ |
| 335 | PMD_SECT_AP_WRITE | \ | 336 | PMD_SECT_AP_WRITE | \ |
