diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2005-11-17 17:43:30 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-11-17 17:43:30 -0500 |
commit | 02b30839220fa3ef80a34ed6ee174fa2d9937eac (patch) | |
tree | faac60850e1e51b892622887c9f7cc37e2891e5e | |
parent | 67a1901ff498363e253b90ba132e336c925203ed (diff) |
[ARM] Fix some corner cases in new mm initialisation
Document that the VMALLOC_END address must be aligned to 2MB since
it must align with a PGD boundary.
Allocate the vectors page early so that the flush_cache_all() later
will cause any dirty cache lines in the direct mapping will be safely
written back.
Move the flush_cache_all() to the second local_flush_cache_tlb() and
remove the now redundant first local_flush_cache_tlb().
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | Documentation/arm/memory.txt | 4 | ||||
-rw-r--r-- | arch/arm/mm/init.c | 24 |
2 files changed, 16 insertions, 12 deletions
diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt index 4b1c93a8177b..dc6045577a8b 100644 --- a/Documentation/arm/memory.txt +++ b/Documentation/arm/memory.txt | |||
@@ -1,7 +1,7 @@ | |||
1 | Kernel Memory Layout on ARM Linux | 1 | Kernel Memory Layout on ARM Linux |
2 | 2 | ||
3 | Russell King <rmk@arm.linux.org.uk> | 3 | Russell King <rmk@arm.linux.org.uk> |
4 | May 21, 2004 (2.6.6) | 4 | November 17, 2005 (2.6.15) |
5 | 5 | ||
6 | This document describes the virtual memory layout which the Linux | 6 | This document describes the virtual memory layout which the Linux |
7 | kernel uses for ARM processors. It indicates which regions are | 7 | kernel uses for ARM processors. It indicates which regions are |
@@ -37,6 +37,8 @@ ff000000 ffbfffff Reserved for future expansion of DMA | |||
37 | mapping region. | 37 | mapping region. |
38 | 38 | ||
39 | VMALLOC_END feffffff Free for platform use, recommended. | 39 | VMALLOC_END feffffff Free for platform use, recommended. |
40 | VMALLOC_END must be aligned to a 2MB | ||
41 | boundary. | ||
40 | 42 | ||
41 | VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() space. | 43 | VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() space. |
42 | Memory returned by vmalloc/ioremap will | 44 | Memory returned by vmalloc/ioremap will |
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index c168f322ef8c..8b276ee38acf 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -420,7 +420,8 @@ static void __init bootmem_init(struct meminfo *mi) | |||
420 | * Set up device the mappings. Since we clear out the page tables for all | 420 | * Set up device the mappings. Since we clear out the page tables for all |
421 | * mappings above VMALLOC_END, we will remove any debug device mappings. | 421 | * mappings above VMALLOC_END, we will remove any debug device mappings. |
422 | * This means you have to be careful how you debug this function, or any | 422 | * This means you have to be careful how you debug this function, or any |
423 | * called function. (Do it by code inspection!) | 423 | * called function. This means you can't use any function or debugging |
424 | * method which may touch any device, otherwise the kernel _will_ crash. | ||
424 | */ | 425 | */ |
425 | static void __init devicemaps_init(struct machine_desc *mdesc) | 426 | static void __init devicemaps_init(struct machine_desc *mdesc) |
426 | { | 427 | { |
@@ -428,6 +429,12 @@ static void __init devicemaps_init(struct machine_desc *mdesc) | |||
428 | unsigned long addr; | 429 | unsigned long addr; |
429 | void *vectors; | 430 | void *vectors; |
430 | 431 | ||
432 | /* | ||
433 | * Allocate the vector page early. | ||
434 | */ | ||
435 | vectors = alloc_bootmem_low_pages(PAGE_SIZE); | ||
436 | BUG_ON(!vectors); | ||
437 | |||
431 | for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) | 438 | for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) |
432 | pmd_clear(pmd_off_k(addr)); | 439 | pmd_clear(pmd_off_k(addr)); |
433 | 440 | ||
@@ -461,12 +468,6 @@ static void __init devicemaps_init(struct machine_desc *mdesc) | |||
461 | create_mapping(&map); | 468 | create_mapping(&map); |
462 | #endif | 469 | #endif |
463 | 470 | ||
464 | flush_cache_all(); | ||
465 | local_flush_tlb_all(); | ||
466 | |||
467 | vectors = alloc_bootmem_low_pages(PAGE_SIZE); | ||
468 | BUG_ON(!vectors); | ||
469 | |||
470 | /* | 471 | /* |
471 | * Create a mapping for the machine vectors at the high-vectors | 472 | * Create a mapping for the machine vectors at the high-vectors |
472 | * location (0xffff0000). If we aren't using high-vectors, also | 473 | * location (0xffff0000). If we aren't using high-vectors, also |
@@ -491,12 +492,13 @@ static void __init devicemaps_init(struct machine_desc *mdesc) | |||
491 | mdesc->map_io(); | 492 | mdesc->map_io(); |
492 | 493 | ||
493 | /* | 494 | /* |
494 | * Finally flush the tlb again - this ensures that we're in a | 495 | * Finally flush the caches and tlb to ensure that we're in a |
495 | * consistent state wrt the writebuffer if the writebuffer needs | 496 | * consistent state wrt the writebuffer. This also ensures that |
496 | * draining. After this point, we can start to touch devices | 497 | * any write-allocated cache lines in the vector page are written |
497 | * again. | 498 | * back. After this point, we can start to touch devices again. |
498 | */ | 499 | */ |
499 | local_flush_tlb_all(); | 500 | local_flush_tlb_all(); |
501 | flush_cache_all(); | ||
500 | } | 502 | } |
501 | 503 | ||
502 | /* | 504 | /* |