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 | |
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>
45 files changed, 540 insertions, 656 deletions
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index 3945d378bd7..70dba1f0e2e 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 2ea4b39efff..9c5194b385d 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 b631cf86ed4..fcd2bad0286 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 7c88e9a5851..8182583c762 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 233d55115d3..00700f7e683 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 6546db6abdb..9ab684d1bb5 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 3be52a34c80..b7ea46645e1 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 0c0a6890240..8d950c778bb 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 8930586e0eb..c75f8aeefc2 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 77a1262751d..2fac27049bf 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 03ecb4e4614..c51d08d218e 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 f7460d897e7..77ca6fd8125 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 5f34d7dc2b8..0748d8147bb 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 0b0d492c953..19b25399d7e 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 e457a40838f..6877ae4cd1d 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 71000299188..e50e56e4ab6 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 090dcca00d2..b80eba0081c 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 60f5dfabb1e..ca11a4c457d 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 009a86e5ded..708ba9b42cd 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 d177d7e5c9d..3c06bfb92a8 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 98d24bc0004..bf0fc5bfbfb 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 4b6ae583c0a..eb314ed23cd 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: |
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c index 5468e5a767e..43e67d6c29d 100644 --- a/drivers/serial/sn_console.c +++ b/drivers/serial/sn_console.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * driver for that. | 6 | * driver for that. |
7 | * | 7 | * |
8 | * | 8 | * |
9 | * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. | 9 | * Copyright (c) 2004-2006 Silicon Graphics, Inc. All Rights Reserved. |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify it | 11 | * This program is free software; you can redistribute it and/or modify it |
12 | * under the terms of version 2 of the GNU General Public License | 12 | * under the terms of version 2 of the GNU General Public License |
@@ -829,8 +829,8 @@ static int __init sn_sal_module_init(void) | |||
829 | misc.name = DEVICE_NAME_DYNAMIC; | 829 | misc.name = DEVICE_NAME_DYNAMIC; |
830 | retval = misc_register(&misc); | 830 | retval = misc_register(&misc); |
831 | if (retval != 0) { | 831 | if (retval != 0) { |
832 | printk | 832 | printk(KERN_WARNING "Failed to register console " |
833 | ("Failed to register console device using misc_register.\n"); | 833 | "device using misc_register.\n"); |
834 | return -ENODEV; | 834 | return -ENODEV; |
835 | } | 835 | } |
836 | sal_console_uart.major = MISC_MAJOR; | 836 | sal_console_uart.major = MISC_MAJOR; |
@@ -942,88 +942,75 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count) | |||
942 | { | 942 | { |
943 | unsigned long flags = 0; | 943 | unsigned long flags = 0; |
944 | struct sn_cons_port *port = &sal_console_port; | 944 | struct sn_cons_port *port = &sal_console_port; |
945 | #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) | ||
946 | static int stole_lock = 0; | 945 | static int stole_lock = 0; |
947 | #endif | ||
948 | 946 | ||
949 | BUG_ON(!port->sc_is_asynch); | 947 | BUG_ON(!port->sc_is_asynch); |
950 | 948 | ||
951 | /* We can't look at the xmit buffer if we're not registered with serial core | 949 | /* We can't look at the xmit buffer if we're not registered with serial core |
952 | * yet. So only do the fancy recovery after registering | 950 | * yet. So only do the fancy recovery after registering |
953 | */ | 951 | */ |
954 | if (port->sc_port.info) { | 952 | if (!port->sc_port.info) { |
955 | 953 | /* Not yet registered with serial core - simple case */ | |
956 | /* somebody really wants this output, might be an | 954 | puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count); |
957 | * oops, kdb, panic, etc. make sure they get it. */ | 955 | return; |
958 | #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) | 956 | } |
959 | if (spin_is_locked(&port->sc_port.lock)) { | ||
960 | int lhead = port->sc_port.info->xmit.head; | ||
961 | int ltail = port->sc_port.info->xmit.tail; | ||
962 | int counter, got_lock = 0; | ||
963 | 957 | ||
964 | /* | 958 | /* somebody really wants this output, might be an |
965 | * We attempt to determine if someone has died with the | 959 | * oops, kdb, panic, etc. make sure they get it. */ |
966 | * lock. We wait ~20 secs after the head and tail ptrs | 960 | if (spin_is_locked(&port->sc_port.lock)) { |
967 | * stop moving and assume the lock holder is not functional | 961 | int lhead = port->sc_port.info->xmit.head; |
968 | * and plow ahead. If the lock is freed within the time out | 962 | int ltail = port->sc_port.info->xmit.tail; |
969 | * period we re-get the lock and go ahead normally. We also | 963 | int counter, got_lock = 0; |
970 | * remember if we have plowed ahead so that we don't have | 964 | |
971 | * to wait out the time out period again - the asumption | 965 | /* |
972 | * is that we will time out again. | 966 | * We attempt to determine if someone has died with the |
973 | */ | 967 | * lock. We wait ~20 secs after the head and tail ptrs |
968 | * stop moving and assume the lock holder is not functional | ||
969 | * and plow ahead. If the lock is freed within the time out | ||
970 | * period we re-get the lock and go ahead normally. We also | ||
971 | * remember if we have plowed ahead so that we don't have | ||
972 | * to wait out the time out period again - the asumption | ||
973 | * is that we will time out again. | ||
974 | */ | ||
974 | 975 | ||
975 | for (counter = 0; counter < 150; mdelay(125), counter++) { | 976 | for (counter = 0; counter < 150; mdelay(125), counter++) { |
976 | if (!spin_is_locked(&port->sc_port.lock) | 977 | if (!spin_is_locked(&port->sc_port.lock) |
977 | || stole_lock) { | 978 | || stole_lock) { |
978 | if (!stole_lock) { | 979 | if (!stole_lock) { |
979 | spin_lock_irqsave(&port-> | 980 | spin_lock_irqsave(&port->sc_port.lock, |
980 | sc_port.lock, | 981 | flags); |
981 | flags); | 982 | got_lock = 1; |
982 | got_lock = 1; | ||
983 | } | ||
984 | break; | ||
985 | } else { | ||
986 | /* still locked */ | ||
987 | if ((lhead != | ||
988 | port->sc_port.info->xmit.head) | ||
989 | || (ltail != | ||
990 | port->sc_port.info->xmit. | ||
991 | tail)) { | ||
992 | lhead = | ||
993 | port->sc_port.info->xmit. | ||
994 | head; | ||
995 | ltail = | ||
996 | port->sc_port.info->xmit. | ||
997 | tail; | ||
998 | counter = 0; | ||
999 | } | ||
1000 | } | 983 | } |
1001 | } | 984 | break; |
1002 | /* flush anything in the serial core xmit buffer, raw */ | ||
1003 | sn_transmit_chars(port, 1); | ||
1004 | if (got_lock) { | ||
1005 | spin_unlock_irqrestore(&port->sc_port.lock, | ||
1006 | flags); | ||
1007 | stole_lock = 0; | ||
1008 | } else { | 985 | } else { |
1009 | /* fell thru */ | 986 | /* still locked */ |
1010 | stole_lock = 1; | 987 | if ((lhead != port->sc_port.info->xmit.head) |
988 | || (ltail != | ||
989 | port->sc_port.info->xmit.tail)) { | ||
990 | lhead = | ||
991 | port->sc_port.info->xmit.head; | ||
992 | ltail = | ||
993 | port->sc_port.info->xmit.tail; | ||
994 | counter = 0; | ||
995 | } | ||
1011 | } | 996 | } |
1012 | puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count); | 997 | } |
1013 | } else { | 998 | /* flush anything in the serial core xmit buffer, raw */ |
1014 | stole_lock = 0; | 999 | sn_transmit_chars(port, 1); |
1015 | #endif | 1000 | if (got_lock) { |
1016 | spin_lock_irqsave(&port->sc_port.lock, flags); | ||
1017 | sn_transmit_chars(port, 1); | ||
1018 | spin_unlock_irqrestore(&port->sc_port.lock, flags); | 1001 | spin_unlock_irqrestore(&port->sc_port.lock, flags); |
1019 | 1002 | stole_lock = 0; | |
1020 | puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count); | 1003 | } else { |
1021 | #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) | 1004 | /* fell thru */ |
1005 | stole_lock = 1; | ||
1022 | } | 1006 | } |
1023 | #endif | 1007 | puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count); |
1024 | } | 1008 | } else { |
1025 | else { | 1009 | stole_lock = 0; |
1026 | /* Not yet registered with serial core - simple case */ | 1010 | spin_lock_irqsave(&port->sc_port.lock, flags); |
1011 | sn_transmit_chars(port, 1); | ||
1012 | spin_unlock_irqrestore(&port->sc_port.lock, flags); | ||
1013 | |||
1027 | puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count); | 1014 | puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count); |
1028 | } | 1015 | } |
1029 | } | 1016 | } |
diff --git a/fs/compat.c b/fs/compat.c index 18b21b4c9e3..ff0bafcff72 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -1743,7 +1743,7 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp, | |||
1743 | if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS) | 1743 | if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS) |
1744 | timeout = -1; /* infinite */ | 1744 | timeout = -1; /* infinite */ |
1745 | else { | 1745 | else { |
1746 | timeout = ROUND_UP(tv.tv_sec, 1000000/HZ); | 1746 | timeout = ROUND_UP(tv.tv_usec, 1000000/HZ); |
1747 | timeout += tv.tv_sec * HZ; | 1747 | timeout += tv.tv_sec * HZ; |
1748 | } | 1748 | } |
1749 | } | 1749 | } |
@@ -1884,7 +1884,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, | |||
1884 | /* We assume that ts.tv_sec is always lower than | 1884 | /* We assume that ts.tv_sec is always lower than |
1885 | the number of seconds that can be expressed in | 1885 | the number of seconds that can be expressed in |
1886 | an s64. Otherwise the compiler bitches at us */ | 1886 | an s64. Otherwise the compiler bitches at us */ |
1887 | timeout = ROUND_UP(ts.tv_sec, 1000000000/HZ); | 1887 | timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ); |
1888 | timeout += ts.tv_sec * HZ; | 1888 | timeout += ts.tv_sec * HZ; |
1889 | } | 1889 | } |
1890 | 1890 | ||
diff --git a/include/asm-ia64/semaphore.h b/include/asm-ia64/semaphore.h index bb8906285fa..f483eeb95dd 100644 --- a/include/asm-ia64/semaphore.h +++ b/include/asm-ia64/semaphore.h | |||
@@ -61,7 +61,7 @@ static inline void | |||
61 | down (struct semaphore *sem) | 61 | down (struct semaphore *sem) |
62 | { | 62 | { |
63 | might_sleep(); | 63 | might_sleep(); |
64 | if (atomic_dec_return(&sem->count) < 0) | 64 | if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1) |
65 | __down(sem); | 65 | __down(sem); |
66 | } | 66 | } |
67 | 67 | ||
@@ -75,7 +75,7 @@ down_interruptible (struct semaphore * sem) | |||
75 | int ret = 0; | 75 | int ret = 0; |
76 | 76 | ||
77 | might_sleep(); | 77 | might_sleep(); |
78 | if (atomic_dec_return(&sem->count) < 0) | 78 | if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1) |
79 | ret = __down_interruptible(sem); | 79 | ret = __down_interruptible(sem); |
80 | return ret; | 80 | return ret; |
81 | } | 81 | } |
@@ -85,7 +85,7 @@ down_trylock (struct semaphore *sem) | |||
85 | { | 85 | { |
86 | int ret = 0; | 86 | int ret = 0; |
87 | 87 | ||
88 | if (atomic_dec_return(&sem->count) < 0) | 88 | if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1) |
89 | ret = __down_trylock(sem); | 89 | ret = __down_trylock(sem); |
90 | return ret; | 90 | return ret; |
91 | } | 91 | } |
@@ -93,7 +93,7 @@ down_trylock (struct semaphore *sem) | |||
93 | static inline void | 93 | static inline void |
94 | up (struct semaphore * sem) | 94 | up (struct semaphore * sem) |
95 | { | 95 | { |
96 | if (atomic_inc_return(&sem->count) <= 0) | 96 | if (ia64_fetchadd(1, &sem->count.counter, rel) <= -1) |
97 | __up(sem); | 97 | __up(sem); |
98 | } | 98 | } |
99 | 99 | ||
diff --git a/include/asm-ia64/sn/xp.h b/include/asm-ia64/sn/xp.h index 203945ae034..9bd2f9bf329 100644 --- a/include/asm-ia64/sn/xp.h +++ b/include/asm-ia64/sn/xp.h | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/cache.h> | 19 | #include <linux/cache.h> |
20 | #include <linux/hardirq.h> | 20 | #include <linux/hardirq.h> |
21 | #include <linux/mutex.h> | ||
21 | #include <asm/sn/types.h> | 22 | #include <asm/sn/types.h> |
22 | #include <asm/sn/bte.h> | 23 | #include <asm/sn/bte.h> |
23 | 24 | ||
@@ -359,7 +360,7 @@ typedef void (*xpc_notify_func)(enum xpc_retval reason, partid_t partid, | |||
359 | * the channel. | 360 | * the channel. |
360 | */ | 361 | */ |
361 | struct xpc_registration { | 362 | struct xpc_registration { |
362 | struct semaphore sema; | 363 | struct mutex mutex; |
363 | xpc_channel_func func; /* function to call */ | 364 | xpc_channel_func func; /* function to call */ |
364 | void *key; /* pointer to user's key */ | 365 | void *key; /* pointer to user's key */ |
365 | u16 nentries; /* #of msg entries in local msg queue */ | 366 | u16 nentries; /* #of msg entries in local msg queue */ |
diff --git a/include/asm-ia64/sn/xpc.h b/include/asm-ia64/sn/xpc.h index 87e9cd58851..0c36928ffd8 100644 --- a/include/asm-ia64/sn/xpc.h +++ b/include/asm-ia64/sn/xpc.h | |||
@@ -19,6 +19,8 @@ | |||
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/sysctl.h> | 20 | #include <linux/sysctl.h> |
21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
22 | #include <linux/mutex.h> | ||
23 | #include <linux/completion.h> | ||
22 | #include <asm/pgtable.h> | 24 | #include <asm/pgtable.h> |
23 | #include <asm/processor.h> | 25 | #include <asm/processor.h> |
24 | #include <asm/sn/bte.h> | 26 | #include <asm/sn/bte.h> |
@@ -335,8 +337,7 @@ struct xpc_openclose_args { | |||
335 | * and consumed by the intended recipient. | 337 | * and consumed by the intended recipient. |
336 | */ | 338 | */ |
337 | struct xpc_notify { | 339 | struct xpc_notify { |
338 | struct semaphore sema; /* notify semaphore */ | 340 | volatile u8 type; /* type of notification */ |
339 | volatile u8 type; /* type of notification */ | ||
340 | 341 | ||
341 | /* the following two fields are only used if type == XPC_N_CALL */ | 342 | /* the following two fields are only used if type == XPC_N_CALL */ |
342 | xpc_notify_func func; /* user's notify function */ | 343 | xpc_notify_func func; /* user's notify function */ |
@@ -465,8 +466,8 @@ struct xpc_channel { | |||
465 | xpc_channel_func func; /* user's channel function */ | 466 | xpc_channel_func func; /* user's channel function */ |
466 | void *key; /* pointer to user's key */ | 467 | void *key; /* pointer to user's key */ |
467 | 468 | ||
468 | struct semaphore msg_to_pull_sema; /* next msg to pull serialization */ | 469 | struct mutex msg_to_pull_mutex; /* next msg to pull serialization */ |
469 | struct semaphore wdisconnect_sema; /* wait for channel disconnect */ | 470 | struct completion wdisconnect_wait; /* wait for channel disconnect */ |
470 | 471 | ||
471 | struct xpc_openclose_args *local_openclose_args; /* args passed on */ | 472 | struct xpc_openclose_args *local_openclose_args; /* args passed on */ |
472 | /* opening or closing of channel */ | 473 | /* opening or closing of channel */ |
diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h index d8aae4da397..412ef8e493a 100644 --- a/include/asm-ia64/topology.h +++ b/include/asm-ia64/topology.h | |||
@@ -18,6 +18,10 @@ | |||
18 | #include <asm/smp.h> | 18 | #include <asm/smp.h> |
19 | 19 | ||
20 | #ifdef CONFIG_NUMA | 20 | #ifdef CONFIG_NUMA |
21 | |||
22 | /* Nodes w/o CPUs are preferred for memory allocations, see build_zonelists */ | ||
23 | #define PENALTY_FOR_NODE_WITH_CPUS 255 | ||
24 | |||
21 | /* | 25 | /* |
22 | * Returns the number of the node containing CPU 'cpu' | 26 | * Returns the number of the node containing CPU 'cpu' |
23 | */ | 27 | */ |
diff --git a/include/asm-sparc/oplib.h b/include/asm-sparc/oplib.h index 95944556d8b..d0d76b30eb4 100644 --- a/include/asm-sparc/oplib.h +++ b/include/asm-sparc/oplib.h | |||
@@ -164,6 +164,7 @@ enum prom_input_device { | |||
164 | PROMDEV_IKBD, /* input from keyboard */ | 164 | PROMDEV_IKBD, /* input from keyboard */ |
165 | PROMDEV_ITTYA, /* input from ttya */ | 165 | PROMDEV_ITTYA, /* input from ttya */ |
166 | PROMDEV_ITTYB, /* input from ttyb */ | 166 | PROMDEV_ITTYB, /* input from ttyb */ |
167 | PROMDEV_IRSC, /* input from rsc */ | ||
167 | PROMDEV_I_UNK, | 168 | PROMDEV_I_UNK, |
168 | }; | 169 | }; |
169 | 170 | ||
@@ -175,6 +176,7 @@ enum prom_output_device { | |||
175 | PROMDEV_OSCREEN, /* to screen */ | 176 | PROMDEV_OSCREEN, /* to screen */ |
176 | PROMDEV_OTTYA, /* to ttya */ | 177 | PROMDEV_OTTYA, /* to ttya */ |
177 | PROMDEV_OTTYB, /* to ttyb */ | 178 | PROMDEV_OTTYB, /* to ttyb */ |
179 | PROMDEV_ORSC, /* to rsc */ | ||
178 | PROMDEV_O_UNK, | 180 | PROMDEV_O_UNK, |
179 | }; | 181 | }; |
180 | 182 | ||
diff --git a/include/asm-sparc/thread_info.h b/include/asm-sparc/thread_info.h index 65f060b040a..91b9f5888c8 100644 --- a/include/asm-sparc/thread_info.h +++ b/include/asm-sparc/thread_info.h | |||
@@ -128,9 +128,10 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *) | |||
128 | * thread information flag bit numbers | 128 | * thread information flag bit numbers |
129 | */ | 129 | */ |
130 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ | 130 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ |
131 | #define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ | 131 | /* flag bit 1 is available */ |
132 | #define TIF_SIGPENDING 2 /* signal pending */ | 132 | #define TIF_SIGPENDING 2 /* signal pending */ |
133 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ | 133 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ |
134 | #define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */ | ||
134 | #define TIF_USEDFPU 8 /* FPU was used by this task | 135 | #define TIF_USEDFPU 8 /* FPU was used by this task |
135 | * this quantum (SMP) */ | 136 | * this quantum (SMP) */ |
136 | #define TIF_POLLING_NRFLAG 9 /* true if poll_idle() is polling | 137 | #define TIF_POLLING_NRFLAG 9 /* true if poll_idle() is polling |
@@ -139,9 +140,9 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *) | |||
139 | 140 | ||
140 | /* as above, but as bit values */ | 141 | /* as above, but as bit values */ |
141 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | 142 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
142 | #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) | ||
143 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) | 143 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) |
144 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) | 144 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) |
145 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) | ||
145 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) | 146 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) |
146 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | 147 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) |
147 | 148 | ||
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index 58dba518239..2ac64e65e33 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h | |||
@@ -300,11 +300,26 @@ | |||
300 | #define __NR_add_key 281 | 300 | #define __NR_add_key 281 |
301 | #define __NR_request_key 282 | 301 | #define __NR_request_key 282 |
302 | #define __NR_keyctl 283 | 302 | #define __NR_keyctl 283 |
303 | #define __NR_openat 284 | ||
304 | #define __NR_mkdirat 285 | ||
305 | #define __NR_mknodat 286 | ||
306 | #define __NR_fchownat 287 | ||
307 | #define __NR_futimesat 288 | ||
308 | #define __NR_newfstatat 289 | ||
309 | #define __NR_unlinkat 290 | ||
310 | #define __NR_renameat 291 | ||
311 | #define __NR_linkat 292 | ||
312 | #define __NR_symlinkat 293 | ||
313 | #define __NR_readlinkat 294 | ||
314 | #define __NR_fchmodat 295 | ||
315 | #define __NR_faccessat 296 | ||
316 | #define __NR_pselect6 297 | ||
317 | #define __NR_ppoll 298 | ||
303 | 318 | ||
304 | /* WARNING: You MAY NOT add syscall numbers larger than 283, since | 319 | /* WARNING: You MAY NOT add syscall numbers larger than 298, since |
305 | * all of the syscall tables in the Sparc kernel are | 320 | * all of the syscall tables in the Sparc kernel are |
306 | * sized to have 283 entries (starting at zero). Therefore | 321 | * sized to have 298 entries (starting at zero). Therefore |
307 | * find a free slot in the 0-282 range. | 322 | * find a free slot in the 0-298 range. |
308 | */ | 323 | */ |
309 | 324 | ||
310 | #define _syscall0(type,name) \ | 325 | #define _syscall0(type,name) \ |
@@ -458,6 +473,7 @@ return -1; \ | |||
458 | #define __ARCH_WANT_SYS_OLDUMOUNT | 473 | #define __ARCH_WANT_SYS_OLDUMOUNT |
459 | #define __ARCH_WANT_SYS_SIGPENDING | 474 | #define __ARCH_WANT_SYS_SIGPENDING |
460 | #define __ARCH_WANT_SYS_SIGPROCMASK | 475 | #define __ARCH_WANT_SYS_SIGPROCMASK |
476 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND | ||
461 | #endif | 477 | #endif |
462 | 478 | ||
463 | #ifdef __KERNEL_SYSCALLS__ | 479 | #ifdef __KERNEL_SYSCALLS__ |
diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h index c94d8b3991b..ac9d068aab4 100644 --- a/include/asm-sparc64/thread_info.h +++ b/include/asm-sparc64/thread_info.h | |||
@@ -221,7 +221,7 @@ register struct thread_info *current_thread_info_reg asm("g6"); | |||
221 | * nop | 221 | * nop |
222 | */ | 222 | */ |
223 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ | 223 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ |
224 | #define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ | 224 | #define TIF_RESTORE_SIGMASK 1 /* restore signal mask in do_signal() */ |
225 | #define TIF_SIGPENDING 2 /* signal pending */ | 225 | #define TIF_SIGPENDING 2 /* signal pending */ |
226 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ | 226 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ |
227 | #define TIF_PERFCTR 4 /* performance counters active */ | 227 | #define TIF_PERFCTR 4 /* performance counters active */ |
@@ -241,7 +241,6 @@ register struct thread_info *current_thread_info_reg asm("g6"); | |||
241 | #define TIF_POLLING_NRFLAG 14 | 241 | #define TIF_POLLING_NRFLAG 14 |
242 | 242 | ||
243 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | 243 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
244 | #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) | ||
245 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) | 244 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) |
246 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) | 245 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) |
247 | #define _TIF_PERFCTR (1<<TIF_PERFCTR) | 246 | #define _TIF_PERFCTR (1<<TIF_PERFCTR) |
@@ -250,11 +249,12 @@ register struct thread_info *current_thread_info_reg asm("g6"); | |||
250 | #define _TIF_32BIT (1<<TIF_32BIT) | 249 | #define _TIF_32BIT (1<<TIF_32BIT) |
251 | #define _TIF_SECCOMP (1<<TIF_SECCOMP) | 250 | #define _TIF_SECCOMP (1<<TIF_SECCOMP) |
252 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) | 251 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) |
252 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) | ||
253 | #define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING) | 253 | #define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING) |
254 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | 254 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) |
255 | 255 | ||
256 | #define _TIF_USER_WORK_MASK ((0xff << TI_FLAG_WSAVED_SHIFT) | \ | 256 | #define _TIF_USER_WORK_MASK ((0xff << TI_FLAG_WSAVED_SHIFT) | \ |
257 | (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \ | 257 | (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | \ |
258 | _TIF_NEED_RESCHED | _TIF_PERFCTR)) | 258 | _TIF_NEED_RESCHED | _TIF_PERFCTR)) |
259 | 259 | ||
260 | #endif /* __KERNEL__ */ | 260 | #endif /* __KERNEL__ */ |
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index 51ec2879b88..84ac2bdb090 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h | |||
@@ -302,11 +302,26 @@ | |||
302 | #define __NR_add_key 281 | 302 | #define __NR_add_key 281 |
303 | #define __NR_request_key 282 | 303 | #define __NR_request_key 282 |
304 | #define __NR_keyctl 283 | 304 | #define __NR_keyctl 283 |
305 | #define __NR_openat 284 | ||
306 | #define __NR_mkdirat 285 | ||
307 | #define __NR_mknodat 286 | ||
308 | #define __NR_fchownat 287 | ||
309 | #define __NR_futimesat 288 | ||
310 | #define __NR_newfstatat 289 | ||
311 | #define __NR_unlinkat 290 | ||
312 | #define __NR_renameat 291 | ||
313 | #define __NR_linkat 292 | ||
314 | #define __NR_symlinkat 293 | ||
315 | #define __NR_readlinkat 294 | ||
316 | #define __NR_fchmodat 295 | ||
317 | #define __NR_faccessat 296 | ||
318 | #define __NR_pselect6 297 | ||
319 | #define __NR_ppoll 298 | ||
305 | 320 | ||
306 | /* WARNING: You MAY NOT add syscall numbers larger than 283, since | 321 | /* WARNING: You MAY NOT add syscall numbers larger than 298, since |
307 | * all of the syscall tables in the Sparc kernel are | 322 | * all of the syscall tables in the Sparc kernel are |
308 | * sized to have 283 entries (starting at zero). Therefore | 323 | * sized to have 298 entries (starting at zero). Therefore |
309 | * find a free slot in the 0-282 range. | 324 | * find a free slot in the 0-298 range. |
310 | */ | 325 | */ |
311 | 326 | ||
312 | #define _syscall0(type,name) \ | 327 | #define _syscall0(type,name) \ |
@@ -501,6 +516,8 @@ asmlinkage long sys_rt_sigaction(int sig, | |||
501 | #define __ARCH_WANT_SYS_OLDUMOUNT | 516 | #define __ARCH_WANT_SYS_OLDUMOUNT |
502 | #define __ARCH_WANT_SYS_SIGPENDING | 517 | #define __ARCH_WANT_SYS_SIGPENDING |
503 | #define __ARCH_WANT_SYS_SIGPROCMASK | 518 | #define __ARCH_WANT_SYS_SIGPROCMASK |
519 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND | ||
520 | #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND | ||
504 | #endif | 521 | #endif |
505 | 522 | ||
506 | /* | 523 | /* |
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 472f0483480..59ff6c430cf 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h | |||
@@ -19,7 +19,7 @@ struct xt_get_revision | |||
19 | /* For standard target */ | 19 | /* For standard target */ |
20 | #define XT_RETURN (-NF_REPEAT - 1) | 20 | #define XT_RETURN (-NF_REPEAT - 1) |
21 | 21 | ||
22 | #define XT_ALIGN(s) (((s) + (__alignof__(void *)-1)) & ~(__alignof__(void *)-1)) | 22 | #define XT_ALIGN(s) (((s) + (__alignof__(u_int64_t)-1)) & ~(__alignof__(u_int64_t)-1)) |
23 | 23 | ||
24 | /* Standard return verdict, or do jump. */ | 24 | /* Standard return verdict, or do jump. */ |
25 | #define XT_STANDARD_TARGET "" | 25 | #define XT_STANDARD_TARGET "" |
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index a553f39f6ae..e673b2c984e 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h | |||
@@ -175,6 +175,8 @@ void sctp_icmp_frag_needed(struct sock *, struct sctp_association *, | |||
175 | void sctp_icmp_proto_unreachable(struct sock *sk, | 175 | void sctp_icmp_proto_unreachable(struct sock *sk, |
176 | struct sctp_association *asoc, | 176 | struct sctp_association *asoc, |
177 | struct sctp_transport *t); | 177 | struct sctp_transport *t); |
178 | void sctp_backlog_migrate(struct sctp_association *assoc, | ||
179 | struct sock *oldsk, struct sock *newsk); | ||
178 | 180 | ||
179 | /* | 181 | /* |
180 | * Section: Macros, externs, and inlines | 182 | * Section: Macros, externs, and inlines |
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index f5c22d77fea..8c522ae031b 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -127,9 +127,9 @@ extern struct sctp_globals { | |||
127 | * RTO.Alpha - 1/8 (3 when converted to right shifts.) | 127 | * RTO.Alpha - 1/8 (3 when converted to right shifts.) |
128 | * RTO.Beta - 1/4 (2 when converted to right shifts.) | 128 | * RTO.Beta - 1/4 (2 when converted to right shifts.) |
129 | */ | 129 | */ |
130 | __u32 rto_initial; | 130 | unsigned long rto_initial; |
131 | __u32 rto_min; | 131 | unsigned long rto_min; |
132 | __u32 rto_max; | 132 | unsigned long rto_max; |
133 | 133 | ||
134 | /* Note: rto_alpha and rto_beta are really defined as inverse | 134 | /* Note: rto_alpha and rto_beta are really defined as inverse |
135 | * powers of two to facilitate integer operations. | 135 | * powers of two to facilitate integer operations. |
@@ -140,12 +140,18 @@ extern struct sctp_globals { | |||
140 | /* Max.Burst - 4 */ | 140 | /* Max.Burst - 4 */ |
141 | int max_burst; | 141 | int max_burst; |
142 | 142 | ||
143 | /* Valid.Cookie.Life - 60 seconds */ | ||
144 | int valid_cookie_life; | ||
145 | |||
146 | /* Whether Cookie Preservative is enabled(1) or not(0) */ | 143 | /* Whether Cookie Preservative is enabled(1) or not(0) */ |
147 | int cookie_preserve_enable; | 144 | int cookie_preserve_enable; |
148 | 145 | ||
146 | /* Valid.Cookie.Life - 60 seconds */ | ||
147 | unsigned long valid_cookie_life; | ||
148 | |||
149 | /* Delayed SACK timeout 200ms default*/ | ||
150 | unsigned long sack_timeout; | ||
151 | |||
152 | /* HB.interval - 30 seconds */ | ||
153 | unsigned long hb_interval; | ||
154 | |||
149 | /* Association.Max.Retrans - 10 attempts | 155 | /* Association.Max.Retrans - 10 attempts |
150 | * Path.Max.Retrans - 5 attempts (per destination address) | 156 | * Path.Max.Retrans - 5 attempts (per destination address) |
151 | * Max.Init.Retransmits - 8 attempts | 157 | * Max.Init.Retransmits - 8 attempts |
@@ -168,12 +174,6 @@ extern struct sctp_globals { | |||
168 | */ | 174 | */ |
169 | int rcvbuf_policy; | 175 | int rcvbuf_policy; |
170 | 176 | ||
171 | /* Delayed SACK timeout 200ms default*/ | ||
172 | int sack_timeout; | ||
173 | |||
174 | /* HB.interval - 30 seconds */ | ||
175 | int hb_interval; | ||
176 | |||
177 | /* The following variables are implementation specific. */ | 177 | /* The following variables are implementation specific. */ |
178 | 178 | ||
179 | /* Default initialization values to be applied to new associations. */ | 179 | /* Default initialization values to be applied to new associations. */ |
@@ -405,8 +405,9 @@ struct sctp_cookie { | |||
405 | /* The format of our cookie that we send to our peer. */ | 405 | /* The format of our cookie that we send to our peer. */ |
406 | struct sctp_signed_cookie { | 406 | struct sctp_signed_cookie { |
407 | __u8 signature[SCTP_SECRET_SIZE]; | 407 | __u8 signature[SCTP_SECRET_SIZE]; |
408 | __u32 __pad; /* force sctp_cookie alignment to 64 bits */ | ||
408 | struct sctp_cookie c; | 409 | struct sctp_cookie c; |
409 | }; | 410 | } __attribute__((packed)); |
410 | 411 | ||
411 | /* This is another convenience type to allocate memory for address | 412 | /* This is another convenience type to allocate memory for address |
412 | * params for the maximum size and pass such structures around | 413 | * params for the maximum size and pass such structures around |
@@ -827,7 +828,7 @@ struct sctp_transport { | |||
827 | __u32 rtt; /* This is the most recent RTT. */ | 828 | __u32 rtt; /* This is the most recent RTT. */ |
828 | 829 | ||
829 | /* RTO : The current retransmission timeout value. */ | 830 | /* RTO : The current retransmission timeout value. */ |
830 | __u32 rto; | 831 | unsigned long rto; |
831 | 832 | ||
832 | /* RTTVAR : The current RTT variation. */ | 833 | /* RTTVAR : The current RTT variation. */ |
833 | __u32 rttvar; | 834 | __u32 rttvar; |
@@ -877,22 +878,10 @@ struct sctp_transport { | |||
877 | /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to | 878 | /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to |
878 | * the destination address every heartbeat interval. | 879 | * the destination address every heartbeat interval. |
879 | */ | 880 | */ |
880 | __u32 hbinterval; | 881 | unsigned long hbinterval; |
881 | |||
882 | /* This is the max_retrans value for the transport and will | ||
883 | * be initialized from the assocs value. This can be changed | ||
884 | * using SCTP_SET_PEER_ADDR_PARAMS socket option. | ||
885 | */ | ||
886 | __u16 pathmaxrxt; | ||
887 | |||
888 | /* PMTU : The current known path MTU. */ | ||
889 | __u32 pathmtu; | ||
890 | 882 | ||
891 | /* SACK delay timeout */ | 883 | /* SACK delay timeout */ |
892 | __u32 sackdelay; | 884 | unsigned long sackdelay; |
893 | |||
894 | /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ | ||
895 | __u32 param_flags; | ||
896 | 885 | ||
897 | /* When was the last time (in jiffies) that we heard from this | 886 | /* When was the last time (in jiffies) that we heard from this |
898 | * transport? We use this to pick new active and retran paths. | 887 | * transport? We use this to pick new active and retran paths. |
@@ -904,6 +893,18 @@ struct sctp_transport { | |||
904 | */ | 893 | */ |
905 | unsigned long last_time_ecne_reduced; | 894 | unsigned long last_time_ecne_reduced; |
906 | 895 | ||
896 | /* This is the max_retrans value for the transport and will | ||
897 | * be initialized from the assocs value. This can be changed | ||
898 | * using SCTP_SET_PEER_ADDR_PARAMS socket option. | ||
899 | */ | ||
900 | __u16 pathmaxrxt; | ||
901 | |||
902 | /* PMTU : The current known path MTU. */ | ||
903 | __u32 pathmtu; | ||
904 | |||
905 | /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ | ||
906 | __u32 param_flags; | ||
907 | |||
907 | /* The number of times INIT has been sent on this transport. */ | 908 | /* The number of times INIT has been sent on this transport. */ |
908 | int init_sent_count; | 909 | int init_sent_count; |
909 | 910 | ||
@@ -1249,6 +1250,14 @@ struct sctp_endpoint { | |||
1249 | int last_key; | 1250 | int last_key; |
1250 | int key_changed_at; | 1251 | int key_changed_at; |
1251 | 1252 | ||
1253 | /* digest: This is a digest of the sctp cookie. This field is | ||
1254 | * only used on the receive path when we try to validate | ||
1255 | * that the cookie has not been tampered with. We put | ||
1256 | * this here so we pre-allocate this once and can re-use | ||
1257 | * on every receive. | ||
1258 | */ | ||
1259 | __u8 digest[SCTP_SIGNATURE_SIZE]; | ||
1260 | |||
1252 | /* sendbuf acct. policy. */ | 1261 | /* sendbuf acct. policy. */ |
1253 | __u32 sndbuf_policy; | 1262 | __u32 sndbuf_policy; |
1254 | 1263 | ||
@@ -1499,9 +1508,9 @@ struct sctp_association { | |||
1499 | * These values will be initialized by system defaults, but can | 1508 | * These values will be initialized by system defaults, but can |
1500 | * be modified via the SCTP_RTOINFO socket option. | 1509 | * be modified via the SCTP_RTOINFO socket option. |
1501 | */ | 1510 | */ |
1502 | __u32 rto_initial; | 1511 | unsigned long rto_initial; |
1503 | __u32 rto_max; | 1512 | unsigned long rto_max; |
1504 | __u32 rto_min; | 1513 | unsigned long rto_min; |
1505 | 1514 | ||
1506 | /* Maximum number of new data packets that can be sent in a burst. */ | 1515 | /* Maximum number of new data packets that can be sent in a burst. */ |
1507 | int max_burst; | 1516 | int max_burst; |
@@ -1519,13 +1528,13 @@ struct sctp_association { | |||
1519 | __u16 init_retries; | 1528 | __u16 init_retries; |
1520 | 1529 | ||
1521 | /* The largest timeout or RTO value to use in attempting an INIT */ | 1530 | /* The largest timeout or RTO value to use in attempting an INIT */ |
1522 | __u16 max_init_timeo; | 1531 | unsigned long max_init_timeo; |
1523 | 1532 | ||
1524 | /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to | 1533 | /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to |
1525 | * the destination address every heartbeat interval. This value | 1534 | * the destination address every heartbeat interval. This value |
1526 | * will be inherited by all new transports. | 1535 | * will be inherited by all new transports. |
1527 | */ | 1536 | */ |
1528 | __u32 hbinterval; | 1537 | unsigned long hbinterval; |
1529 | 1538 | ||
1530 | /* This is the max_retrans value for new transports in the | 1539 | /* This is the max_retrans value for new transports in the |
1531 | * association. | 1540 | * association. |
@@ -1537,13 +1546,14 @@ struct sctp_association { | |||
1537 | */ | 1546 | */ |
1538 | __u32 pathmtu; | 1547 | __u32 pathmtu; |
1539 | 1548 | ||
1540 | /* SACK delay timeout */ | ||
1541 | __u32 sackdelay; | ||
1542 | |||
1543 | /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ | 1549 | /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ |
1544 | __u32 param_flags; | 1550 | __u32 param_flags; |
1545 | 1551 | ||
1546 | int timeouts[SCTP_NUM_TIMEOUT_TYPES]; | 1552 | /* SACK delay timeout */ |
1553 | unsigned long sackdelay; | ||
1554 | |||
1555 | |||
1556 | unsigned long timeouts[SCTP_NUM_TIMEOUT_TYPES]; | ||
1547 | struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES]; | 1557 | struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES]; |
1548 | 1558 | ||
1549 | /* Transport to which SHUTDOWN chunk was last sent. */ | 1559 | /* Transport to which SHUTDOWN chunk was last sent. */ |
@@ -1648,7 +1658,10 @@ struct sctp_association { | |||
1648 | /* How many duplicated TSNs have we seen? */ | 1658 | /* How many duplicated TSNs have we seen? */ |
1649 | int numduptsns; | 1659 | int numduptsns; |
1650 | 1660 | ||
1651 | /* Number of seconds of idle time before an association is closed. */ | 1661 | /* Number of seconds of idle time before an association is closed. |
1662 | * In the association context, this is really used as a boolean | ||
1663 | * since the real timeout is stored in the timeouts array | ||
1664 | */ | ||
1652 | __u32 autoclose; | 1665 | __u32 autoclose; |
1653 | 1666 | ||
1654 | /* These are to support | 1667 | /* These are to support |
diff --git a/net/sctp/input.c b/net/sctp/input.c index 4aa6fc60357..cb78b50868e 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -257,20 +257,26 @@ int sctp_rcv(struct sk_buff *skb) | |||
257 | */ | 257 | */ |
258 | sctp_bh_lock_sock(sk); | 258 | sctp_bh_lock_sock(sk); |
259 | 259 | ||
260 | /* It is possible that the association could have moved to a different | ||
261 | * socket if it is peeled off. If so, update the sk. | ||
262 | */ | ||
263 | if (sk != rcvr->sk) { | ||
264 | sctp_bh_lock_sock(rcvr->sk); | ||
265 | sctp_bh_unlock_sock(sk); | ||
266 | sk = rcvr->sk; | ||
267 | } | ||
268 | |||
260 | if (sock_owned_by_user(sk)) | 269 | if (sock_owned_by_user(sk)) |
261 | sk_add_backlog(sk, skb); | 270 | sk_add_backlog(sk, skb); |
262 | else | 271 | else |
263 | sctp_backlog_rcv(sk, skb); | 272 | sctp_backlog_rcv(sk, skb); |
264 | 273 | ||
265 | /* Release the sock and any reference counts we took in the | 274 | /* Release the sock and the sock ref we took in the lookup calls. |
266 | * lookup calls. | 275 | * The asoc/ep ref will be released in sctp_backlog_rcv. |
267 | */ | 276 | */ |
268 | sctp_bh_unlock_sock(sk); | 277 | sctp_bh_unlock_sock(sk); |
269 | if (asoc) | ||
270 | sctp_association_put(asoc); | ||
271 | else | ||
272 | sctp_endpoint_put(ep); | ||
273 | sock_put(sk); | 278 | sock_put(sk); |
279 | |||
274 | return ret; | 280 | return ret; |
275 | 281 | ||
276 | discard_it: | 282 | discard_it: |
@@ -296,12 +302,50 @@ discard_release: | |||
296 | int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) | 302 | int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) |
297 | { | 303 | { |
298 | struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; | 304 | struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; |
299 | struct sctp_inq *inqueue = &chunk->rcvr->inqueue; | 305 | struct sctp_inq *inqueue = NULL; |
300 | 306 | struct sctp_ep_common *rcvr = NULL; | |
301 | sctp_inq_push(inqueue, chunk); | 307 | |
308 | rcvr = chunk->rcvr; | ||
309 | |||
310 | BUG_TRAP(rcvr->sk == sk); | ||
311 | |||
312 | if (rcvr->dead) { | ||
313 | sctp_chunk_free(chunk); | ||
314 | } else { | ||
315 | inqueue = &chunk->rcvr->inqueue; | ||
316 | sctp_inq_push(inqueue, chunk); | ||
317 | } | ||
318 | |||
319 | /* Release the asoc/ep ref we took in the lookup calls in sctp_rcv. */ | ||
320 | if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) | ||
321 | sctp_association_put(sctp_assoc(rcvr)); | ||
322 | else | ||
323 | sctp_endpoint_put(sctp_ep(rcvr)); | ||
324 | |||
302 | return 0; | 325 | return 0; |
303 | } | 326 | } |
304 | 327 | ||
328 | void sctp_backlog_migrate(struct sctp_association *assoc, | ||
329 | struct sock *oldsk, struct sock *newsk) | ||
330 | { | ||
331 | struct sk_buff *skb; | ||
332 | struct sctp_chunk *chunk; | ||
333 | |||
334 | skb = oldsk->sk_backlog.head; | ||
335 | oldsk->sk_backlog.head = oldsk->sk_backlog.tail = NULL; | ||
336 | while (skb != NULL) { | ||
337 | struct sk_buff *next = skb->next; | ||
338 | |||
339 | chunk = SCTP_INPUT_CB(skb)->chunk; | ||
340 | skb->next = NULL; | ||
341 | if (&assoc->base == chunk->rcvr) | ||
342 | sk_add_backlog(newsk, skb); | ||
343 | else | ||
344 | sk_add_backlog(oldsk, skb); | ||
345 | skb = next; | ||
346 | } | ||
347 | } | ||
348 | |||
305 | /* Handle icmp frag needed error. */ | 349 | /* Handle icmp frag needed error. */ |
306 | void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, | 350 | void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, |
307 | struct sctp_transport *t, __u32 pmtu) | 351 | struct sctp_transport *t, __u32 pmtu) |
@@ -544,10 +588,16 @@ int sctp_rcv_ootb(struct sk_buff *skb) | |||
544 | sctp_errhdr_t *err; | 588 | sctp_errhdr_t *err; |
545 | 589 | ||
546 | ch = (sctp_chunkhdr_t *) skb->data; | 590 | ch = (sctp_chunkhdr_t *) skb->data; |
547 | ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length)); | ||
548 | 591 | ||
549 | /* Scan through all the chunks in the packet. */ | 592 | /* Scan through all the chunks in the packet. */ |
550 | while (ch_end > (__u8 *)ch && ch_end < skb->tail) { | 593 | do { |
594 | /* Break out if chunk length is less then minimal. */ | ||
595 | if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t)) | ||
596 | break; | ||
597 | |||
598 | ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); | ||
599 | if (ch_end > skb->tail) | ||
600 | break; | ||
551 | 601 | ||
552 | /* RFC 8.4, 2) If the OOTB packet contains an ABORT chunk, the | 602 | /* RFC 8.4, 2) If the OOTB packet contains an ABORT chunk, the |
553 | * receiver MUST silently discard the OOTB packet and take no | 603 | * receiver MUST silently discard the OOTB packet and take no |
@@ -578,8 +628,7 @@ int sctp_rcv_ootb(struct sk_buff *skb) | |||
578 | } | 628 | } |
579 | 629 | ||
580 | ch = (sctp_chunkhdr_t *) ch_end; | 630 | ch = (sctp_chunkhdr_t *) ch_end; |
581 | ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length)); | 631 | } while (ch_end < skb->tail); |
582 | } | ||
583 | 632 | ||
584 | return 0; | 633 | return 0; |
585 | 634 | ||
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c index 2d33922c044..297b8951463 100644 --- a/net/sctp/inqueue.c +++ b/net/sctp/inqueue.c | |||
@@ -73,8 +73,10 @@ void sctp_inq_free(struct sctp_inq *queue) | |||
73 | /* If there is a packet which is currently being worked on, | 73 | /* If there is a packet which is currently being worked on, |
74 | * free it as well. | 74 | * free it as well. |
75 | */ | 75 | */ |
76 | if (queue->in_progress) | 76 | if (queue->in_progress) { |
77 | sctp_chunk_free(queue->in_progress); | 77 | sctp_chunk_free(queue->in_progress); |
78 | queue->in_progress = NULL; | ||
79 | } | ||
78 | 80 | ||
79 | if (queue->malloced) { | 81 | if (queue->malloced) { |
80 | /* Dump the master memory segment. */ | 82 | /* Dump the master memory segment. */ |
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index 6e4dc28874d..d47a52c303a 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
@@ -176,7 +176,7 @@ static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_associa | |||
176 | 176 | ||
177 | static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos) | 177 | static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos) |
178 | { | 178 | { |
179 | if (*pos > sctp_ep_hashsize) | 179 | if (*pos >= sctp_ep_hashsize) |
180 | return NULL; | 180 | return NULL; |
181 | 181 | ||
182 | if (*pos < 0) | 182 | if (*pos < 0) |
@@ -185,8 +185,6 @@ static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos) | |||
185 | if (*pos == 0) | 185 | if (*pos == 0) |
186 | seq_printf(seq, " ENDPT SOCK STY SST HBKT LPORT UID INODE LADDRS\n"); | 186 | seq_printf(seq, " ENDPT SOCK STY SST HBKT LPORT UID INODE LADDRS\n"); |
187 | 187 | ||
188 | ++*pos; | ||
189 | |||
190 | return (void *)pos; | 188 | return (void *)pos; |
191 | } | 189 | } |
192 | 190 | ||
@@ -198,11 +196,9 @@ static void sctp_eps_seq_stop(struct seq_file *seq, void *v) | |||
198 | 196 | ||
199 | static void * sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 197 | static void * sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
200 | { | 198 | { |
201 | if (*pos > sctp_ep_hashsize) | 199 | if (++*pos >= sctp_ep_hashsize) |
202 | return NULL; | 200 | return NULL; |
203 | 201 | ||
204 | ++*pos; | ||
205 | |||
206 | return pos; | 202 | return pos; |
207 | } | 203 | } |
208 | 204 | ||
@@ -214,19 +210,19 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v) | |||
214 | struct sctp_ep_common *epb; | 210 | struct sctp_ep_common *epb; |
215 | struct sctp_endpoint *ep; | 211 | struct sctp_endpoint *ep; |
216 | struct sock *sk; | 212 | struct sock *sk; |
217 | int hash = *(int *)v; | 213 | int hash = *(loff_t *)v; |
218 | 214 | ||
219 | if (hash > sctp_ep_hashsize) | 215 | if (hash >= sctp_ep_hashsize) |
220 | return -ENOMEM; | 216 | return -ENOMEM; |
221 | 217 | ||
222 | head = &sctp_ep_hashtable[hash-1]; | 218 | head = &sctp_ep_hashtable[hash]; |
223 | sctp_local_bh_disable(); | 219 | sctp_local_bh_disable(); |
224 | read_lock(&head->lock); | 220 | read_lock(&head->lock); |
225 | for (epb = head->chain; epb; epb = epb->next) { | 221 | for (epb = head->chain; epb; epb = epb->next) { |
226 | ep = sctp_ep(epb); | 222 | ep = sctp_ep(epb); |
227 | sk = epb->sk; | 223 | sk = epb->sk; |
228 | seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, | 224 | seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, |
229 | sctp_sk(sk)->type, sk->sk_state, hash-1, | 225 | sctp_sk(sk)->type, sk->sk_state, hash, |
230 | epb->bind_addr.port, | 226 | epb->bind_addr.port, |
231 | sock_i_uid(sk), sock_i_ino(sk)); | 227 | sock_i_uid(sk), sock_i_ino(sk)); |
232 | 228 | ||
@@ -283,7 +279,7 @@ void sctp_eps_proc_exit(void) | |||
283 | 279 | ||
284 | static void * sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos) | 280 | static void * sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos) |
285 | { | 281 | { |
286 | if (*pos > sctp_assoc_hashsize) | 282 | if (*pos >= sctp_assoc_hashsize) |
287 | return NULL; | 283 | return NULL; |
288 | 284 | ||
289 | if (*pos < 0) | 285 | if (*pos < 0) |
@@ -293,8 +289,6 @@ static void * sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos) | |||
293 | seq_printf(seq, " ASSOC SOCK STY SST ST HBKT ASSOC-ID TX_QUEUE RX_QUEUE UID INODE LPORT " | 289 | seq_printf(seq, " ASSOC SOCK STY SST ST HBKT ASSOC-ID TX_QUEUE RX_QUEUE UID INODE LPORT " |
294 | "RPORT LADDRS <-> RADDRS\n"); | 290 | "RPORT LADDRS <-> RADDRS\n"); |
295 | 291 | ||
296 | ++*pos; | ||
297 | |||
298 | return (void *)pos; | 292 | return (void *)pos; |
299 | } | 293 | } |
300 | 294 | ||
@@ -306,11 +300,9 @@ static void sctp_assocs_seq_stop(struct seq_file *seq, void *v) | |||
306 | 300 | ||
307 | static void * sctp_assocs_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 301 | static void * sctp_assocs_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
308 | { | 302 | { |
309 | if (*pos > sctp_assoc_hashsize) | 303 | if (++*pos >= sctp_assoc_hashsize) |
310 | return NULL; | 304 | return NULL; |
311 | 305 | ||
312 | ++*pos; | ||
313 | |||
314 | return pos; | 306 | return pos; |
315 | } | 307 | } |
316 | 308 | ||
@@ -321,12 +313,12 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) | |||
321 | struct sctp_ep_common *epb; | 313 | struct sctp_ep_common *epb; |
322 | struct sctp_association *assoc; | 314 | struct sctp_association *assoc; |
323 | struct sock *sk; | 315 | struct sock *sk; |
324 | int hash = *(int *)v; | 316 | int hash = *(loff_t *)v; |
325 | 317 | ||
326 | if (hash > sctp_assoc_hashsize) | 318 | if (hash >= sctp_assoc_hashsize) |
327 | return -ENOMEM; | 319 | return -ENOMEM; |
328 | 320 | ||
329 | head = &sctp_assoc_hashtable[hash-1]; | 321 | head = &sctp_assoc_hashtable[hash]; |
330 | sctp_local_bh_disable(); | 322 | sctp_local_bh_disable(); |
331 | read_lock(&head->lock); | 323 | read_lock(&head->lock); |
332 | for (epb = head->chain; epb; epb = epb->next) { | 324 | for (epb = head->chain; epb; epb = epb->next) { |
@@ -335,7 +327,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) | |||
335 | seq_printf(seq, | 327 | seq_printf(seq, |
336 | "%8p %8p %-3d %-3d %-2d %-4d %4d %8d %8d %7d %5lu %-5d %5d ", | 328 | "%8p %8p %-3d %-3d %-2d %-4d %4d %8d %8d %7d %5lu %-5d %5d ", |
337 | assoc, sk, sctp_sk(sk)->type, sk->sk_state, | 329 | assoc, sk, sctp_sk(sk)->type, sk->sk_state, |
338 | assoc->state, hash-1, assoc->assoc_id, | 330 | assoc->state, hash, assoc->assoc_id, |
339 | (sk->sk_rcvbuf - assoc->rwnd), | 331 | (sk->sk_rcvbuf - assoc->rwnd), |
340 | assoc->sndbuf_used, | 332 | assoc->sndbuf_used, |
341 | sock_i_uid(sk), sock_i_ino(sk), | 333 | sock_i_uid(sk), sock_i_ino(sk), |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 556c495c692..5e0de3c0eea 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -1275,7 +1275,12 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep, | |||
1275 | unsigned int keylen; | 1275 | unsigned int keylen; |
1276 | char *key; | 1276 | char *key; |
1277 | 1277 | ||
1278 | headersize = sizeof(sctp_paramhdr_t) + SCTP_SECRET_SIZE; | 1278 | /* Header size is static data prior to the actual cookie, including |
1279 | * any padding. | ||
1280 | */ | ||
1281 | headersize = sizeof(sctp_paramhdr_t) + | ||
1282 | (sizeof(struct sctp_signed_cookie) - | ||
1283 | sizeof(struct sctp_cookie)); | ||
1279 | bodysize = sizeof(struct sctp_cookie) | 1284 | bodysize = sizeof(struct sctp_cookie) |
1280 | + ntohs(init_chunk->chunk_hdr->length) + addrs_len; | 1285 | + ntohs(init_chunk->chunk_hdr->length) + addrs_len; |
1281 | 1286 | ||
@@ -1354,7 +1359,7 @@ struct sctp_association *sctp_unpack_cookie( | |||
1354 | struct sctp_signed_cookie *cookie; | 1359 | struct sctp_signed_cookie *cookie; |
1355 | struct sctp_cookie *bear_cookie; | 1360 | struct sctp_cookie *bear_cookie; |
1356 | int headersize, bodysize, fixed_size; | 1361 | int headersize, bodysize, fixed_size; |
1357 | __u8 digest[SCTP_SIGNATURE_SIZE]; | 1362 | __u8 *digest = ep->digest; |
1358 | struct scatterlist sg; | 1363 | struct scatterlist sg; |
1359 | unsigned int keylen, len; | 1364 | unsigned int keylen, len; |
1360 | char *key; | 1365 | char *key; |
@@ -1362,7 +1367,12 @@ struct sctp_association *sctp_unpack_cookie( | |||
1362 | struct sk_buff *skb = chunk->skb; | 1367 | struct sk_buff *skb = chunk->skb; |
1363 | struct timeval tv; | 1368 | struct timeval tv; |
1364 | 1369 | ||
1365 | headersize = sizeof(sctp_chunkhdr_t) + SCTP_SECRET_SIZE; | 1370 | /* Header size is static data prior to the actual cookie, including |
1371 | * any padding. | ||
1372 | */ | ||
1373 | headersize = sizeof(sctp_chunkhdr_t) + | ||
1374 | (sizeof(struct sctp_signed_cookie) - | ||
1375 | sizeof(struct sctp_cookie)); | ||
1366 | bodysize = ntohs(chunk->chunk_hdr->length) - headersize; | 1376 | bodysize = ntohs(chunk->chunk_hdr->length) - headersize; |
1367 | fixed_size = headersize + sizeof(struct sctp_cookie); | 1377 | fixed_size = headersize + sizeof(struct sctp_cookie); |
1368 | 1378 | ||
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index b8b38aba92b..8d1dc24bab4 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -1300,7 +1300,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1300 | "T1 INIT Timeout adjustment" | 1300 | "T1 INIT Timeout adjustment" |
1301 | " init_err_counter: %d" | 1301 | " init_err_counter: %d" |
1302 | " cycle: %d" | 1302 | " cycle: %d" |
1303 | " timeout: %d\n", | 1303 | " timeout: %ld\n", |
1304 | asoc->init_err_counter, | 1304 | asoc->init_err_counter, |
1305 | asoc->init_cycle, | 1305 | asoc->init_cycle, |
1306 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT]); | 1306 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT]); |
@@ -1328,7 +1328,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1328 | SCTP_DEBUG_PRINTK( | 1328 | SCTP_DEBUG_PRINTK( |
1329 | "T1 COOKIE Timeout adjustment" | 1329 | "T1 COOKIE Timeout adjustment" |
1330 | " init_err_counter: %d" | 1330 | " init_err_counter: %d" |
1331 | " timeout: %d\n", | 1331 | " timeout: %ld\n", |
1332 | asoc->init_err_counter, | 1332 | asoc->init_err_counter, |
1333 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE]); | 1333 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE]); |
1334 | 1334 | ||
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 477d7f80dba..71c9a961c32 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -3090,6 +3090,8 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | |||
3090 | break; | 3090 | break; |
3091 | 3091 | ||
3092 | ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); | 3092 | ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); |
3093 | if (ch_end > skb->tail) | ||
3094 | break; | ||
3093 | 3095 | ||
3094 | if (SCTP_CID_SHUTDOWN_ACK == ch->type) | 3096 | if (SCTP_CID_SHUTDOWN_ACK == ch->type) |
3095 | ootb_shut_ack = 1; | 3097 | ootb_shut_ack = 1; |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index c98ee375ba5..fb1821d9f33 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -2995,7 +2995,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
2995 | sp->hbinterval = jiffies_to_msecs(sctp_hb_interval); | 2995 | sp->hbinterval = jiffies_to_msecs(sctp_hb_interval); |
2996 | sp->pathmaxrxt = sctp_max_retrans_path; | 2996 | sp->pathmaxrxt = sctp_max_retrans_path; |
2997 | sp->pathmtu = 0; // allow default discovery | 2997 | sp->pathmtu = 0; // allow default discovery |
2998 | sp->sackdelay = sctp_sack_timeout; | 2998 | sp->sackdelay = jiffies_to_msecs(sctp_sack_timeout); |
2999 | sp->param_flags = SPP_HB_ENABLE | | 2999 | sp->param_flags = SPP_HB_ENABLE | |
3000 | SPP_PMTUD_ENABLE | | 3000 | SPP_PMTUD_ENABLE | |
3001 | SPP_SACKDELAY_ENABLE; | 3001 | SPP_SACKDELAY_ENABLE; |
@@ -5602,8 +5602,12 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
5602 | */ | 5602 | */ |
5603 | newsp->type = type; | 5603 | newsp->type = type; |
5604 | 5604 | ||
5605 | spin_lock_bh(&oldsk->sk_lock.slock); | ||
5606 | /* Migrate the backlog from oldsk to newsk. */ | ||
5607 | sctp_backlog_migrate(assoc, oldsk, newsk); | ||
5605 | /* Migrate the association to the new socket. */ | 5608 | /* Migrate the association to the new socket. */ |
5606 | sctp_assoc_migrate(assoc, newsk); | 5609 | sctp_assoc_migrate(assoc, newsk); |
5610 | spin_unlock_bh(&oldsk->sk_lock.slock); | ||
5607 | 5611 | ||
5608 | /* If the association on the newsk is already closed before accept() | 5612 | /* If the association on the newsk is already closed before accept() |
5609 | * is called, set RCV_SHUTDOWN flag. | 5613 | * is called, set RCV_SHUTDOWN flag. |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index fcd7096c953..dc6f3ff3235 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -159,12 +159,9 @@ static ctl_table sctp_table[] = { | |||
159 | .ctl_name = NET_SCTP_PRESERVE_ENABLE, | 159 | .ctl_name = NET_SCTP_PRESERVE_ENABLE, |
160 | .procname = "cookie_preserve_enable", | 160 | .procname = "cookie_preserve_enable", |
161 | .data = &sctp_cookie_preserve_enable, | 161 | .data = &sctp_cookie_preserve_enable, |
162 | .maxlen = sizeof(long), | 162 | .maxlen = sizeof(int), |
163 | .mode = 0644, | 163 | .mode = 0644, |
164 | .proc_handler = &proc_doulongvec_ms_jiffies_minmax, | 164 | .proc_handler = &proc_dointvec |
165 | .strategy = &sctp_sysctl_jiffies_ms, | ||
166 | .extra1 = &rto_timer_min, | ||
167 | .extra2 = &rto_timer_max | ||
168 | }, | 165 | }, |
169 | { | 166 | { |
170 | .ctl_name = NET_SCTP_RTO_ALPHA, | 167 | .ctl_name = NET_SCTP_RTO_ALPHA, |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 68d73e2dd15..160f62ad1cc 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -350,7 +350,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) | |||
350 | tp->rto_pending = 0; | 350 | tp->rto_pending = 0; |
351 | 351 | ||
352 | SCTP_DEBUG_PRINTK("%s: transport: %p, rtt: %d, srtt: %d " | 352 | SCTP_DEBUG_PRINTK("%s: transport: %p, rtt: %d, srtt: %d " |
353 | "rttvar: %d, rto: %d\n", __FUNCTION__, | 353 | "rttvar: %d, rto: %ld\n", __FUNCTION__, |
354 | tp, rtt, tp->srtt, tp->rttvar, tp->rto); | 354 | tp, rtt, tp->srtt, tp->rttvar, tp->rto); |
355 | } | 355 | } |
356 | 356 | ||