original_kernel/arch/arc/include/asm
Christian Ruppert 79e5f05edc ARC: Add implicit compiler barrier to raw_local_irq* functions
ARC irqsave/restore macros were missing the compiler barrier, causing a
stale load in irq-enabled region be used in irq-safe region, despite
being changed, because the register holding the value was still live.

The problem manifested as random crashes in timer code when stress
testing ARCLinux (3.9-rc3) on a !SMP && !PREEMPT_COUNT

Here's the exact sequence which caused this:
 (0). tv1[x] <----> t1 <---> t2
 (1). mod_timer(t1) interrupted after it calls timer_pending()
 (2). mod_timer(t2) completes
 (3). mod_timer(t1) resumes but messes up the list
 (4). __runt_timers( ) uses bogus timer_list entry / crashes in
      timer->function

Essentially mod_timer() was racing against itself and while the spinlock
serialized the tv1[] timer link list, timer_pending() called outside the
spinlock, cached timer link list element in a register.
With low register pressure (and a deep register file), lack of barrier
in raw_local_irqsave() as well as preempt_disable (!PREEMPT_COUNT
version), there was nothing to force gcc to reload across the spinlock,
causing a stale value in reg be used for link list manipulation - ensuing
a corruption.

ARcompact disassembly which shows the culprit generated code:

mod_timer:
    push_s blink
    mov_s r13,r0	# timer, timer
..
    ###### timer_pending( )
    ld_s r3,[r13]       # <------ <variable>.entry.next LOADED
    brne r3, 0, @.L163

.L163:
..
    ###### spin_lock_irq( )
    lr  r5, [status32]  # flags
    bic r4, r5, 6       # temp, flags,
    and.f 0, r5, 6      # flags,
    flag.nz r4

    ###### detach_if_pending( ) begins

    tst_s r3,r3  <--------------
			# timer_pending( ) checks timer->entry.next
                        # r3 is NOT reloaded by gcc, using stale value
    beq.d @.L169
    mov.eq r0,0

    #####  detach_timer( ): __list_del( )

    ld r4,[r13,4]    	# <variable>.entry.prev, D.31439
    st r4,[r3,4]     	# <variable>.prev, D.31439
    st r3,[r4]       	# <variable>.next, D.30246

We initially tried to fix this by adding barrier() to preempt_* macros
for !PREEMPT_COUNT but Linus clarified that it was anything but wrong.
http://www.spinics.net/lists/kernel/msg1512709.html

[vgupta: updated commitlog]

Reported-by/Signed-off-by: Christian Ruppert <christian.ruppert@abilis.com>
Cc: Christian Ruppert <christian.ruppert@abilis.com>
Cc: Pierrick Hascoet <pierrick.hascoet@abilis.com>
Debugged-by/Signed-off-by: Vineet Gupta <vgupta@synopsys.com>

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-04-08 16:10:26 -07:00
..
Kbuild ARC: UAPI Disintegrate arch/arc/include/asm 2013-02-15 23:16:11 +05:30
arcregs.h ARC: Boot #2: Verbose Boot reporting / feature verification 2013-02-15 23:16:07 +05:30
asm-offsets.h
atomic.h
barrier.h
bitops.h
bug.h
cache.h
cacheflush.h
checksum.h
clk.h ARC: [DeviceTree] Convert some Kconfig items to runtime values 2013-02-15 23:15:56 +05:30
cmpxchg.h
current.h ARC: [optim] Cache "current" in Register r25 2013-02-15 23:15:58 +05:30
defines.h ARC: Boot #2: Verbose Boot reporting / feature verification 2013-02-15 23:16:07 +05:30
delay.h
disasm.h ARC: disassembly (needed by kprobes/kgdb/unaligned-access-emul) 2013-02-15 23:16:04 +05:30
dma-mapping.h arc: fix dma_address assignment during dma_map_sg() 2013-03-19 15:34:53 +05:30
dma.h ARC: I/O and DMA Mappings 2013-02-15 23:15:54 +05:30
elf.h ARC: Remove SET_PERSONALITY (tracks cross-arch change) 2013-03-18 14:37:05 +05:30
entry.h ARC: Fix the typo in event identifier flags used by ptrace 2013-03-20 18:45:45 +05:30
exec.h
futex.h ARC: Futex support 2013-02-15 23:16:00 +05:30
io.h ARC: Add support for ioremap_prot API 2013-02-15 23:16:11 +05:30
irq.h ARC: [Review] Multi-platform image #5: NR_IRQS defined by ARC core 2013-02-15 23:16:15 +05:30
irqflags.h ARC: Add implicit compiler barrier to raw_local_irq* functions 2013-04-08 16:10:26 -07:00
kdebug.h
kgdb.h ARC: make allyesconfig build breakages 2013-03-11 19:01:09 +05:30
kprobes.h ARC: kprobes support 2013-02-15 23:16:05 +05:30
linkage.h ARC: Support for single cycle Close Coupled Mem (CCM) 2013-02-15 23:16:10 +05:30
mach_desc.h ARC: make a copy of flat DT 2013-02-26 14:25:18 +05:30
mmu.h
mmu_context.h ARC: SMP support 2013-02-15 23:16:02 +05:30
module.h ARC: DWARF2 .debug_frame based stack unwinder 2013-02-15 23:16:03 +05:30
mutex.h ARC: SMP support 2013-02-15 23:16:02 +05:30
page.h ARC: Add support for ioremap_prot API 2013-02-15 23:16:11 +05:30
perf_event.h ARC: perf support (software counters only) 2013-02-15 23:16:09 +05:30
pgalloc.h
pgtable.h ARC: SMP support 2013-02-15 23:16:02 +05:30
processor.h ARC: SMP support 2013-02-15 23:16:02 +05:30
prom.h ARC: [Review] Multi-platform image #2: Board callback Infrastructure 2013-02-15 23:16:13 +05:30
ptrace.h ARC: Fix the typo in event identifier flags used by ptrace 2013-03-20 18:45:45 +05:30
sections.h ARC: [DeviceTree] Basic support 2013-02-15 23:15:55 +05:30
segment.h
serial.h ARC: Provide a default serial.h for uart drivers needing BASE_BAUD 2013-02-15 23:16:18 +05:30
setup.h ARC: UAPI Disintegrate arch/arc/include/asm 2013-02-15 23:16:11 +05:30
smp.h ARC: [Review] Multi-platform image #7: SMP common code to use callbacks 2013-02-15 23:16:16 +05:30
spinlock.h
spinlock_types.h
string.h
switch_to.h
syscall.h
syscalls.h ARC: ABIv3: fork/vfork wrappers not needed in "no-legacy-syscall" ABI 2013-03-11 19:01:10 +05:30
thread_info.h
timex.h
tlb-mmu1.h ARC: MMU Exception Handling 2013-02-15 23:15:52 +05:30
tlb.h ARC: TLB flush Handling 2013-02-15 23:15:53 +05:30
tlbflush.h ARC: TLB flush Handling 2013-02-15 23:15:53 +05:30
uaccess.h
unaligned.h ARC: Unaligned access emulation 2013-02-15 23:16:06 +05:30
unwind.h ARC: DWARF2 .debug_frame based stack unwinder 2013-02-15 23:16:03 +05:30