diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-03-16 19:35:25 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-03-16 19:35:25 -0400 |
commit | 1f0090a1eaa1b750a2fc5c99c91b790d5322a1fd (patch) | |
tree | c685060f260410e6704c9dfd457ed8c347141f1d /arch | |
parent | 2472f3c8d8fc18b25b2cf1574c036e238187c0ff (diff) | |
parent | 10a8c3839810ac9af1aec836d61b92e7a879f5fa (diff) |
Merge branch 'misc' into devel
Conflicts:
arch/arm/Kconfig
Diffstat (limited to 'arch')
38 files changed, 461 insertions, 791 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 38bf684448e7..1fd3f280b584 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -63,6 +63,10 @@ config GENERIC_CLOCKEVENTS_BROADCAST | |||
63 | depends on GENERIC_CLOCKEVENTS | 63 | depends on GENERIC_CLOCKEVENTS |
64 | default y if SMP | 64 | default y if SMP |
65 | 65 | ||
66 | config KTIME_SCALAR | ||
67 | bool | ||
68 | default y | ||
69 | |||
66 | config HAVE_TCM | 70 | config HAVE_TCM |
67 | bool | 71 | bool |
68 | select GENERIC_ALLOCATOR | 72 | select GENERIC_ALLOCATOR |
@@ -178,11 +182,6 @@ config FIQ | |||
178 | config ARCH_MTD_XIP | 182 | config ARCH_MTD_XIP |
179 | bool | 183 | bool |
180 | 184 | ||
181 | config ARM_L1_CACHE_SHIFT_6 | ||
182 | bool | ||
183 | help | ||
184 | Setting ARM L1 cache line size to 64 Bytes. | ||
185 | |||
186 | config VECTORS_BASE | 185 | config VECTORS_BASE |
187 | hex | 186 | hex |
188 | default 0xffff0000 if MMU || CPU_HIGH_VECTOR | 187 | default 0xffff0000 if MMU || CPU_HIGH_VECTOR |
@@ -1152,7 +1151,7 @@ config ARM_ERRATA_742231 | |||
1152 | 1151 | ||
1153 | config PL310_ERRATA_588369 | 1152 | config PL310_ERRATA_588369 |
1154 | bool "Clean & Invalidate maintenance operations do not invalidate clean lines" | 1153 | bool "Clean & Invalidate maintenance operations do not invalidate clean lines" |
1155 | depends on CACHE_L2X0 && ARCH_OMAP4 | 1154 | depends on CACHE_L2X0 |
1156 | help | 1155 | help |
1157 | The PL310 L2 cache controller implements three types of Clean & | 1156 | The PL310 L2 cache controller implements three types of Clean & |
1158 | Invalidate maintenance operations: by Physical Address | 1157 | Invalidate maintenance operations: by Physical Address |
@@ -1161,8 +1160,7 @@ config PL310_ERRATA_588369 | |||
1161 | clean operation followed immediately by an invalidate operation, | 1160 | clean operation followed immediately by an invalidate operation, |
1162 | both performing to the same memory location. This functionality | 1161 | both performing to the same memory location. This functionality |
1163 | is not correctly implemented in PL310 as clean lines are not | 1162 | is not correctly implemented in PL310 as clean lines are not |
1164 | invalidated as a result of these operations. Note that this errata | 1163 | invalidated as a result of these operations. |
1165 | uses Texas Instrument's secure monitor api. | ||
1166 | 1164 | ||
1167 | config ARM_ERRATA_720789 | 1165 | config ARM_ERRATA_720789 |
1168 | bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID" | 1166 | bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID" |
@@ -1176,6 +1174,17 @@ config ARM_ERRATA_720789 | |||
1176 | tables. The workaround changes the TLB flushing routines to invalidate | 1174 | tables. The workaround changes the TLB flushing routines to invalidate |
1177 | entries regardless of the ASID. | 1175 | entries regardless of the ASID. |
1178 | 1176 | ||
1177 | config PL310_ERRATA_727915 | ||
1178 | bool "Background Clean & Invalidate by Way operation can cause data corruption" | ||
1179 | depends on CACHE_L2X0 | ||
1180 | help | ||
1181 | PL310 implements the Clean & Invalidate by Way L2 cache maintenance | ||
1182 | operation (offset 0x7FC). This operation runs in background so that | ||
1183 | PL310 can handle normal accesses while it is in progress. Under very | ||
1184 | rare circumstances, due to this erratum, write data can be lost when | ||
1185 | PL310 treats a cacheable write transaction during a Clean & | ||
1186 | Invalidate by Way operation. | ||
1187 | |||
1179 | config ARM_ERRATA_743622 | 1188 | config ARM_ERRATA_743622 |
1180 | bool "ARM errata: Faulty hazard checking in the Store Buffer may lead to data corruption" | 1189 | bool "ARM errata: Faulty hazard checking in the Store Buffer may lead to data corruption" |
1181 | depends on CPU_V7 | 1190 | depends on CPU_V7 |
@@ -1430,6 +1439,37 @@ config THUMB2_KERNEL | |||
1430 | 1439 | ||
1431 | If unsure, say N. | 1440 | If unsure, say N. |
1432 | 1441 | ||
1442 | config THUMB2_AVOID_R_ARM_THM_JUMP11 | ||
1443 | bool "Work around buggy Thumb-2 short branch relocations in gas" | ||
1444 | depends on THUMB2_KERNEL && MODULES | ||
1445 | default y | ||
1446 | help | ||
1447 | Various binutils versions can resolve Thumb-2 branches to | ||
1448 | locally-defined, preemptible global symbols as short-range "b.n" | ||
1449 | branch instructions. | ||
1450 | |||
1451 | This is a problem, because there's no guarantee the final | ||
1452 | destination of the symbol, or any candidate locations for a | ||
1453 | trampoline, are within range of the branch. For this reason, the | ||
1454 | kernel does not support fixing up the R_ARM_THM_JUMP11 (102) | ||
1455 | relocation in modules at all, and it makes little sense to add | ||
1456 | support. | ||
1457 | |||
1458 | The symptom is that the kernel fails with an "unsupported | ||
1459 | relocation" error when loading some modules. | ||
1460 | |||
1461 | Until fixed tools are available, passing | ||
1462 | -fno-optimize-sibling-calls to gcc should prevent gcc generating | ||
1463 | code which hits this problem, at the cost of a bit of extra runtime | ||
1464 | stack usage in some cases. | ||
1465 | |||
1466 | The problem is described in more detail at: | ||
1467 | https://bugs.launchpad.net/binutils-linaro/+bug/725126 | ||
1468 | |||
1469 | Only Thumb-2 kernels are affected. | ||
1470 | |||
1471 | Unless you are sure your tools don't have this problem, say Y. | ||
1472 | |||
1433 | config ARM_ASM_UNIFIED | 1473 | config ARM_ASM_UNIFIED |
1434 | bool | 1474 | bool |
1435 | 1475 | ||
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index cd56c9129a1a..55eca9ed7604 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
@@ -105,6 +105,10 @@ AFLAGS_AUTOIT :=$(call as-option,-Wa$(comma)-mimplicit-it=always,-Wa$(comma)-mau | |||
105 | AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W) | 105 | AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W) |
106 | CFLAGS_THUMB2 :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN) | 106 | CFLAGS_THUMB2 :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN) |
107 | AFLAGS_THUMB2 :=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb | 107 | AFLAGS_THUMB2 :=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb |
108 | # Work around buggy relocation from gas if requested: | ||
109 | ifeq ($(CONFIG_THUMB2_AVOID_R_ARM_THM_JUMP11),y) | ||
110 | CFLAGS_MODULE +=-fno-optimize-sibling-calls | ||
111 | endif | ||
108 | endif | 112 | endif |
109 | 113 | ||
110 | # Need -Uarm for gcc < 3.x | 114 | # Need -Uarm for gcc < 3.x |
@@ -281,7 +285,7 @@ bzImage: zImage | |||
281 | zImage Image xipImage bootpImage uImage: vmlinux | 285 | zImage Image xipImage bootpImage uImage: vmlinux |
282 | $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ | 286 | $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ |
283 | 287 | ||
284 | zinstall install: vmlinux | 288 | zinstall uinstall install: vmlinux |
285 | $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ | 289 | $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ |
286 | 290 | ||
287 | # We use MRPROPER_FILES and CLEAN_FILES now | 291 | # We use MRPROPER_FILES and CLEAN_FILES now |
@@ -302,6 +306,7 @@ define archhelp | |||
302 | echo ' (supply initrd image via make variable INITRD=<path>)' | 306 | echo ' (supply initrd image via make variable INITRD=<path>)' |
303 | echo ' install - Install uncompressed kernel' | 307 | echo ' install - Install uncompressed kernel' |
304 | echo ' zinstall - Install compressed kernel' | 308 | echo ' zinstall - Install compressed kernel' |
309 | echo ' uinstall - Install U-Boot wrapped compressed kernel' | ||
305 | echo ' Install using (your) ~/bin/$(INSTALLKERNEL) or' | 310 | echo ' Install using (your) ~/bin/$(INSTALLKERNEL) or' |
306 | echo ' (distribution) /sbin/$(INSTALLKERNEL) or' | 311 | echo ' (distribution) /sbin/$(INSTALLKERNEL) or' |
307 | echo ' install to $$(INSTALL_PATH) and run lilo' | 312 | echo ' install to $$(INSTALL_PATH) and run lilo' |
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index 4d26f2c52a75..9128fddf1109 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile | |||
@@ -99,6 +99,10 @@ zinstall: $(obj)/zImage | |||
99 | $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ | 99 | $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ |
100 | $(obj)/zImage System.map "$(INSTALL_PATH)" | 100 | $(obj)/zImage System.map "$(INSTALL_PATH)" |
101 | 101 | ||
102 | uinstall: $(obj)/uImage | ||
103 | $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ | ||
104 | $(obj)/uImage System.map "$(INSTALL_PATH)" | ||
105 | |||
102 | zi: | 106 | zi: |
103 | $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ | 107 | $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ |
104 | $(obj)/zImage System.map "$(INSTALL_PATH)" | 108 | $(obj)/zImage System.map "$(INSTALL_PATH)" |
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 5f3a1614dc63..f9f77c65dff3 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile | |||
@@ -98,9 +98,11 @@ endif | |||
98 | EXTRA_CFLAGS := -fpic -fno-builtin | 98 | EXTRA_CFLAGS := -fpic -fno-builtin |
99 | EXTRA_AFLAGS := -Wa,-march=all | 99 | EXTRA_AFLAGS := -Wa,-march=all |
100 | 100 | ||
101 | # Provide size of uncompressed kernel to the decompressor via a linker symbol. | ||
102 | LDFLAGS_vmlinux = --defsym _image_size=$(shell stat -c "%s" $(obj)/../Image) | ||
101 | # Supply ZRELADDR to the decompressor via a linker symbol. | 103 | # Supply ZRELADDR to the decompressor via a linker symbol. |
102 | ifneq ($(CONFIG_AUTO_ZRELADDR),y) | 104 | ifneq ($(CONFIG_AUTO_ZRELADDR),y) |
103 | LDFLAGS_vmlinux := --defsym zreladdr=$(ZRELADDR) | 105 | LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR) |
104 | endif | 106 | endif |
105 | ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) | 107 | ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) |
106 | LDFLAGS_vmlinux += --be8 | 108 | LDFLAGS_vmlinux += --be8 |
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 7193884ed8b0..39859216af00 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
@@ -128,14 +128,14 @@ wait: mrc p14, 0, pc, c0, c1, 0 | |||
128 | .arm @ Always enter in ARM state | 128 | .arm @ Always enter in ARM state |
129 | start: | 129 | start: |
130 | .type start,#function | 130 | .type start,#function |
131 | THUMB( adr r12, BSYM(1f) ) | 131 | .rept 7 |
132 | THUMB( bx r12 ) | ||
133 | THUMB( .rept 6 ) | ||
134 | ARM( .rept 8 ) | ||
135 | mov r0, r0 | 132 | mov r0, r0 |
136 | .endr | 133 | .endr |
134 | ARM( mov r0, r0 ) | ||
135 | ARM( b 1f ) | ||
136 | THUMB( adr r12, BSYM(1f) ) | ||
137 | THUMB( bx r12 ) | ||
137 | 138 | ||
138 | b 1f | ||
139 | .word 0x016f2818 @ Magic numbers to help the loader | 139 | .word 0x016f2818 @ Magic numbers to help the loader |
140 | .word start @ absolute load/run zImage address | 140 | .word start @ absolute load/run zImage address |
141 | .word _edata @ zImage end address | 141 | .word _edata @ zImage end address |
@@ -174,9 +174,7 @@ not_angel: | |||
174 | */ | 174 | */ |
175 | 175 | ||
176 | .text | 176 | .text |
177 | adr r0, LC0 | 177 | |
178 | ldmia r0, {r1, r2, r3, r5, r6, r11, ip} | ||
179 | ldr sp, [r0, #28] | ||
180 | #ifdef CONFIG_AUTO_ZRELADDR | 178 | #ifdef CONFIG_AUTO_ZRELADDR |
181 | @ determine final kernel image address | 179 | @ determine final kernel image address |
182 | mov r4, pc | 180 | mov r4, pc |
@@ -185,35 +183,108 @@ not_angel: | |||
185 | #else | 183 | #else |
186 | ldr r4, =zreladdr | 184 | ldr r4, =zreladdr |
187 | #endif | 185 | #endif |
188 | subs r0, r0, r1 @ calculate the delta offset | ||
189 | 186 | ||
190 | @ if delta is zero, we are | 187 | bl cache_on |
191 | beq not_relocated @ running at the address we | 188 | |
192 | @ were linked at. | 189 | restart: adr r0, LC0 |
190 | ldmia r0, {r1, r2, r3, r5, r6, r9, r11, r12} | ||
191 | ldr sp, [r0, #32] | ||
192 | |||
193 | /* | ||
194 | * We might be running at a different address. We need | ||
195 | * to fix up various pointers. | ||
196 | */ | ||
197 | sub r0, r0, r1 @ calculate the delta offset | ||
198 | add r5, r5, r0 @ _start | ||
199 | add r6, r6, r0 @ _edata | ||
193 | 200 | ||
201 | #ifndef CONFIG_ZBOOT_ROM | ||
202 | /* malloc space is above the relocated stack (64k max) */ | ||
203 | add sp, sp, r0 | ||
204 | add r10, sp, #0x10000 | ||
205 | #else | ||
194 | /* | 206 | /* |
195 | * We're running at a different address. We need to fix | 207 | * With ZBOOT_ROM the bss/stack is non relocatable, |
196 | * up various pointers: | 208 | * but someone could still run this code from RAM, |
197 | * r5 - zImage base address (_start) | 209 | * in which case our reference is _edata. |
198 | * r6 - size of decompressed image | ||
199 | * r11 - GOT start | ||
200 | * ip - GOT end | ||
201 | */ | 210 | */ |
202 | add r5, r5, r0 | 211 | mov r10, r6 |
212 | #endif | ||
213 | |||
214 | /* | ||
215 | * Check to see if we will overwrite ourselves. | ||
216 | * r4 = final kernel address | ||
217 | * r5 = start of this image | ||
218 | * r9 = size of decompressed image | ||
219 | * r10 = end of this image, including bss/stack/malloc space if non XIP | ||
220 | * We basically want: | ||
221 | * r4 >= r10 -> OK | ||
222 | * r4 + image length <= r5 -> OK | ||
223 | */ | ||
224 | cmp r4, r10 | ||
225 | bhs wont_overwrite | ||
226 | add r10, r4, r9 | ||
227 | cmp r10, r5 | ||
228 | bls wont_overwrite | ||
229 | |||
230 | /* | ||
231 | * Relocate ourselves past the end of the decompressed kernel. | ||
232 | * r5 = start of this image | ||
233 | * r6 = _edata | ||
234 | * r10 = end of the decompressed kernel | ||
235 | * Because we always copy ahead, we need to do it from the end and go | ||
236 | * backward in case the source and destination overlap. | ||
237 | */ | ||
238 | /* Round up to next 256-byte boundary. */ | ||
239 | add r10, r10, #256 | ||
240 | bic r10, r10, #255 | ||
241 | |||
242 | sub r9, r6, r5 @ size to copy | ||
243 | add r9, r9, #31 @ rounded up to a multiple | ||
244 | bic r9, r9, #31 @ ... of 32 bytes | ||
245 | add r6, r9, r5 | ||
246 | add r9, r9, r10 | ||
247 | |||
248 | 1: ldmdb r6!, {r0 - r3, r10 - r12, lr} | ||
249 | cmp r6, r5 | ||
250 | stmdb r9!, {r0 - r3, r10 - r12, lr} | ||
251 | bhi 1b | ||
252 | |||
253 | /* Preserve offset to relocated code. */ | ||
254 | sub r6, r9, r6 | ||
255 | |||
256 | bl cache_clean_flush | ||
257 | |||
258 | adr r0, BSYM(restart) | ||
259 | add r0, r0, r6 | ||
260 | mov pc, r0 | ||
261 | |||
262 | wont_overwrite: | ||
263 | /* | ||
264 | * If delta is zero, we are running at the address we were linked at. | ||
265 | * r0 = delta | ||
266 | * r2 = BSS start | ||
267 | * r3 = BSS end | ||
268 | * r4 = kernel execution address | ||
269 | * r7 = architecture ID | ||
270 | * r8 = atags pointer | ||
271 | * r11 = GOT start | ||
272 | * r12 = GOT end | ||
273 | * sp = stack pointer | ||
274 | */ | ||
275 | teq r0, #0 | ||
276 | beq not_relocated | ||
203 | add r11, r11, r0 | 277 | add r11, r11, r0 |
204 | add ip, ip, r0 | 278 | add r12, r12, r0 |
205 | 279 | ||
206 | #ifndef CONFIG_ZBOOT_ROM | 280 | #ifndef CONFIG_ZBOOT_ROM |
207 | /* | 281 | /* |
208 | * If we're running fully PIC === CONFIG_ZBOOT_ROM = n, | 282 | * If we're running fully PIC === CONFIG_ZBOOT_ROM = n, |
209 | * we need to fix up pointers into the BSS region. | 283 | * we need to fix up pointers into the BSS region. |
210 | * r2 - BSS start | 284 | * Note that the stack pointer has already been fixed up. |
211 | * r3 - BSS end | ||
212 | * sp - stack pointer | ||
213 | */ | 285 | */ |
214 | add r2, r2, r0 | 286 | add r2, r2, r0 |
215 | add r3, r3, r0 | 287 | add r3, r3, r0 |
216 | add sp, sp, r0 | ||
217 | 288 | ||
218 | /* | 289 | /* |
219 | * Relocate all entries in the GOT table. | 290 | * Relocate all entries in the GOT table. |
@@ -221,7 +292,7 @@ not_angel: | |||
221 | 1: ldr r1, [r11, #0] @ relocate entries in the GOT | 292 | 1: ldr r1, [r11, #0] @ relocate entries in the GOT |
222 | add r1, r1, r0 @ table. This fixes up the | 293 | add r1, r1, r0 @ table. This fixes up the |
223 | str r1, [r11], #4 @ C references. | 294 | str r1, [r11], #4 @ C references. |
224 | cmp r11, ip | 295 | cmp r11, r12 |
225 | blo 1b | 296 | blo 1b |
226 | #else | 297 | #else |
227 | 298 | ||
@@ -234,7 +305,7 @@ not_angel: | |||
234 | cmphs r3, r1 @ _end < entry | 305 | cmphs r3, r1 @ _end < entry |
235 | addlo r1, r1, r0 @ table. This fixes up the | 306 | addlo r1, r1, r0 @ table. This fixes up the |
236 | str r1, [r11], #4 @ C references. | 307 | str r1, [r11], #4 @ C references. |
237 | cmp r11, ip | 308 | cmp r11, r12 |
238 | blo 1b | 309 | blo 1b |
239 | #endif | 310 | #endif |
240 | 311 | ||
@@ -246,76 +317,24 @@ not_relocated: mov r0, #0 | |||
246 | cmp r2, r3 | 317 | cmp r2, r3 |
247 | blo 1b | 318 | blo 1b |
248 | 319 | ||
249 | /* | ||
250 | * The C runtime environment should now be setup | ||
251 | * sufficiently. Turn the cache on, set up some | ||
252 | * pointers, and start decompressing. | ||
253 | */ | ||
254 | bl cache_on | ||
255 | |||
256 | mov r1, sp @ malloc space above stack | ||
257 | add r2, sp, #0x10000 @ 64k max | ||
258 | |||
259 | /* | 320 | /* |
260 | * Check to see if we will overwrite ourselves. | 321 | * The C runtime environment should now be setup sufficiently. |
261 | * r4 = final kernel address | 322 | * Set up some pointers, and start decompressing. |
262 | * r5 = start of this image | 323 | * r4 = kernel execution address |
263 | * r6 = size of decompressed image | 324 | * r7 = architecture ID |
264 | * r2 = end of malloc space (and therefore this image) | 325 | * r8 = atags pointer |
265 | * We basically want: | ||
266 | * r4 >= r2 -> OK | ||
267 | * r4 + image length <= r5 -> OK | ||
268 | */ | 326 | */ |
269 | cmp r4, r2 | 327 | mov r0, r4 |
270 | bhs wont_overwrite | 328 | mov r1, sp @ malloc space above stack |
271 | add r0, r4, r6 | 329 | add r2, sp, #0x10000 @ 64k max |
272 | cmp r0, r5 | ||
273 | bls wont_overwrite | ||
274 | |||
275 | mov r5, r2 @ decompress after malloc space | ||
276 | mov r0, r5 | ||
277 | mov r3, r7 | 330 | mov r3, r7 |
278 | bl decompress_kernel | 331 | bl decompress_kernel |
279 | |||
280 | add r0, r0, #127 + 128 @ alignment + stack | ||
281 | bic r0, r0, #127 @ align the kernel length | ||
282 | /* | ||
283 | * r0 = decompressed kernel length | ||
284 | * r1-r3 = unused | ||
285 | * r4 = kernel execution address | ||
286 | * r5 = decompressed kernel start | ||
287 | * r7 = architecture ID | ||
288 | * r8 = atags pointer | ||
289 | * r9-r12,r14 = corrupted | ||
290 | */ | ||
291 | add r1, r5, r0 @ end of decompressed kernel | ||
292 | adr r2, reloc_start | ||
293 | ldr r3, LC1 | ||
294 | add r3, r2, r3 | ||
295 | 1: ldmia r2!, {r9 - r12, r14} @ copy relocation code | ||
296 | stmia r1!, {r9 - r12, r14} | ||
297 | ldmia r2!, {r9 - r12, r14} | ||
298 | stmia r1!, {r9 - r12, r14} | ||
299 | cmp r2, r3 | ||
300 | blo 1b | ||
301 | mov sp, r1 | ||
302 | add sp, sp, #128 @ relocate the stack | ||
303 | |||
304 | bl cache_clean_flush | 332 | bl cache_clean_flush |
305 | ARM( add pc, r5, r0 ) @ call relocation code | 333 | bl cache_off |
306 | THUMB( add r12, r5, r0 ) | 334 | mov r0, #0 @ must be zero |
307 | THUMB( mov pc, r12 ) @ call relocation code | 335 | mov r1, r7 @ restore architecture number |
308 | 336 | mov r2, r8 @ restore atags pointer | |
309 | /* | 337 | mov pc, r4 @ call kernel |
310 | * We're not in danger of overwriting ourselves. Do this the simple way. | ||
311 | * | ||
312 | * r4 = kernel execution address | ||
313 | * r7 = architecture ID | ||
314 | */ | ||
315 | wont_overwrite: mov r0, r4 | ||
316 | mov r3, r7 | ||
317 | bl decompress_kernel | ||
318 | b call_kernel | ||
319 | 338 | ||
320 | .align 2 | 339 | .align 2 |
321 | .type LC0, #object | 340 | .type LC0, #object |
@@ -323,11 +342,11 @@ LC0: .word LC0 @ r1 | |||
323 | .word __bss_start @ r2 | 342 | .word __bss_start @ r2 |
324 | .word _end @ r3 | 343 | .word _end @ r3 |
325 | .word _start @ r5 | 344 | .word _start @ r5 |
326 | .word _image_size @ r6 | 345 | .word _edata @ r6 |
346 | .word _image_size @ r9 | ||
327 | .word _got_start @ r11 | 347 | .word _got_start @ r11 |
328 | .word _got_end @ ip | 348 | .word _got_end @ ip |
329 | .word user_stack_end @ sp | 349 | .word user_stack_end @ sp |
330 | LC1: .word reloc_end - reloc_start | ||
331 | .size LC0, . - LC0 | 350 | .size LC0, . - LC0 |
332 | 351 | ||
333 | #ifdef CONFIG_ARCH_RPC | 352 | #ifdef CONFIG_ARCH_RPC |
@@ -353,7 +372,7 @@ params: ldr r0, =0x10000100 @ params_phys for RPC | |||
353 | * On exit, | 372 | * On exit, |
354 | * r0, r1, r2, r3, r9, r10, r12 corrupted | 373 | * r0, r1, r2, r3, r9, r10, r12 corrupted |
355 | * This routine must preserve: | 374 | * This routine must preserve: |
356 | * r4, r5, r6, r7, r8 | 375 | * r4, r7, r8 |
357 | */ | 376 | */ |
358 | .align 5 | 377 | .align 5 |
359 | cache_on: mov r3, #8 @ cache_on function | 378 | cache_on: mov r3, #8 @ cache_on function |
@@ -551,43 +570,6 @@ __common_mmu_cache_on: | |||
551 | #endif | 570 | #endif |
552 | 571 | ||
553 | /* | 572 | /* |
554 | * All code following this line is relocatable. It is relocated by | ||
555 | * the above code to the end of the decompressed kernel image and | ||
556 | * executed there. During this time, we have no stacks. | ||
557 | * | ||
558 | * r0 = decompressed kernel length | ||
559 | * r1-r3 = unused | ||
560 | * r4 = kernel execution address | ||
561 | * r5 = decompressed kernel start | ||
562 | * r7 = architecture ID | ||
563 | * r8 = atags pointer | ||
564 | * r9-r12,r14 = corrupted | ||
565 | */ | ||
566 | .align 5 | ||
567 | reloc_start: add r9, r5, r0 | ||
568 | sub r9, r9, #128 @ do not copy the stack | ||
569 | debug_reloc_start | ||
570 | mov r1, r4 | ||
571 | 1: | ||
572 | .rept 4 | ||
573 | ldmia r5!, {r0, r2, r3, r10 - r12, r14} @ relocate kernel | ||
574 | stmia r1!, {r0, r2, r3, r10 - r12, r14} | ||
575 | .endr | ||
576 | |||
577 | cmp r5, r9 | ||
578 | blo 1b | ||
579 | mov sp, r1 | ||
580 | add sp, sp, #128 @ relocate the stack | ||
581 | debug_reloc_end | ||
582 | |||
583 | call_kernel: bl cache_clean_flush | ||
584 | bl cache_off | ||
585 | mov r0, #0 @ must be zero | ||
586 | mov r1, r7 @ restore architecture number | ||
587 | mov r2, r8 @ restore atags pointer | ||
588 | mov pc, r4 @ call kernel | ||
589 | |||
590 | /* | ||
591 | * Here follow the relocatable cache support functions for the | 573 | * Here follow the relocatable cache support functions for the |
592 | * various processors. This is a generic hook for locating an | 574 | * various processors. This is a generic hook for locating an |
593 | * entry and jumping to an instruction at the specified offset | 575 | * entry and jumping to an instruction at the specified offset |
@@ -791,7 +773,7 @@ proc_types: | |||
791 | * On exit, | 773 | * On exit, |
792 | * r0, r1, r2, r3, r9, r12 corrupted | 774 | * r0, r1, r2, r3, r9, r12 corrupted |
793 | * This routine must preserve: | 775 | * This routine must preserve: |
794 | * r4, r6, r7 | 776 | * r4, r7, r8 |
795 | */ | 777 | */ |
796 | .align 5 | 778 | .align 5 |
797 | cache_off: mov r3, #12 @ cache_off function | 779 | cache_off: mov r3, #12 @ cache_off function |
@@ -866,7 +848,7 @@ __armv3_mmu_cache_off: | |||
866 | * On exit, | 848 | * On exit, |
867 | * r1, r2, r3, r9, r10, r11, r12 corrupted | 849 | * r1, r2, r3, r9, r10, r11, r12 corrupted |
868 | * This routine must preserve: | 850 | * This routine must preserve: |
869 | * r0, r4, r5, r6, r7 | 851 | * r4, r6, r7, r8 |
870 | */ | 852 | */ |
871 | .align 5 | 853 | .align 5 |
872 | cache_clean_flush: | 854 | cache_clean_flush: |
@@ -1088,7 +1070,6 @@ memdump: mov r12, r0 | |||
1088 | #endif | 1070 | #endif |
1089 | 1071 | ||
1090 | .ltorg | 1072 | .ltorg |
1091 | reloc_end: | ||
1092 | 1073 | ||
1093 | .align | 1074 | .align |
1094 | .section ".stack", "aw", %nobits | 1075 | .section ".stack", "aw", %nobits |
diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in index 366a924019ac..5309909d7282 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.in +++ b/arch/arm/boot/compressed/vmlinux.lds.in | |||
@@ -43,9 +43,6 @@ SECTIONS | |||
43 | 43 | ||
44 | _etext = .; | 44 | _etext = .; |
45 | 45 | ||
46 | /* Assume size of decompressed image is 4x the compressed image */ | ||
47 | _image_size = (_etext - _text) * 4; | ||
48 | |||
49 | _got_start = .; | 46 | _got_start = .; |
50 | .got : { *(.got) } | 47 | .got : { *(.got) } |
51 | _got_end = .; | 48 | _got_end = .; |
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 224377211151..cb6b041c39d2 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c | |||
@@ -44,6 +44,19 @@ struct gic_chip_data { | |||
44 | void __iomem *cpu_base; | 44 | void __iomem *cpu_base; |
45 | }; | 45 | }; |
46 | 46 | ||
47 | /* | ||
48 | * Supported arch specific GIC irq extension. | ||
49 | * Default make them NULL. | ||
50 | */ | ||
51 | struct irq_chip gic_arch_extn = { | ||
52 | .irq_ack = NULL, | ||
53 | .irq_mask = NULL, | ||
54 | .irq_unmask = NULL, | ||
55 | .irq_retrigger = NULL, | ||
56 | .irq_set_type = NULL, | ||
57 | .irq_set_wake = NULL, | ||
58 | }; | ||
59 | |||
47 | #ifndef MAX_GIC_NR | 60 | #ifndef MAX_GIC_NR |
48 | #define MAX_GIC_NR 1 | 61 | #define MAX_GIC_NR 1 |
49 | #endif | 62 | #endif |
@@ -74,6 +87,8 @@ static inline unsigned int gic_irq(struct irq_data *d) | |||
74 | static void gic_ack_irq(struct irq_data *d) | 87 | static void gic_ack_irq(struct irq_data *d) |
75 | { | 88 | { |
76 | spin_lock(&irq_controller_lock); | 89 | spin_lock(&irq_controller_lock); |
90 | if (gic_arch_extn.irq_ack) | ||
91 | gic_arch_extn.irq_ack(d); | ||
77 | writel(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI); | 92 | writel(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI); |
78 | spin_unlock(&irq_controller_lock); | 93 | spin_unlock(&irq_controller_lock); |
79 | } | 94 | } |
@@ -84,6 +99,8 @@ static void gic_mask_irq(struct irq_data *d) | |||
84 | 99 | ||
85 | spin_lock(&irq_controller_lock); | 100 | spin_lock(&irq_controller_lock); |
86 | writel(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4); | 101 | writel(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4); |
102 | if (gic_arch_extn.irq_mask) | ||
103 | gic_arch_extn.irq_mask(d); | ||
87 | spin_unlock(&irq_controller_lock); | 104 | spin_unlock(&irq_controller_lock); |
88 | } | 105 | } |
89 | 106 | ||
@@ -92,6 +109,8 @@ static void gic_unmask_irq(struct irq_data *d) | |||
92 | u32 mask = 1 << (d->irq % 32); | 109 | u32 mask = 1 << (d->irq % 32); |
93 | 110 | ||
94 | spin_lock(&irq_controller_lock); | 111 | spin_lock(&irq_controller_lock); |
112 | if (gic_arch_extn.irq_unmask) | ||
113 | gic_arch_extn.irq_unmask(d); | ||
95 | writel(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4); | 114 | writel(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4); |
96 | spin_unlock(&irq_controller_lock); | 115 | spin_unlock(&irq_controller_lock); |
97 | } | 116 | } |
@@ -116,6 +135,9 @@ static int gic_set_type(struct irq_data *d, unsigned int type) | |||
116 | 135 | ||
117 | spin_lock(&irq_controller_lock); | 136 | spin_lock(&irq_controller_lock); |
118 | 137 | ||
138 | if (gic_arch_extn.irq_set_type) | ||
139 | gic_arch_extn.irq_set_type(d, type); | ||
140 | |||
119 | val = readl(base + GIC_DIST_CONFIG + confoff); | 141 | val = readl(base + GIC_DIST_CONFIG + confoff); |
120 | if (type == IRQ_TYPE_LEVEL_HIGH) | 142 | if (type == IRQ_TYPE_LEVEL_HIGH) |
121 | val &= ~confmask; | 143 | val &= ~confmask; |
@@ -141,32 +163,54 @@ static int gic_set_type(struct irq_data *d, unsigned int type) | |||
141 | return 0; | 163 | return 0; |
142 | } | 164 | } |
143 | 165 | ||
166 | static int gic_retrigger(struct irq_data *d) | ||
167 | { | ||
168 | if (gic_arch_extn.irq_retrigger) | ||
169 | return gic_arch_extn.irq_retrigger(d); | ||
170 | |||
171 | return -ENXIO; | ||
172 | } | ||
173 | |||
144 | #ifdef CONFIG_SMP | 174 | #ifdef CONFIG_SMP |
145 | static int | 175 | static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, |
146 | gic_set_cpu(struct irq_data *d, const struct cpumask *mask_val, bool force) | 176 | bool force) |
147 | { | 177 | { |
148 | void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3); | 178 | void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3); |
149 | unsigned int shift = (d->irq % 4) * 8; | 179 | unsigned int shift = (d->irq % 4) * 8; |
150 | unsigned int cpu = cpumask_first(mask_val); | 180 | unsigned int cpu = cpumask_first(mask_val); |
151 | u32 val; | 181 | u32 val, mask, bit; |
152 | struct irq_desc *desc; | ||
153 | 182 | ||
154 | spin_lock(&irq_controller_lock); | 183 | if (cpu >= 8) |
155 | desc = irq_to_desc(d->irq); | ||
156 | if (desc == NULL) { | ||
157 | spin_unlock(&irq_controller_lock); | ||
158 | return -EINVAL; | 184 | return -EINVAL; |
159 | } | 185 | |
186 | mask = 0xff << shift; | ||
187 | bit = 1 << (cpu + shift); | ||
188 | |||
189 | spin_lock(&irq_controller_lock); | ||
160 | d->node = cpu; | 190 | d->node = cpu; |
161 | val = readl(reg) & ~(0xff << shift); | 191 | val = readl(reg) & ~mask; |
162 | val |= 1 << (cpu + shift); | 192 | writel(val | bit, reg); |
163 | writel(val, reg); | ||
164 | spin_unlock(&irq_controller_lock); | 193 | spin_unlock(&irq_controller_lock); |
165 | 194 | ||
166 | return 0; | 195 | return 0; |
167 | } | 196 | } |
168 | #endif | 197 | #endif |
169 | 198 | ||
199 | #ifdef CONFIG_PM | ||
200 | static int gic_set_wake(struct irq_data *d, unsigned int on) | ||
201 | { | ||
202 | int ret = -ENXIO; | ||
203 | |||
204 | if (gic_arch_extn.irq_set_wake) | ||
205 | ret = gic_arch_extn.irq_set_wake(d, on); | ||
206 | |||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | #else | ||
211 | #define gic_set_wake NULL | ||
212 | #endif | ||
213 | |||
170 | static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) | 214 | static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) |
171 | { | 215 | { |
172 | struct gic_chip_data *chip_data = get_irq_data(irq); | 216 | struct gic_chip_data *chip_data = get_irq_data(irq); |
@@ -202,9 +246,11 @@ static struct irq_chip gic_chip = { | |||
202 | .irq_mask = gic_mask_irq, | 246 | .irq_mask = gic_mask_irq, |
203 | .irq_unmask = gic_unmask_irq, | 247 | .irq_unmask = gic_unmask_irq, |
204 | .irq_set_type = gic_set_type, | 248 | .irq_set_type = gic_set_type, |
249 | .irq_retrigger = gic_retrigger, | ||
205 | #ifdef CONFIG_SMP | 250 | #ifdef CONFIG_SMP |
206 | .irq_set_affinity = gic_set_cpu, | 251 | .irq_set_affinity = gic_set_affinity, |
207 | #endif | 252 | #endif |
253 | .irq_set_wake = gic_set_wake, | ||
208 | }; | 254 | }; |
209 | 255 | ||
210 | void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) | 256 | void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) |
diff --git a/arch/arm/include/asm/a.out-core.h b/arch/arm/include/asm/a.out-core.h index 93d04acaa31f..92f10cb5c70c 100644 --- a/arch/arm/include/asm/a.out-core.h +++ b/arch/arm/include/asm/a.out-core.h | |||
@@ -32,11 +32,7 @@ static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump) | |||
32 | dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT; | 32 | dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT; |
33 | dump->u_ssize = 0; | 33 | dump->u_ssize = 0; |
34 | 34 | ||
35 | dump->u_debugreg[0] = tsk->thread.debug.bp[0].address; | 35 | memset(dump->u_debugreg, 0, sizeof(dump->u_debugreg)); |
36 | dump->u_debugreg[1] = tsk->thread.debug.bp[1].address; | ||
37 | dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn.arm; | ||
38 | dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn.arm; | ||
39 | dump->u_debugreg[4] = tsk->thread.debug.nsaved; | ||
40 | 36 | ||
41 | if (dump->start_stack < 0x04000000) | 37 | if (dump->start_stack < 0x04000000) |
42 | dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT; | 38 | dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT; |
diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index 20ae96cc0020..ed5bc9e05a4e 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h | |||
@@ -23,6 +23,8 @@ | |||
23 | #define CPUID_EXT_ISAR4 "c2, 4" | 23 | #define CPUID_EXT_ISAR4 "c2, 4" |
24 | #define CPUID_EXT_ISAR5 "c2, 5" | 24 | #define CPUID_EXT_ISAR5 "c2, 5" |
25 | 25 | ||
26 | extern unsigned int processor_id; | ||
27 | |||
26 | #ifdef CONFIG_CPU_CP15 | 28 | #ifdef CONFIG_CPU_CP15 |
27 | #define read_cpuid(reg) \ | 29 | #define read_cpuid(reg) \ |
28 | ({ \ | 30 | ({ \ |
@@ -43,7 +45,6 @@ | |||
43 | __val; \ | 45 | __val; \ |
44 | }) | 46 | }) |
45 | #else | 47 | #else |
46 | extern unsigned int processor_id; | ||
47 | #define read_cpuid(reg) (processor_id) | 48 | #define read_cpuid(reg) (processor_id) |
48 | #define read_cpuid_ext(reg) 0 | 49 | #define read_cpuid_ext(reg) 0 |
49 | #endif | 50 | #endif |
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 84557d321001..0691f9dcc500 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | #ifndef __ASSEMBLY__ | 35 | #ifndef __ASSEMBLY__ |
36 | extern void __iomem *gic_cpu_base_addr; | 36 | extern void __iomem *gic_cpu_base_addr; |
37 | extern struct irq_chip gic_arch_extn; | ||
37 | 38 | ||
38 | void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *); | 39 | void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *); |
39 | void gic_secondary_init(unsigned int); | 40 | void gic_secondary_init(unsigned int); |
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h index 7080e2c8fa62..a4edd19dd3d6 100644 --- a/arch/arm/include/asm/highmem.h +++ b/arch/arm/include/asm/highmem.h | |||
@@ -19,11 +19,36 @@ | |||
19 | 19 | ||
20 | extern pte_t *pkmap_page_table; | 20 | extern pte_t *pkmap_page_table; |
21 | 21 | ||
22 | extern void *kmap_high(struct page *page); | ||
23 | extern void kunmap_high(struct page *page); | ||
24 | |||
25 | /* | ||
26 | * The reason for kmap_high_get() is to ensure that the currently kmap'd | ||
27 | * page usage count does not decrease to zero while we're using its | ||
28 | * existing virtual mapping in an atomic context. With a VIVT cache this | ||
29 | * is essential to do, but with a VIPT cache this is only an optimization | ||
30 | * so not to pay the price of establishing a second mapping if an existing | ||
31 | * one can be used. However, on platforms without hardware TLB maintenance | ||
32 | * broadcast, we simply cannot use ARCH_NEEDS_KMAP_HIGH_GET at all since | ||
33 | * the locking involved must also disable IRQs which is incompatible with | ||
34 | * the IPI mechanism used by global TLB operations. | ||
35 | */ | ||
22 | #define ARCH_NEEDS_KMAP_HIGH_GET | 36 | #define ARCH_NEEDS_KMAP_HIGH_GET |
37 | #if defined(CONFIG_SMP) && defined(CONFIG_CPU_TLB_V6) | ||
38 | #undef ARCH_NEEDS_KMAP_HIGH_GET | ||
39 | #if defined(CONFIG_HIGHMEM) && defined(CONFIG_CPU_CACHE_VIVT) | ||
40 | #error "The sum of features in your kernel config cannot be supported together" | ||
41 | #endif | ||
42 | #endif | ||
23 | 43 | ||
24 | extern void *kmap_high(struct page *page); | 44 | #ifdef ARCH_NEEDS_KMAP_HIGH_GET |
25 | extern void *kmap_high_get(struct page *page); | 45 | extern void *kmap_high_get(struct page *page); |
26 | extern void kunmap_high(struct page *page); | 46 | #else |
47 | static inline void *kmap_high_get(struct page *page) | ||
48 | { | ||
49 | return NULL; | ||
50 | } | ||
51 | #endif | ||
27 | 52 | ||
28 | /* | 53 | /* |
29 | * The following functions are already defined by <linux/highmem.h> | 54 | * The following functions are already defined by <linux/highmem.h> |
diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h index 22ac140edd9e..febe495d0c6e 100644 --- a/arch/arm/include/asm/mach/irq.h +++ b/arch/arm/include/asm/mach/irq.h | |||
@@ -34,4 +34,35 @@ do { \ | |||
34 | raw_spin_unlock(&desc->lock); \ | 34 | raw_spin_unlock(&desc->lock); \ |
35 | } while(0) | 35 | } while(0) |
36 | 36 | ||
37 | #ifndef __ASSEMBLY__ | ||
38 | /* | ||
39 | * Entry/exit functions for chained handlers where the primary IRQ chip | ||
40 | * may implement either fasteoi or level-trigger flow control. | ||
41 | */ | ||
42 | static inline void chained_irq_enter(struct irq_chip *chip, | ||
43 | struct irq_desc *desc) | ||
44 | { | ||
45 | /* FastEOI controllers require no action on entry. */ | ||
46 | if (chip->irq_eoi) | ||
47 | return; | ||
48 | |||
49 | if (chip->irq_mask_ack) { | ||
50 | chip->irq_mask_ack(&desc->irq_data); | ||
51 | } else { | ||
52 | chip->irq_mask(&desc->irq_data); | ||
53 | if (chip->irq_ack) | ||
54 | chip->irq_ack(&desc->irq_data); | ||
55 | } | ||
56 | } | ||
57 | |||
58 | static inline void chained_irq_exit(struct irq_chip *chip, | ||
59 | struct irq_desc *desc) | ||
60 | { | ||
61 | if (chip->irq_eoi) | ||
62 | chip->irq_eoi(&desc->irq_data); | ||
63 | else | ||
64 | chip->irq_unmask(&desc->irq_data); | ||
65 | } | ||
66 | #endif | ||
67 | |||
37 | #endif | 68 | #endif |
diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h index fc1900925275..348d513afa92 100644 --- a/arch/arm/include/asm/outercache.h +++ b/arch/arm/include/asm/outercache.h | |||
@@ -31,6 +31,7 @@ struct outer_cache_fns { | |||
31 | #ifdef CONFIG_OUTER_CACHE_SYNC | 31 | #ifdef CONFIG_OUTER_CACHE_SYNC |
32 | void (*sync)(void); | 32 | void (*sync)(void); |
33 | #endif | 33 | #endif |
34 | void (*set_debug)(unsigned long); | ||
34 | }; | 35 | }; |
35 | 36 | ||
36 | #ifdef CONFIG_OUTER_CACHE | 37 | #ifdef CONFIG_OUTER_CACHE |
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h index 7a1f03c10f1b..b2d9df5667af 100644 --- a/arch/arm/include/asm/processor.h +++ b/arch/arm/include/asm/processor.h | |||
@@ -29,19 +29,7 @@ | |||
29 | #define STACK_TOP_MAX TASK_SIZE | 29 | #define STACK_TOP_MAX TASK_SIZE |
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | union debug_insn { | ||
33 | u32 arm; | ||
34 | u16 thumb; | ||
35 | }; | ||
36 | |||
37 | struct debug_entry { | ||
38 | u32 address; | ||
39 | union debug_insn insn; | ||
40 | }; | ||
41 | |||
42 | struct debug_info { | 32 | struct debug_info { |
43 | int nsaved; | ||
44 | struct debug_entry bp[2]; | ||
45 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | 33 | #ifdef CONFIG_HAVE_HW_BREAKPOINT |
46 | struct perf_event *hbp[ARM_MAX_HBP_SLOTS]; | 34 | struct perf_event *hbp[ARM_MAX_HBP_SLOTS]; |
47 | #endif | 35 | #endif |
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 783d50f32618..a8ff22b2a391 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h | |||
@@ -130,8 +130,6 @@ struct pt_regs { | |||
130 | 130 | ||
131 | #ifdef __KERNEL__ | 131 | #ifdef __KERNEL__ |
132 | 132 | ||
133 | #define arch_has_single_step() (1) | ||
134 | |||
135 | #define user_mode(regs) \ | 133 | #define user_mode(regs) \ |
136 | (((regs)->ARM_cpsr & 0xf) == 0) | 134 | (((regs)->ARM_cpsr & 0xf) == 0) |
137 | 135 | ||
diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h index 1b960d5ef6a5..f90756dc16dc 100644 --- a/arch/arm/include/asm/traps.h +++ b/arch/arm/include/asm/traps.h | |||
@@ -45,6 +45,7 @@ static inline int in_exception_text(unsigned long ptr) | |||
45 | 45 | ||
46 | extern void __init early_trap_init(void); | 46 | extern void __init early_trap_init(void); |
47 | extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame); | 47 | extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame); |
48 | extern void ptrace_break(struct task_struct *tsk, struct pt_regs *regs); | ||
48 | 49 | ||
49 | extern void *vectors_page; | 50 | extern void *vectors_page; |
50 | 51 | ||
diff --git a/arch/arm/include/asm/user.h b/arch/arm/include/asm/user.h index 05ac4b06876a..35917b3a97f9 100644 --- a/arch/arm/include/asm/user.h +++ b/arch/arm/include/asm/user.h | |||
@@ -71,7 +71,7 @@ struct user{ | |||
71 | /* the registers. */ | 71 | /* the registers. */ |
72 | unsigned long magic; /* To uniquely identify a core file */ | 72 | unsigned long magic; /* To uniquely identify a core file */ |
73 | char u_comm[32]; /* User command that was responsible */ | 73 | char u_comm[32]; /* User command that was responsible */ |
74 | int u_debugreg[8]; | 74 | int u_debugreg[8]; /* No longer used */ |
75 | struct user_fp u_fp; /* FP state */ | 75 | struct user_fp u_fp; /* FP state */ |
76 | struct user_fp_struct * u_fp0;/* Used by gdb to help find the values for */ | 76 | struct user_fp_struct * u_fp0;/* Used by gdb to help find the values for */ |
77 | /* the FP registers. */ | 77 | /* the FP registers. */ |
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index c6273a3bfc25..d86fcd44b220 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c | |||
@@ -583,6 +583,11 @@ void __init pci_common_init(struct hw_pci *hw) | |||
583 | * Assign resources. | 583 | * Assign resources. |
584 | */ | 584 | */ |
585 | pci_bus_assign_resources(bus); | 585 | pci_bus_assign_resources(bus); |
586 | |||
587 | /* | ||
588 | * Enable bridges | ||
589 | */ | ||
590 | pci_enable_bridges(bus); | ||
586 | } | 591 | } |
587 | 592 | ||
588 | /* | 593 | /* |
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 8f57515bbdb0..c84b57d27d07 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S | |||
@@ -25,83 +25,6 @@ | |||
25 | * machine ID for example). | 25 | * machine ID for example). |
26 | */ | 26 | */ |
27 | __HEAD | 27 | __HEAD |
28 | __error_a: | ||
29 | #ifdef CONFIG_DEBUG_LL | ||
30 | mov r4, r1 @ preserve machine ID | ||
31 | adr r0, str_a1 | ||
32 | bl printascii | ||
33 | mov r0, r4 | ||
34 | bl printhex8 | ||
35 | adr r0, str_a2 | ||
36 | bl printascii | ||
37 | adr r3, __lookup_machine_type_data | ||
38 | ldmia r3, {r4, r5, r6} @ get machine desc list | ||
39 | sub r4, r3, r4 @ get offset between virt&phys | ||
40 | add r5, r5, r4 @ convert virt addresses to | ||
41 | add r6, r6, r4 @ physical address space | ||
42 | 1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type | ||
43 | bl printhex8 | ||
44 | mov r0, #'\t' | ||
45 | bl printch | ||
46 | ldr r0, [r5, #MACHINFO_NAME] @ get machine name | ||
47 | add r0, r0, r4 | ||
48 | bl printascii | ||
49 | mov r0, #'\n' | ||
50 | bl printch | ||
51 | add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc | ||
52 | cmp r5, r6 | ||
53 | blo 1b | ||
54 | adr r0, str_a3 | ||
55 | bl printascii | ||
56 | b __error | ||
57 | ENDPROC(__error_a) | ||
58 | |||
59 | str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x" | ||
60 | str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n" | ||
61 | str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n" | ||
62 | .align | ||
63 | #else | ||
64 | b __error | ||
65 | #endif | ||
66 | |||
67 | /* | ||
68 | * Lookup machine architecture in the linker-build list of architectures. | ||
69 | * Note that we can't use the absolute addresses for the __arch_info | ||
70 | * lists since we aren't running with the MMU on (and therefore, we are | ||
71 | * not in the correct address space). We have to calculate the offset. | ||
72 | * | ||
73 | * r1 = machine architecture number | ||
74 | * Returns: | ||
75 | * r3, r4, r6 corrupted | ||
76 | * r5 = mach_info pointer in physical address space | ||
77 | */ | ||
78 | __lookup_machine_type: | ||
79 | adr r3, __lookup_machine_type_data | ||
80 | ldmia r3, {r4, r5, r6} | ||
81 | sub r3, r3, r4 @ get offset between virt&phys | ||
82 | add r5, r5, r3 @ convert virt addresses to | ||
83 | add r6, r6, r3 @ physical address space | ||
84 | 1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type | ||
85 | teq r3, r1 @ matches loader number? | ||
86 | beq 2f @ found | ||
87 | add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc | ||
88 | cmp r5, r6 | ||
89 | blo 1b | ||
90 | mov r5, #0 @ unknown machine | ||
91 | 2: mov pc, lr | ||
92 | ENDPROC(__lookup_machine_type) | ||
93 | |||
94 | /* | ||
95 | * Look in arch/arm/kernel/arch.[ch] for information about the | ||
96 | * __arch_info structures. | ||
97 | */ | ||
98 | .align 2 | ||
99 | .type __lookup_machine_type_data, %object | ||
100 | __lookup_machine_type_data: | ||
101 | .long . | ||
102 | .long __arch_info_begin | ||
103 | .long __arch_info_end | ||
104 | .size __lookup_machine_type_data, . - __lookup_machine_type_data | ||
105 | 28 | ||
106 | /* Determine validity of the r2 atags pointer. The heuristic requires | 29 | /* Determine validity of the r2 atags pointer. The heuristic requires |
107 | * that the pointer be aligned, in the first 16k of physical RAM and | 30 | * that the pointer be aligned, in the first 16k of physical RAM and |
@@ -109,8 +32,6 @@ __lookup_machine_type_data: | |||
109 | * of this function may be more lenient with the physical address and | 32 | * of this function may be more lenient with the physical address and |
110 | * may also be able to move the ATAGS block if necessary. | 33 | * may also be able to move the ATAGS block if necessary. |
111 | * | 34 | * |
112 | * r8 = machinfo | ||
113 | * | ||
114 | * Returns: | 35 | * Returns: |
115 | * r2 either valid atags pointer, or zero | 36 | * r2 either valid atags pointer, or zero |
116 | * r5, r6 corrupted | 37 | * r5, r6 corrupted |
@@ -185,17 +106,6 @@ __mmap_switched_data: | |||
185 | .size __mmap_switched_data, . - __mmap_switched_data | 106 | .size __mmap_switched_data, . - __mmap_switched_data |
186 | 107 | ||
187 | /* | 108 | /* |
188 | * This provides a C-API version of __lookup_machine_type | ||
189 | */ | ||
190 | ENTRY(lookup_machine_type) | ||
191 | stmfd sp!, {r4 - r6, lr} | ||
192 | mov r1, r0 | ||
193 | bl __lookup_machine_type | ||
194 | mov r0, r5 | ||
195 | ldmfd sp!, {r4 - r6, pc} | ||
196 | ENDPROC(lookup_machine_type) | ||
197 | |||
198 | /* | ||
199 | * This provides a C-API version of __lookup_processor_type | 109 | * This provides a C-API version of __lookup_processor_type |
200 | */ | 110 | */ |
201 | ENTRY(lookup_processor_type) | 111 | ENTRY(lookup_processor_type) |
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index 814ce1a73270..6b1e0ad9ec3b 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S | |||
@@ -44,9 +44,6 @@ ENTRY(stext) | |||
44 | bl __lookup_processor_type @ r5=procinfo r9=cpuid | 44 | bl __lookup_processor_type @ r5=procinfo r9=cpuid |
45 | movs r10, r5 @ invalid processor (r5=0)? | 45 | movs r10, r5 @ invalid processor (r5=0)? |
46 | beq __error_p @ yes, error 'p' | 46 | beq __error_p @ yes, error 'p' |
47 | bl __lookup_machine_type @ r5=machinfo | ||
48 | movs r8, r5 @ invalid machine (r5=0)? | ||
49 | beq __error_a @ yes, error 'a' | ||
50 | 47 | ||
51 | adr lr, BSYM(__after_proc_init) @ return (PIC) address | 48 | adr lr, BSYM(__after_proc_init) @ return (PIC) address |
52 | ARM( add pc, r10, #PROCINFO_INITFUNC ) | 49 | ARM( add pc, r10, #PROCINFO_INITFUNC ) |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index f06ff9feb0db..60fe2795f4a3 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
@@ -87,14 +87,10 @@ ENTRY(stext) | |||
87 | movs r10, r5 @ invalid processor (r5=0)? | 87 | movs r10, r5 @ invalid processor (r5=0)? |
88 | THUMB( it eq ) @ force fixup-able long branch encoding | 88 | THUMB( it eq ) @ force fixup-able long branch encoding |
89 | beq __error_p @ yes, error 'p' | 89 | beq __error_p @ yes, error 'p' |
90 | bl __lookup_machine_type @ r5=machinfo | ||
91 | movs r8, r5 @ invalid machine (r5=0)? | ||
92 | THUMB( it eq ) @ force fixup-able long branch encoding | ||
93 | beq __error_a @ yes, error 'a' | ||
94 | 90 | ||
95 | /* | 91 | /* |
96 | * r1 = machine no, r2 = atags, | 92 | * r1 = machine no, r2 = atags, |
97 | * r8 = machinfo, r9 = cpuid, r10 = procinfo | 93 | * r9 = cpuid, r10 = procinfo |
98 | */ | 94 | */ |
99 | bl __vet_atags | 95 | bl __vet_atags |
100 | #ifdef CONFIG_SMP_ON_UP | 96 | #ifdef CONFIG_SMP_ON_UP |
@@ -105,7 +101,7 @@ ENTRY(stext) | |||
105 | /* | 101 | /* |
106 | * The following calls CPU specific code in a position independent | 102 | * The following calls CPU specific code in a position independent |
107 | * manner. See arch/arm/mm/proc-*.S for details. r10 = base of | 103 | * manner. See arch/arm/mm/proc-*.S for details. r10 = base of |
108 | * xxx_proc_info structure selected by __lookup_machine_type | 104 | * xxx_proc_info structure selected by __lookup_processor_type |
109 | * above. On return, the CPU will be ready for the MMU to be | 105 | * above. On return, the CPU will be ready for the MMU to be |
110 | * turned on, and r0 will hold the CPU control register value. | 106 | * turned on, and r0 will hold the CPU control register value. |
111 | */ | 107 | */ |
@@ -124,7 +120,6 @@ ENDPROC(stext) | |||
124 | * amount which are required to get the kernel running, which | 120 | * amount which are required to get the kernel running, which |
125 | * generally means mapping in the kernel code. | 121 | * generally means mapping in the kernel code. |
126 | * | 122 | * |
127 | * r8 = machinfo | ||
128 | * r9 = cpuid | 123 | * r9 = cpuid |
129 | * r10 = procinfo | 124 | * r10 = procinfo |
130 | * | 125 | * |
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 28536e352deb..3535d3793e65 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c | |||
@@ -179,14 +179,21 @@ int __init arch_probe_nr_irqs(void) | |||
179 | 179 | ||
180 | #ifdef CONFIG_HOTPLUG_CPU | 180 | #ifdef CONFIG_HOTPLUG_CPU |
181 | 181 | ||
182 | static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu) | 182 | static bool migrate_one_irq(struct irq_data *d) |
183 | { | 183 | { |
184 | pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->irq_data.node, cpu); | 184 | unsigned int cpu = cpumask_any_and(d->affinity, cpu_online_mask); |
185 | bool ret = false; | ||
185 | 186 | ||
186 | raw_spin_lock_irq(&desc->lock); | 187 | if (cpu >= nr_cpu_ids) { |
187 | desc->irq_data.chip->irq_set_affinity(&desc->irq_data, | 188 | cpu = cpumask_any(cpu_online_mask); |
188 | cpumask_of(cpu), false); | 189 | ret = true; |
189 | raw_spin_unlock_irq(&desc->lock); | 190 | } |
191 | |||
192 | pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", d->irq, d->node, cpu); | ||
193 | |||
194 | d->chip->irq_set_affinity(d, cpumask_of(cpu), true); | ||
195 | |||
196 | return ret; | ||
190 | } | 197 | } |
191 | 198 | ||
192 | /* | 199 | /* |
@@ -198,25 +205,30 @@ void migrate_irqs(void) | |||
198 | { | 205 | { |
199 | unsigned int i, cpu = smp_processor_id(); | 206 | unsigned int i, cpu = smp_processor_id(); |
200 | struct irq_desc *desc; | 207 | struct irq_desc *desc; |
208 | unsigned long flags; | ||
209 | |||
210 | local_irq_save(flags); | ||
201 | 211 | ||
202 | for_each_irq_desc(i, desc) { | 212 | for_each_irq_desc(i, desc) { |
203 | struct irq_data *d = &desc->irq_data; | 213 | struct irq_data *d = &desc->irq_data; |
214 | bool affinity_broken = false; | ||
204 | 215 | ||
205 | if (d->node == cpu) { | 216 | raw_spin_lock(&desc->lock); |
206 | unsigned int newcpu = cpumask_any_and(d->affinity, | 217 | do { |
207 | cpu_online_mask); | 218 | if (desc->action == NULL) |
208 | if (newcpu >= nr_cpu_ids) { | 219 | break; |
209 | if (printk_ratelimit()) | ||
210 | printk(KERN_INFO "IRQ%u no longer affine to CPU%u\n", | ||
211 | i, cpu); | ||
212 | 220 | ||
213 | cpumask_setall(d->affinity); | 221 | if (d->node != cpu) |
214 | newcpu = cpumask_any_and(d->affinity, | 222 | break; |
215 | cpu_online_mask); | ||
216 | } | ||
217 | 223 | ||
218 | route_irq(desc, i, newcpu); | 224 | affinity_broken = migrate_one_irq(d); |
219 | } | 225 | } while (0); |
226 | raw_spin_unlock(&desc->lock); | ||
227 | |||
228 | if (affinity_broken && printk_ratelimit()) | ||
229 | pr_warning("IRQ%u no longer affine to CPU%u\n", i, cpu); | ||
220 | } | 230 | } |
231 | |||
232 | local_irq_restore(flags); | ||
221 | } | 233 | } |
222 | #endif /* CONFIG_HOTPLUG_CPU */ | 234 | #endif /* CONFIG_HOTPLUG_CPU */ |
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 6d4105e6872f..6fcf22cf385c 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c | |||
@@ -76,6 +76,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, | |||
76 | for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) { | 76 | for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) { |
77 | unsigned long loc; | 77 | unsigned long loc; |
78 | Elf32_Sym *sym; | 78 | Elf32_Sym *sym; |
79 | const char *symname; | ||
79 | s32 offset; | 80 | s32 offset; |
80 | #ifdef CONFIG_THUMB2_KERNEL | 81 | #ifdef CONFIG_THUMB2_KERNEL |
81 | u32 upper, lower, sign, j1, j2; | 82 | u32 upper, lower, sign, j1, j2; |
@@ -83,18 +84,18 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, | |||
83 | 84 | ||
84 | offset = ELF32_R_SYM(rel->r_info); | 85 | offset = ELF32_R_SYM(rel->r_info); |
85 | if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { | 86 | if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { |
86 | printk(KERN_ERR "%s: bad relocation, section %d reloc %d\n", | 87 | pr_err("%s: section %u reloc %u: bad relocation sym offset\n", |
87 | module->name, relindex, i); | 88 | module->name, relindex, i); |
88 | return -ENOEXEC; | 89 | return -ENOEXEC; |
89 | } | 90 | } |
90 | 91 | ||
91 | sym = ((Elf32_Sym *)symsec->sh_addr) + offset; | 92 | sym = ((Elf32_Sym *)symsec->sh_addr) + offset; |
93 | symname = strtab + sym->st_name; | ||
92 | 94 | ||
93 | if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) { | 95 | if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) { |
94 | printk(KERN_ERR "%s: out of bounds relocation, " | 96 | pr_err("%s: section %u reloc %u sym '%s': out of bounds relocation, offset %d size %u\n", |
95 | "section %d reloc %d offset %d size %d\n", | 97 | module->name, relindex, i, symname, |
96 | module->name, relindex, i, rel->r_offset, | 98 | rel->r_offset, dstsec->sh_size); |
97 | dstsec->sh_size); | ||
98 | return -ENOEXEC; | 99 | return -ENOEXEC; |
99 | } | 100 | } |
100 | 101 | ||
@@ -120,10 +121,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, | |||
120 | if (offset & 3 || | 121 | if (offset & 3 || |
121 | offset <= (s32)0xfe000000 || | 122 | offset <= (s32)0xfe000000 || |
122 | offset >= (s32)0x02000000) { | 123 | offset >= (s32)0x02000000) { |
123 | printk(KERN_ERR | 124 | pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n", |
124 | "%s: relocation out of range, section " | 125 | module->name, relindex, i, symname, |
125 | "%d reloc %d sym '%s'\n", module->name, | 126 | ELF32_R_TYPE(rel->r_info), loc, |
126 | relindex, i, strtab + sym->st_name); | 127 | sym->st_value); |
127 | return -ENOEXEC; | 128 | return -ENOEXEC; |
128 | } | 129 | } |
129 | 130 | ||
@@ -196,10 +197,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, | |||
196 | if (!(offset & 1) || | 197 | if (!(offset & 1) || |
197 | offset <= (s32)0xff000000 || | 198 | offset <= (s32)0xff000000 || |
198 | offset >= (s32)0x01000000) { | 199 | offset >= (s32)0x01000000) { |
199 | printk(KERN_ERR | 200 | pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n", |
200 | "%s: relocation out of range, section " | 201 | module->name, relindex, i, symname, |
201 | "%d reloc %d sym '%s'\n", module->name, | 202 | ELF32_R_TYPE(rel->r_info), loc, |
202 | relindex, i, strtab + sym->st_name); | 203 | sym->st_value); |
203 | return -ENOEXEC; | 204 | return -ENOEXEC; |
204 | } | 205 | } |
205 | 206 | ||
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index b13e70f63d71..2bf27f364d09 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
@@ -26,8 +26,6 @@ | |||
26 | #include <asm/system.h> | 26 | #include <asm/system.h> |
27 | #include <asm/traps.h> | 27 | #include <asm/traps.h> |
28 | 28 | ||
29 | #include "ptrace.h" | ||
30 | |||
31 | #define REG_PC 15 | 29 | #define REG_PC 15 |
32 | #define REG_PSR 16 | 30 | #define REG_PSR 16 |
33 | /* | 31 | /* |
@@ -184,389 +182,12 @@ put_user_reg(struct task_struct *task, int offset, long data) | |||
184 | return ret; | 182 | return ret; |
185 | } | 183 | } |
186 | 184 | ||
187 | static inline int | ||
188 | read_u32(struct task_struct *task, unsigned long addr, u32 *res) | ||
189 | { | ||
190 | int ret; | ||
191 | |||
192 | ret = access_process_vm(task, addr, res, sizeof(*res), 0); | ||
193 | |||
194 | return ret == sizeof(*res) ? 0 : -EIO; | ||
195 | } | ||
196 | |||
197 | static inline int | ||
198 | read_instr(struct task_struct *task, unsigned long addr, u32 *res) | ||
199 | { | ||
200 | int ret; | ||
201 | |||
202 | if (addr & 1) { | ||
203 | u16 val; | ||
204 | ret = access_process_vm(task, addr & ~1, &val, sizeof(val), 0); | ||
205 | ret = ret == sizeof(val) ? 0 : -EIO; | ||
206 | *res = val; | ||
207 | } else { | ||
208 | u32 val; | ||
209 | ret = access_process_vm(task, addr & ~3, &val, sizeof(val), 0); | ||
210 | ret = ret == sizeof(val) ? 0 : -EIO; | ||
211 | *res = val; | ||
212 | } | ||
213 | return ret; | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * Get value of register `rn' (in the instruction) | ||
218 | */ | ||
219 | static unsigned long | ||
220 | ptrace_getrn(struct task_struct *child, unsigned long insn) | ||
221 | { | ||
222 | unsigned int reg = (insn >> 16) & 15; | ||
223 | unsigned long val; | ||
224 | |||
225 | val = get_user_reg(child, reg); | ||
226 | if (reg == 15) | ||
227 | val += 8; | ||
228 | |||
229 | return val; | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * Get value of operand 2 (in an ALU instruction) | ||
234 | */ | ||
235 | static unsigned long | ||
236 | ptrace_getaluop2(struct task_struct *child, unsigned long insn) | ||
237 | { | ||
238 | unsigned long val; | ||
239 | int shift; | ||
240 | int type; | ||
241 | |||
242 | if (insn & 1 << 25) { | ||
243 | val = insn & 255; | ||
244 | shift = (insn >> 8) & 15; | ||
245 | type = 3; | ||
246 | } else { | ||
247 | val = get_user_reg (child, insn & 15); | ||
248 | |||
249 | if (insn & (1 << 4)) | ||
250 | shift = (int)get_user_reg (child, (insn >> 8) & 15); | ||
251 | else | ||
252 | shift = (insn >> 7) & 31; | ||
253 | |||
254 | type = (insn >> 5) & 3; | ||
255 | } | ||
256 | |||
257 | switch (type) { | ||
258 | case 0: val <<= shift; break; | ||
259 | case 1: val >>= shift; break; | ||
260 | case 2: | ||
261 | val = (((signed long)val) >> shift); | ||
262 | break; | ||
263 | case 3: | ||
264 | val = (val >> shift) | (val << (32 - shift)); | ||
265 | break; | ||
266 | } | ||
267 | return val; | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * Get value of operand 2 (in a LDR instruction) | ||
272 | */ | ||
273 | static unsigned long | ||
274 | ptrace_getldrop2(struct task_struct *child, unsigned long insn) | ||
275 | { | ||
276 | unsigned long val; | ||
277 | int shift; | ||
278 | int type; | ||
279 | |||
280 | val = get_user_reg(child, insn & 15); | ||
281 | shift = (insn >> 7) & 31; | ||
282 | type = (insn >> 5) & 3; | ||
283 | |||
284 | switch (type) { | ||
285 | case 0: val <<= shift; break; | ||
286 | case 1: val >>= shift; break; | ||
287 | case 2: | ||
288 | val = (((signed long)val) >> shift); | ||
289 | break; | ||
290 | case 3: | ||
291 | val = (val >> shift) | (val << (32 - shift)); | ||
292 | break; | ||
293 | } | ||
294 | return val; | ||
295 | } | ||
296 | |||
297 | #define OP_MASK 0x01e00000 | ||
298 | #define OP_AND 0x00000000 | ||
299 | #define OP_EOR 0x00200000 | ||
300 | #define OP_SUB 0x00400000 | ||
301 | #define OP_RSB 0x00600000 | ||
302 | #define OP_ADD 0x00800000 | ||
303 | #define OP_ADC 0x00a00000 | ||
304 | #define OP_SBC 0x00c00000 | ||
305 | #define OP_RSC 0x00e00000 | ||
306 | #define OP_ORR 0x01800000 | ||
307 | #define OP_MOV 0x01a00000 | ||
308 | #define OP_BIC 0x01c00000 | ||
309 | #define OP_MVN 0x01e00000 | ||
310 | |||
311 | static unsigned long | ||
312 | get_branch_address(struct task_struct *child, unsigned long pc, unsigned long insn) | ||
313 | { | ||
314 | u32 alt = 0; | ||
315 | |||
316 | switch (insn & 0x0e000000) { | ||
317 | case 0x00000000: | ||
318 | case 0x02000000: { | ||
319 | /* | ||
320 | * data processing | ||
321 | */ | ||
322 | long aluop1, aluop2, ccbit; | ||
323 | |||
324 | if ((insn & 0x0fffffd0) == 0x012fff10) { | ||
325 | /* | ||
326 | * bx or blx | ||
327 | */ | ||
328 | alt = get_user_reg(child, insn & 15); | ||
329 | break; | ||
330 | } | ||
331 | |||
332 | |||
333 | if ((insn & 0xf000) != 0xf000) | ||
334 | break; | ||
335 | |||
336 | aluop1 = ptrace_getrn(child, insn); | ||
337 | aluop2 = ptrace_getaluop2(child, insn); | ||
338 | ccbit = get_user_reg(child, REG_PSR) & PSR_C_BIT ? 1 : 0; | ||
339 | |||
340 | switch (insn & OP_MASK) { | ||
341 | case OP_AND: alt = aluop1 & aluop2; break; | ||
342 | case OP_EOR: alt = aluop1 ^ aluop2; break; | ||
343 | case OP_SUB: alt = aluop1 - aluop2; break; | ||
344 | case OP_RSB: alt = aluop2 - aluop1; break; | ||
345 | case OP_ADD: alt = aluop1 + aluop2; break; | ||
346 | case OP_ADC: alt = aluop1 + aluop2 + ccbit; break; | ||
347 | case OP_SBC: alt = aluop1 - aluop2 + ccbit; break; | ||
348 | case OP_RSC: alt = aluop2 - aluop1 + ccbit; break; | ||
349 | case OP_ORR: alt = aluop1 | aluop2; break; | ||
350 | case OP_MOV: alt = aluop2; break; | ||
351 | case OP_BIC: alt = aluop1 & ~aluop2; break; | ||
352 | case OP_MVN: alt = ~aluop2; break; | ||
353 | } | ||
354 | break; | ||
355 | } | ||
356 | |||
357 | case 0x04000000: | ||
358 | case 0x06000000: | ||
359 | /* | ||
360 | * ldr | ||
361 | */ | ||
362 | if ((insn & 0x0010f000) == 0x0010f000) { | ||
363 | unsigned long base; | ||
364 | |||
365 | base = ptrace_getrn(child, insn); | ||
366 | if (insn & 1 << 24) { | ||
367 | long aluop2; | ||
368 | |||
369 | if (insn & 0x02000000) | ||
370 | aluop2 = ptrace_getldrop2(child, insn); | ||
371 | else | ||
372 | aluop2 = insn & 0xfff; | ||
373 | |||
374 | if (insn & 1 << 23) | ||
375 | base += aluop2; | ||
376 | else | ||
377 | base -= aluop2; | ||
378 | } | ||
379 | read_u32(child, base, &alt); | ||
380 | } | ||
381 | break; | ||
382 | |||
383 | case 0x08000000: | ||
384 | /* | ||
385 | * ldm | ||
386 | */ | ||
387 | if ((insn & 0x00108000) == 0x00108000) { | ||
388 | unsigned long base; | ||
389 | unsigned int nr_regs; | ||
390 | |||
391 | if (insn & (1 << 23)) { | ||
392 | nr_regs = hweight16(insn & 65535) << 2; | ||
393 | |||
394 | if (!(insn & (1 << 24))) | ||
395 | nr_regs -= 4; | ||
396 | } else { | ||
397 | if (insn & (1 << 24)) | ||
398 | nr_regs = -4; | ||
399 | else | ||
400 | nr_regs = 0; | ||
401 | } | ||
402 | |||
403 | base = ptrace_getrn(child, insn); | ||
404 | |||
405 | read_u32(child, base + nr_regs, &alt); | ||
406 | break; | ||
407 | } | ||
408 | break; | ||
409 | |||
410 | case 0x0a000000: { | ||
411 | /* | ||
412 | * bl or b | ||
413 | */ | ||
414 | signed long displ; | ||
415 | /* It's a branch/branch link: instead of trying to | ||
416 | * figure out whether the branch will be taken or not, | ||
417 | * we'll put a breakpoint at both locations. This is | ||
418 | * simpler, more reliable, and probably not a whole lot | ||
419 | * slower than the alternative approach of emulating the | ||
420 | * branch. | ||
421 | */ | ||
422 | displ = (insn & 0x00ffffff) << 8; | ||
423 | displ = (displ >> 6) + 8; | ||
424 | if (displ != 0 && displ != 4) | ||
425 | alt = pc + displ; | ||
426 | } | ||
427 | break; | ||
428 | } | ||
429 | |||
430 | return alt; | ||
431 | } | ||
432 | |||
433 | static int | ||
434 | swap_insn(struct task_struct *task, unsigned long addr, | ||
435 | void *old_insn, void *new_insn, int size) | ||
436 | { | ||
437 | int ret; | ||
438 | |||
439 | ret = access_process_vm(task, addr, old_insn, size, 0); | ||
440 | if (ret == size) | ||
441 | ret = access_process_vm(task, addr, new_insn, size, 1); | ||
442 | return ret; | ||
443 | } | ||
444 | |||
445 | static void | ||
446 | add_breakpoint(struct task_struct *task, struct debug_info *dbg, unsigned long addr) | ||
447 | { | ||
448 | int nr = dbg->nsaved; | ||
449 | |||
450 | if (nr < 2) { | ||
451 | u32 new_insn = BREAKINST_ARM; | ||
452 | int res; | ||
453 | |||
454 | res = swap_insn(task, addr, &dbg->bp[nr].insn, &new_insn, 4); | ||
455 | |||
456 | if (res == 4) { | ||
457 | dbg->bp[nr].address = addr; | ||
458 | dbg->nsaved += 1; | ||
459 | } | ||
460 | } else | ||
461 | printk(KERN_ERR "ptrace: too many breakpoints\n"); | ||
462 | } | ||
463 | |||
464 | /* | ||
465 | * Clear one breakpoint in the user program. We copy what the hardware | ||
466 | * does and use bit 0 of the address to indicate whether this is a Thumb | ||
467 | * breakpoint or an ARM breakpoint. | ||
468 | */ | ||
469 | static void clear_breakpoint(struct task_struct *task, struct debug_entry *bp) | ||
470 | { | ||
471 | unsigned long addr = bp->address; | ||
472 | union debug_insn old_insn; | ||
473 | int ret; | ||
474 | |||
475 | if (addr & 1) { | ||
476 | ret = swap_insn(task, addr & ~1, &old_insn.thumb, | ||
477 | &bp->insn.thumb, 2); | ||
478 | |||
479 | if (ret != 2 || old_insn.thumb != BREAKINST_THUMB) | ||
480 | printk(KERN_ERR "%s:%d: corrupted Thumb breakpoint at " | ||
481 | "0x%08lx (0x%04x)\n", task->comm, | ||
482 | task_pid_nr(task), addr, old_insn.thumb); | ||
483 | } else { | ||
484 | ret = swap_insn(task, addr & ~3, &old_insn.arm, | ||
485 | &bp->insn.arm, 4); | ||
486 | |||
487 | if (ret != 4 || old_insn.arm != BREAKINST_ARM) | ||
488 | printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at " | ||
489 | "0x%08lx (0x%08x)\n", task->comm, | ||
490 | task_pid_nr(task), addr, old_insn.arm); | ||
491 | } | ||
492 | } | ||
493 | |||
494 | void ptrace_set_bpt(struct task_struct *child) | ||
495 | { | ||
496 | struct pt_regs *regs; | ||
497 | unsigned long pc; | ||
498 | u32 insn; | ||
499 | int res; | ||
500 | |||
501 | regs = task_pt_regs(child); | ||
502 | pc = instruction_pointer(regs); | ||
503 | |||
504 | if (thumb_mode(regs)) { | ||
505 | printk(KERN_WARNING "ptrace: can't handle thumb mode\n"); | ||
506 | return; | ||
507 | } | ||
508 | |||
509 | res = read_instr(child, pc, &insn); | ||
510 | if (!res) { | ||
511 | struct debug_info *dbg = &child->thread.debug; | ||
512 | unsigned long alt; | ||
513 | |||
514 | dbg->nsaved = 0; | ||
515 | |||
516 | alt = get_branch_address(child, pc, insn); | ||
517 | if (alt) | ||
518 | add_breakpoint(child, dbg, alt); | ||
519 | |||
520 | /* | ||
521 | * Note that we ignore the result of setting the above | ||
522 | * breakpoint since it may fail. When it does, this is | ||
523 | * not so much an error, but a forewarning that we may | ||
524 | * be receiving a prefetch abort shortly. | ||
525 | * | ||
526 | * If we don't set this breakpoint here, then we can | ||
527 | * lose control of the thread during single stepping. | ||
528 | */ | ||
529 | if (!alt || predicate(insn) != PREDICATE_ALWAYS) | ||
530 | add_breakpoint(child, dbg, pc + 4); | ||
531 | } | ||
532 | } | ||
533 | |||
534 | /* | ||
535 | * Ensure no single-step breakpoint is pending. Returns non-zero | ||
536 | * value if child was being single-stepped. | ||
537 | */ | ||
538 | void ptrace_cancel_bpt(struct task_struct *child) | ||
539 | { | ||
540 | int i, nsaved = child->thread.debug.nsaved; | ||
541 | |||
542 | child->thread.debug.nsaved = 0; | ||
543 | |||
544 | if (nsaved > 2) { | ||
545 | printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved); | ||
546 | nsaved = 2; | ||
547 | } | ||
548 | |||
549 | for (i = 0; i < nsaved; i++) | ||
550 | clear_breakpoint(child, &child->thread.debug.bp[i]); | ||
551 | } | ||
552 | |||
553 | void user_disable_single_step(struct task_struct *task) | ||
554 | { | ||
555 | task->ptrace &= ~PT_SINGLESTEP; | ||
556 | ptrace_cancel_bpt(task); | ||
557 | } | ||
558 | |||
559 | void user_enable_single_step(struct task_struct *task) | ||
560 | { | ||
561 | task->ptrace |= PT_SINGLESTEP; | ||
562 | } | ||
563 | |||
564 | /* | 185 | /* |
565 | * Called by kernel/ptrace.c when detaching.. | 186 | * Called by kernel/ptrace.c when detaching.. |
566 | */ | 187 | */ |
567 | void ptrace_disable(struct task_struct *child) | 188 | void ptrace_disable(struct task_struct *child) |
568 | { | 189 | { |
569 | user_disable_single_step(child); | 190 | /* Nothing to do. */ |
570 | } | 191 | } |
571 | 192 | ||
572 | /* | 193 | /* |
@@ -576,8 +197,6 @@ void ptrace_break(struct task_struct *tsk, struct pt_regs *regs) | |||
576 | { | 197 | { |
577 | siginfo_t info; | 198 | siginfo_t info; |
578 | 199 | ||
579 | ptrace_cancel_bpt(tsk); | ||
580 | |||
581 | info.si_signo = SIGTRAP; | 200 | info.si_signo = SIGTRAP; |
582 | info.si_errno = 0; | 201 | info.si_errno = 0; |
583 | info.si_code = TRAP_BRKPT; | 202 | info.si_code = TRAP_BRKPT; |
diff --git a/arch/arm/kernel/ptrace.h b/arch/arm/kernel/ptrace.h deleted file mode 100644 index 3926605b82ea..000000000000 --- a/arch/arm/kernel/ptrace.h +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/kernel/ptrace.h | ||
3 | * | ||
4 | * Copyright (C) 2000-2003 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/ptrace.h> | ||
11 | |||
12 | extern void ptrace_cancel_bpt(struct task_struct *); | ||
13 | extern void ptrace_set_bpt(struct task_struct *); | ||
14 | extern void ptrace_break(struct task_struct *, struct pt_regs *); | ||
15 | |||
16 | /* | ||
17 | * Send SIGTRAP if we're single-stepping | ||
18 | */ | ||
19 | static inline void single_step_trap(struct task_struct *task) | ||
20 | { | ||
21 | if (task->ptrace & PT_SINGLESTEP) { | ||
22 | ptrace_cancel_bpt(task); | ||
23 | send_sig(SIGTRAP, task, 1); | ||
24 | } | ||
25 | } | ||
26 | |||
27 | static inline void single_step_clear(struct task_struct *task) | ||
28 | { | ||
29 | if (task->ptrace & PT_SINGLESTEP) | ||
30 | ptrace_cancel_bpt(task); | ||
31 | } | ||
32 | |||
33 | static inline void single_step_set(struct task_struct *task) | ||
34 | { | ||
35 | if (task->ptrace & PT_SINGLESTEP) | ||
36 | ptrace_set_bpt(task); | ||
37 | } | ||
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c index df246da4ceca..0b13a72f855d 100644 --- a/arch/arm/kernel/return_address.c +++ b/arch/arm/kernel/return_address.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * the Free Software Foundation. | 9 | * the Free Software Foundation. |
10 | */ | 10 | */ |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/ftrace.h> | ||
12 | 13 | ||
13 | #if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) | 14 | #if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) |
14 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 5ea4fb718b97..db2382853450 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -308,7 +308,44 @@ static void __init cacheid_init(void) | |||
308 | * already provide the required functionality. | 308 | * already provide the required functionality. |
309 | */ | 309 | */ |
310 | extern struct proc_info_list *lookup_processor_type(unsigned int); | 310 | extern struct proc_info_list *lookup_processor_type(unsigned int); |
311 | extern struct machine_desc *lookup_machine_type(unsigned int); | 311 | |
312 | static void __init early_print(const char *str, ...) | ||
313 | { | ||
314 | extern void printascii(const char *); | ||
315 | char buf[256]; | ||
316 | va_list ap; | ||
317 | |||
318 | va_start(ap, str); | ||
319 | vsnprintf(buf, sizeof(buf), str, ap); | ||
320 | va_end(ap); | ||
321 | |||
322 | #ifdef CONFIG_DEBUG_LL | ||
323 | printascii(buf); | ||
324 | #endif | ||
325 | printk("%s", buf); | ||
326 | } | ||
327 | |||
328 | static struct machine_desc * __init lookup_machine_type(unsigned int type) | ||
329 | { | ||
330 | extern struct machine_desc __arch_info_begin[], __arch_info_end[]; | ||
331 | struct machine_desc *p; | ||
332 | |||
333 | for (p = __arch_info_begin; p < __arch_info_end; p++) | ||
334 | if (type == p->nr) | ||
335 | return p; | ||
336 | |||
337 | early_print("\n" | ||
338 | "Error: unrecognized/unsupported machine ID (r1 = 0x%08x).\n\n" | ||
339 | "Available machine support:\n\nID (hex)\tNAME\n", type); | ||
340 | |||
341 | for (p = __arch_info_begin; p < __arch_info_end; p++) | ||
342 | early_print("%08x\t%s\n", p->nr, p->name); | ||
343 | |||
344 | early_print("\nPlease check your kernel config and/or bootloader.\n"); | ||
345 | |||
346 | while (true) | ||
347 | /* can't use cpu_relax() here as it may require MMU setup */; | ||
348 | } | ||
312 | 349 | ||
313 | static void __init feat_v6_fixup(void) | 350 | static void __init feat_v6_fixup(void) |
314 | { | 351 | { |
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index abaf8445ce25..cb8398317644 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <asm/unistd.h> | 20 | #include <asm/unistd.h> |
21 | #include <asm/vfp.h> | 21 | #include <asm/vfp.h> |
22 | 22 | ||
23 | #include "ptrace.h" | ||
24 | #include "signal.h" | 23 | #include "signal.h" |
25 | 24 | ||
26 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 25 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
@@ -348,8 +347,6 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs) | |||
348 | if (restore_sigframe(regs, frame)) | 347 | if (restore_sigframe(regs, frame)) |
349 | goto badframe; | 348 | goto badframe; |
350 | 349 | ||
351 | single_step_trap(current); | ||
352 | |||
353 | return regs->ARM_r0; | 350 | return regs->ARM_r0; |
354 | 351 | ||
355 | badframe: | 352 | badframe: |
@@ -383,8 +380,6 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) | |||
383 | if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT) | 380 | if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT) |
384 | goto badframe; | 381 | goto badframe; |
385 | 382 | ||
386 | single_step_trap(current); | ||
387 | |||
388 | return regs->ARM_r0; | 383 | return regs->ARM_r0; |
389 | 384 | ||
390 | badframe: | 385 | badframe: |
@@ -706,8 +701,6 @@ static void do_signal(struct pt_regs *regs, int syscall) | |||
706 | if (try_to_freeze()) | 701 | if (try_to_freeze()) |
707 | goto no_signal; | 702 | goto no_signal; |
708 | 703 | ||
709 | single_step_clear(current); | ||
710 | |||
711 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 704 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
712 | if (signr > 0) { | 705 | if (signr > 0) { |
713 | sigset_t *oldset; | 706 | sigset_t *oldset; |
@@ -726,7 +719,6 @@ static void do_signal(struct pt_regs *regs, int syscall) | |||
726 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 719 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
727 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 720 | clear_thread_flag(TIF_RESTORE_SIGMASK); |
728 | } | 721 | } |
729 | single_step_set(current); | ||
730 | return; | 722 | return; |
731 | } | 723 | } |
732 | 724 | ||
@@ -772,7 +764,6 @@ static void do_signal(struct pt_regs *regs, int syscall) | |||
772 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | 764 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); |
773 | } | 765 | } |
774 | } | 766 | } |
775 | single_step_set(current); | ||
776 | } | 767 | } |
777 | 768 | ||
778 | asmlinkage void | 769 | asmlinkage void |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index ee57640ba2bb..21ac43f1c2d0 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/kexec.h> | 23 | #include <linux/kexec.h> |
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/sched.h> | ||
26 | 27 | ||
27 | #include <asm/atomic.h> | 28 | #include <asm/atomic.h> |
28 | #include <asm/cacheflush.h> | 29 | #include <asm/cacheflush.h> |
@@ -32,7 +33,6 @@ | |||
32 | #include <asm/unwind.h> | 33 | #include <asm/unwind.h> |
33 | #include <asm/tls.h> | 34 | #include <asm/tls.h> |
34 | 35 | ||
35 | #include "ptrace.h" | ||
36 | #include "signal.h" | 36 | #include "signal.h" |
37 | 37 | ||
38 | static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; | 38 | static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; |
@@ -256,7 +256,7 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt | |||
256 | return ret; | 256 | return ret; |
257 | } | 257 | } |
258 | 258 | ||
259 | DEFINE_SPINLOCK(die_lock); | 259 | static DEFINE_SPINLOCK(die_lock); |
260 | 260 | ||
261 | /* | 261 | /* |
262 | * This function is protected against re-entrancy. | 262 | * This function is protected against re-entrancy. |
diff --git a/arch/arm/mach-footbridge/include/mach/hardware.h b/arch/arm/mach-footbridge/include/mach/hardware.h index 51dd902043ad..b6fdf23ecf6c 100644 --- a/arch/arm/mach-footbridge/include/mach/hardware.h +++ b/arch/arm/mach-footbridge/include/mach/hardware.h | |||
@@ -23,26 +23,33 @@ | |||
23 | * 0xf9000000 0x50000000 1MB Cache flush | 23 | * 0xf9000000 0x50000000 1MB Cache flush |
24 | * 0xf0000000 0x80000000 16MB ISA memory | 24 | * 0xf0000000 0x80000000 16MB ISA memory |
25 | */ | 25 | */ |
26 | |||
27 | #ifdef CONFIG_MMU | ||
28 | #define MMU_IO(a, b) (a) | ||
29 | #else | ||
30 | #define MMU_IO(a, b) (b) | ||
31 | #endif | ||
32 | |||
26 | #define XBUS_SIZE 0x00100000 | 33 | #define XBUS_SIZE 0x00100000 |
27 | #define XBUS_BASE 0xff800000 | 34 | #define XBUS_BASE MMU_IO(0xff800000, 0x40000000) |
28 | 35 | ||
29 | #define ARMCSR_SIZE 0x00100000 | 36 | #define ARMCSR_SIZE 0x00100000 |
30 | #define ARMCSR_BASE 0xfe000000 | 37 | #define ARMCSR_BASE MMU_IO(0xfe000000, 0x42000000) |
31 | 38 | ||
32 | #define WFLUSH_SIZE 0x00100000 | 39 | #define WFLUSH_SIZE 0x00100000 |
33 | #define WFLUSH_BASE 0xfd000000 | 40 | #define WFLUSH_BASE MMU_IO(0xfd000000, 0x78000000) |
34 | 41 | ||
35 | #define PCIIACK_SIZE 0x00100000 | 42 | #define PCIIACK_SIZE 0x00100000 |
36 | #define PCIIACK_BASE 0xfc000000 | 43 | #define PCIIACK_BASE MMU_IO(0xfc000000, 0x79000000) |
37 | 44 | ||
38 | #define PCICFG1_SIZE 0x01000000 | 45 | #define PCICFG1_SIZE 0x01000000 |
39 | #define PCICFG1_BASE 0xfb000000 | 46 | #define PCICFG1_BASE MMU_IO(0xfb000000, 0x7a000000) |
40 | 47 | ||
41 | #define PCICFG0_SIZE 0x01000000 | 48 | #define PCICFG0_SIZE 0x01000000 |
42 | #define PCICFG0_BASE 0xfa000000 | 49 | #define PCICFG0_BASE MMU_IO(0xfa000000, 0x7b000000) |
43 | 50 | ||
44 | #define PCIMEM_SIZE 0x01000000 | 51 | #define PCIMEM_SIZE 0x01000000 |
45 | #define PCIMEM_BASE 0xf0000000 | 52 | #define PCIMEM_BASE MMU_IO(0xf0000000, 0x80000000) |
46 | 53 | ||
47 | #define XBUS_LEDS ((volatile unsigned char *)(XBUS_BASE + 0x12000)) | 54 | #define XBUS_LEDS ((volatile unsigned char *)(XBUS_BASE + 0x12000)) |
48 | #define XBUS_LED_AMBER (1 << 0) | 55 | #define XBUS_LED_AMBER (1 << 0) |
diff --git a/arch/arm/mach-footbridge/include/mach/io.h b/arch/arm/mach-footbridge/include/mach/io.h index 101a4fe90bde..32e4cc397c28 100644 --- a/arch/arm/mach-footbridge/include/mach/io.h +++ b/arch/arm/mach-footbridge/include/mach/io.h | |||
@@ -14,8 +14,14 @@ | |||
14 | #ifndef __ASM_ARM_ARCH_IO_H | 14 | #ifndef __ASM_ARM_ARCH_IO_H |
15 | #define __ASM_ARM_ARCH_IO_H | 15 | #define __ASM_ARM_ARCH_IO_H |
16 | 16 | ||
17 | #define PCIO_SIZE 0x00100000 | 17 | #ifdef CONFIG_MMU |
18 | #define PCIO_BASE 0xff000000 | 18 | #define MMU_IO(a, b) (a) |
19 | #else | ||
20 | #define MMU_IO(a, b) (b) | ||
21 | #endif | ||
22 | |||
23 | #define PCIO_SIZE 0x00100000 | ||
24 | #define PCIO_BASE MMU_IO(0xff000000, 0x7c000000) | ||
19 | 25 | ||
20 | #define IO_SPACE_LIMIT 0xffff | 26 | #define IO_SPACE_LIMIT 0xffff |
21 | 27 | ||
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 1a2cf6226a55..b69fa0a0299e 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -45,6 +45,7 @@ config ARCH_OMAP4 | |||
45 | select CPU_V7 | 45 | select CPU_V7 |
46 | select ARM_GIC | 46 | select ARM_GIC |
47 | select PL310_ERRATA_588369 | 47 | select PL310_ERRATA_588369 |
48 | select PL310_ERRATA_727915 | ||
48 | select ARM_ERRATA_720789 | 49 | select ARM_ERRATA_720789 |
49 | select ARCH_HAS_OPP | 50 | select ARCH_HAS_OPP |
50 | select PM_OPP if PM | 51 | select PM_OPP if PM |
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 19268647ce36..9ef8c29dd817 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c | |||
@@ -52,6 +52,12 @@ static void omap4_l2x0_disable(void) | |||
52 | omap_smc1(0x102, 0x0); | 52 | omap_smc1(0x102, 0x0); |
53 | } | 53 | } |
54 | 54 | ||
55 | static void omap4_l2x0_set_debug(unsigned long val) | ||
56 | { | ||
57 | /* Program PL310 L2 Cache controller debug register */ | ||
58 | omap_smc1(0x100, val); | ||
59 | } | ||
60 | |||
55 | static int __init omap_l2_cache_init(void) | 61 | static int __init omap_l2_cache_init(void) |
56 | { | 62 | { |
57 | u32 aux_ctrl = 0; | 63 | u32 aux_ctrl = 0; |
@@ -99,6 +105,7 @@ static int __init omap_l2_cache_init(void) | |||
99 | * specific one | 105 | * specific one |
100 | */ | 106 | */ |
101 | outer_cache.disable = omap4_l2x0_disable; | 107 | outer_cache.disable = omap4_l2x0_disable; |
108 | outer_cache.set_debug = omap4_l2x0_set_debug; | ||
102 | 109 | ||
103 | return 0; | 110 | return 0; |
104 | } | 111 | } |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index e4509bae8fc4..05b26a03c209 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -845,6 +845,11 @@ config CACHE_XSC3L2 | |||
845 | help | 845 | help |
846 | This option enables the L2 cache on XScale3. | 846 | This option enables the L2 cache on XScale3. |
847 | 847 | ||
848 | config ARM_L1_CACHE_SHIFT_6 | ||
849 | bool | ||
850 | help | ||
851 | Setting ARM L1 cache line size to 64 Bytes. | ||
852 | |||
848 | config ARM_L1_CACHE_SHIFT | 853 | config ARM_L1_CACHE_SHIFT |
849 | int | 854 | int |
850 | default 6 if ARM_L1_CACHE_SHIFT_6 | 855 | default 6 if ARM_L1_CACHE_SHIFT_6 |
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index f2ce38e085d2..ef59099a5463 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c | |||
@@ -73,18 +73,24 @@ static inline void l2x0_inv_line(unsigned long addr) | |||
73 | writel_relaxed(addr, base + L2X0_INV_LINE_PA); | 73 | writel_relaxed(addr, base + L2X0_INV_LINE_PA); |
74 | } | 74 | } |
75 | 75 | ||
76 | #ifdef CONFIG_PL310_ERRATA_588369 | 76 | #if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915) |
77 | static void debug_writel(unsigned long val) | ||
78 | { | ||
79 | extern void omap_smc1(u32 fn, u32 arg); | ||
80 | 77 | ||
81 | /* | 78 | #define debug_writel(val) outer_cache.set_debug(val) |
82 | * Texas Instrument secure monitor api to modify the | 79 | |
83 | * PL310 Debug Control Register. | 80 | static void l2x0_set_debug(unsigned long val) |
84 | */ | 81 | { |
85 | omap_smc1(0x100, val); | 82 | writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL); |
86 | } | 83 | } |
84 | #else | ||
85 | /* Optimised out for non-errata case */ | ||
86 | static inline void debug_writel(unsigned long val) | ||
87 | { | ||
88 | } | ||
89 | |||
90 | #define l2x0_set_debug NULL | ||
91 | #endif | ||
87 | 92 | ||
93 | #ifdef CONFIG_PL310_ERRATA_588369 | ||
88 | static inline void l2x0_flush_line(unsigned long addr) | 94 | static inline void l2x0_flush_line(unsigned long addr) |
89 | { | 95 | { |
90 | void __iomem *base = l2x0_base; | 96 | void __iomem *base = l2x0_base; |
@@ -97,11 +103,6 @@ static inline void l2x0_flush_line(unsigned long addr) | |||
97 | } | 103 | } |
98 | #else | 104 | #else |
99 | 105 | ||
100 | /* Optimised out for non-errata case */ | ||
101 | static inline void debug_writel(unsigned long val) | ||
102 | { | ||
103 | } | ||
104 | |||
105 | static inline void l2x0_flush_line(unsigned long addr) | 106 | static inline void l2x0_flush_line(unsigned long addr) |
106 | { | 107 | { |
107 | void __iomem *base = l2x0_base; | 108 | void __iomem *base = l2x0_base; |
@@ -125,9 +126,11 @@ static void l2x0_flush_all(void) | |||
125 | 126 | ||
126 | /* clean all ways */ | 127 | /* clean all ways */ |
127 | spin_lock_irqsave(&l2x0_lock, flags); | 128 | spin_lock_irqsave(&l2x0_lock, flags); |
129 | debug_writel(0x03); | ||
128 | writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY); | 130 | writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY); |
129 | cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask); | 131 | cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask); |
130 | cache_sync(); | 132 | cache_sync(); |
133 | debug_writel(0x00); | ||
131 | spin_unlock_irqrestore(&l2x0_lock, flags); | 134 | spin_unlock_irqrestore(&l2x0_lock, flags); |
132 | } | 135 | } |
133 | 136 | ||
@@ -335,6 +338,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) | |||
335 | outer_cache.flush_all = l2x0_flush_all; | 338 | outer_cache.flush_all = l2x0_flush_all; |
336 | outer_cache.inv_all = l2x0_inv_all; | 339 | outer_cache.inv_all = l2x0_inv_all; |
337 | outer_cache.disable = l2x0_disable; | 340 | outer_cache.disable = l2x0_disable; |
341 | outer_cache.set_debug = l2x0_set_debug; | ||
338 | 342 | ||
339 | printk(KERN_INFO "%s cache controller enabled\n", type); | 343 | printk(KERN_INFO "%s cache controller enabled\n", type); |
340 | printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n", | 344 | printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n", |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 3c67e92f7d59..ff7b43b5885a 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -827,16 +827,6 @@ static void __init sanity_check_meminfo(void) | |||
827 | * rather difficult. | 827 | * rather difficult. |
828 | */ | 828 | */ |
829 | reason = "with VIPT aliasing cache"; | 829 | reason = "with VIPT aliasing cache"; |
830 | } else if (is_smp() && tlb_ops_need_broadcast()) { | ||
831 | /* | ||
832 | * kmap_high needs to occasionally flush TLB entries, | ||
833 | * however, if the TLB entries need to be broadcast | ||
834 | * we may deadlock: | ||
835 | * kmap_high(irqs off)->flush_all_zero_pkmaps-> | ||
836 | * flush_tlb_kernel_range->smp_call_function_many | ||
837 | * (must not be called with irqs off) | ||
838 | */ | ||
839 | reason = "without hardware TLB ops broadcasting"; | ||
840 | } | 830 | } |
841 | if (reason) { | 831 | if (reason) { |
842 | printk(KERN_CRIT "HIGHMEM is not supported %s, ignoring high memory\n", | 832 | printk(KERN_CRIT "HIGHMEM is not supported %s, ignoring high memory\n", |
diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c index 935993e1b1ef..036fdbfdd62f 100644 --- a/arch/arm/mm/vmregion.c +++ b/arch/arm/mm/vmregion.c | |||
@@ -38,7 +38,7 @@ struct arm_vmregion * | |||
38 | arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align, | 38 | arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align, |
39 | size_t size, gfp_t gfp) | 39 | size_t size, gfp_t gfp) |
40 | { | 40 | { |
41 | unsigned long addr = head->vm_start, end = head->vm_end - size; | 41 | unsigned long start = head->vm_start, addr = head->vm_end; |
42 | unsigned long flags; | 42 | unsigned long flags; |
43 | struct arm_vmregion *c, *new; | 43 | struct arm_vmregion *c, *new; |
44 | 44 | ||
@@ -54,21 +54,20 @@ arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align, | |||
54 | 54 | ||
55 | spin_lock_irqsave(&head->vm_lock, flags); | 55 | spin_lock_irqsave(&head->vm_lock, flags); |
56 | 56 | ||
57 | list_for_each_entry(c, &head->vm_list, vm_list) { | 57 | addr = rounddown(addr - size, align); |
58 | if ((addr + size) < addr) | 58 | list_for_each_entry_reverse(c, &head->vm_list, vm_list) { |
59 | goto nospc; | 59 | if (addr >= c->vm_end) |
60 | if ((addr + size) <= c->vm_start) | ||
61 | goto found; | 60 | goto found; |
62 | addr = ALIGN(c->vm_end, align); | 61 | addr = rounddown(c->vm_start - size, align); |
63 | if (addr > end) | 62 | if (addr < start) |
64 | goto nospc; | 63 | goto nospc; |
65 | } | 64 | } |
66 | 65 | ||
67 | found: | 66 | found: |
68 | /* | 67 | /* |
69 | * Insert this entry _before_ the one we found. | 68 | * Insert this entry after the one we found. |
70 | */ | 69 | */ |
71 | list_add_tail(&new->vm_list, &c->vm_list); | 70 | list_add(&new->vm_list, &c->vm_list); |
72 | new->vm_start = addr; | 71 | new->vm_start = addr; |
73 | new->vm_end = addr + size; | 72 | new->vm_end = addr + size; |
74 | new->vm_active = 1; | 73 | new->vm_active = 1; |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 0797cb528b46..bbf3da012afd 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -153,7 +153,7 @@ static struct notifier_block vfp_notifier_block = { | |||
153 | * Raise a SIGFPE for the current process. | 153 | * Raise a SIGFPE for the current process. |
154 | * sicode describes the signal being raised. | 154 | * sicode describes the signal being raised. |
155 | */ | 155 | */ |
156 | void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs) | 156 | static void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs) |
157 | { | 157 | { |
158 | siginfo_t info; | 158 | siginfo_t info; |
159 | 159 | ||
@@ -489,8 +489,11 @@ void vfp_flush_hwstate(struct thread_info *thread) | |||
489 | 489 | ||
490 | /* | 490 | /* |
491 | * VFP hardware can lose all context when a CPU goes offline. | 491 | * VFP hardware can lose all context when a CPU goes offline. |
492 | * Safely clear our held state when a CPU has been killed, and | 492 | * As we will be running in SMP mode with CPU hotplug, we will save the |
493 | * re-enable access to VFP when the CPU comes back online. | 493 | * hardware state at every thread switch. We clear our held state when |
494 | * a CPU has been killed, indicating that the VFP hardware doesn't contain | ||
495 | * a threads VFP state. When a CPU starts up, we re-enable access to the | ||
496 | * VFP hardware. | ||
494 | * | 497 | * |
495 | * Both CPU_DYING and CPU_STARTING are called on the CPU which | 498 | * Both CPU_DYING and CPU_STARTING are called on the CPU which |
496 | * is being offlined/onlined. | 499 | * is being offlined/onlined. |