diff options
| author | Steve French <sfrench@us.ibm.com> | 2006-01-23 15:51:00 -0500 |
|---|---|---|
| committer | Steve French <sfrench@us.ibm.com> | 2006-01-23 15:51:00 -0500 |
| commit | 4c8af5254e741983e141e10002e01abba87f8419 (patch) | |
| tree | a932954630715a0e9b4f20fdfe74255b441096c5 /arch | |
| parent | 0820e15a35b3cf37caadf550ddb7c75a7a77afd0 (diff) | |
| parent | 3ee68c4af3fd7228c1be63254b9f884614f9ebb2 (diff) | |
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/ia64/ia32/sys_ia32.c | 28 | ||||
| -rw-r--r-- | arch/ia64/kernel/perfmon.c | 11 | ||||
| -rw-r--r-- | arch/ia64/kernel/uncached.c | 1 | ||||
| -rw-r--r-- | arch/ia64/sn/include/xtalk/hubdev.h | 9 | ||||
| -rw-r--r-- | arch/ia64/sn/kernel/io_init.c | 54 | ||||
| -rw-r--r-- | arch/ia64/sn/kernel/mca.c | 7 | ||||
| -rw-r--r-- | arch/ia64/sn/kernel/xp_main.c | 17 | ||||
| -rw-r--r-- | arch/ia64/sn/kernel/xpc_channel.c | 34 | ||||
| -rw-r--r-- | arch/ia64/sn/kernel/xpc_main.c | 17 | ||||
| -rw-r--r-- | arch/ia64/sn/pci/pcibr/pcibr_provider.c | 12 | ||||
| -rw-r--r-- | arch/sparc/kernel/entry.S | 56 | ||||
| -rw-r--r-- | arch/sparc/kernel/rtrap.S | 9 | ||||
| -rw-r--r-- | arch/sparc/kernel/signal.c | 117 | ||||
| -rw-r--r-- | arch/sparc/kernel/sparc_ksyms.c | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/systbls.S | 10 | ||||
| -rw-r--r-- | arch/sparc64/kernel/entry.S | 23 | ||||
| -rw-r--r-- | arch/sparc64/kernel/rtrap.S | 33 | ||||
| -rw-r--r-- | arch/sparc64/kernel/signal.c | 151 | ||||
| -rw-r--r-- | arch/sparc64/kernel/signal32.c | 122 | ||||
| -rw-r--r-- | arch/sparc64/kernel/sparc64_ksyms.c | 4 | ||||
| -rw-r--r-- | arch/sparc64/kernel/systbls.S | 21 | ||||
| -rw-r--r-- | arch/sparc64/solaris/entry64.S | 2 |
22 files changed, 262 insertions, 478 deletions
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index 3945d378bd7e..70dba1f0e2ee 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c | |||
| @@ -52,9 +52,9 @@ | |||
| 52 | #include <linux/compat.h> | 52 | #include <linux/compat.h> |
| 53 | #include <linux/vfs.h> | 53 | #include <linux/vfs.h> |
| 54 | #include <linux/mman.h> | 54 | #include <linux/mman.h> |
| 55 | #include <linux/mutex.h> | ||
| 55 | 56 | ||
| 56 | #include <asm/intrinsics.h> | 57 | #include <asm/intrinsics.h> |
| 57 | #include <asm/semaphore.h> | ||
| 58 | #include <asm/types.h> | 58 | #include <asm/types.h> |
| 59 | #include <asm/uaccess.h> | 59 | #include <asm/uaccess.h> |
| 60 | #include <asm/unistd.h> | 60 | #include <asm/unistd.h> |
| @@ -86,7 +86,7 @@ | |||
| 86 | * while doing so. | 86 | * while doing so. |
| 87 | */ | 87 | */ |
| 88 | /* XXX make per-mm: */ | 88 | /* XXX make per-mm: */ |
| 89 | static DECLARE_MUTEX(ia32_mmap_sem); | 89 | static DEFINE_MUTEX(ia32_mmap_mutex); |
| 90 | 90 | ||
| 91 | asmlinkage long | 91 | asmlinkage long |
| 92 | sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp, | 92 | sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp, |
| @@ -895,11 +895,11 @@ ia32_do_mmap (struct file *file, unsigned long addr, unsigned long len, int prot | |||
| 895 | prot = get_prot32(prot); | 895 | prot = get_prot32(prot); |
| 896 | 896 | ||
| 897 | #if PAGE_SHIFT > IA32_PAGE_SHIFT | 897 | #if PAGE_SHIFT > IA32_PAGE_SHIFT |
| 898 | down(&ia32_mmap_sem); | 898 | mutex_lock(&ia32_mmap_mutex); |
| 899 | { | 899 | { |
| 900 | addr = emulate_mmap(file, addr, len, prot, flags, offset); | 900 | addr = emulate_mmap(file, addr, len, prot, flags, offset); |
| 901 | } | 901 | } |
| 902 | up(&ia32_mmap_sem); | 902 | mutex_unlock(&ia32_mmap_mutex); |
| 903 | #else | 903 | #else |
| 904 | down_write(¤t->mm->mmap_sem); | 904 | down_write(¤t->mm->mmap_sem); |
| 905 | { | 905 | { |
| @@ -1000,11 +1000,9 @@ sys32_munmap (unsigned int start, unsigned int len) | |||
| 1000 | if (start >= end) | 1000 | if (start >= end) |
| 1001 | return 0; | 1001 | return 0; |
| 1002 | 1002 | ||
| 1003 | down(&ia32_mmap_sem); | 1003 | mutex_lock(&ia32_mmap_mutex); |
| 1004 | { | 1004 | ret = sys_munmap(start, end - start); |
| 1005 | ret = sys_munmap(start, end - start); | 1005 | mutex_unlock(&ia32_mmap_mutex); |
| 1006 | } | ||
| 1007 | up(&ia32_mmap_sem); | ||
| 1008 | #endif | 1006 | #endif |
| 1009 | return ret; | 1007 | return ret; |
| 1010 | } | 1008 | } |
| @@ -1056,7 +1054,7 @@ sys32_mprotect (unsigned int start, unsigned int len, int prot) | |||
| 1056 | if (retval < 0) | 1054 | if (retval < 0) |
| 1057 | return retval; | 1055 | return retval; |
| 1058 | 1056 | ||
| 1059 | down(&ia32_mmap_sem); | 1057 | mutex_lock(&ia32_mmap_mutex); |
| 1060 | { | 1058 | { |
| 1061 | if (offset_in_page(start)) { | 1059 | if (offset_in_page(start)) { |
| 1062 | /* start address is 4KB aligned but not page aligned. */ | 1060 | /* start address is 4KB aligned but not page aligned. */ |
| @@ -1080,7 +1078,7 @@ sys32_mprotect (unsigned int start, unsigned int len, int prot) | |||
| 1080 | retval = sys_mprotect(start, end - start, prot); | 1078 | retval = sys_mprotect(start, end - start, prot); |
| 1081 | } | 1079 | } |
| 1082 | out: | 1080 | out: |
| 1083 | up(&ia32_mmap_sem); | 1081 | mutex_unlock(&ia32_mmap_mutex); |
| 1084 | return retval; | 1082 | return retval; |
| 1085 | #endif | 1083 | #endif |
| 1086 | } | 1084 | } |
| @@ -1124,11 +1122,9 @@ sys32_mremap (unsigned int addr, unsigned int old_len, unsigned int new_len, | |||
| 1124 | old_len = PAGE_ALIGN(old_end) - addr; | 1122 | old_len = PAGE_ALIGN(old_end) - addr; |
| 1125 | new_len = PAGE_ALIGN(new_end) - addr; | 1123 | new_len = PAGE_ALIGN(new_end) - addr; |
| 1126 | 1124 | ||
| 1127 | down(&ia32_mmap_sem); | 1125 | mutex_lock(&ia32_mmap_mutex); |
| 1128 | { | 1126 | ret = sys_mremap(addr, old_len, new_len, flags, new_addr); |
| 1129 | ret = sys_mremap(addr, old_len, new_len, flags, new_addr); | 1127 | mutex_unlock(&ia32_mmap_mutex); |
| 1130 | } | ||
| 1131 | up(&ia32_mmap_sem); | ||
| 1132 | 1128 | ||
| 1133 | if ((ret >= 0) && (old_len < new_len)) { | 1129 | if ((ret >= 0) && (old_len < new_len)) { |
| 1134 | /* mremap expanded successfully */ | 1130 | /* mremap expanded successfully */ |
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 2ea4b39efffa..9c5194b385da 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #include <linux/bitops.h> | 40 | #include <linux/bitops.h> |
| 41 | #include <linux/capability.h> | 41 | #include <linux/capability.h> |
| 42 | #include <linux/rcupdate.h> | 42 | #include <linux/rcupdate.h> |
| 43 | #include <linux/completion.h> | ||
| 43 | 44 | ||
| 44 | #include <asm/errno.h> | 45 | #include <asm/errno.h> |
| 45 | #include <asm/intrinsics.h> | 46 | #include <asm/intrinsics.h> |
| @@ -286,7 +287,7 @@ typedef struct pfm_context { | |||
| 286 | 287 | ||
| 287 | unsigned long ctx_ovfl_regs[4]; /* which registers overflowed (notification) */ | 288 | unsigned long ctx_ovfl_regs[4]; /* which registers overflowed (notification) */ |
| 288 | 289 | ||
| 289 | struct semaphore ctx_restart_sem; /* use for blocking notification mode */ | 290 | struct completion ctx_restart_done; /* use for blocking notification mode */ |
| 290 | 291 | ||
| 291 | unsigned long ctx_used_pmds[4]; /* bitmask of PMD used */ | 292 | unsigned long ctx_used_pmds[4]; /* bitmask of PMD used */ |
| 292 | unsigned long ctx_all_pmds[4]; /* bitmask of all accessible PMDs */ | 293 | unsigned long ctx_all_pmds[4]; /* bitmask of all accessible PMDs */ |
| @@ -1991,7 +1992,7 @@ pfm_close(struct inode *inode, struct file *filp) | |||
| 1991 | /* | 1992 | /* |
| 1992 | * force task to wake up from MASKED state | 1993 | * force task to wake up from MASKED state |
| 1993 | */ | 1994 | */ |
| 1994 | up(&ctx->ctx_restart_sem); | 1995 | complete(&ctx->ctx_restart_done); |
| 1995 | 1996 | ||
| 1996 | DPRINT(("waking up ctx_state=%d\n", state)); | 1997 | DPRINT(("waking up ctx_state=%d\n", state)); |
| 1997 | 1998 | ||
| @@ -2706,7 +2707,7 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg | |||
| 2706 | /* | 2707 | /* |
| 2707 | * init restart semaphore to locked | 2708 | * init restart semaphore to locked |
| 2708 | */ | 2709 | */ |
| 2709 | sema_init(&ctx->ctx_restart_sem, 0); | 2710 | init_completion(&ctx->ctx_restart_done); |
| 2710 | 2711 | ||
| 2711 | /* | 2712 | /* |
| 2712 | * activation is used in SMP only | 2713 | * activation is used in SMP only |
| @@ -3687,7 +3688,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) | |||
| 3687 | */ | 3688 | */ |
| 3688 | if (CTX_OVFL_NOBLOCK(ctx) == 0 && state == PFM_CTX_MASKED) { | 3689 | if (CTX_OVFL_NOBLOCK(ctx) == 0 && state == PFM_CTX_MASKED) { |
| 3689 | DPRINT(("unblocking [%d] \n", task->pid)); | 3690 | DPRINT(("unblocking [%d] \n", task->pid)); |
| 3690 | up(&ctx->ctx_restart_sem); | 3691 | complete(&ctx->ctx_restart_done); |
| 3691 | } else { | 3692 | } else { |
| 3692 | DPRINT(("[%d] armed exit trap\n", task->pid)); | 3693 | DPRINT(("[%d] armed exit trap\n", task->pid)); |
| 3693 | 3694 | ||
| @@ -5089,7 +5090,7 @@ pfm_handle_work(void) | |||
| 5089 | * may go through without blocking on SMP systems | 5090 | * may go through without blocking on SMP systems |
| 5090 | * if restart has been received already by the time we call down() | 5091 | * if restart has been received already by the time we call down() |
| 5091 | */ | 5092 | */ |
| 5092 | ret = down_interruptible(&ctx->ctx_restart_sem); | 5093 | ret = wait_for_completion_interruptible(&ctx->ctx_restart_done); |
| 5093 | 5094 | ||
| 5094 | DPRINT(("after block sleeping ret=%d\n", ret)); | 5095 | DPRINT(("after block sleeping ret=%d\n", ret)); |
| 5095 | 5096 | ||
diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c index b631cf86ed44..fcd2bad0286f 100644 --- a/arch/ia64/kernel/uncached.c +++ b/arch/ia64/kernel/uncached.c | |||
| @@ -210,6 +210,7 @@ uncached_build_memmap(unsigned long start, unsigned long end, void *arg) | |||
| 210 | 210 | ||
| 211 | dprintk(KERN_ERR "uncached_build_memmap(%lx %lx)\n", start, end); | 211 | dprintk(KERN_ERR "uncached_build_memmap(%lx %lx)\n", start, end); |
| 212 | 212 | ||
| 213 | touch_softlockup_watchdog(); | ||
| 213 | memset((char *)start, 0, length); | 214 | memset((char *)start, 0, length); |
| 214 | 215 | ||
| 215 | node = paddr_to_nid(start - __IA64_UNCACHED_OFFSET); | 216 | node = paddr_to_nid(start - __IA64_UNCACHED_OFFSET); |
diff --git a/arch/ia64/sn/include/xtalk/hubdev.h b/arch/ia64/sn/include/xtalk/hubdev.h index 7c88e9a58516..8182583c762c 100644 --- a/arch/ia64/sn/include/xtalk/hubdev.h +++ b/arch/ia64/sn/include/xtalk/hubdev.h | |||
| @@ -51,6 +51,15 @@ struct sn_flush_device_kernel { | |||
| 51 | struct sn_flush_device_common *common; | 51 | struct sn_flush_device_common *common; |
| 52 | }; | 52 | }; |
| 53 | 53 | ||
| 54 | /* 01/16/06 This struct is the old PROM/kernel struct and needs to be included | ||
| 55 | * for older official PROMs to function on the new kernel base. This struct | ||
| 56 | * will be removed when the next official PROM release occurs. */ | ||
| 57 | |||
| 58 | struct sn_flush_device_war { | ||
| 59 | struct sn_flush_device_common common; | ||
| 60 | u32 filler; /* older PROMs expect the default size of a spinlock_t */ | ||
| 61 | }; | ||
| 62 | |||
| 54 | /* | 63 | /* |
| 55 | * **widget_p - Used as an array[wid_num][device] of sn_flush_device_kernel. | 64 | * **widget_p - Used as an array[wid_num][device] of sn_flush_device_kernel. |
| 56 | */ | 65 | */ |
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 233d55115d33..00700f7e6837 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
| @@ -165,8 +165,45 @@ sn_pcidev_info_get(struct pci_dev *dev) | |||
| 165 | return NULL; | 165 | return NULL; |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | /* Older PROM flush WAR | ||
| 169 | * | ||
| 170 | * 01/16/06 -- This war will be in place until a new official PROM is released. | ||
| 171 | * Additionally note that the struct sn_flush_device_war also has to be | ||
| 172 | * removed from arch/ia64/sn/include/xtalk/hubdev.h | ||
| 173 | */ | ||
| 174 | static u8 war_implemented = 0; | ||
| 175 | |||
| 176 | static void sn_device_fixup_war(u64 nasid, u64 widget, int device, | ||
| 177 | struct sn_flush_device_common *common) | ||
| 178 | { | ||
| 179 | struct sn_flush_device_war *war_list; | ||
| 180 | struct sn_flush_device_war *dev_entry; | ||
| 181 | struct ia64_sal_retval isrv = {0,0,0,0}; | ||
| 182 | |||
| 183 | if (!war_implemented) { | ||
| 184 | printk(KERN_WARNING "PROM version < 4.50 -- implementing old " | ||
| 185 | "PROM flush WAR\n"); | ||
| 186 | war_implemented = 1; | ||
| 187 | } | ||
| 188 | |||
| 189 | war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL); | ||
| 190 | if (!war_list) | ||
| 191 | BUG(); | ||
| 192 | |||
| 193 | SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST, | ||
| 194 | nasid, widget, __pa(war_list), 0, 0, 0 ,0); | ||
| 195 | if (isrv.status) | ||
| 196 | panic("sn_device_fixup_war failed: %s\n", | ||
| 197 | ia64_sal_strerror(isrv.status)); | ||
| 198 | |||
| 199 | dev_entry = war_list + device; | ||
| 200 | memcpy(common,dev_entry, sizeof(*common)); | ||
| 201 | |||
| 202 | kfree(war_list); | ||
| 203 | } | ||
| 204 | |||
| 168 | /* | 205 | /* |
| 169 | * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for | 206 | * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for |
| 170 | * each node in the system. | 207 | * each node in the system. |
| 171 | */ | 208 | */ |
| 172 | static void sn_fixup_ionodes(void) | 209 | static void sn_fixup_ionodes(void) |
| @@ -246,8 +283,19 @@ static void sn_fixup_ionodes(void) | |||
| 246 | widget, | 283 | widget, |
| 247 | device, | 284 | device, |
| 248 | (u64)(dev_entry->common)); | 285 | (u64)(dev_entry->common)); |
| 249 | if (status) | 286 | if (status) { |
| 250 | BUG(); | 287 | if (sn_sal_rev() < 0x0450) { |
| 288 | /* shortlived WAR for older | ||
| 289 | * PROM images | ||
| 290 | */ | ||
| 291 | sn_device_fixup_war(nasid, | ||
| 292 | widget, | ||
| 293 | device, | ||
| 294 | dev_entry->common); | ||
| 295 | } | ||
| 296 | else | ||
| 297 | BUG(); | ||
| 298 | } | ||
| 251 | 299 | ||
| 252 | spin_lock_init(&dev_entry->sfdl_flush_lock); | 300 | spin_lock_init(&dev_entry->sfdl_flush_lock); |
| 253 | } | 301 | } |
diff --git a/arch/ia64/sn/kernel/mca.c b/arch/ia64/sn/kernel/mca.c index 6546db6abdba..9ab684d1bb55 100644 --- a/arch/ia64/sn/kernel/mca.c +++ b/arch/ia64/sn/kernel/mca.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
| 11 | #include <linux/timer.h> | 11 | #include <linux/timer.h> |
| 12 | #include <linux/vmalloc.h> | 12 | #include <linux/vmalloc.h> |
| 13 | #include <linux/mutex.h> | ||
| 13 | #include <asm/mca.h> | 14 | #include <asm/mca.h> |
| 14 | #include <asm/sal.h> | 15 | #include <asm/sal.h> |
| 15 | #include <asm/sn/sn_sal.h> | 16 | #include <asm/sn/sn_sal.h> |
| @@ -27,7 +28,7 @@ void sn_init_cpei_timer(void); | |||
| 27 | /* Printing oemdata from mca uses data that is not passed through SAL, it is | 28 | /* Printing oemdata from mca uses data that is not passed through SAL, it is |
| 28 | * global. Only one user at a time. | 29 | * global. Only one user at a time. |
| 29 | */ | 30 | */ |
| 30 | static DECLARE_MUTEX(sn_oemdata_mutex); | 31 | static DEFINE_MUTEX(sn_oemdata_mutex); |
| 31 | static u8 **sn_oemdata; | 32 | static u8 **sn_oemdata; |
| 32 | static u64 *sn_oemdata_size, sn_oemdata_bufsize; | 33 | static u64 *sn_oemdata_size, sn_oemdata_bufsize; |
| 33 | 34 | ||
| @@ -89,7 +90,7 @@ static int | |||
| 89 | sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata, | 90 | sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata, |
| 90 | u64 * oemdata_size) | 91 | u64 * oemdata_size) |
| 91 | { | 92 | { |
| 92 | down(&sn_oemdata_mutex); | 93 | mutex_lock(&sn_oemdata_mutex); |
| 93 | sn_oemdata = oemdata; | 94 | sn_oemdata = oemdata; |
| 94 | sn_oemdata_size = oemdata_size; | 95 | sn_oemdata_size = oemdata_size; |
| 95 | sn_oemdata_bufsize = 0; | 96 | sn_oemdata_bufsize = 0; |
| @@ -107,7 +108,7 @@ sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata, | |||
| 107 | *sn_oemdata_size = 0; | 108 | *sn_oemdata_size = 0; |
| 108 | ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header); | 109 | ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header); |
| 109 | } | 110 | } |
| 110 | up(&sn_oemdata_mutex); | 111 | mutex_unlock(&sn_oemdata_mutex); |
| 111 | return 0; | 112 | return 0; |
| 112 | } | 113 | } |
| 113 | 114 | ||
diff --git a/arch/ia64/sn/kernel/xp_main.c b/arch/ia64/sn/kernel/xp_main.c index 3be52a34c80f..b7ea46645e12 100644 --- a/arch/ia64/sn/kernel/xp_main.c +++ b/arch/ia64/sn/kernel/xp_main.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
| 20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
| 21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 22 | #include <linux/mutex.h> | ||
| 22 | #include <asm/sn/intr.h> | 23 | #include <asm/sn/intr.h> |
| 23 | #include <asm/sn/sn_sal.h> | 24 | #include <asm/sn/sn_sal.h> |
| 24 | #include <asm/sn/xp.h> | 25 | #include <asm/sn/xp.h> |
| @@ -136,13 +137,13 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size, | |||
| 136 | 137 | ||
| 137 | registration = &xpc_registrations[ch_number]; | 138 | registration = &xpc_registrations[ch_number]; |
| 138 | 139 | ||
| 139 | if (down_interruptible(®istration->sema) != 0) { | 140 | if (mutex_lock_interruptible(®istration->mutex) != 0) { |
| 140 | return xpcInterrupted; | 141 | return xpcInterrupted; |
| 141 | } | 142 | } |
| 142 | 143 | ||
| 143 | /* if XPC_CHANNEL_REGISTERED(ch_number) */ | 144 | /* if XPC_CHANNEL_REGISTERED(ch_number) */ |
| 144 | if (registration->func != NULL) { | 145 | if (registration->func != NULL) { |
| 145 | up(®istration->sema); | 146 | mutex_unlock(®istration->mutex); |
| 146 | return xpcAlreadyRegistered; | 147 | return xpcAlreadyRegistered; |
| 147 | } | 148 | } |
| 148 | 149 | ||
| @@ -154,7 +155,7 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size, | |||
| 154 | registration->key = key; | 155 | registration->key = key; |
| 155 | registration->func = func; | 156 | registration->func = func; |
| 156 | 157 | ||
| 157 | up(®istration->sema); | 158 | mutex_unlock(®istration->mutex); |
| 158 | 159 | ||
| 159 | xpc_interface.connect(ch_number); | 160 | xpc_interface.connect(ch_number); |
| 160 | 161 | ||
| @@ -190,11 +191,11 @@ xpc_disconnect(int ch_number) | |||
| 190 | * figured XPC's users will just turn around and call xpc_disconnect() | 191 | * figured XPC's users will just turn around and call xpc_disconnect() |
| 191 | * again anyways, so we might as well wait, if need be. | 192 | * again anyways, so we might as well wait, if need be. |
| 192 | */ | 193 | */ |
| 193 | down(®istration->sema); | 194 | mutex_lock(®istration->mutex); |
| 194 | 195 | ||
| 195 | /* if !XPC_CHANNEL_REGISTERED(ch_number) */ | 196 | /* if !XPC_CHANNEL_REGISTERED(ch_number) */ |
| 196 | if (registration->func == NULL) { | 197 | if (registration->func == NULL) { |
| 197 | up(®istration->sema); | 198 | mutex_unlock(®istration->mutex); |
| 198 | return; | 199 | return; |
| 199 | } | 200 | } |
| 200 | 201 | ||
| @@ -208,7 +209,7 @@ xpc_disconnect(int ch_number) | |||
| 208 | 209 | ||
| 209 | xpc_interface.disconnect(ch_number); | 210 | xpc_interface.disconnect(ch_number); |
| 210 | 211 | ||
| 211 | up(®istration->sema); | 212 | mutex_unlock(®istration->mutex); |
| 212 | 213 | ||
| 213 | return; | 214 | return; |
| 214 | } | 215 | } |
| @@ -250,9 +251,9 @@ xp_init(void) | |||
| 250 | xp_nofault_PIOR_target = SH1_IPI_ACCESS; | 251 | xp_nofault_PIOR_target = SH1_IPI_ACCESS; |
| 251 | } | 252 | } |
| 252 | 253 | ||
| 253 | /* initialize the connection registration semaphores */ | 254 | /* initialize the connection registration mutex */ |
| 254 | for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) { | 255 | for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) { |
| 255 | sema_init(&xpc_registrations[ch_number].sema, 1); /* mutex */ | 256 | mutex_init(&xpc_registrations[ch_number].mutex); |
| 256 | } | 257 | } |
| 257 | 258 | ||
| 258 | return 0; | 259 | return 0; |
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c index 0c0a68902409..8d950c778bb6 100644 --- a/arch/ia64/sn/kernel/xpc_channel.c +++ b/arch/ia64/sn/kernel/xpc_channel.c | |||
| @@ -22,6 +22,8 @@ | |||
| 22 | #include <linux/cache.h> | 22 | #include <linux/cache.h> |
| 23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
| 24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
| 25 | #include <linux/mutex.h> | ||
| 26 | #include <linux/completion.h> | ||
| 25 | #include <asm/sn/bte.h> | 27 | #include <asm/sn/bte.h> |
| 26 | #include <asm/sn/sn_sal.h> | 28 | #include <asm/sn/sn_sal.h> |
| 27 | #include <asm/sn/xpc.h> | 29 | #include <asm/sn/xpc.h> |
| @@ -56,8 +58,8 @@ xpc_initialize_channels(struct xpc_partition *part, partid_t partid) | |||
| 56 | atomic_set(&ch->n_to_notify, 0); | 58 | atomic_set(&ch->n_to_notify, 0); |
| 57 | 59 | ||
| 58 | spin_lock_init(&ch->lock); | 60 | spin_lock_init(&ch->lock); |
| 59 | sema_init(&ch->msg_to_pull_sema, 1); /* mutex */ | 61 | mutex_init(&ch->msg_to_pull_mutex); |
| 60 | sema_init(&ch->wdisconnect_sema, 0); /* event wait */ | 62 | init_completion(&ch->wdisconnect_wait); |
| 61 | 63 | ||
| 62 | atomic_set(&ch->n_on_msg_allocate_wq, 0); | 64 | atomic_set(&ch->n_on_msg_allocate_wq, 0); |
| 63 | init_waitqueue_head(&ch->msg_allocate_wq); | 65 | init_waitqueue_head(&ch->msg_allocate_wq); |
| @@ -534,7 +536,6 @@ static enum xpc_retval | |||
| 534 | xpc_allocate_msgqueues(struct xpc_channel *ch) | 536 | xpc_allocate_msgqueues(struct xpc_channel *ch) |
| 535 | { | 537 | { |
| 536 | unsigned long irq_flags; | 538 | unsigned long irq_flags; |
| 537 | int i; | ||
| 538 | enum xpc_retval ret; | 539 | enum xpc_retval ret; |
| 539 | 540 | ||
| 540 | 541 | ||
| @@ -552,11 +553,6 @@ xpc_allocate_msgqueues(struct xpc_channel *ch) | |||
| 552 | return ret; | 553 | return ret; |
| 553 | } | 554 | } |
| 554 | 555 | ||
| 555 | for (i = 0; i < ch->local_nentries; i++) { | ||
| 556 | /* use a semaphore as an event wait queue */ | ||
| 557 | sema_init(&ch->notify_queue[i].sema, 0); | ||
| 558 | } | ||
| 559 | |||
| 560 | spin_lock_irqsave(&ch->lock, irq_flags); | 556 | spin_lock_irqsave(&ch->lock, irq_flags); |
| 561 | ch->flags |= XPC_C_SETUP; | 557 | ch->flags |= XPC_C_SETUP; |
| 562 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 558 | spin_unlock_irqrestore(&ch->lock, irq_flags); |
| @@ -799,10 +795,8 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) | |||
| 799 | } | 795 | } |
| 800 | 796 | ||
| 801 | if (ch->flags & XPC_C_WDISCONNECT) { | 797 | if (ch->flags & XPC_C_WDISCONNECT) { |
| 802 | spin_unlock_irqrestore(&ch->lock, *irq_flags); | 798 | /* we won't lose the CPU since we're holding ch->lock */ |
| 803 | up(&ch->wdisconnect_sema); | 799 | complete(&ch->wdisconnect_wait); |
| 804 | spin_lock_irqsave(&ch->lock, *irq_flags); | ||
| 805 | |||
| 806 | } else if (ch->delayed_IPI_flags) { | 800 | } else if (ch->delayed_IPI_flags) { |
| 807 | if (part->act_state != XPC_P_DEACTIVATING) { | 801 | if (part->act_state != XPC_P_DEACTIVATING) { |
| 808 | /* time to take action on any delayed IPI flags */ | 802 | /* time to take action on any delayed IPI flags */ |
| @@ -1092,12 +1086,12 @@ xpc_connect_channel(struct xpc_channel *ch) | |||
| 1092 | struct xpc_registration *registration = &xpc_registrations[ch->number]; | 1086 | struct xpc_registration *registration = &xpc_registrations[ch->number]; |
| 1093 | 1087 | ||
| 1094 | 1088 | ||
| 1095 | if (down_trylock(®istration->sema) != 0) { | 1089 | if (mutex_trylock(®istration->mutex) == 0) { |
| 1096 | return xpcRetry; | 1090 | return xpcRetry; |
| 1097 | } | 1091 | } |
| 1098 | 1092 | ||
| 1099 | if (!XPC_CHANNEL_REGISTERED(ch->number)) { | 1093 | if (!XPC_CHANNEL_REGISTERED(ch->number)) { |
| 1100 | up(®istration->sema); | 1094 | mutex_unlock(®istration->mutex); |
| 1101 | return xpcUnregistered; | 1095 | return xpcUnregistered; |
| 1102 | } | 1096 | } |
| 1103 | 1097 | ||
| @@ -1108,7 +1102,7 @@ xpc_connect_channel(struct xpc_channel *ch) | |||
| 1108 | 1102 | ||
| 1109 | if (ch->flags & XPC_C_DISCONNECTING) { | 1103 | if (ch->flags & XPC_C_DISCONNECTING) { |
| 1110 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 1104 | spin_unlock_irqrestore(&ch->lock, irq_flags); |
| 1111 | up(®istration->sema); | 1105 | mutex_unlock(®istration->mutex); |
| 1112 | return ch->reason; | 1106 | return ch->reason; |
| 1113 | } | 1107 | } |
| 1114 | 1108 | ||
| @@ -1140,7 +1134,7 @@ xpc_connect_channel(struct xpc_channel *ch) | |||
| 1140 | * channel lock be locked and will unlock and relock | 1134 | * channel lock be locked and will unlock and relock |
| 1141 | * the channel lock as needed. | 1135 | * the channel lock as needed. |
| 1142 | */ | 1136 | */ |
| 1143 | up(®istration->sema); | 1137 | mutex_unlock(®istration->mutex); |
| 1144 | XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes, | 1138 | XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes, |
| 1145 | &irq_flags); | 1139 | &irq_flags); |
| 1146 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 1140 | spin_unlock_irqrestore(&ch->lock, irq_flags); |
| @@ -1155,7 +1149,7 @@ xpc_connect_channel(struct xpc_channel *ch) | |||
| 1155 | atomic_inc(&xpc_partitions[ch->partid].nchannels_active); | 1149 | atomic_inc(&xpc_partitions[ch->partid].nchannels_active); |
| 1156 | } | 1150 | } |
| 1157 | 1151 | ||
| 1158 | up(®istration->sema); | 1152 | mutex_unlock(®istration->mutex); |
| 1159 | 1153 | ||
| 1160 | 1154 | ||
| 1161 | /* initiate the connection */ | 1155 | /* initiate the connection */ |
| @@ -2089,7 +2083,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get) | |||
| 2089 | enum xpc_retval ret; | 2083 | enum xpc_retval ret; |
| 2090 | 2084 | ||
| 2091 | 2085 | ||
| 2092 | if (down_interruptible(&ch->msg_to_pull_sema) != 0) { | 2086 | if (mutex_lock_interruptible(&ch->msg_to_pull_mutex) != 0) { |
| 2093 | /* we were interrupted by a signal */ | 2087 | /* we were interrupted by a signal */ |
| 2094 | return NULL; | 2088 | return NULL; |
| 2095 | } | 2089 | } |
| @@ -2125,7 +2119,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get) | |||
| 2125 | 2119 | ||
| 2126 | XPC_DEACTIVATE_PARTITION(part, ret); | 2120 | XPC_DEACTIVATE_PARTITION(part, ret); |
| 2127 | 2121 | ||
| 2128 | up(&ch->msg_to_pull_sema); | 2122 | mutex_unlock(&ch->msg_to_pull_mutex); |
| 2129 | return NULL; | 2123 | return NULL; |
| 2130 | } | 2124 | } |
| 2131 | 2125 | ||
| @@ -2134,7 +2128,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get) | |||
| 2134 | ch->next_msg_to_pull += nmsgs; | 2128 | ch->next_msg_to_pull += nmsgs; |
| 2135 | } | 2129 | } |
| 2136 | 2130 | ||
| 2137 | up(&ch->msg_to_pull_sema); | 2131 | mutex_unlock(&ch->msg_to_pull_mutex); |
| 2138 | 2132 | ||
| 2139 | /* return the message we were looking for */ | 2133 | /* return the message we were looking for */ |
| 2140 | msg_offset = (get % ch->remote_nentries) * ch->msg_size; | 2134 | msg_offset = (get % ch->remote_nentries) * ch->msg_size; |
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c index 8930586e0eb4..c75f8aeefc2b 100644 --- a/arch/ia64/sn/kernel/xpc_main.c +++ b/arch/ia64/sn/kernel/xpc_main.c | |||
| @@ -55,6 +55,7 @@ | |||
| 55 | #include <linux/slab.h> | 55 | #include <linux/slab.h> |
| 56 | #include <linux/delay.h> | 56 | #include <linux/delay.h> |
| 57 | #include <linux/reboot.h> | 57 | #include <linux/reboot.h> |
| 58 | #include <linux/completion.h> | ||
| 58 | #include <asm/sn/intr.h> | 59 | #include <asm/sn/intr.h> |
| 59 | #include <asm/sn/sn_sal.h> | 60 | #include <asm/sn/sn_sal.h> |
| 60 | #include <asm/kdebug.h> | 61 | #include <asm/kdebug.h> |
| @@ -177,10 +178,10 @@ static DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq); | |||
| 177 | static unsigned long xpc_hb_check_timeout; | 178 | static unsigned long xpc_hb_check_timeout; |
| 178 | 179 | ||
| 179 | /* notification that the xpc_hb_checker thread has exited */ | 180 | /* notification that the xpc_hb_checker thread has exited */ |
| 180 | static DECLARE_MUTEX_LOCKED(xpc_hb_checker_exited); | 181 | static DECLARE_COMPLETION(xpc_hb_checker_exited); |
| 181 | 182 | ||
| 182 | /* notification that the xpc_discovery thread has exited */ | 183 | /* notification that the xpc_discovery thread has exited */ |
| 183 | static DECLARE_MUTEX_LOCKED(xpc_discovery_exited); | 184 | static DECLARE_COMPLETION(xpc_discovery_exited); |
| 184 | 185 | ||
| 185 | 186 | ||
| 186 | static struct timer_list xpc_hb_timer; | 187 | static struct timer_list xpc_hb_timer; |
| @@ -321,7 +322,7 @@ xpc_hb_checker(void *ignore) | |||
| 321 | 322 | ||
| 322 | 323 | ||
| 323 | /* mark this thread as having exited */ | 324 | /* mark this thread as having exited */ |
| 324 | up(&xpc_hb_checker_exited); | 325 | complete(&xpc_hb_checker_exited); |
| 325 | return 0; | 326 | return 0; |
| 326 | } | 327 | } |
| 327 | 328 | ||
| @@ -341,7 +342,7 @@ xpc_initiate_discovery(void *ignore) | |||
| 341 | dev_dbg(xpc_part, "discovery thread is exiting\n"); | 342 | dev_dbg(xpc_part, "discovery thread is exiting\n"); |
| 342 | 343 | ||
| 343 | /* mark this thread as having exited */ | 344 | /* mark this thread as having exited */ |
| 344 | up(&xpc_discovery_exited); | 345 | complete(&xpc_discovery_exited); |
| 345 | return 0; | 346 | return 0; |
| 346 | } | 347 | } |
| 347 | 348 | ||
| @@ -893,7 +894,7 @@ xpc_disconnect_wait(int ch_number) | |||
| 893 | continue; | 894 | continue; |
| 894 | } | 895 | } |
| 895 | 896 | ||
| 896 | (void) down(&ch->wdisconnect_sema); | 897 | wait_for_completion(&ch->wdisconnect_wait); |
| 897 | 898 | ||
| 898 | spin_lock_irqsave(&ch->lock, irq_flags); | 899 | spin_lock_irqsave(&ch->lock, irq_flags); |
| 899 | DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED)); | 900 | DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED)); |
| @@ -946,10 +947,10 @@ xpc_do_exit(enum xpc_retval reason) | |||
| 946 | free_irq(SGI_XPC_ACTIVATE, NULL); | 947 | free_irq(SGI_XPC_ACTIVATE, NULL); |
| 947 | 948 | ||
| 948 | /* wait for the discovery thread to exit */ | 949 | /* wait for the discovery thread to exit */ |
| 949 | down(&xpc_discovery_exited); | 950 | wait_for_completion(&xpc_discovery_exited); |
| 950 | 951 | ||
| 951 | /* wait for the heartbeat checker thread to exit */ | 952 | /* wait for the heartbeat checker thread to exit */ |
| 952 | down(&xpc_hb_checker_exited); | 953 | wait_for_completion(&xpc_hb_checker_exited); |
| 953 | 954 | ||
| 954 | 955 | ||
| 955 | /* sleep for a 1/3 of a second or so */ | 956 | /* sleep for a 1/3 of a second or so */ |
| @@ -1367,7 +1368,7 @@ xpc_init(void) | |||
| 1367 | dev_err(xpc_part, "failed while forking discovery thread\n"); | 1368 | dev_err(xpc_part, "failed while forking discovery thread\n"); |
| 1368 | 1369 | ||
| 1369 | /* mark this new thread as a non-starter */ | 1370 | /* mark this new thread as a non-starter */ |
| 1370 | up(&xpc_discovery_exited); | 1371 | complete(&xpc_discovery_exited); |
| 1371 | 1372 | ||
| 1372 | xpc_do_exit(xpcUnloading); | 1373 | xpc_do_exit(xpcUnloading); |
| 1373 | return -EBUSY; | 1374 | return -EBUSY; |
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 77a1262751d3..2fac27049bf6 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c | |||
| @@ -24,13 +24,15 @@ sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp) | |||
| 24 | { | 24 | { |
| 25 | struct ia64_sal_retval ret_stuff; | 25 | struct ia64_sal_retval ret_stuff; |
| 26 | u64 busnum; | 26 | u64 busnum; |
| 27 | u64 segment; | ||
| 27 | 28 | ||
| 28 | ret_stuff.status = 0; | 29 | ret_stuff.status = 0; |
| 29 | ret_stuff.v0 = 0; | 30 | ret_stuff.v0 = 0; |
| 30 | 31 | ||
| 32 | segment = soft->pbi_buscommon.bs_persist_segment; | ||
| 31 | busnum = soft->pbi_buscommon.bs_persist_busnum; | 33 | busnum = soft->pbi_buscommon.bs_persist_busnum; |
| 32 | SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, (u64) busnum, | 34 | SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, segment, |
| 33 | (u64) device, (u64) resp, 0, 0, 0, 0); | 35 | busnum, (u64) device, (u64) resp, 0, 0, 0); |
| 34 | 36 | ||
| 35 | return (int)ret_stuff.v0; | 37 | return (int)ret_stuff.v0; |
| 36 | } | 38 | } |
| @@ -41,14 +43,16 @@ sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action, | |||
| 41 | { | 43 | { |
| 42 | struct ia64_sal_retval ret_stuff; | 44 | struct ia64_sal_retval ret_stuff; |
| 43 | u64 busnum; | 45 | u64 busnum; |
| 46 | u64 segment; | ||
| 44 | 47 | ||
| 45 | ret_stuff.status = 0; | 48 | ret_stuff.status = 0; |
| 46 | ret_stuff.v0 = 0; | 49 | ret_stuff.v0 = 0; |
| 47 | 50 | ||
| 51 | segment = soft->pbi_buscommon.bs_persist_segment; | ||
| 48 | busnum = soft->pbi_buscommon.bs_persist_busnum; | 52 | busnum = soft->pbi_buscommon.bs_persist_busnum; |
| 49 | SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_DISABLE, | 53 | SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_DISABLE, |
| 50 | (u64) busnum, (u64) device, (u64) action, | 54 | segment, busnum, (u64) device, (u64) action, |
| 51 | (u64) resp, 0, 0, 0); | 55 | (u64) resp, 0, 0); |
| 52 | 56 | ||
| 53 | return (int)ret_stuff.v0; | 57 | return (int)ret_stuff.v0; |
| 54 | } | 58 | } |
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 03ecb4e4614e..c51d08d218ef 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S | |||
| @@ -1277,62 +1277,6 @@ sys_sigstack: | |||
| 1277 | mov %l5, %o7 | 1277 | mov %l5, %o7 |
| 1278 | 1278 | ||
| 1279 | .align 4 | 1279 | .align 4 |
| 1280 | .globl sys_sigpause | ||
| 1281 | sys_sigpause: | ||
| 1282 | /* Note: %o0 already has correct value... */ | ||
| 1283 | call do_sigpause | ||
| 1284 | add %sp, STACKFRAME_SZ, %o1 | ||
| 1285 | |||
| 1286 | ld [%curptr + TI_FLAGS], %l5 | ||
| 1287 | andcc %l5, _TIF_SYSCALL_TRACE, %g0 | ||
| 1288 | be 1f | ||
| 1289 | nop | ||
| 1290 | |||
| 1291 | call syscall_trace | ||
| 1292 | nop | ||
| 1293 | |||
| 1294 | 1: | ||
| 1295 | /* We are returning to a signal handler. */ | ||
| 1296 | RESTORE_ALL | ||
| 1297 | |||
| 1298 | .align 4 | ||
| 1299 | .globl sys_sigsuspend | ||
| 1300 | sys_sigsuspend: | ||
| 1301 | call do_sigsuspend | ||
| 1302 | add %sp, STACKFRAME_SZ, %o0 | ||
| 1303 | |||
| 1304 | ld [%curptr + TI_FLAGS], %l5 | ||
| 1305 | andcc %l5, _TIF_SYSCALL_TRACE, %g0 | ||
| 1306 | be 1f | ||
| 1307 | nop | ||
| 1308 | |||
| 1309 | call syscall_trace | ||
| 1310 | nop | ||
| 1311 | |||
| 1312 | 1: | ||
| 1313 | /* We are returning to a signal handler. */ | ||
| 1314 | RESTORE_ALL | ||
| 1315 | |||
| 1316 | .align 4 | ||
| 1317 | .globl sys_rt_sigsuspend | ||
| 1318 | sys_rt_sigsuspend: | ||
| 1319 | /* Note: %o0, %o1 already have correct value... */ | ||
| 1320 | call do_rt_sigsuspend | ||
| 1321 | add %sp, STACKFRAME_SZ, %o2 | ||
| 1322 | |||
| 1323 | ld [%curptr + TI_FLAGS], %l5 | ||
| 1324 | andcc %l5, _TIF_SYSCALL_TRACE, %g0 | ||
| 1325 | be 1f | ||
| 1326 | nop | ||
| 1327 | |||
| 1328 | call syscall_trace | ||
| 1329 | nop | ||
| 1330 | |||
| 1331 | 1: | ||
| 1332 | /* We are returning to a signal handler. */ | ||
| 1333 | RESTORE_ALL | ||
| 1334 | |||
| 1335 | .align 4 | ||
| 1336 | .globl sys_sigreturn | 1280 | .globl sys_sigreturn |
| 1337 | sys_sigreturn: | 1281 | sys_sigreturn: |
| 1338 | call do_sigreturn | 1282 | call do_sigreturn |
diff --git a/arch/sparc/kernel/rtrap.S b/arch/sparc/kernel/rtrap.S index f7460d897e79..77ca6fd81253 100644 --- a/arch/sparc/kernel/rtrap.S +++ b/arch/sparc/kernel/rtrap.S | |||
| @@ -68,15 +68,14 @@ ret_trap_lockless_ipi: | |||
| 68 | 68 | ||
| 69 | ld [%curptr + TI_FLAGS], %g2 | 69 | ld [%curptr + TI_FLAGS], %g2 |
| 70 | signal_p: | 70 | signal_p: |
| 71 | andcc %g2, (_TIF_NOTIFY_RESUME|_TIF_SIGPENDING), %g0 | 71 | andcc %g2, (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %g0 |
| 72 | bz,a ret_trap_continue | 72 | bz,a ret_trap_continue |
| 73 | ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr | 73 | ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr |
| 74 | 74 | ||
| 75 | clr %o0 | 75 | mov %l5, %o1 |
| 76 | mov %l5, %o2 | 76 | mov %l6, %o2 |
| 77 | mov %l6, %o3 | ||
| 78 | call do_signal | 77 | call do_signal |
| 79 | add %sp, STACKFRAME_SZ, %o1 ! pt_regs ptr | 78 | add %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr |
| 80 | 79 | ||
| 81 | /* Fall through. */ | 80 | /* Fall through. */ |
| 82 | ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr | 81 | ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr |
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c index 5f34d7dc2b89..0748d8147bbf 100644 --- a/arch/sparc/kernel/signal.c +++ b/arch/sparc/kernel/signal.c | |||
| @@ -35,9 +35,6 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr, | |||
| 35 | void *fpqueue, unsigned long *fpqdepth); | 35 | void *fpqueue, unsigned long *fpqdepth); |
| 36 | extern void fpload(unsigned long *fpregs, unsigned long *fsr); | 36 | extern void fpload(unsigned long *fpregs, unsigned long *fsr); |
| 37 | 37 | ||
| 38 | asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, | ||
| 39 | unsigned long orig_o0, int restart_syscall); | ||
| 40 | |||
| 41 | /* Signal frames: the original one (compatible with SunOS): | 38 | /* Signal frames: the original one (compatible with SunOS): |
| 42 | * | 39 | * |
| 43 | * Set up a signal frame... Make the stack look the way SunOS | 40 | * Set up a signal frame... Make the stack look the way SunOS |
| @@ -95,98 +92,30 @@ struct rt_signal_frame { | |||
| 95 | #define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame) + 7) & (~7))) | 92 | #define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame) + 7) & (~7))) |
| 96 | #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7))) | 93 | #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7))) |
| 97 | 94 | ||
| 98 | /* | 95 | static int _sigpause_common(old_sigset_t set) |
| 99 | * atomically swap in the new signal mask, and wait for a signal. | ||
| 100 | * This is really tricky on the Sparc, watch out... | ||
| 101 | */ | ||
| 102 | asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs) | ||
| 103 | { | 96 | { |
| 104 | sigset_t saveset; | ||
| 105 | |||
| 106 | set &= _BLOCKABLE; | 97 | set &= _BLOCKABLE; |
| 107 | spin_lock_irq(¤t->sighand->siglock); | 98 | spin_lock_irq(¤t->sighand->siglock); |
| 108 | saveset = current->blocked; | 99 | current->saved_sigmask = current->blocked; |
| 109 | siginitset(¤t->blocked, set); | 100 | siginitset(¤t->blocked, set); |
| 110 | recalc_sigpending(); | 101 | recalc_sigpending(); |
| 111 | spin_unlock_irq(¤t->sighand->siglock); | 102 | spin_unlock_irq(¤t->sighand->siglock); |
| 112 | 103 | ||
| 113 | regs->pc = regs->npc; | 104 | current->state = TASK_INTERRUPTIBLE; |
| 114 | regs->npc += 4; | 105 | schedule(); |
| 115 | 106 | set_thread_flag(TIF_RESTORE_SIGMASK); | |
| 116 | /* Condition codes and return value where set here for sigpause, | ||
| 117 | * and so got used by setup_frame, which again causes sigreturn() | ||
| 118 | * to return -EINTR. | ||
| 119 | */ | ||
| 120 | while (1) { | ||
| 121 | current->state = TASK_INTERRUPTIBLE; | ||
| 122 | schedule(); | ||
| 123 | /* | ||
| 124 | * Return -EINTR and set condition code here, | ||
| 125 | * so the interrupted system call actually returns | ||
| 126 | * these. | ||
| 127 | */ | ||
| 128 | regs->psr |= PSR_C; | ||
| 129 | regs->u_regs[UREG_I0] = EINTR; | ||
| 130 | if (do_signal(&saveset, regs, 0, 0)) | ||
| 131 | return; | ||
| 132 | } | ||
| 133 | } | ||
| 134 | 107 | ||
| 135 | asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs) | 108 | return -ERESTARTNOHAND; |
| 136 | { | ||
| 137 | _sigpause_common(set, regs); | ||
| 138 | } | 109 | } |
| 139 | 110 | ||
| 140 | asmlinkage void do_sigsuspend (struct pt_regs *regs) | 111 | asmlinkage int sys_sigpause(unsigned int set) |
| 141 | { | 112 | { |
| 142 | _sigpause_common(regs->u_regs[UREG_I0], regs); | 113 | return _sigpause_common(set); |
| 143 | } | 114 | } |
| 144 | 115 | ||
| 145 | asmlinkage void do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, | 116 | asmlinkage int sys_sigsuspend(old_sigset_t set) |
| 146 | struct pt_regs *regs) | ||
| 147 | { | 117 | { |
| 148 | sigset_t oldset, set; | 118 | return _sigpause_common(set); |
| 149 | |||
| 150 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
| 151 | if (sigsetsize != sizeof(sigset_t)) { | ||
| 152 | regs->psr |= PSR_C; | ||
| 153 | regs->u_regs[UREG_I0] = EINVAL; | ||
| 154 | return; | ||
| 155 | } | ||
| 156 | |||
| 157 | if (copy_from_user(&set, uset, sizeof(set))) { | ||
| 158 | regs->psr |= PSR_C; | ||
| 159 | regs->u_regs[UREG_I0] = EFAULT; | ||
| 160 | return; | ||
| 161 | } | ||
| 162 | |||
| 163 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
| 164 | spin_lock_irq(¤t->sighand->siglock); | ||
| 165 | oldset = current->blocked; | ||
| 166 | current->blocked = set; | ||
| 167 | recalc_sigpending(); | ||
| 168 | spin_unlock_irq(¤t->sighand->siglock); | ||
| 169 | |||
| 170 | regs->pc = regs->npc; | ||
| 171 | regs->npc += 4; | ||
| 172 | |||
| 173 | /* Condition codes and return value where set here for sigpause, | ||
| 174 | * and so got used by setup_frame, which again causes sigreturn() | ||
| 175 | * to return -EINTR. | ||
| 176 | */ | ||
| 177 | while (1) { | ||
| 178 | current->state = TASK_INTERRUPTIBLE; | ||
| 179 | schedule(); | ||
| 180 | /* | ||
| 181 | * Return -EINTR and set condition code here, | ||
| 182 | * so the interrupted system call actually returns | ||
| 183 | * these. | ||
| 184 | */ | ||
| 185 | regs->psr |= PSR_C; | ||
| 186 | regs->u_regs[UREG_I0] = EINTR; | ||
| 187 | if (do_signal(&oldset, regs, 0, 0)) | ||
| 188 | return; | ||
| 189 | } | ||
| 190 | } | 119 | } |
| 191 | 120 | ||
| 192 | static inline int | 121 | static inline int |
| @@ -1067,13 +996,13 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | |||
| 1067 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | 996 | * want to handle. Thus you cannot kill init even with a SIGKILL even by |
| 1068 | * mistake. | 997 | * mistake. |
| 1069 | */ | 998 | */ |
| 1070 | asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, | 999 | asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int restart_syscall) |
| 1071 | unsigned long orig_i0, int restart_syscall) | ||
| 1072 | { | 1000 | { |
| 1073 | siginfo_t info; | 1001 | siginfo_t info; |
| 1074 | struct sparc_deliver_cookie cookie; | 1002 | struct sparc_deliver_cookie cookie; |
| 1075 | struct k_sigaction ka; | 1003 | struct k_sigaction ka; |
| 1076 | int signr; | 1004 | int signr; |
| 1005 | sigset_t *oldset; | ||
| 1077 | 1006 | ||
| 1078 | /* | 1007 | /* |
| 1079 | * XXX Disable svr4 signal handling until solaris emulation works. | 1008 | * XXX Disable svr4 signal handling until solaris emulation works. |
| @@ -1089,7 +1018,9 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, | |||
| 1089 | cookie.restart_syscall = restart_syscall; | 1018 | cookie.restart_syscall = restart_syscall; |
| 1090 | cookie.orig_i0 = orig_i0; | 1019 | cookie.orig_i0 = orig_i0; |
| 1091 | 1020 | ||
| 1092 | if (!oldset) | 1021 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
| 1022 | oldset = ¤t->saved_sigmask; | ||
| 1023 | else | ||
| 1093 | oldset = ¤t->blocked; | 1024 | oldset = ¤t->blocked; |
| 1094 | 1025 | ||
| 1095 | signr = get_signal_to_deliver(&info, &ka, regs, &cookie); | 1026 | signr = get_signal_to_deliver(&info, &ka, regs, &cookie); |
| @@ -1098,7 +1029,14 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, | |||
| 1098 | syscall_restart(cookie.orig_i0, regs, &ka.sa); | 1029 | syscall_restart(cookie.orig_i0, regs, &ka.sa); |
| 1099 | handle_signal(signr, &ka, &info, oldset, | 1030 | handle_signal(signr, &ka, &info, oldset, |
| 1100 | regs, svr4_signal); | 1031 | regs, svr4_signal); |
| 1101 | return 1; | 1032 | /* a signal was successfully delivered; the saved |
| 1033 | * sigmask will have been stored in the signal frame, | ||
| 1034 | * and will be restored by sigreturn, so we can simply | ||
| 1035 | * clear the TIF_RESTORE_SIGMASK flag. | ||
| 1036 | */ | ||
| 1037 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
| 1038 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 1039 | return; | ||
| 1102 | } | 1040 | } |
| 1103 | if (cookie.restart_syscall && | 1041 | if (cookie.restart_syscall && |
| 1104 | (regs->u_regs[UREG_I0] == ERESTARTNOHAND || | 1042 | (regs->u_regs[UREG_I0] == ERESTARTNOHAND || |
| @@ -1115,7 +1053,14 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, | |||
| 1115 | regs->pc -= 4; | 1053 | regs->pc -= 4; |
| 1116 | regs->npc -= 4; | 1054 | regs->npc -= 4; |
| 1117 | } | 1055 | } |
| 1118 | return 0; | 1056 | |
| 1057 | /* if there's no signal to deliver, we just put the saved sigmask | ||
| 1058 | * back | ||
| 1059 | */ | ||
| 1060 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | ||
| 1061 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 1062 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
| 1063 | } | ||
| 1119 | } | 1064 | } |
| 1120 | 1065 | ||
| 1121 | asmlinkage int | 1066 | asmlinkage int |
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 0b0d492c953b..19b25399d7e4 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c | |||
| @@ -66,7 +66,6 @@ struct poll { | |||
| 66 | 66 | ||
| 67 | extern int svr4_getcontext (svr4_ucontext_t *, struct pt_regs *); | 67 | extern int svr4_getcontext (svr4_ucontext_t *, struct pt_regs *); |
| 68 | extern int svr4_setcontext (svr4_ucontext_t *, struct pt_regs *); | 68 | extern int svr4_setcontext (svr4_ucontext_t *, struct pt_regs *); |
| 69 | void _sigpause_common (unsigned int set, struct pt_regs *); | ||
| 70 | extern void (*__copy_1page)(void *, const void *); | 69 | extern void (*__copy_1page)(void *, const void *); |
| 71 | extern void __memmove(void *, const void *, __kernel_size_t); | 70 | extern void __memmove(void *, const void *, __kernel_size_t); |
| 72 | extern void (*bzero_1page)(void *); | 71 | extern void (*bzero_1page)(void *); |
| @@ -227,7 +226,6 @@ EXPORT_SYMBOL(kunmap_atomic); | |||
| 227 | /* Solaris/SunOS binary compatibility */ | 226 | /* Solaris/SunOS binary compatibility */ |
| 228 | EXPORT_SYMBOL(svr4_setcontext); | 227 | EXPORT_SYMBOL(svr4_setcontext); |
| 229 | EXPORT_SYMBOL(svr4_getcontext); | 228 | EXPORT_SYMBOL(svr4_getcontext); |
| 230 | EXPORT_SYMBOL(_sigpause_common); | ||
| 231 | 229 | ||
| 232 | EXPORT_SYMBOL(dump_thread); | 230 | EXPORT_SYMBOL(dump_thread); |
| 233 | 231 | ||
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index e457a40838fc..6877ae4cd1d9 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S | |||
| @@ -75,7 +75,10 @@ sys_call_table: | |||
| 75 | /*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy | 75 | /*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy |
| 76 | /*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink | 76 | /*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink |
| 77 | /*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid | 77 | /*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid |
| 78 | /*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl | 78 | /*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat |
| 79 | /*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_newfstatat | ||
| 80 | /*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat | ||
| 81 | /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll | ||
| 79 | 82 | ||
| 80 | #ifdef CONFIG_SUNOS_EMUL | 83 | #ifdef CONFIG_SUNOS_EMUL |
| 81 | /* Now the SunOS syscall table. */ | 84 | /* Now the SunOS syscall table. */ |
| @@ -181,6 +184,11 @@ sunos_sys_table: | |||
| 181 | .long sunos_nosys, sunos_nosys, sunos_nosys | 184 | .long sunos_nosys, sunos_nosys, sunos_nosys |
| 182 | .long sunos_nosys | 185 | .long sunos_nosys |
| 183 | /*280*/ .long sunos_nosys, sunos_nosys, sunos_nosys | 186 | /*280*/ .long sunos_nosys, sunos_nosys, sunos_nosys |
| 187 | .long sunos_nosys, sunos_nosys, sunos_nosys | ||
| 188 | .long sunos_nosys, sunos_nosys, sunos_nosys | ||
| 184 | .long sunos_nosys | 189 | .long sunos_nosys |
| 190 | /*290*/ .long sunos_nosys, sunos_nosys, sunos_nosys | ||
| 191 | .long sunos_nosys, sunos_nosys, sunos_nosys | ||
| 192 | .long sunos_nosys, sunos_nosys, sunos_nosys | ||
| 185 | 193 | ||
| 186 | #endif | 194 | #endif |
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 710002991888..e50e56e4ab61 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S | |||
| @@ -1416,7 +1416,6 @@ execve_merge: | |||
| 1416 | add %sp, PTREGS_OFF, %o0 | 1416 | add %sp, PTREGS_OFF, %o0 |
| 1417 | 1417 | ||
| 1418 | .globl sys_pipe, sys_sigpause, sys_nis_syscall | 1418 | .globl sys_pipe, sys_sigpause, sys_nis_syscall |
| 1419 | .globl sys_sigsuspend, sys_rt_sigsuspend | ||
| 1420 | .globl sys_rt_sigreturn | 1419 | .globl sys_rt_sigreturn |
| 1421 | .globl sys_ptrace | 1420 | .globl sys_ptrace |
| 1422 | .globl sys_sigaltstack | 1421 | .globl sys_sigaltstack |
| @@ -1440,28 +1439,6 @@ sys32_sigaltstack: | |||
| 1440 | mov %i6, %o2 | 1439 | mov %i6, %o2 |
| 1441 | #endif | 1440 | #endif |
| 1442 | .align 32 | 1441 | .align 32 |
| 1443 | sys_sigsuspend: add %sp, PTREGS_OFF, %o0 | ||
| 1444 | call do_sigsuspend | ||
| 1445 | add %o7, 1f-.-4, %o7 | ||
| 1446 | nop | ||
| 1447 | sys_rt_sigsuspend: /* NOTE: %o0,%o1 have a correct value already */ | ||
| 1448 | add %sp, PTREGS_OFF, %o2 | ||
| 1449 | call do_rt_sigsuspend | ||
| 1450 | add %o7, 1f-.-4, %o7 | ||
| 1451 | nop | ||
| 1452 | #ifdef CONFIG_COMPAT | ||
| 1453 | .globl sys32_rt_sigsuspend | ||
| 1454 | sys32_rt_sigsuspend: /* NOTE: %o0,%o1 have a correct value already */ | ||
| 1455 | srl %o0, 0, %o0 | ||
| 1456 | add %sp, PTREGS_OFF, %o2 | ||
| 1457 | call do_rt_sigsuspend32 | ||
| 1458 | add %o7, 1f-.-4, %o7 | ||
| 1459 | #endif | ||
| 1460 | /* NOTE: %o0 has a correct value already */ | ||
| 1461 | sys_sigpause: add %sp, PTREGS_OFF, %o1 | ||
| 1462 | call do_sigpause | ||
| 1463 | add %o7, 1f-.-4, %o7 | ||
| 1464 | nop | ||
| 1465 | #ifdef CONFIG_COMPAT | 1442 | #ifdef CONFIG_COMPAT |
| 1466 | .globl sys32_sigreturn | 1443 | .globl sys32_sigreturn |
| 1467 | sys32_sigreturn: | 1444 | sys32_sigreturn: |
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index 090dcca00d2a..b80eba0081ca 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S | |||
| @@ -53,14 +53,13 @@ __handle_user_windows: | |||
| 53 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | 53 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate |
| 54 | ldx [%g6 + TI_FLAGS], %l0 | 54 | ldx [%g6 + TI_FLAGS], %l0 |
| 55 | 55 | ||
| 56 | 1: andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0 | 56 | 1: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 |
| 57 | be,pt %xcc, __handle_user_windows_continue | 57 | be,pt %xcc, __handle_user_windows_continue |
| 58 | nop | 58 | nop |
| 59 | clr %o0 | 59 | mov %l5, %o1 |
| 60 | mov %l5, %o2 | 60 | mov %l6, %o2 |
| 61 | mov %l6, %o3 | 61 | add %sp, PTREGS_OFF, %o0 |
| 62 | add %sp, PTREGS_OFF, %o1 | 62 | mov %l0, %o3 |
| 63 | mov %l0, %o4 | ||
| 64 | 63 | ||
| 65 | call do_notify_resume | 64 | call do_notify_resume |
| 66 | wrpr %g0, RTRAP_PSTATE, %pstate | 65 | wrpr %g0, RTRAP_PSTATE, %pstate |
| @@ -96,15 +95,14 @@ __handle_perfctrs: | |||
| 96 | wrpr %g0, RTRAP_PSTATE, %pstate | 95 | wrpr %g0, RTRAP_PSTATE, %pstate |
| 97 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | 96 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate |
| 98 | ldx [%g6 + TI_FLAGS], %l0 | 97 | ldx [%g6 + TI_FLAGS], %l0 |
| 99 | 1: andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0 | 98 | 1: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 |
| 100 | 99 | ||
| 101 | be,pt %xcc, __handle_perfctrs_continue | 100 | be,pt %xcc, __handle_perfctrs_continue |
| 102 | sethi %hi(TSTATE_PEF), %o0 | 101 | sethi %hi(TSTATE_PEF), %o0 |
| 103 | clr %o0 | 102 | mov %l5, %o1 |
| 104 | mov %l5, %o2 | 103 | mov %l6, %o2 |
| 105 | mov %l6, %o3 | 104 | add %sp, PTREGS_OFF, %o0 |
| 106 | add %sp, PTREGS_OFF, %o1 | 105 | mov %l0, %o3 |
| 107 | mov %l0, %o4 | ||
| 108 | call do_notify_resume | 106 | call do_notify_resume |
| 109 | 107 | ||
| 110 | wrpr %g0, RTRAP_PSTATE, %pstate | 108 | wrpr %g0, RTRAP_PSTATE, %pstate |
| @@ -129,11 +127,10 @@ __handle_userfpu: | |||
| 129 | ba,a,pt %xcc, __handle_userfpu_continue | 127 | ba,a,pt %xcc, __handle_userfpu_continue |
| 130 | 128 | ||
| 131 | __handle_signal: | 129 | __handle_signal: |
| 132 | clr %o0 | 130 | mov %l5, %o1 |
| 133 | mov %l5, %o2 | 131 | mov %l6, %o2 |
| 134 | mov %l6, %o3 | 132 | add %sp, PTREGS_OFF, %o0 |
| 135 | add %sp, PTREGS_OFF, %o1 | 133 | mov %l0, %o3 |
| 136 | mov %l0, %o4 | ||
| 137 | call do_notify_resume | 134 | call do_notify_resume |
| 138 | wrpr %g0, RTRAP_PSTATE, %pstate | 135 | wrpr %g0, RTRAP_PSTATE, %pstate |
| 139 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | 136 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate |
| @@ -200,7 +197,7 @@ __handle_preemption_continue: | |||
| 200 | andcc %l1, %o0, %g0 | 197 | andcc %l1, %o0, %g0 |
| 201 | andcc %l0, _TIF_NEED_RESCHED, %g0 | 198 | andcc %l0, _TIF_NEED_RESCHED, %g0 |
| 202 | bne,pn %xcc, __handle_preemption | 199 | bne,pn %xcc, __handle_preemption |
| 203 | andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0 | 200 | andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 |
| 204 | bne,pn %xcc, __handle_signal | 201 | bne,pn %xcc, __handle_signal |
| 205 | __handle_signal_continue: | 202 | __handle_signal_continue: |
| 206 | ldub [%g6 + TI_WSAVED], %o2 | 203 | ldub [%g6 + TI_WSAVED], %o2 |
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index 60f5dfabb1e1..ca11a4c457d4 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c | |||
| @@ -36,9 +36,6 @@ | |||
| 36 | 36 | ||
| 37 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 37 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
| 38 | 38 | ||
| 39 | static int do_signal(sigset_t *oldset, struct pt_regs * regs, | ||
| 40 | unsigned long orig_o0, int ret_from_syscall); | ||
| 41 | |||
| 42 | /* {set, get}context() needed for 64-bit SparcLinux userland. */ | 39 | /* {set, get}context() needed for 64-bit SparcLinux userland. */ |
| 43 | asmlinkage void sparc64_set_context(struct pt_regs *regs) | 40 | asmlinkage void sparc64_set_context(struct pt_regs *regs) |
| 44 | { | 41 | { |
| @@ -242,114 +239,29 @@ struct rt_signal_frame { | |||
| 242 | /* Align macros */ | 239 | /* Align macros */ |
| 243 | #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7))) | 240 | #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7))) |
| 244 | 241 | ||
| 245 | /* | 242 | static long _sigpause_common(old_sigset_t set) |
| 246 | * atomically swap in the new signal mask, and wait for a signal. | ||
| 247 | * This is really tricky on the Sparc, watch out... | ||
| 248 | */ | ||
| 249 | asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs) | ||
| 250 | { | 243 | { |
| 251 | sigset_t saveset; | ||
| 252 | |||
| 253 | #ifdef CONFIG_SPARC32_COMPAT | ||
| 254 | if (test_thread_flag(TIF_32BIT)) { | ||
| 255 | extern asmlinkage void _sigpause32_common(compat_old_sigset_t, | ||
| 256 | struct pt_regs *); | ||
| 257 | _sigpause32_common(set, regs); | ||
| 258 | return; | ||
| 259 | } | ||
| 260 | #endif | ||
| 261 | set &= _BLOCKABLE; | 244 | set &= _BLOCKABLE; |
| 262 | spin_lock_irq(¤t->sighand->siglock); | 245 | spin_lock_irq(¤t->sighand->siglock); |
| 263 | saveset = current->blocked; | 246 | current->saved_sigmask = current->blocked; |
| 264 | siginitset(¤t->blocked, set); | 247 | siginitset(¤t->blocked, set); |
| 265 | recalc_sigpending(); | 248 | recalc_sigpending(); |
| 266 | spin_unlock_irq(¤t->sighand->siglock); | 249 | spin_unlock_irq(¤t->sighand->siglock); |
| 267 | |||
| 268 | if (test_thread_flag(TIF_32BIT)) { | ||
| 269 | regs->tpc = (regs->tnpc & 0xffffffff); | ||
| 270 | regs->tnpc = (regs->tnpc + 4) & 0xffffffff; | ||
| 271 | } else { | ||
| 272 | regs->tpc = regs->tnpc; | ||
| 273 | regs->tnpc += 4; | ||
| 274 | } | ||
| 275 | 250 | ||
| 276 | /* Condition codes and return value where set here for sigpause, | 251 | current->state = TASK_INTERRUPTIBLE; |
| 277 | * and so got used by setup_frame, which again causes sigreturn() | 252 | schedule(); |
| 278 | * to return -EINTR. | 253 | set_thread_flag(TIF_RESTORE_SIGMASK); |
| 279 | */ | 254 | return -ERESTARTNOHAND; |
| 280 | while (1) { | ||
| 281 | current->state = TASK_INTERRUPTIBLE; | ||
| 282 | schedule(); | ||
| 283 | /* | ||
| 284 | * Return -EINTR and set condition code here, | ||
| 285 | * so the interrupted system call actually returns | ||
| 286 | * these. | ||
| 287 | */ | ||
| 288 | regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY); | ||
| 289 | regs->u_regs[UREG_I0] = EINTR; | ||
| 290 | if (do_signal(&saveset, regs, 0, 0)) | ||
| 291 | return; | ||
| 292 | } | ||
| 293 | } | 255 | } |
| 294 | 256 | ||
| 295 | asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs) | 257 | asmlinkage long sys_sigpause(unsigned int set) |
| 296 | { | 258 | { |
| 297 | _sigpause_common(set, regs); | 259 | return _sigpause_common(set); |
| 298 | } | 260 | } |
| 299 | 261 | ||
| 300 | asmlinkage void do_sigsuspend(struct pt_regs *regs) | 262 | asmlinkage long sys_sigsuspend(old_sigset_t set) |
| 301 | { | 263 | { |
| 302 | _sigpause_common(regs->u_regs[UREG_I0], regs); | 264 | return _sigpause_common(set); |
| 303 | } | ||
| 304 | |||
| 305 | asmlinkage void do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, struct pt_regs *regs) | ||
| 306 | { | ||
| 307 | sigset_t oldset, set; | ||
| 308 | |||
| 309 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
| 310 | if (sigsetsize != sizeof(sigset_t)) { | ||
| 311 | regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY); | ||
| 312 | regs->u_regs[UREG_I0] = EINVAL; | ||
| 313 | return; | ||
| 314 | } | ||
| 315 | if (copy_from_user(&set, uset, sizeof(set))) { | ||
| 316 | regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY); | ||
| 317 | regs->u_regs[UREG_I0] = EFAULT; | ||
| 318 | return; | ||
| 319 | } | ||
| 320 | |||
| 321 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
| 322 | spin_lock_irq(¤t->sighand->siglock); | ||
| 323 | oldset = current->blocked; | ||
| 324 | current->blocked = set; | ||
| 325 | recalc_sigpending(); | ||
| 326 | spin_unlock_irq(¤t->sighand->siglock); | ||
| 327 | |||
| 328 | if (test_thread_flag(TIF_32BIT)) { | ||
| 329 | regs->tpc = (regs->tnpc & 0xffffffff); | ||
| 330 | regs->tnpc = (regs->tnpc + 4) & 0xffffffff; | ||
| 331 | } else { | ||
| 332 | regs->tpc = regs->tnpc; | ||
| 333 | regs->tnpc += 4; | ||
| 334 | } | ||
| 335 | |||
| 336 | /* Condition codes and return value where set here for sigpause, | ||
| 337 | * and so got used by setup_frame, which again causes sigreturn() | ||
| 338 | * to return -EINTR. | ||
| 339 | */ | ||
| 340 | while (1) { | ||
| 341 | current->state = TASK_INTERRUPTIBLE; | ||
| 342 | schedule(); | ||
| 343 | /* | ||
| 344 | * Return -EINTR and set condition code here, | ||
| 345 | * so the interrupted system call actually returns | ||
| 346 | * these. | ||
| 347 | */ | ||
| 348 | regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY); | ||
| 349 | regs->u_regs[UREG_I0] = EINTR; | ||
| 350 | if (do_signal(&oldset, regs, 0, 0)) | ||
| 351 | return; | ||
| 352 | } | ||
| 353 | } | 265 | } |
| 354 | 266 | ||
| 355 | static inline int | 267 | static inline int |
| @@ -607,26 +519,29 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | |||
| 607 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | 519 | * want to handle. Thus you cannot kill init even with a SIGKILL even by |
| 608 | * mistake. | 520 | * mistake. |
| 609 | */ | 521 | */ |
| 610 | static int do_signal(sigset_t *oldset, struct pt_regs * regs, | 522 | static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall) |
| 611 | unsigned long orig_i0, int restart_syscall) | ||
| 612 | { | 523 | { |
| 613 | siginfo_t info; | 524 | siginfo_t info; |
| 614 | struct signal_deliver_cookie cookie; | 525 | struct signal_deliver_cookie cookie; |
| 615 | struct k_sigaction ka; | 526 | struct k_sigaction ka; |
| 616 | int signr; | 527 | int signr; |
| 528 | sigset_t *oldset; | ||
| 617 | 529 | ||
| 618 | cookie.restart_syscall = restart_syscall; | 530 | cookie.restart_syscall = restart_syscall; |
| 619 | cookie.orig_i0 = orig_i0; | 531 | cookie.orig_i0 = orig_i0; |
| 620 | 532 | ||
| 621 | if (!oldset) | 533 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
| 534 | oldset = ¤t->saved_sigmask; | ||
| 535 | else | ||
| 622 | oldset = ¤t->blocked; | 536 | oldset = ¤t->blocked; |
| 623 | 537 | ||
| 624 | #ifdef CONFIG_SPARC32_COMPAT | 538 | #ifdef CONFIG_SPARC32_COMPAT |
| 625 | if (test_thread_flag(TIF_32BIT)) { | 539 | if (test_thread_flag(TIF_32BIT)) { |
| 626 | extern int do_signal32(sigset_t *, struct pt_regs *, | 540 | extern void do_signal32(sigset_t *, struct pt_regs *, |
| 627 | unsigned long, int); | 541 | unsigned long, int); |
| 628 | return do_signal32(oldset, regs, orig_i0, | 542 | do_signal32(oldset, regs, orig_i0, |
| 629 | cookie.restart_syscall); | 543 | cookie.restart_syscall); |
| 544 | return; | ||
| 630 | } | 545 | } |
| 631 | #endif | 546 | #endif |
| 632 | 547 | ||
| @@ -635,7 +550,15 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, | |||
| 635 | if (cookie.restart_syscall) | 550 | if (cookie.restart_syscall) |
| 636 | syscall_restart(orig_i0, regs, &ka.sa); | 551 | syscall_restart(orig_i0, regs, &ka.sa); |
| 637 | handle_signal(signr, &ka, &info, oldset, regs); | 552 | handle_signal(signr, &ka, &info, oldset, regs); |
| 638 | return 1; | 553 | |
| 554 | /* a signal was successfully delivered; the saved | ||
| 555 | * sigmask will have been stored in the signal frame, | ||
| 556 | * and will be restored by sigreturn, so we can simply | ||
| 557 | * clear the TIF_RESTORE_SIGMASK flag. | ||
| 558 | */ | ||
| 559 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
| 560 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 561 | return; | ||
| 639 | } | 562 | } |
| 640 | if (cookie.restart_syscall && | 563 | if (cookie.restart_syscall && |
| 641 | (regs->u_regs[UREG_I0] == ERESTARTNOHAND || | 564 | (regs->u_regs[UREG_I0] == ERESTARTNOHAND || |
| @@ -652,15 +575,21 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, | |||
| 652 | regs->tpc -= 4; | 575 | regs->tpc -= 4; |
| 653 | regs->tnpc -= 4; | 576 | regs->tnpc -= 4; |
| 654 | } | 577 | } |
| 655 | return 0; | 578 | |
| 579 | /* if there's no signal to deliver, we just put the saved sigmask | ||
| 580 | * back | ||
| 581 | */ | ||
| 582 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | ||
| 583 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 584 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
| 585 | } | ||
| 656 | } | 586 | } |
| 657 | 587 | ||
| 658 | void do_notify_resume(sigset_t *oldset, struct pt_regs *regs, | 588 | void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall, |
| 659 | unsigned long orig_i0, int restart_syscall, | ||
| 660 | unsigned long thread_info_flags) | 589 | unsigned long thread_info_flags) |
| 661 | { | 590 | { |
| 662 | if (thread_info_flags & _TIF_SIGPENDING) | 591 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) |
| 663 | do_signal(oldset, regs, orig_i0, restart_syscall); | 592 | do_signal(regs, orig_i0, restart_syscall); |
| 664 | } | 593 | } |
| 665 | 594 | ||
| 666 | void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) | 595 | void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) |
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 009a86e5ded4..708ba9b42cda 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c | |||
| @@ -32,9 +32,6 @@ | |||
| 32 | 32 | ||
| 33 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 33 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
| 34 | 34 | ||
| 35 | int do_signal32(sigset_t *oldset, struct pt_regs *regs, | ||
| 36 | unsigned long orig_o0, int ret_from_syscall); | ||
| 37 | |||
| 38 | /* Signal frames: the original one (compatible with SunOS): | 35 | /* Signal frames: the original one (compatible with SunOS): |
| 39 | * | 36 | * |
| 40 | * Set up a signal frame... Make the stack look the way SunOS | 37 | * Set up a signal frame... Make the stack look the way SunOS |
| @@ -226,102 +223,6 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) | |||
| 226 | return 0; | 223 | return 0; |
| 227 | } | 224 | } |
| 228 | 225 | ||
| 229 | /* | ||
| 230 | * atomically swap in the new signal mask, and wait for a signal. | ||
| 231 | * This is really tricky on the Sparc, watch out... | ||
| 232 | */ | ||
| 233 | asmlinkage void _sigpause32_common(compat_old_sigset_t set, struct pt_regs *regs) | ||
| 234 | { | ||
| 235 | sigset_t saveset; | ||
| 236 | |||
| 237 | set &= _BLOCKABLE; | ||
| 238 | spin_lock_irq(¤t->sighand->siglock); | ||
| 239 | saveset = current->blocked; | ||
| 240 | siginitset(¤t->blocked, set); | ||
| 241 | recalc_sigpending(); | ||
| 242 | spin_unlock_irq(¤t->sighand->siglock); | ||
| 243 | |||
| 244 | regs->tpc = regs->tnpc; | ||
| 245 | regs->tnpc += 4; | ||
| 246 | if (test_thread_flag(TIF_32BIT)) { | ||
| 247 | regs->tpc &= 0xffffffff; | ||
| 248 | regs->tnpc &= 0xffffffff; | ||
| 249 | } | ||
| 250 | |||
| 251 | /* Condition codes and return value where set here for sigpause, | ||
| 252 | * and so got used by setup_frame, which again causes sigreturn() | ||
| 253 | * to return -EINTR. | ||
| 254 | */ | ||
| 255 | while (1) { | ||
| 256 | current->state = TASK_INTERRUPTIBLE; | ||
| 257 | schedule(); | ||
| 258 | /* | ||
| 259 | * Return -EINTR and set condition code here, | ||
| 260 | * so the interrupted system call actually returns | ||
| 261 | * these. | ||
| 262 | */ | ||
| 263 | regs->tstate |= TSTATE_ICARRY; | ||
| 264 | regs->u_regs[UREG_I0] = EINTR; | ||
| 265 | if (do_signal32(&saveset, regs, 0, 0)) | ||
| 266 | return; | ||
| 267 | } | ||
| 268 | } | ||
| 269 | |||
| 270 | asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs *regs) | ||
| 271 | { | ||
| 272 | sigset_t oldset, set; | ||
| 273 | compat_sigset_t set32; | ||
| 274 | |||
| 275 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
| 276 | if (((compat_size_t)sigsetsize) != sizeof(sigset_t)) { | ||
| 277 | regs->tstate |= TSTATE_ICARRY; | ||
| 278 | regs->u_regs[UREG_I0] = EINVAL; | ||
| 279 | return; | ||
| 280 | } | ||
| 281 | if (copy_from_user(&set32, compat_ptr(uset), sizeof(set32))) { | ||
| 282 | regs->tstate |= TSTATE_ICARRY; | ||
| 283 | regs->u_regs[UREG_I0] = EFAULT; | ||
| 284 | return; | ||
| 285 | } | ||
| 286 | switch (_NSIG_WORDS) { | ||
| 287 | case 4: set.sig[3] = set32.sig[6] + (((long)set32.sig[7]) << 32); | ||
| 288 | case 3: set.sig[2] = set32.sig[4] + (((long)set32.sig[5]) << 32); | ||
| 289 | case 2: set.sig[1] = set32.sig[2] + (((long)set32.sig[3]) << 32); | ||
| 290 | case 1: set.sig[0] = set32.sig[0] + (((long)set32.sig[1]) << 32); | ||
| 291 | } | ||
| 292 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
| 293 | spin_lock_irq(¤t->sighand->siglock); | ||
| 294 | oldset = current->blocked; | ||
| 295 | current->blocked = set; | ||
| 296 | recalc_sigpending(); | ||
| 297 | spin_unlock_irq(¤t->sighand->siglock); | ||
| 298 | |||
| 299 | regs->tpc = regs->tnpc; | ||
| 300 | regs->tnpc += 4; | ||
| 301 | if (test_thread_flag(TIF_32BIT)) { | ||
| 302 | regs->tpc &= 0xffffffff; | ||
| 303 | regs->tnpc &= 0xffffffff; | ||
| 304 | } | ||
| 305 | |||
| 306 | /* Condition codes and return value where set here for sigpause, | ||
| 307 | * and so got used by setup_frame, which again causes sigreturn() | ||
| 308 | * to return -EINTR. | ||
| 309 | */ | ||
| 310 | while (1) { | ||
| 311 | current->state = TASK_INTERRUPTIBLE; | ||
| 312 | schedule(); | ||
| 313 | /* | ||
| 314 | * Return -EINTR and set condition code here, | ||
| 315 | * so the interrupted system call actually returns | ||
| 316 | * these. | ||
| 317 | */ | ||
| 318 | regs->tstate |= TSTATE_ICARRY; | ||
| 319 | regs->u_regs[UREG_I0] = EINTR; | ||
| 320 | if (do_signal32(&oldset, regs, 0, 0)) | ||
| 321 | return; | ||
| 322 | } | ||
| 323 | } | ||
| 324 | |||
| 325 | static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) | 226 | static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) |
| 326 | { | 227 | { |
| 327 | unsigned long *fpregs = current_thread_info()->fpregs; | 228 | unsigned long *fpregs = current_thread_info()->fpregs; |
| @@ -1362,8 +1263,8 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs | |||
| 1362 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | 1263 | * want to handle. Thus you cannot kill init even with a SIGKILL even by |
| 1363 | * mistake. | 1264 | * mistake. |
| 1364 | */ | 1265 | */ |
| 1365 | int do_signal32(sigset_t *oldset, struct pt_regs * regs, | 1266 | void do_signal32(sigset_t *oldset, struct pt_regs * regs, |
| 1366 | unsigned long orig_i0, int restart_syscall) | 1267 | unsigned long orig_i0, int restart_syscall) |
| 1367 | { | 1268 | { |
| 1368 | siginfo_t info; | 1269 | siginfo_t info; |
| 1369 | struct signal_deliver_cookie cookie; | 1270 | struct signal_deliver_cookie cookie; |
| @@ -1380,7 +1281,15 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, | |||
| 1380 | syscall_restart32(orig_i0, regs, &ka.sa); | 1281 | syscall_restart32(orig_i0, regs, &ka.sa); |
| 1381 | handle_signal32(signr, &ka, &info, oldset, | 1282 | handle_signal32(signr, &ka, &info, oldset, |
| 1382 | regs, svr4_signal); | 1283 | regs, svr4_signal); |
| 1383 | return 1; | 1284 | |
| 1285 | /* a signal was successfully delivered; the saved | ||
| 1286 | * sigmask will have been stored in the signal frame, | ||
| 1287 | * and will be restored by sigreturn, so we can simply | ||
| 1288 | * clear the TIF_RESTORE_SIGMASK flag. | ||
| 1289 | */ | ||
| 1290 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
| 1291 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 1292 | return; | ||
| 1384 | } | 1293 | } |
| 1385 | if (cookie.restart_syscall && | 1294 | if (cookie.restart_syscall && |
| 1386 | (regs->u_regs[UREG_I0] == ERESTARTNOHAND || | 1295 | (regs->u_regs[UREG_I0] == ERESTARTNOHAND || |
| @@ -1397,7 +1306,14 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, | |||
| 1397 | regs->tpc -= 4; | 1306 | regs->tpc -= 4; |
| 1398 | regs->tnpc -= 4; | 1307 | regs->tnpc -= 4; |
| 1399 | } | 1308 | } |
| 1400 | return 0; | 1309 | |
| 1310 | /* if there's no signal to deliver, we just put the saved sigmask | ||
| 1311 | * back | ||
| 1312 | */ | ||
| 1313 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | ||
| 1314 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 1315 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
| 1316 | } | ||
| 1401 | } | 1317 | } |
| 1402 | 1318 | ||
| 1403 | struct sigstack32 { | 1319 | struct sigstack32 { |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index d177d7e5c9d3..3c06bfb92a8c 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
| @@ -69,7 +69,6 @@ struct poll { | |||
| 69 | 69 | ||
| 70 | extern void die_if_kernel(char *str, struct pt_regs *regs); | 70 | extern void die_if_kernel(char *str, struct pt_regs *regs); |
| 71 | extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); | 71 | extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); |
| 72 | void _sigpause_common (unsigned int set, struct pt_regs *); | ||
| 73 | extern void *__bzero(void *, size_t); | 72 | extern void *__bzero(void *, size_t); |
| 74 | extern void *__memscan_zero(void *, size_t); | 73 | extern void *__memscan_zero(void *, size_t); |
| 75 | extern void *__memscan_generic(void *, int, size_t); | 74 | extern void *__memscan_generic(void *, int, size_t); |
| @@ -236,9 +235,10 @@ EXPORT_SYMBOL(pci_dma_supported); | |||
| 236 | /* I/O device mmaping on Sparc64. */ | 235 | /* I/O device mmaping on Sparc64. */ |
| 237 | EXPORT_SYMBOL(io_remap_pfn_range); | 236 | EXPORT_SYMBOL(io_remap_pfn_range); |
| 238 | 237 | ||
| 238 | #ifdef CONFIG_COMPAT | ||
| 239 | /* Solaris/SunOS binary compatibility */ | 239 | /* Solaris/SunOS binary compatibility */ |
| 240 | EXPORT_SYMBOL(_sigpause_common); | ||
| 241 | EXPORT_SYMBOL(verify_compat_iovec); | 240 | EXPORT_SYMBOL(verify_compat_iovec); |
| 241 | #endif | ||
| 242 | 242 | ||
| 243 | EXPORT_SYMBOL(dump_fpu); | 243 | EXPORT_SYMBOL(dump_fpu); |
| 244 | EXPORT_SYMBOL(pte_alloc_one_kernel); | 244 | EXPORT_SYMBOL(pte_alloc_one_kernel); |
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 98d24bc00044..bf0fc5bfbfbe 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S | |||
| @@ -41,7 +41,7 @@ sys_call_table32: | |||
| 41 | /*90*/ .word sys_dup2, sys_setfsuid, compat_sys_fcntl, sys32_select, sys_setfsgid | 41 | /*90*/ .word sys_dup2, sys_setfsuid, compat_sys_fcntl, sys32_select, sys_setfsgid |
| 42 | .word sys_fsync, sys32_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall | 42 | .word sys_fsync, sys32_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall |
| 43 | /*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending | 43 | /*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending |
| 44 | .word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys_setresuid, sys_getresuid | 44 | .word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, compat_sys_rt_sigsuspend, sys_setresuid, sys_getresuid |
| 45 | /*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall | 45 | /*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall |
| 46 | .word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd | 46 | .word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd |
| 47 | /*120*/ .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod | 47 | /*120*/ .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod |
| @@ -76,7 +76,10 @@ sys_call_table32: | |||
| 76 | .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy | 76 | .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy |
| 77 | /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink | 77 | /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink |
| 78 | .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid | 78 | .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid |
| 79 | /*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl | 79 | /*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat |
| 80 | .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_newfstatat | ||
| 81 | /*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat | ||
| 82 | .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll | ||
| 80 | 83 | ||
| 81 | #endif /* CONFIG_COMPAT */ | 84 | #endif /* CONFIG_COMPAT */ |
| 82 | 85 | ||
| @@ -142,7 +145,10 @@ sys_call_table: | |||
| 142 | .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy | 145 | .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy |
| 143 | /*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink | 146 | /*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink |
| 144 | .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid | 147 | .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid |
| 145 | /*280*/ .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl | 148 | /*280*/ .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat |
| 149 | .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, compat_sys_newfstatat | ||
| 150 | /*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat | ||
| 151 | .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll | ||
| 146 | 152 | ||
| 147 | #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ | 153 | #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ |
| 148 | defined(CONFIG_SOLARIS_EMUL_MODULE) | 154 | defined(CONFIG_SOLARIS_EMUL_MODULE) |
| @@ -239,13 +245,20 @@ sunos_sys_table: | |||
| 239 | /*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys | 245 | /*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys |
| 240 | .word sunos_nosys, sunos_nosys, sunos_nosys | 246 | .word sunos_nosys, sunos_nosys, sunos_nosys |
| 241 | .word sunos_nosys, sunos_nosys, sunos_nosys | 247 | .word sunos_nosys, sunos_nosys, sunos_nosys |
| 248 | .word sunos_nosys | ||
| 249 | /*260*/ .word sunos_nosys, sunos_nosys, sunos_nosys | ||
| 242 | .word sunos_nosys, sunos_nosys, sunos_nosys | 250 | .word sunos_nosys, sunos_nosys, sunos_nosys |
| 243 | .word sunos_nosys, sunos_nosys, sunos_nosys | 251 | .word sunos_nosys, sunos_nosys, sunos_nosys |
| 252 | .word sunos_nosys | ||
| 253 | /*270*/ .word sunos_nosys, sunos_nosys, sunos_nosys | ||
| 244 | .word sunos_nosys, sunos_nosys, sunos_nosys | 254 | .word sunos_nosys, sunos_nosys, sunos_nosys |
| 245 | .word sunos_nosys, sunos_nosys, sunos_nosys | 255 | .word sunos_nosys, sunos_nosys, sunos_nosys |
| 256 | .word sunos_nosys | ||
| 257 | /*280*/ .word sunos_nosys, sunos_nosys, sunos_nosys | ||
| 246 | .word sunos_nosys, sunos_nosys, sunos_nosys | 258 | .word sunos_nosys, sunos_nosys, sunos_nosys |
| 247 | .word sunos_nosys, sunos_nosys, sunos_nosys | 259 | .word sunos_nosys, sunos_nosys, sunos_nosys |
| 260 | .word sunos_nosys | ||
| 261 | /*290*/ .word sunos_nosys, sunos_nosys, sunos_nosys | ||
| 248 | .word sunos_nosys, sunos_nosys, sunos_nosys | 262 | .word sunos_nosys, sunos_nosys, sunos_nosys |
| 249 | .word sunos_nosys, sunos_nosys, sunos_nosys | 263 | .word sunos_nosys, sunos_nosys, sunos_nosys |
| 250 | .word sunos_nosys | ||
| 251 | #endif | 264 | #endif |
diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S index 4b6ae583c0a3..eb314ed23cdb 100644 --- a/arch/sparc64/solaris/entry64.S +++ b/arch/sparc64/solaris/entry64.S | |||
| @@ -180,6 +180,8 @@ solaris_sigsuspend: | |||
| 180 | nop | 180 | nop |
| 181 | call sys_sigsuspend | 181 | call sys_sigsuspend |
| 182 | stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] | 182 | stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] |
| 183 | b,pt %xcc, ret_from_solaris | ||
| 184 | nop | ||
| 183 | 185 | ||
| 184 | .globl solaris_getpid | 186 | .globl solaris_getpid |
| 185 | solaris_getpid: | 187 | solaris_getpid: |
