aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-08-20 09:46:24 -0400
committerHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-09-01 07:04:04 -0400
commit9e3f544d792fd2ff7e31ca4a72e5194f1491ed14 (patch)
tree706d3f133b930e0085df63fcc171f4f49c9cd1db
parentbef69ea0dcce574a425feb0a5aa4c63dd108b9a6 (diff)
avr32: Fix lockup after Java stack underflow in user mode
When using the Java Extension Module hardware, a Java stack underflow or overflow trap may cause the system to enter an infinite exception loop. Although there's no kernel support for the Java hardware yet, we need to be able to recover from this situation and keep the system running. This patch adds code to detect and fixup this situation in the critical exception handler and terminate the faulting process. We may have to rethink how to handle this more gracefully when the necessary kernel support for hardware-accelerated Java is added. Reported-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
-rw-r--r--arch/avr32/kernel/asm-offsets.c6
-rw-r--r--arch/avr32/kernel/entry-avr32b.S59
2 files changed, 63 insertions, 2 deletions
diff --git a/arch/avr32/kernel/asm-offsets.c b/arch/avr32/kernel/asm-offsets.c
index e4796c67a831..d6a8193a1d2f 100644
--- a/arch/avr32/kernel/asm-offsets.c
+++ b/arch/avr32/kernel/asm-offsets.c
@@ -4,6 +4,8 @@
4 * to extract and format the required data. 4 * to extract and format the required data.
5 */ 5 */
6 6
7#include <linux/mm.h>
8#include <linux/sched.h>
7#include <linux/thread_info.h> 9#include <linux/thread_info.h>
8#include <linux/kbuild.h> 10#include <linux/kbuild.h>
9 11
@@ -17,4 +19,8 @@ void foo(void)
17 OFFSET(TI_rar_saved, thread_info, rar_saved); 19 OFFSET(TI_rar_saved, thread_info, rar_saved);
18 OFFSET(TI_rsr_saved, thread_info, rsr_saved); 20 OFFSET(TI_rsr_saved, thread_info, rsr_saved);
19 OFFSET(TI_restart_block, thread_info, restart_block); 21 OFFSET(TI_restart_block, thread_info, restart_block);
22 BLANK();
23 OFFSET(TSK_active_mm, task_struct, active_mm);
24 BLANK();
25 OFFSET(MM_pgd, mm_struct, pgd);
20} 26}
diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S
index 2b398cae110c..33d49377b8be 100644
--- a/arch/avr32/kernel/entry-avr32b.S
+++ b/arch/avr32/kernel/entry-avr32b.S
@@ -334,9 +334,64 @@ save_full_context_ex:
334 334
335 /* Low-level exception handlers */ 335 /* Low-level exception handlers */
336handle_critical: 336handle_critical:
337 /*
338 * AT32AP700x errata:
339 *
340 * After a Java stack overflow or underflow trap, any CPU
341 * memory access may cause erratic behavior. This will happen
342 * when the four least significant bits of the JOSP system
343 * register contains any value between 9 and 15 (inclusive).
344 *
345 * Possible workarounds:
346 * - Don't use the Java Extension Module
347 * - Ensure that the stack overflow and underflow trap
348 * handlers do not do any memory access or trigger any
349 * exceptions before the overflow/underflow condition is
350 * cleared (by incrementing or decrementing the JOSP)
351 * - Make sure that JOSP does not contain any problematic
352 * value before doing any exception or interrupt
353 * processing.
354 * - Set up a critical exception handler which writes a
355 * known-to-be-safe value, e.g. 4, to JOSP before doing
356 * any further processing.
357 *
358 * We'll use the last workaround for now since we cannot
359 * guarantee that user space processes don't use Java mode.
360 * Non-well-behaving userland will be terminated with extreme
361 * prejudice.
362 */
363#ifdef CONFIG_CPU_AT32AP700X
364 /*
365 * There's a chance we can't touch memory, so temporarily
366 * borrow PTBR to save the stack pointer while we fix things
367 * up...
368 */
369 mtsr SYSREG_PTBR, sp
370 mov sp, 4
371 mtsr SYSREG_JOSP, sp
372 mfsr sp, SYSREG_PTBR
373 sub pc, -2
374
375 /* Push most of pt_regs on stack. We'll do the rest later */
337 sub sp, 4 376 sub sp, 4
338 stmts --sp, r0-lr 377 pushm r0-r12
339 rcall save_full_context_ex 378
379 /* PTBR mirrors current_thread_info()->task->active_mm->pgd */
380 get_thread_info r0
381 ld.w r1, r0[TI_task]
382 ld.w r2, r1[TSK_active_mm]
383 ld.w r3, r2[MM_pgd]
384 mtsr SYSREG_PTBR, r3
385#else
386 sub sp, 4
387 pushm r0-r12
388#endif
389 sub r0, sp, -(14 * 4)
390 mov r1, lr
391 mfsr r2, SYSREG_RAR_EX
392 mfsr r3, SYSREG_RSR_EX
393 pushm r0-r3
394
340 mfsr r12, SYSREG_ECR 395 mfsr r12, SYSREG_ECR
341 mov r11, sp 396 mov r11, sp
342 rcall do_critical_exception 397 rcall do_critical_exception