]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Wed, 9 May 2007 20:38:45 +0000 (13:38 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Wed, 9 May 2007 20:38:45 +0000 (13:38 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6:
  [IA64] wire up pselect, ppoll
  [IA64] Add TIF_RESTORE_SIGMASK
  [IA64] unwind did not work for processes born with CLONE_STOPPED
  [IA64] Optional method to purge the TLB on SN systems
  [IA64] SPIN_LOCK_UNLOCKED macro cleanup in arch/ia64
  [IA64-SN2][KJ] mmtimer.c-kzalloc
  [IA64] fix stack alignment for ia32 signal handlers
  [IA64] - Altix: hotplug after intr redirect can crash system
  [IA64] save and restore cpus_allowed in cpu_idle_wait
  [IA64] Removal of percpu TR cleanup in kexec code
  [IA64] Fix some section mismatch errors

1  2 
arch/ia64/ia32/ia32_signal.c
arch/ia64/kernel/iosapic.c
arch/ia64/kernel/irq_ia64.c
arch/ia64/kernel/process.c
arch/ia64/kernel/signal.c
arch/ia64/kernel/traps.c
include/asm-ia64/thread_info.h

index 10510e5852048011e3d3892cf274cc8e42912f5a,b2bb7f227920e3735df59961b5428527857b82f8..85e82f32e480c4707de98d4fcdb73e801f2ebc95
@@@ -18,6 -18,7 +18,6 @@@
  #include <linux/sched.h>
  #include <linux/signal.h>
  #include <linux/smp.h>
 -#include <linux/smp_lock.h>
  #include <linux/stddef.h>
  #include <linux/syscalls.h>
  #include <linux/unistd.h>
@@@ -451,59 -452,20 +451,20 @@@ sigact_set_handler (struct k_sigaction 
                sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler);
  }
  
- long
__ia32_rt_sigsuspend (compat_sigset_t *sset, unsigned int sigsetsize, struct sigscratch *scr)
asmlinkage long
sys32_sigsuspend (int history0, int history1, old_sigset_t mask)
  {
-       extern long ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall);
-       sigset_t oldset, set;
-       scr->scratch_unat = 0;  /* avoid leaking kernel bits to user level */
-       memset(&set, 0, sizeof(set));
-       memcpy(&set.sig, &sset->sig, sigsetsize);
-       sigdelsetmask(&set, ~_BLOCKABLE);
+       mask &= _BLOCKABLE;
        spin_lock_irq(&current->sighand->siglock);
-       {
-               oldset = current->blocked;
-               current->blocked = set;
-               recalc_sigpending();
-       }
+       current->saved_sigmask = current->blocked;
+       siginitset(&current->blocked, mask);
+       recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
  
-       /*
-        * The return below usually returns to the signal handler.  We need to pre-set the
-        * correct error code here to ensure that the right values get saved in sigcontext
-        * by ia64_do_signal.
-        */
-       scr->pt.r8 = -EINTR;
-       while (1) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule();
-               if (ia64_do_signal(&oldset, scr, 1))
-                       return -EINTR;
-       }
- }
- asmlinkage long
- ia32_rt_sigsuspend (compat_sigset_t __user *uset, unsigned int sigsetsize, struct sigscratch *scr)
- {
-       compat_sigset_t set;
-       if (sigsetsize > sizeof(compat_sigset_t))
-               return -EINVAL;
-       if (copy_from_user(&set.sig, &uset->sig, sigsetsize))
-               return -EFAULT;
-       return __ia32_rt_sigsuspend(&set, sigsetsize, scr);
- }
- asmlinkage long
- ia32_sigsuspend (unsigned int mask, struct sigscratch *scr)
- {
-       return __ia32_rt_sigsuspend((compat_sigset_t *) &mask, sizeof(mask), scr);
+       current->state = TASK_INTERRUPTIBLE;
+       schedule();
+       set_thread_flag(TIF_RESTORE_SIGMASK);
+       return -ERESTARTNOHAND;
  }
  
  asmlinkage long
