Skip to content

Commit

Permalink
[AVR32] Fix random segfault with preemption
Browse files Browse the repository at this point in the history
As explained on:
http://www.avrfreaks.net/index.php?nameÿphpBB2&fileÿewtopic&tS307
If the current process is preempted before it can copy RAR_SUP and
RSR_SUP both register are lost and the process will segfault as soon
as it return from the syscall since the return adress will be
corrupted.

This patch disable IRQ as soon as we enter the syscall path and
reenable them when the copy is done.

In the interrupt handlers, check if we are interrupting the srrf
instruction, if so disable interrupts and return. The interrupt
handler will be re-called immediatly when the interrupts are
reenabled.

After some stressing workload:
 - find / > /dev/null in loop
 - top (in ssh)
 - ping -f avr32

The segfaults are not seen anymore.

Signed-off-by: Philippe Rétornaz <philippe.retornaz@epfl.ch>
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
  • Loading branch information
Philippe Rétornaz authored and Haavard Skinnemoen committed Oct 11, 2007
1 parent bb7aa6d commit a7e30b8
Showing 1 changed file with 25 additions and 1 deletion.
26 changes: 25 additions & 1 deletion arch/avr32/kernel/entry-avr32b.S
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,18 @@ handle_vmalloc_miss:

.section .scall.text,"ax",@progbits
system_call:
#ifdef CONFIG_PREEMPT
mask_interrupts
#endif
pushm r12 /* r12_orig */
stmts --sp, r0-lr
zero_fp

mfsr r0, SYSREG_RAR_SUP
mfsr r1, SYSREG_RSR_SUP
#ifdef CONFIG_PREEMPT
unmask_interrupts
#endif
zero_fp
stm --sp, r0-r1

/* check for syscall tracing */
Expand Down Expand Up @@ -638,6 +645,13 @@ irq_level\level:
stmts --sp,r0-lr
mfsr r8, rar_int\level
mfsr r9, rsr_int\level

#ifdef CONFIG_PREEMPT
sub r11, pc, (. - system_call)
cp.w r11, r8
breq 4f
#endif

pushm r8-r9

mov r11, sp
Expand Down Expand Up @@ -668,6 +682,16 @@ irq_level\level:
sub sp, -4 /* ignore r12_orig */
rete

#ifdef CONFIG_PREEMPT
4: mask_interrupts
mfsr r8, rsr_int\level
sbr r8, 16
mtsr rsr_int\level, r8
ldmts sp++, r0-lr
sub sp, -4 /* ignore r12_orig */
rete
#endif

2: get_thread_info r0
ld.w r1, r0[TI_flags]
bld r1, TIF_CPU_GOING_TO_SLEEP
Expand Down

0 comments on commit a7e30b8

Please sign in to comment.