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>
This commit is contained in:
Haavard Skinnemoen 2008-08-20 15:46:24 +02:00
parent bef69ea0dc
commit 9e3f544d79
2 changed files with 63 additions and 2 deletions

View File

@ -4,6 +4,8 @@
* to extract and format the required data.
*/
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/thread_info.h>
#include <linux/kbuild.h>
@ -17,4 +19,8 @@ void foo(void)
OFFSET(TI_rar_saved, thread_info, rar_saved);
OFFSET(TI_rsr_saved, thread_info, rsr_saved);
OFFSET(TI_restart_block, thread_info, restart_block);
BLANK();
OFFSET(TSK_active_mm, task_struct, active_mm);
BLANK();
OFFSET(MM_pgd, mm_struct, pgd);
}

View File

@ -334,9 +334,64 @@ save_full_context_ex:
/* Low-level exception handlers */
handle_critical:
/*
* AT32AP700x errata:
*
* After a Java stack overflow or underflow trap, any CPU
* memory access may cause erratic behavior. This will happen
* when the four least significant bits of the JOSP system
* register contains any value between 9 and 15 (inclusive).
*
* Possible workarounds:
* - Don't use the Java Extension Module
* - Ensure that the stack overflow and underflow trap
* handlers do not do any memory access or trigger any
* exceptions before the overflow/underflow condition is
* cleared (by incrementing or decrementing the JOSP)
* - Make sure that JOSP does not contain any problematic
* value before doing any exception or interrupt
* processing.
* - Set up a critical exception handler which writes a
* known-to-be-safe value, e.g. 4, to JOSP before doing
* any further processing.
*
* We'll use the last workaround for now since we cannot
* guarantee that user space processes don't use Java mode.
* Non-well-behaving userland will be terminated with extreme
* prejudice.
*/
#ifdef CONFIG_CPU_AT32AP700X
/*
* There's a chance we can't touch memory, so temporarily
* borrow PTBR to save the stack pointer while we fix things
* up...
*/
mtsr SYSREG_PTBR, sp
mov sp, 4
mtsr SYSREG_JOSP, sp
mfsr sp, SYSREG_PTBR
sub pc, -2
/* Push most of pt_regs on stack. We'll do the rest later */
sub sp, 4
stmts --sp, r0-lr
rcall save_full_context_ex
pushm r0-r12
/* PTBR mirrors current_thread_info()->task->active_mm->pgd */
get_thread_info r0
ld.w r1, r0[TI_task]
ld.w r2, r1[TSK_active_mm]
ld.w r3, r2[MM_pgd]
mtsr SYSREG_PTBR, r3
#else
sub sp, 4
pushm r0-r12
#endif
sub r0, sp, -(14 * 4)
mov r1, lr
mfsr r2, SYSREG_RAR_EX
mfsr r3, SYSREG_RSR_EX
pushm r0-r3
mfsr r12, SYSREG_ECR
mov r11, sp
rcall do_critical_exception