@@@ -810,7 -772,11 +771,11 @@@ get_sigframe (struct k_sigaction *ka, s
        }
        /* Legacy stack switching not supported */
  
-       return (void __user *)((esp - frame_size) & -8ul);
+       esp -= frame_size;
+       /* Align the stack pointer according to the i386 ABI,
+        * i.e. so that on function entry ((sp + 4) & 15) == 0. */
+       esp = ((esp + 4) & -16ul) - 4;
+       return (void __user *) esp;
  }
  
  static int
index 93d9ab14ba24fa7bd64acd1a3888d5654c490df1,e87dd93d4db71ebf3b054ba1d46a1bb8b26a46ad..37f46527d233eef451ead5c8b6adcc2b24e33ca9
@@@ -87,6 -87,7 +87,6 @@@
  #include <linux/list.h>
  #include <linux/pci.h>
  #include <linux/smp.h>
 -#include <linux/smp_lock.h>
  #include <linux/string.h>
  #include <linux/bootmem.h>
  
@@@ -1012,7 -1013,7 +1012,7 @@@ iosapic_register_platform_intr (u32 int
  /*
   * ACPI calls this when it finds an entry for a legacy ISA IRQ override.
   */
- void __init
+ void __devinit
  iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
                          unsigned long polarity,
                          unsigned long trigger)
index 1c5044a809584b592ac5b069f7cc69fa0eead7e1,9a5f41be760ba11b933d1532d040c55cc85c740f..dce5341303dea25ecb12777058df025d4be6601b
@@@ -27,6 -27,7 +27,6 @@@
  #include <linux/random.h>     /* for rand_initialize_irq() */
  #include <linux/signal.h>
  #include <linux/smp.h>
 -#include <linux/smp_lock.h>
  #include <linux/threads.h>
  #include <linux/bitops.h>
  #include <linux/irq.h>
@@@ -38,6 -39,7 +38,7 @@@
  #include <asm/machvec.h>
  #include <asm/pgtable.h>
  #include <asm/system.h>
+ #include <asm/tlbflush.h>
  
  #ifdef CONFIG_PERFMON
  # include <asm/perfmon.h>
