diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-18 14:13:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-18 14:13:20 -0400 |
commit | 114e3bae37a2976563fb7a678efe3cf3aff80ed2 (patch) | |
tree | 4c4779bc8b484168a7aedb205826614cfec825a5 | |
parent | 395c4342920b5abd082e74af3808a74f221e2fdc (diff) | |
parent | 87eed3c74d7c65556f744230a90bf9556dd29146 (diff) |
Merge branch 'fixes' of git://git.armlinux.org.uk/~rmk/linux-arm
Pull ARM fixes from Russell King:
"Only three fixes this time:
- Emil found an overflow problem with the memory layout sanity check.
- Ard Biesheuvel noticed that late-allocated page tables (for EFI)
weren't being properly constructed.
- Guenter Roeck reported a problem found on qemu caused by the recent
addr_limit changes"
* 'fixes' of git://git.armlinux.org.uk/~rmk/linux-arm:
ARM: fix address limit restoration for undefined instructions
ARM: 8591/1: mm: use fully constructed struct pages for EFI pgd allocations
ARM: 8590/1: sanity_check_meminfo(): avoid overflow on vmalloc_limit
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 1 | ||||
-rw-r--r-- | arch/arm/mm/mmu.c | 21 |
2 files changed, 17 insertions, 5 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index bc5f50799d75..9f157e7c51e7 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -295,6 +295,7 @@ __und_svc_fault: | |||
295 | bl __und_fault | 295 | bl __und_fault |
296 | 296 | ||
297 | __und_svc_finish: | 297 | __und_svc_finish: |
298 | get_thread_info tsk | ||
298 | ldr r5, [sp, #S_PSR] @ Get SVC cpsr | 299 | ldr r5, [sp, #S_PSR] @ Get SVC cpsr |
299 | svc_exit r5 @ return from exception | 300 | svc_exit r5 @ return from exception |
300 | UNWIND(.fnend ) | 301 | UNWIND(.fnend ) |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 62f4d01941f7..6344913f0804 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -728,7 +728,8 @@ static void *__init late_alloc(unsigned long sz) | |||
728 | { | 728 | { |
729 | void *ptr = (void *)__get_free_pages(PGALLOC_GFP, get_order(sz)); | 729 | void *ptr = (void *)__get_free_pages(PGALLOC_GFP, get_order(sz)); |
730 | 730 | ||
731 | BUG_ON(!ptr); | 731 | if (!ptr || !pgtable_page_ctor(virt_to_page(ptr))) |
732 | BUG(); | ||
732 | return ptr; | 733 | return ptr; |
733 | } | 734 | } |
734 | 735 | ||
@@ -1155,10 +1156,19 @@ void __init sanity_check_meminfo(void) | |||
1155 | { | 1156 | { |
1156 | phys_addr_t memblock_limit = 0; | 1157 | phys_addr_t memblock_limit = 0; |
1157 | int highmem = 0; | 1158 | int highmem = 0; |
1158 | phys_addr_t vmalloc_limit = __pa(vmalloc_min - 1) + 1; | 1159 | u64 vmalloc_limit; |
1159 | struct memblock_region *reg; | 1160 | struct memblock_region *reg; |
1160 | bool should_use_highmem = false; | 1161 | bool should_use_highmem = false; |
1161 | 1162 | ||
1163 | /* | ||
1164 | * Let's use our own (unoptimized) equivalent of __pa() that is | ||
1165 | * not affected by wrap-arounds when sizeof(phys_addr_t) == 4. | ||
1166 | * The result is used as the upper bound on physical memory address | ||
1167 | * and may itself be outside the valid range for which phys_addr_t | ||
1168 | * and therefore __pa() is defined. | ||
1169 | */ | ||
1170 | vmalloc_limit = (u64)(uintptr_t)vmalloc_min - PAGE_OFFSET + PHYS_OFFSET; | ||
1171 | |||
1162 | for_each_memblock(memory, reg) { | 1172 | for_each_memblock(memory, reg) { |
1163 | phys_addr_t block_start = reg->base; | 1173 | phys_addr_t block_start = reg->base; |
1164 | phys_addr_t block_end = reg->base + reg->size; | 1174 | phys_addr_t block_end = reg->base + reg->size; |
@@ -1183,10 +1193,11 @@ void __init sanity_check_meminfo(void) | |||
1183 | if (reg->size > size_limit) { | 1193 | if (reg->size > size_limit) { |
1184 | phys_addr_t overlap_size = reg->size - size_limit; | 1194 | phys_addr_t overlap_size = reg->size - size_limit; |
1185 | 1195 | ||
1186 | pr_notice("Truncating RAM at %pa-%pa to -%pa", | 1196 | pr_notice("Truncating RAM at %pa-%pa", |
1187 | &block_start, &block_end, &vmalloc_limit); | 1197 | &block_start, &block_end); |
1188 | memblock_remove(vmalloc_limit, overlap_size); | ||
1189 | block_end = vmalloc_limit; | 1198 | block_end = vmalloc_limit; |
1199 | pr_cont(" to -%pa", &block_end); | ||
1200 | memblock_remove(vmalloc_limit, overlap_size); | ||
1190 | should_use_highmem = true; | 1201 | should_use_highmem = true; |
1191 | } | 1202 | } |
1192 | } | 1203 | } |