Merge branch 'audit' of git://git.linaro.org/people/rmk/linux-arm
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 Aug 2012 23:35:37 +0000 (16:35 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 Aug 2012 23:35:37 +0000 (16:35 -0700)
Pull ARM audit/signal updates from Russell King:
 "ARM audit/signal handling updates from Al and Will.  This improves on
  the work Viro did last merge window, and sorts out some of the issues
  found with that work."

* 'audit' of git://git.linaro.org/people/rmk/linux-arm:
  ARM: 7475/1: sys_trace: allow all syscall arguments to be updated via ptrace
  ARM: 7474/1: get rid of TIF_SYSCALL_RESTARTSYS
  ARM: 7473/1: deal with handlerless restarts without leaving the kernel
  ARM: 7472/1: pull all work_pending logics into C function
  ARM: 7471/1: Revert "7442/1: Revert "remove unused restart trampoline""
  ARM: 7470/1: Revert "7443/1: Revert "new way of handling ERESTART_RESTARTBLOCK""

1  2 
arch/arm/kernel/traps.c

diff --combined arch/arm/kernel/traps.c
index 7978d4f0f3aef59ee177a0525db44c6819110ed6,4928d89758f4ce0dea767acdf9fcf2299dff7833..f7945218b8c63a722cf08badc229345d7083b052
@@@ -233,9 -233,9 +233,9 @@@ void show_stack(struct task_struct *tsk
  #define S_ISA " ARM"
  #endif
  
 -static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
 +static int __die(const char *str, int err, struct pt_regs *regs)
  {
 -      struct task_struct *tsk = thread->task;
 +      struct task_struct *tsk = current;
        static int die_counter;
        int ret;
  
        /* trap and error numbers are mostly meaningless on ARM */
        ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
        if (ret == NOTIFY_STOP)
 -              return ret;
 +              return 1;
  
        print_modules();
        __show_regs(regs);
        printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
 -              TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1);
 +              TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk));
  
        if (!user_mode(regs) || in_interrupt()) {
                dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
                dump_instr(KERN_EMERG, regs);
        }
  
 -      return ret;
 +      return 0;
  }
  
 -static DEFINE_RAW_SPINLOCK(die_lock);
 +static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;
 +static int die_owner = -1;
 +static unsigned int die_nest_count;
  
 -/*
 - * This function is protected against re-entrancy.
 - */
 -void die(const char *str, struct pt_regs *regs, int err)
 +static unsigned long oops_begin(void)
  {
 -      struct thread_info *thread = current_thread_info();
 -      int ret;
 -      enum bug_trap_type bug_type = BUG_TRAP_TYPE_NONE;
 +      int cpu;
 +      unsigned long flags;
  
        oops_enter();
  
 -      raw_spin_lock_irq(&die_lock);
 +      /* racy, but better than risking deadlock. */
 +      raw_local_irq_save(flags);
 +      cpu = smp_processor_id();
 +      if (!arch_spin_trylock(&die_lock)) {
 +              if (cpu == die_owner)
 +                      /* nested oops. should stop eventually */;
 +              else
 +                      arch_spin_lock(&die_lock);
 +      }
 +      die_nest_count++;
 +      die_owner = cpu;
        console_verbose();
        bust_spinlocks(1);
 -      if (!user_mode(regs))
 -              bug_type = report_bug(regs->ARM_pc, regs);
 -      if (bug_type != BUG_TRAP_TYPE_NONE)
 -              str = "Oops - BUG";
 -      ret = __die(str, err, thread, regs);
 +      return flags;
 +}
  
 -      if (regs && kexec_should_crash(thread->task))
 +static void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
 +{
 +      if (regs && kexec_should_crash(current))
                crash_kexec(regs);
  
        bust_spinlocks(0);
 +      die_owner = -1;
        add_taint(TAINT_DIE);
 -      raw_spin_unlock_irq(&die_lock);
 +      die_nest_count--;
 +      if (!die_nest_count)
 +              /* Nest count reaches zero, release the lock. */
 +              arch_spin_unlock(&die_lock);
 +      raw_local_irq_restore(flags);
        oops_exit();
  
        if (in_interrupt())
                panic("Fatal exception in interrupt");
        if (panic_on_oops)
                panic("Fatal exception");
 -      if (ret != NOTIFY_STOP)
 -              do_exit(SIGSEGV);
 +      if (signr)
 +              do_exit(signr);
 +}
 +
 +/*
 + * This function is protected against re-entrancy.
 + */
 +void die(const char *str, struct pt_regs *regs, int err)
 +{
 +      enum bug_trap_type bug_type = BUG_TRAP_TYPE_NONE;
 +      unsigned long flags = oops_begin();
 +      int sig = SIGSEGV;
 +
 +      if (!user_mode(regs))
 +              bug_type = report_bug(regs->ARM_pc, regs);
 +      if (bug_type != BUG_TRAP_TYPE_NONE)
 +              str = "Oops - BUG";
 +
 +      if (__die(str, err, regs))
 +              sig = 0;
 +
 +      oops_end(flags, regs, sig);
  }
  
  void arm_notify_die(const char *str, struct pt_regs *regs,
@@@ -402,10 -370,18 +402,10 @@@ static int call_undef_hook(struct pt_re
  
  asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
  {
 -      unsigned int correction = thumb_mode(regs) ? 2 : 4;
        unsigned int instr;
        siginfo_t info;
        void __user *pc;
  
 -      /*
 -       * According to the ARM ARM, PC is 2 or 4 bytes ahead,
 -       * depending whether we're in Thumb mode or not.
 -       * Correct this offset.
 -       */
 -      regs->ARM_pc -= correction;
 -
        pc = (void __user *)instruction_pointer(regs);
  
        if (processor_mode(regs) == SVC_MODE) {
@@@ -844,8 -820,6 +844,6 @@@ void __init early_trap_init(void *vecto
         */
        memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
               sigreturn_codes, sizeof(sigreturn_codes));
-       memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE),
-              syscall_restart_code, sizeof(syscall_restart_code));
  
        flush_icache_range(vectors, vectors + PAGE_SIZE);
        modify_domain(DOMAIN_USER, DOMAIN_CLIENT);