@@@ -126,8 -128,10 +127,10 @@@ void destroy_irq(unsigned int irq
  
  #ifdef CONFIG_SMP
  #     define IS_RESCHEDULE(vec)       (vec == IA64_IPI_RESCHEDULE)
+ #     define IS_LOCAL_TLB_FLUSH(vec)  (vec == IA64_IPI_LOCAL_TLB_FLUSH)
  #else
  #     define IS_RESCHEDULE(vec)       (0)
+ #     define IS_LOCAL_TLB_FLUSH(vec)  (0)
  #endif
  /*
   * That's where the IVT branches when we get an external
@@@ -179,8 -183,11 +182,11 @@@ ia64_handle_irq (ia64_vector vector, st
        saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
        ia64_srlz_d();
        while (vector != IA64_SPURIOUS_INT_VECTOR) {
-               if (unlikely(IS_RESCHEDULE(vector)))
-                        kstat_this_cpu.irqs[vector]++;
+               if (unlikely(IS_LOCAL_TLB_FLUSH(vector))) {
+                       smp_local_flush_tlb();
+                       kstat_this_cpu.irqs[vector]++;
+               } else if (unlikely(IS_RESCHEDULE(vector)))
+                       kstat_this_cpu.irqs[vector]++;
                else {
                        ia64_setreg(_IA64_REG_CR_TPR, vector);
                        ia64_srlz_d();
@@@ -226,8 -233,11 +232,11 @@@ void ia64_process_pending_intr(void
          * Perform normal interrupt style processing
          */
        while (vector != IA64_SPURIOUS_INT_VECTOR) {
-               if (unlikely(IS_RESCHEDULE(vector)))
-                        kstat_this_cpu.irqs[vector]++;
+               if (unlikely(IS_LOCAL_TLB_FLUSH(vector))) {
+                       smp_local_flush_tlb();
+                       kstat_this_cpu.irqs[vector]++;
+               } else if (unlikely(IS_RESCHEDULE(vector)))
+                       kstat_this_cpu.irqs[vector]++;
                else {
                        struct pt_regs *old_regs = set_irq_regs(NULL);
  
  
  
  #ifdef CONFIG_SMP
- extern irqreturn_t handle_IPI (int irq, void *dev_id);
  
  static irqreturn_t dummy_handler (int irq, void *dev_id)
  {
        BUG();
  }
+ extern irqreturn_t handle_IPI (int irq, void *dev_id);
  
  static struct irqaction ipi_irqaction = {
        .handler =      handle_IPI,
@@@ -277,6 -287,13 +286,13 @@@ static struct irqaction resched_irqacti
        .flags =        IRQF_DISABLED,
        .name =         "resched"
  };
+ static struct irqaction tlb_irqaction = {
+       .handler =      dummy_handler,
+       .flags =        SA_INTERRUPT,
+       .name =         "tlb_flush"
+ };
  #endif
  
  void
@@@ -302,6 -319,7 +318,7 @@@ init_IRQ (void
  #ifdef CONFIG_SMP
        register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
        register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction);
+       register_percpu_irq(IA64_IPI_LOCAL_TLB_FLUSH, &tlb_irqaction);
  #endif
  #ifdef CONFIG_PERFMON
        pfm_init_percpu();
index 8bb571a8a73840447a23531c49cccb4602008c5c,d7b7d3da1ebbddd071f8ef9186be24206fda364a..d1c3ed9943e52d8ccad85553e1d1008ae7dc3629
  #include <linux/personality.h>
  #include <linux/sched.h>
  #include <linux/slab.h>
 -#include <linux/smp_lock.h>
  #include <linux/stddef.h>
  #include <linux/thread_info.h>
  #include <linux/unistd.h>
  #include <linux/efi.h>
  #include <linux/interrupt.h>
  #include <linux/delay.h>
 +#include <linux/kdebug.h>
  
  #include <asm/cpu.h>
  #include <asm/delay.h>
  #include <asm/elf.h>
  #include <asm/ia32.h>
  #include <asm/irq.h>
 -#include <asm/kdebug.h>
  #include <asm/kexec.h>
  #include <asm/pgalloc.h>
  #include <asm/processor.h>
@@@ -155,7 -156,7 +155,7 @@@ show_regs (struct pt_regs *regs
  }
  
  void
- do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
+ do_notify_resume_user (sigset_t *unused, struct sigscratch *scr, long in_syscall)
  {
        if (fsys_mode(current, &scr->pt)) {
                /* defer signal-handling etc. until we return to privilege-level 0.  */
  #endif
  
        /* deal with pending signal delivery */
-       if (test_thread_flag(TIF_SIGPENDING))
-               ia64_do_signal(oldset, scr, in_syscall);
+       if (test_thread_flag(TIF_SIGPENDING)||test_thread_flag(TIF_RESTORE_SIGMASK))
+               ia64_do_signal(scr, in_syscall);
  }
  
  static int pal_halt        = 1;
@@@ -236,6 -237,7 +236,7 @@@ void cpu_idle_wait(void
  {
        unsigned int cpu, this_cpu = get_cpu();
        cpumask_t map;
+       cpumask_t tmp = current->cpus_allowed;
  
        set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
        put_cpu();
                }
                cpus_and(map, map, cpu_online_map);
        } while (!cpus_empty(map));
+       set_cpus_allowed(current, tmp);
  }
  EXPORT_SYMBOL_GPL(cpu_idle_wait);
  
index 0dcd56da600181937e8670f1fc6cedc468d650f9,034b81d62bb1eff23b559a4e9a98df5733260257..aeec8184e862535e6676b2cafae699f502fa56f0
@@@ -14,6 -14,7 +14,6 @@@
  #include <linux/sched.h>
  #include <linux/signal.h>
  #include <linux/smp.h>
 -#include <linux/smp_lock.h>
  #include <linux/stddef.h>
  #include <linux/tty.h>
  #include <linux/binfmts.h>
  # define GET_SIGSET(k,u)      __get_user((k)->sig[0], &(u)->sig[0])
  #endif
  
- long
- ia64_rt_sigsuspend (sigset_t __user *uset, size_t sigsetsize, struct sigscratch *scr)
- {
-       sigset_t oldset, set;
-       /* XXX: Don't preclude handling different sized sigset_t's.  */
-       if (sigsetsize != sizeof(sigset_t))
-               return -EINVAL;
-       if (!access_ok(VERIFY_READ, uset, sigsetsize))
-               return -EFAULT;
-       if (GET_SIGSET(&set, uset))
-               return -EFAULT;
-       sigdelsetmask(&set, ~_BLOCKABLE);
-       spin_lock_irq(&current->sighand->siglock);
-       {
-               oldset = current->blocked;
-               current->blocked = set;
-               recalc_sigpending();
-       }
-       spin_unlock_irq(&current->sighand->siglock);
-       /*
-        * The return below usually returns to the signal handler.  We need to
-        * pre-set the correct error code here to ensure that the right values
-        * get saved in sigcontext by ia64_do_signal.
-        */
-       scr->pt.r8 = EINTR;
-       scr->pt.r10 = -1;
-       while (1) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule();
-               if (ia64_do_signal(&oldset, scr, 1))
-                       return -EINTR;
-       }
- }
  asmlinkage long
  sys_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, long arg2,
                 long arg3, long arg4, long arg5, long arg6, long arg7,
@@@ -477,10 -437,11 +436,11 @@@ handle_signal (unsigned long sig, struc
   * Note that `init' is a special process: it doesn't get signals it doesn't want to
   * handle.  Thus you cannot kill init even with a SIGKILL even by mistake.
   */
- long
- ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
+ void
+ ia64_do_signal (struct sigscratch *scr, long in_syscall)
  {
        struct k_sigaction ka;
+       sigset_t *oldset;
        siginfo_t info;
        long restart = in_syscall;
        long errno = scr->pt.r8;
         * doing anything if so.
         */
        if (!user_mode(&scr->pt))
-               return 0;
+               return;
  
-       if (!oldset)
+       if (test_thread_flag(TIF_RESTORE_SIGMASK))
+               oldset = &current->saved_sigmask;
+       else
                oldset = &current->blocked;
  
        /*
                 * Whee!  Actually deliver the signal.  If the delivery failed, we need to
                 * continue to iterate in this loop so we can deliver the SIGSEGV...
                 */
-               if (handle_signal(signr, &ka, &info, oldset, scr))
-                       return 1;
+               if (handle_signal(signr, &ka, &info, oldset, scr)) {
+                       /* a signal was successfully delivered; the saved
+                        * sigmask will have been stored in the signal frame,
+                        * and will be restored by sigreturn, so we can simply
+                        * clear the TIF_RESTORE_SIGMASK flag */
+                       if (test_thread_flag(TIF_RESTORE_SIGMASK))
+                               clear_thread_flag(TIF_RESTORE_SIGMASK);
+                       return;
+               }
        }
  
        /* Did we come from a system call? */
                        }
                }
        }
-       return 0;
+       /* if there's no signal to deliver, we just put the saved sigmask
+        * back */
+       if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+               clear_thread_flag(TIF_RESTORE_SIGMASK);
+               sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+       }
  }
diff --combined arch/ia64/kernel/traps.c
index 5bfb8be02b702cd018e91fcce985970f9b7dab40,cd5189f996297bd20a80d6a7c5f82774b389bd9f..b8e0d70bf9893f21451d7baad5f6dfd033bac527
  #include <linux/hardirq.h>
  #include <linux/kprobes.h>
  #include <linux/delay.h>              /* for ssleep() */
 +#include <linux/kdebug.h>
  
  #include <asm/fpswa.h>
  #include <asm/ia32.h>
  #include <asm/intrinsics.h>
  #include <asm/processor.h>
  #include <asm/uaccess.h>
 -#include <asm/kdebug.h>
  
  fpswa_interface_t *fpswa_interface;
  EXPORT_SYMBOL(fpswa_interface);
  
 -ATOMIC_NOTIFIER_HEAD(ia64die_chain);
 -
 -int
 -register_die_notifier(struct notifier_block *nb)
 -{
 -      return atomic_notifier_chain_register(&ia64die_chain, nb);
 -}
 -EXPORT_SYMBOL_GPL(register_die_notifier);
 -
 -int
 -unregister_die_notifier(struct notifier_block *nb)
 -{
 -      return atomic_notifier_chain_unregister(&ia64die_chain, nb);
 -}
 -EXPORT_SYMBOL_GPL(unregister_die_notifier);
 -
  void __init
  trap_init (void)
  {
@@@ -43,9 -59,9 +43,9 @@@ die (const char *str, struct pt_regs *r
                u32 lock_owner;
                int lock_owner_depth;
        } die = {
-               .lock =                 SPIN_LOCK_UNLOCKED,
-               .lock_owner =           -1,
-               .lock_owner_depth =     0
+               .lock = __SPIN_LOCK_UNLOCKED(die.lock),
+               .lock_owner = -1,
+               .lock_owner_depth = 0
        };
        static int die_counter;
        int cpu = get_cpu();
index d281475065856341d0a34b7413b5c8ba8c9556f4,077d6778575a2b0f4bffedc26519f8d9f745b5f3..7d0241db622b0e19f6ca350782b214c348d05e4c
@@@ -85,6 -85,7 +85,7 @@@ struct thread_info 
  #define TIF_SYSCALL_TRACE     3       /* syscall trace active */
  #define TIF_SYSCALL_AUDIT     4       /* syscall auditing active */
  #define TIF_SINGLESTEP                5       /* restore singlestep on return to user mode */
+ #define TIF_RESTORE_SIGMASK   6       /* restore signal mask in do_signal() */
  #define TIF_POLLING_NRFLAG    16      /* true if poll_idle() is polling TIF_NEED_RESCHED */
  #define TIF_MEMDIE            17
  #define TIF_MCA_INIT          18      /* this task is processing MCA or INIT */
@@@ -96,6 -97,7 +97,7 @@@
  #define _TIF_SINGLESTEP               (1 << TIF_SINGLESTEP)
  #define _TIF_SYSCALL_TRACEAUDIT       (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP)
  #define _TIF_NOTIFY_RESUME    (1 << TIF_NOTIFY_RESUME)
+ #define _TIF_RESTORE_SIGMASK  (1 << TIF_RESTORE_SIGMASK)
  #define _TIF_SIGPENDING               (1 << TIF_SIGPENDING)
  #define _TIF_NEED_RESCHED     (1 << TIF_NEED_RESCHED)
  #define _TIF_POLLING_NRFLAG   (1 << TIF_POLLING_NRFLAG)
  #define _TIF_FREEZE           (1 << TIF_FREEZE)
  
  /* "work to do on user-return" bits */
- #define TIF_ALLWORK_MASK      (_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
+ #define TIF_ALLWORK_MASK      (_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_RESTORE_SIGMASK)
  /* like TIF_ALLWORK_BITS but sans TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT */
  #define TIF_WORK_MASK         (TIF_ALLWORK_MASK&~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT))
  
  #define TS_POLLING            1       /* true if in idle loop and not sleeping */
  
 -#define tsk_is_polling(t) ((t)->thread_info->status & TS_POLLING)
 +#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
  
  #endif /* _ASM_IA64_THREAD_INFO_H */