Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6: avr32: pm_standby low-power ram bug fix avr32: Fix lockup after Java stack underflow in user mode
This commit is contained in:
commit
82a28c794f
3 changed files with 64 additions and 3 deletions
|
@ -4,6 +4,8 @@
|
||||||
* to extract and format the required data.
|
* to extract and format the required data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
#include <linux/thread_info.h>
|
#include <linux/thread_info.h>
|
||||||
#include <linux/kbuild.h>
|
#include <linux/kbuild.h>
|
||||||
|
|
||||||
|
@ -17,4 +19,8 @@ void foo(void)
|
||||||
OFFSET(TI_rar_saved, thread_info, rar_saved);
|
OFFSET(TI_rar_saved, thread_info, rar_saved);
|
||||||
OFFSET(TI_rsr_saved, thread_info, rsr_saved);
|
OFFSET(TI_rsr_saved, thread_info, rsr_saved);
|
||||||
OFFSET(TI_restart_block, thread_info, restart_block);
|
OFFSET(TI_restart_block, thread_info, restart_block);
|
||||||
|
BLANK();
|
||||||
|
OFFSET(TSK_active_mm, task_struct, active_mm);
|
||||||
|
BLANK();
|
||||||
|
OFFSET(MM_pgd, mm_struct, pgd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -334,9 +334,64 @@ save_full_context_ex:
|
||||||
|
|
||||||
/* Low-level exception handlers */
|
/* Low-level exception handlers */
|
||||||
handle_critical:
|
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
|
sub sp, 4
|
||||||
stmts --sp, r0-lr
|
pushm r0-r12
|
||||||
rcall save_full_context_ex
|
|
||||||
|
/* 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
|
mfsr r12, SYSREG_ECR
|
||||||
mov r11, sp
|
mov r11, sp
|
||||||
rcall do_critical_exception
|
rcall do_critical_exception
|
||||||
|
|
|
@ -134,7 +134,7 @@ pm_standby:
|
||||||
mov r11, SDRAMC_LPR_LPCB_SELF_RFR
|
mov r11, SDRAMC_LPR_LPCB_SELF_RFR
|
||||||
bfins r10, r11, 0, 2 /* LPCB <- self Refresh */
|
bfins r10, r11, 0, 2 /* LPCB <- self Refresh */
|
||||||
sync 0 /* flush write buffer */
|
sync 0 /* flush write buffer */
|
||||||
st.w r12[SDRAMC_LPR], r11 /* put SDRAM in self-refresh mode */
|
st.w r12[SDRAMC_LPR], r10 /* put SDRAM in self-refresh mode */
|
||||||
ld.w r11, r12[SDRAMC_LPR]
|
ld.w r11, r12[SDRAMC_LPR]
|
||||||
unmask_interrupts
|
unmask_interrupts
|
||||||
sleep CPU_SLEEP_FROZEN
|
sleep CPU_SLEEP_FROZEN
|
||||||
|
|
Loading…
Reference in a new issue