diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-02 16:20:43 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-02 16:20:43 -0700 |
commit | a037a79dceaf717409fbf42f4ad209b9c15f435c (patch) | |
tree | c30b5b033c74ab9470e875554bded16464bbdf9b /arch/arm/mm/mmu.c | |
parent | 90d5ffc729e92bffc0f84e2447e2e6dc280240a5 (diff) | |
parent | d25ef8b86e6a58f5476bf6e4a8da730b335f68fa (diff) |
Merge master.kernel.org:/home/rmk/linux-2.6-arm
* master.kernel.org:/home/rmk/linux-2.6-arm: (25 commits)
ARM: 5728/1: Proper prefetch abort handling on ARMv6 and ARMv7
ARM: 5727/1: Pass IFSR register to do_PrefetchAbort()
ARM: 5740/1: fix valid_phys_addr_range() range check
ARM: 5739/1: ARM: allow empty ATAG_CORE
ARM: 5735/1: sa1111: CodingStyle cleanups
ARM: 5738/1: Correct TCM documentation
ARM: 5734/1: arm: fix compilation of entry-common.S for older CPUs
ARM: 5733/1: fix bcmring compile error
ARM: 5732/1: remove redundant include file
ARM: 5731/2: Fix U300 generic GPIO, remove ifdefs from MMCI v3
ARM: Ensure do_cache_op takes mmap_sem
ARM: Fix __cpuexit section mismatch warnings
ARM: Don't allow highmem on SMP platforms without h/w TLB ops broadcast
ARM: includecheck fix: mach-davinci, board-dm365-evm.c
ARM: Remove unused CONFIG SA1100_H3XXX
ARM: Fix warning: unused variable 'highmem'
ARM: Fix warning: #warning syscall migrate_pages not implemented
ARM: Fix SA11x0 clocksource warning
ARM: Fix SA1100 Neponset serial section mismatch
ARM: Fix SA1100 Assabet/Neponset PCMCIA section mismatch warnings
...
Diffstat (limited to 'arch/arm/mm/mmu.c')
-rw-r--r-- | arch/arm/mm/mmu.c | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 4426ee67ceca..02243eeccf50 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -21,6 +21,7 @@ #include <asm/cachetype.h> #include <asm/setup.h> #include <asm/sizes.h> +#include <asm/smp_plat.h> #include <asm/tlb.h> #include <asm/highmem.h> @@ -709,10 +710,6 @@ static void __init sanity_check_meminfo(void) if (meminfo.nr_banks >= NR_BANKS) { printk(KERN_CRIT "NR_BANKS too low, " "ignoring high memory\n"); - } else if (cache_is_vipt_aliasing()) { - printk(KERN_CRIT "HIGHMEM is not yet supported " - "with VIPT aliasing cache, " - "ignoring high memory\n"); } else { memmove(bank + 1, bank, (meminfo.nr_banks - i) * sizeof(*bank)); @@ -726,6 +723,8 @@ static void __init sanity_check_meminfo(void) bank->size = VMALLOC_MIN - __va(bank->start); } #else + bank->highmem = highmem; + /* * Check whether this memory bank would entirely overlap * the vmalloc area. @@ -754,6 +753,38 @@ static void __init sanity_check_meminfo(void) #endif j++; } +#ifdef CONFIG_HIGHMEM + if (highmem) { + const char *reason = NULL; + + if (cache_is_vipt_aliasing()) { + /* + * Interactions between kmap and other mappings + * make highmem support with aliasing VIPT caches + * rather difficult. + */ + reason = "with VIPT aliasing cache"; +#ifdef CONFIG_SMP + } else if (tlb_ops_need_broadcast()) { + /* + * kmap_high needs to occasionally flush TLB entries, + * however, if the TLB entries need to be broadcast + * we may deadlock: + * kmap_high(irqs off)->flush_all_zero_pkmaps-> + * flush_tlb_kernel_range->smp_call_function_many + * (must not be called with irqs off) + */ + reason = "without hardware TLB ops broadcasting"; +#endif + } + if (reason) { + printk(KERN_CRIT "HIGHMEM is not supported %s, ignoring high memory\n", + reason); + while (j > 0 && meminfo.bank[j - 1].highmem) + j--; + } + } +#endif meminfo.nr_banks = j; } |