diff options
author | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-05-31 08:57:05 +0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-05-31 08:57:05 +0400 |
commit | 5bc65793cbf8da0d35f19ef025dda22887e79e80 (patch) | |
tree | 8291998abd73055de6f487fafa174ee2a5d3afee /arch/alpha/kernel | |
parent | 6edae708bf77e012d855a7e2c7766f211d234f4f (diff) | |
parent | 3f0a6766e0cc5a577805732e5adb50a585c58175 (diff) | |
download | linux-5bc65793cbf8da0d35f19ef025dda22887e79e80.tar.xz |
[SCSI] Merge up to linux-2.6 head
Conflicts:
drivers/scsi/jazz_esp.c
Same changes made by both SCSI and SPARC trees: problem with UTF-8
conversion in the copyright.
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'arch/alpha/kernel')
-rw-r--r-- | arch/alpha/kernel/entry.S | 7 | ||||
-rw-r--r-- | arch/alpha/kernel/pci_iommu.c | 3 | ||||
-rw-r--r-- | arch/alpha/kernel/setup.c | 3 | ||||
-rw-r--r-- | arch/alpha/kernel/signal.c | 110 | ||||
-rw-r--r-- | arch/alpha/kernel/systbls.S | 32 | ||||
-rw-r--r-- | arch/alpha/kernel/vmlinux.lds.S | 4 |
6 files changed, 104 insertions, 55 deletions
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index c95e95e1ab04..debc8f03886c 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -391,11 +391,10 @@ $work_resched: bne $2, $work_resched $work_notifysig: - mov $sp, $17 + mov $sp, $16 br $1, do_switch_stack - mov $5, $21 - mov $sp, $18 - mov $31, $16 + mov $sp, $17 + mov $5, $18 jsr $26, do_notify_resume bsr $1, undo_switch_stack br restore_all diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index 6e7d1fe6e935..28c84e55feb9 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -7,6 +7,7 @@ #include <linux/pci.h> #include <linux/slab.h> #include <linux/bootmem.h> +#include <linux/log2.h> #include <asm/io.h> #include <asm/hwrpb.h> @@ -53,7 +54,7 @@ size_for_memory(unsigned long max) { unsigned long mem = max_low_pfn << PAGE_SHIFT; if (mem < max) - max = 1UL << ceil_log2(mem); + max = roundup_pow_of_two(mem); return max; } diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 915f26345c45..bd5e68cd61e8 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -43,6 +43,7 @@ #include <linux/notifier.h> #include <asm/setup.h> #include <asm/io.h> +#include <linux/log2.h> extern struct atomic_notifier_head panic_notifier_list; static int alpha_panic_event(struct notifier_block *, unsigned long, void *); @@ -1303,7 +1304,7 @@ external_cache_probe(int minsize, int width) long size = minsize, maxsize = MAX_BCACHE_SIZE * 2; if (maxsize > (max_low_pfn + 1) << PAGE_SHIFT) - maxsize = 1 << (floor_log2(max_low_pfn + 1) + PAGE_SHIFT); + maxsize = 1 << (ilog2(max_low_pfn + 1) + PAGE_SHIFT); /* Get the first block cached. */ read_mem_block(__va(0), stride, size); diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index 7f64aa767d5a..410af4f3140e 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c @@ -32,8 +32,8 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) asmlinkage void ret_from_sys_call(void); -static int do_signal(sigset_t *, struct pt_regs *, struct switch_stack *, - unsigned long, unsigned long); +static void do_signal(struct pt_regs *, struct switch_stack *, + unsigned long, unsigned long); /* @@ -146,11 +146,9 @@ sys_rt_sigaction(int sig, const struct sigaction __user *act, asmlinkage int do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw) { - sigset_t oldset; - mask &= _BLOCKABLE; spin_lock_irq(¤t->sighand->siglock); - oldset = current->blocked; + current->saved_sigmask = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); @@ -160,19 +158,17 @@ do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw) regs->r0 = EINTR; regs->r19 = 1; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal(&oldset, regs, sw, 0, 0)) - return -EINTR; - } + current->state = TASK_INTERRUPTIBLE; + schedule(); + set_thread_flag(TIF_RESTORE_SIGMASK); + return -ERESTARTNOHAND; } asmlinkage int do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, struct pt_regs *regs, struct switch_stack *sw) { - sigset_t oldset, set; + sigset_t set; /* XXX: Don't preclude handling different sized sigset_t's. */ if (sigsetsize != sizeof(sigset_t)) @@ -182,7 +178,7 @@ do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); - oldset = current->blocked; + current->saved_sigmask = current->blocked; current->blocked = set; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); @@ -192,12 +188,10 @@ do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, regs->r0 = EINTR; regs->r19 = 1; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal(&oldset, regs, sw, 0, 0)) - return -EINTR; - } + current->state = TASK_INTERRUPTIBLE; + schedule(); + set_thread_flag(TIF_RESTORE_SIGMASK); + return -ERESTARTNOHAND; } asmlinkage int @@ -436,7 +430,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, return err; } -static void +static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *regs, struct switch_stack * sw) { @@ -481,13 +475,14 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, current->comm, current->pid, frame, regs->pc, regs->r26); #endif - return; + return 0; give_sigsegv: force_sigsegv(sig, current); + return -EFAULT; } -static void +static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs, struct switch_stack * sw) { @@ -543,34 +538,38 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, current->comm, current->pid, frame, regs->pc, regs->r26); #endif - return; + return 0; give_sigsegv: force_sigsegv(sig, current); + return -EFAULT; } /* * OK, we're invoking a handler. */ -static inline void +static inline int handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw) { + int ret; + if (ka->sa.sa_flags & SA_SIGINFO) - setup_rt_frame(sig, ka, info, oldset, regs, sw); + ret = setup_rt_frame(sig, ka, info, oldset, regs, sw); else - setup_frame(sig, ka, oldset, regs, sw); + ret = setup_frame(sig, ka, oldset, regs, sw); - if (ka->sa.sa_flags & SA_RESETHAND) - ka->sa.sa_handler = SIG_DFL; + if (ret == 0) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(¤t->blocked,sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked,sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + return ret; } static inline void @@ -611,30 +610,42 @@ syscall_restart(unsigned long r0, unsigned long r19, * restart. "r0" is also used as an indicator whether we can restart at * all (if we get here from anything but a syscall return, it will be 0) */ -static int -do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw, +static void +do_signal(struct pt_regs * regs, struct switch_stack * sw, unsigned long r0, unsigned long r19) { siginfo_t info; int signr; unsigned long single_stepping = ptrace_cancel_bpt(current); struct k_sigaction ka; + sigset_t *oldset; - if (!oldset) + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + oldset = ¤t->saved_sigmask; + else oldset = ¤t->blocked; /* This lets the debugger run, ... */ signr = get_signal_to_deliver(&info, &ka, regs, NULL); + /* ... so re-check the single stepping. */ single_stepping |= ptrace_cancel_bpt(current); if (signr > 0) { /* Whee! Actually deliver the signal. */ - if (r0) syscall_restart(r0, r19, regs, &ka); - handle_signal(signr, &ka, &info, oldset, regs, sw); + if (r0) + syscall_restart(r0, r19, regs, &ka); + if (handle_signal(signr, &ka, &info, oldset, regs, sw) == 0) { + /* A signal was successfully delivered, and the + saved sigmask was stored on the signal frame, + and will be restored by sigreturn. So we can + simply clear the restore sigmask flag. */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + clear_thread_flag(TIF_RESTORE_SIGMASK); + } if (single_stepping) ptrace_set_bpt(current); /* re-set bpt */ - return 1; + return; } if (r0) { @@ -654,17 +665,22 @@ do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw, break; } } + + /* If there's no signal to deliver, we just restore the saved mask. */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { + clear_thread_flag(TIF_RESTORE_SIGMASK); + sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); + } + if (single_stepping) ptrace_set_bpt(current); /* re-set breakpoint */ - - return 0; } void -do_notify_resume(sigset_t *oldset, struct pt_regs *regs, - struct switch_stack *sw, unsigned long r0, - unsigned long r19, unsigned long thread_info_flags) +do_notify_resume(struct pt_regs *regs, struct switch_stack *sw, + unsigned long thread_info_flags, + unsigned long r0, unsigned long r19) { - if (thread_info_flags & _TIF_SIGPENDING) - do_signal(oldset, regs, sw, r0, r19); + if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) + do_signal(regs, sw, r0, r19); } diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index f6cfe8ce3f96..79de99e32c35 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S @@ -465,6 +465,38 @@ sys_call_table: .quad sys_inotify_init .quad sys_inotify_add_watch /* 445 */ .quad sys_inotify_rm_watch + .quad sys_fdatasync + .quad sys_kexec_load + .quad sys_migrate_pages + .quad sys_openat /* 450 */ + .quad sys_mkdirat + .quad sys_mknodat + .quad sys_fchownat + .quad sys_futimesat + .quad sys_fstatat64 /* 455 */ + .quad sys_unlinkat + .quad sys_renameat + .quad sys_linkat + .quad sys_symlinkat + .quad sys_readlinkat /* 460 */ + .quad sys_fchmodat + .quad sys_faccessat + .quad sys_pselect6 + .quad sys_ppoll + .quad sys_unshare /* 465 */ + .quad sys_set_robust_list + .quad sys_get_robust_list + .quad sys_splice + .quad sys_sync_file_range + .quad sys_tee /* 470 */ + .quad sys_vmsplice + .quad sys_move_pages + .quad sys_getcpu + .quad sys_epoll_pwait + .quad sys_utimensat /* 475 */ + .quad sys_signalfd + .quad sys_timerfd + .quad sys_eventfd .size sys_call_table, . - sys_call_table .type sys_call_table, @object diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S index cf1e6fc6c686..449e76f118d3 100644 --- a/arch/alpha/kernel/vmlinux.lds.S +++ b/arch/alpha/kernel/vmlinux.lds.S @@ -15,7 +15,7 @@ SECTIONS _text = .; /* Text and read-only data */ .text : { - *(.text) + TEXT_TEXT SCHED_TEXT LOCK_TEXT *(.fixup) @@ -89,7 +89,7 @@ SECTIONS _data = .; .data : { /* Data */ - *(.data) + DATA_DATA CONSTRUCTORS } |