linux/arch/cris/arch-v32/kernel
Rabin Vincent db4a35c651 CRISv32: don't attempt syscall restart on irq exit
r9 is used to determine whether syscall restarting must be performed or
not.  Unfortunately, r9 is never set to zero in the non-syscall path,
and r9 is on top of that a callee-saved register which can be set to
non-zero by the C functions that are called during IRQ handling.

This means that if r10 (used for the syscall return value) is one of the
-ERESTART* values when a hardware interrupt occurs which leads to a
signal being delivered to the process, the kernel will "restart" a
syscall which never occurred.  This will lead to the PC being moved back
by 2 on return to user space.

Fix the problem by setting r9 to zero in the interrupt path.

Test case (should loop forever but ends up executing the break 8 trap
instruction):

  #include <signal.h>
  #include <stdlib.h>
  #include <sys/time.h>

  void f(int n)
  {
  	register int r9 asm ("r9") = 1;
  	register int r10 asm ("r10") = n;

          __asm__ __volatile__(
  		"ba	1f	\n"
  		"nop		\n"
  		"break	8	\n"
  		"1: ba	.	\n"
  		"nop		\n"
  		:
  		: "r" (r9), "r" (r10)
  		: "memory");
  }

  void handler1(int sig) { }

  int main(int argc, char *argv[])
  {
          struct itimerval t1 = { .it_value = {1} };

          signal(SIGALRM, handler1);
          setitimer(ITIMER_REAL, &t1, NULL);

          f(-513); /* -ERESTARTNOINTR */

          return 0;
  }

Signed-off-by: Rabin Vincent <rabin@rab.in>
Signed-off-by: Jesper Nilsson <jespern@axis.com>
2015-03-25 10:49:31 +01:00
..
cache.c [CRIS] Move header files from include to arch/cris/include. 2008-10-29 17:29:44 +01:00
cacheflush.S CRIS: Add debug for assembler functions 2010-08-04 12:59:43 +02:00
crisksyms.c CRIS: Don't use mask_irq as symbol name 2010-05-25 17:48:14 +02:00
debugport.c CRISv32: Implement early console 2014-12-20 00:05:49 +01:00
entry.S CRISv32: don't attempt syscall restart on irq exit 2015-03-25 10:49:31 +01:00
fasttimer.c cris: remove deprecated IRQF_DISABLED 2014-01-08 16:10:18 +01:00
head.S CRIS: Remove VCS simulator specific code 2012-10-03 09:57:01 +02:00
irq.c CRISv32: add irq domains support 2015-03-25 09:47:43 +01:00
kgdb_asm.S CRIS: v32: Correct path for intr_vect.h 2010-08-04 13:00:53 +02:00
kgdb.c CRIS: Remove VCS simulator specific code 2012-10-03 09:57:01 +02:00
Makefile CRISv32: Remove obsolete vcs_hook.o from Makefile 2009-04-21 13:10:33 +02:00
process.c dump_stack: unify debug information printed by show_regs() 2013-04-30 17:04:02 -07:00
ptrace.c cris:removed the unused variable 2012-04-03 13:09:18 +02:00
setup.c CRIS: More ARTPEC-3 support and i2c-boardinfo. 2010-08-04 13:01:50 +02:00
signal.c all arches, signal: move restart_block to struct task_struct 2015-02-12 18:54:12 -08:00
smp.c cris: remove deprecated IRQF_DISABLED 2014-01-08 16:10:18 +01:00
time.c CRISv32: Avoid warning of unused variable 2015-01-29 10:10:08 +01:00
traps.c CRIS: Minor formatting fix in traps.c 2010-08-04 13:02:15 +02:00