aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/kernel/power.c2
-rw-r--r--arch/sparc64/kernel/process.c4
-rw-r--r--arch/sparc64/kernel/systbls.S8
-rw-r--r--arch/sparc64/mm/init.c23
-rw-r--r--arch/sparc64/solaris/socket.c193
5 files changed, 140 insertions, 90 deletions
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index 533104c7907d..946cee0257ea 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -69,8 +69,6 @@ void machine_power_off(void)
69 machine_halt(); 69 machine_halt();
70} 70}
71 71
72EXPORT_SYMBOL(machine_power_off);
73
74#ifdef CONFIG_PCI 72#ifdef CONFIG_PCI
75static int powerd(void *__unused) 73static int powerd(void *__unused)
76{ 74{
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index cffb1c8ab4fc..07424b075938 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -124,8 +124,6 @@ void machine_halt(void)
124 panic("Halt failed!"); 124 panic("Halt failed!");
125} 125}
126 126
127EXPORT_SYMBOL(machine_halt);
128
129void machine_alt_power_off(void) 127void machine_alt_power_off(void)
130{ 128{
131 if (!serial_console && prom_palette) 129 if (!serial_console && prom_palette)
@@ -154,8 +152,6 @@ void machine_restart(char * cmd)
154 panic("Reboot failed!"); 152 panic("Reboot failed!");
155} 153}
156 154
157EXPORT_SYMBOL(machine_restart);
158
159static void show_regwindow32(struct pt_regs *regs) 155static void show_regwindow32(struct pt_regs *regs)
160{ 156{
161 struct reg_window32 __user *rw; 157 struct reg_window32 __user *rw;
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index bceb91a8a2bd..53eaf2345fe9 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -50,8 +50,8 @@ sys_call_table32:
50 .word sys_nis_syscall, sys32_mkdir, sys_rmdir, sys32_utimes, compat_sys_stat64 50 .word sys_nis_syscall, sys32_mkdir, sys_rmdir, sys32_utimes, compat_sys_stat64
51/*140*/ .word sys32_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit 51/*140*/ .word sys32_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit
52 .word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys_pciconfig_read, sys_pciconfig_write 52 .word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys_pciconfig_read, sys_pciconfig_write
53/*150*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64 53/*150*/ .word sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
54 .word compat_sys_fcntl64, sys_ni_syscall, compat_sys_statfs, compat_sys_fstatfs, sys_oldumount 54 .word compat_sys_fcntl64, sys_inotify_rm_watch, compat_sys_statfs, compat_sys_fstatfs, sys_oldumount
55/*160*/ .word compat_sys_sched_setaffinity, compat_sys_sched_getaffinity, sys32_getdomainname, sys32_setdomainname, sys_nis_syscall 55/*160*/ .word compat_sys_sched_setaffinity, compat_sys_sched_getaffinity, sys32_getdomainname, sys32_setdomainname, sys_nis_syscall
56 .word sys_quotactl, sys_set_tid_address, compat_sys_mount, sys_ustat, sys32_setxattr 56 .word sys_quotactl, sys_set_tid_address, compat_sys_mount, sys_ustat, sys32_setxattr
57/*170*/ .word sys32_lsetxattr, sys32_fsetxattr, sys_getxattr, sys_lgetxattr, compat_sys_getdents 57/*170*/ .word sys32_lsetxattr, sys32_fsetxattr, sys_getxattr, sys_lgetxattr, compat_sys_getdents
@@ -116,8 +116,8 @@ sys_call_table:
116 .word sys_socketpair, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64 116 .word sys_socketpair, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64
117/*140*/ .word sys_sendfile64, sys_getpeername, sys_futex, sys_gettid, sys_getrlimit 117/*140*/ .word sys_sendfile64, sys_getpeername, sys_futex, sys_gettid, sys_getrlimit
118 .word sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write 118 .word sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
119/*150*/ .word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64 119/*150*/ .word sys_getsockname, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
120 .word sys_nis_syscall, sys_ni_syscall, sys_statfs, sys_fstatfs, sys_oldumount 120 .word sys_nis_syscall, sys_inotify_rm_watch, sys_statfs, sys_fstatfs, sys_oldumount
121/*160*/ .word sys_sched_setaffinity, sys_sched_getaffinity, sys_getdomainname, sys_setdomainname, sys_utrap_install 121/*160*/ .word sys_sched_setaffinity, sys_sched_getaffinity, sys_getdomainname, sys_setdomainname, sys_utrap_install
122 .word sys_quotactl, sys_set_tid_address, sys_mount, sys_ustat, sys_setxattr 122 .word sys_quotactl, sys_set_tid_address, sys_mount, sys_ustat, sys_setxattr
123/*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents 123/*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index 8fc413cb6acd..3fbaf342a452 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -121,15 +121,24 @@ __inline__ void flush_dcache_page_impl(struct page *page)
121} 121}
122 122
123#define PG_dcache_dirty PG_arch_1 123#define PG_dcache_dirty PG_arch_1
124#define PG_dcache_cpu_shift 24
125#define PG_dcache_cpu_mask (256 - 1)
126
127#if NR_CPUS > 256
128#error D-cache dirty tracking and thread_info->cpu need fixing for > 256 cpus
129#endif
124 130
125#define dcache_dirty_cpu(page) \ 131#define dcache_dirty_cpu(page) \
126 (((page)->flags >> 24) & (NR_CPUS - 1UL)) 132 (((page)->flags >> PG_dcache_cpu_shift) & PG_dcache_cpu_mask)
127 133
128static __inline__ void set_dcache_dirty(struct page *page, int this_cpu) 134static __inline__ void set_dcache_dirty(struct page *page, int this_cpu)
129{ 135{
130 unsigned long mask = this_cpu; 136 unsigned long mask = this_cpu;
131 unsigned long non_cpu_bits = ~((NR_CPUS - 1UL) << 24UL); 137 unsigned long non_cpu_bits;
132 mask = (mask << 24) | (1UL << PG_dcache_dirty); 138
139 non_cpu_bits = ~(PG_dcache_cpu_mask << PG_dcache_cpu_shift);
140 mask = (mask << PG_dcache_cpu_shift) | (1UL << PG_dcache_dirty);
141
133 __asm__ __volatile__("1:\n\t" 142 __asm__ __volatile__("1:\n\t"
134 "ldx [%2], %%g7\n\t" 143 "ldx [%2], %%g7\n\t"
135 "and %%g7, %1, %%g1\n\t" 144 "and %%g7, %1, %%g1\n\t"
@@ -151,7 +160,7 @@ static __inline__ void clear_dcache_dirty_cpu(struct page *page, unsigned long c
151 __asm__ __volatile__("! test_and_clear_dcache_dirty\n" 160 __asm__ __volatile__("! test_and_clear_dcache_dirty\n"
152 "1:\n\t" 161 "1:\n\t"
153 "ldx [%2], %%g7\n\t" 162 "ldx [%2], %%g7\n\t"
154 "srlx %%g7, 24, %%g1\n\t" 163 "srlx %%g7, %4, %%g1\n\t"
155 "and %%g1, %3, %%g1\n\t" 164 "and %%g1, %3, %%g1\n\t"
156 "cmp %%g1, %0\n\t" 165 "cmp %%g1, %0\n\t"
157 "bne,pn %%icc, 2f\n\t" 166 "bne,pn %%icc, 2f\n\t"
@@ -164,7 +173,8 @@ static __inline__ void clear_dcache_dirty_cpu(struct page *page, unsigned long c
164 "2:" 173 "2:"
165 : /* no outputs */ 174 : /* no outputs */
166 : "r" (cpu), "r" (mask), "r" (&page->flags), 175 : "r" (cpu), "r" (mask), "r" (&page->flags),
167 "i" (NR_CPUS - 1UL) 176 "i" (PG_dcache_cpu_mask),
177 "i" (PG_dcache_cpu_shift)
168 : "g1", "g7"); 178 : "g1", "g7");
169} 179}
170 180
@@ -180,7 +190,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p
180 if (pfn_valid(pfn) && 190 if (pfn_valid(pfn) &&
181 (page = pfn_to_page(pfn), page_mapping(page)) && 191 (page = pfn_to_page(pfn), page_mapping(page)) &&
182 ((pg_flags = page->flags) & (1UL << PG_dcache_dirty))) { 192 ((pg_flags = page->flags) & (1UL << PG_dcache_dirty))) {
183 int cpu = ((pg_flags >> 24) & (NR_CPUS - 1UL)); 193 int cpu = ((pg_flags >> PG_dcache_cpu_shift) &
194 PG_dcache_cpu_mask);
184 int this_cpu = get_cpu(); 195 int this_cpu = get_cpu();
185 196
186 /* This is just to optimize away some function calls 197 /* This is just to optimize away some function calls
diff --git a/arch/sparc64/solaris/socket.c b/arch/sparc64/solaris/socket.c
index 06740582717e..d3a66ea74a7f 100644
--- a/arch/sparc64/solaris/socket.c
+++ b/arch/sparc64/solaris/socket.c
@@ -16,6 +16,7 @@
16#include <linux/net.h> 16#include <linux/net.h>
17#include <linux/compat.h> 17#include <linux/compat.h>
18#include <net/compat.h> 18#include <net/compat.h>
19#include <net/sock.h>
19 20
20#include <asm/uaccess.h> 21#include <asm/uaccess.h>
21#include <asm/string.h> 22#include <asm/string.h>
@@ -297,121 +298,165 @@ asmlinkage int solaris_sendmsg(int fd, struct sol_nmsghdr __user *user_msg, unsi
297{ 298{
298 struct socket *sock; 299 struct socket *sock;
299 char address[MAX_SOCK_ADDR]; 300 char address[MAX_SOCK_ADDR];
300 struct iovec iov[UIO_FASTIOV]; 301 struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
301 unsigned char ctl[sizeof(struct cmsghdr) + 20]; 302 unsigned char ctl[sizeof(struct cmsghdr) + 20];
302 unsigned char *ctl_buf = ctl; 303 unsigned char *ctl_buf = ctl;
303 struct msghdr kern_msg; 304 struct msghdr msg_sys;
304 int err, total_len; 305 int err, ctl_len, iov_size, total_len;
305 306
306 if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) 307 err = -EFAULT;
307 return -EFAULT; 308 if (msghdr_from_user32_to_kern(&msg_sys, user_msg))
308 if(kern_msg.msg_iovlen > UIO_MAXIOV) 309 goto out;
309 return -EINVAL; 310
310 err = verify_compat_iovec(&kern_msg, iov, address, VERIFY_READ); 311 sock = sockfd_lookup(fd, &err);
311 if (err < 0) 312 if (!sock)
312 goto out; 313 goto out;
314
315 /* do not move before msg_sys is valid */
316 err = -EMSGSIZE;
317 if (msg_sys.msg_iovlen > UIO_MAXIOV)
318 goto out_put;
319
320 /* Check whether to allocate the iovec area*/
321 err = -ENOMEM;
322 iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
323 if (msg_sys.msg_iovlen > UIO_FASTIOV) {
324 iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
325 if (!iov)
326 goto out_put;
327 }
328
329 err = verify_compat_iovec(&msg_sys, iov, address, VERIFY_READ);
330 if (err < 0)
331 goto out_freeiov;
313 total_len = err; 332 total_len = err;
314 333
315 if(kern_msg.msg_controllen) { 334 err = -ENOBUFS;
316 struct sol_cmsghdr __user *ucmsg = kern_msg.msg_control; 335 if (msg_sys.msg_controllen > INT_MAX)
336 goto out_freeiov;
337
338 ctl_len = msg_sys.msg_controllen;
339 if (ctl_len) {
340 struct sol_cmsghdr __user *ucmsg = msg_sys.msg_control;
317 unsigned long *kcmsg; 341 unsigned long *kcmsg;
318 compat_size_t cmlen; 342 compat_size_t cmlen;
319 343
320 if (kern_msg.msg_controllen <= sizeof(compat_size_t)) 344 err = -EINVAL;
321 return -EINVAL; 345 if (ctl_len <= sizeof(compat_size_t))
346 goto out_freeiov;
322 347
323 if(kern_msg.msg_controllen > sizeof(ctl)) { 348 if (ctl_len > sizeof(ctl)) {
324 err = -ENOBUFS; 349 err = -ENOBUFS;
325 ctl_buf = kmalloc(kern_msg.msg_controllen, GFP_KERNEL); 350 ctl_buf = kmalloc(ctl_len, GFP_KERNEL);
326 if(!ctl_buf) 351 if (!ctl_buf)
327 goto out_freeiov; 352 goto out_freeiov;
328 } 353 }
329 __get_user(cmlen, &ucmsg->cmsg_len); 354 __get_user(cmlen, &ucmsg->cmsg_len);
330 kcmsg = (unsigned long *) ctl_buf; 355 kcmsg = (unsigned long *) ctl_buf;
331 *kcmsg++ = (unsigned long)cmlen; 356 *kcmsg++ = (unsigned long)cmlen;
332 err = -EFAULT; 357 err = -EFAULT;
333 if(copy_from_user(kcmsg, &ucmsg->cmsg_level, 358 if (copy_from_user(kcmsg, &ucmsg->cmsg_level,
334 kern_msg.msg_controllen - sizeof(compat_size_t))) 359 ctl_len - sizeof(compat_size_t)))
335 goto out_freectl; 360 goto out_freectl;
336 kern_msg.msg_control = ctl_buf; 361 msg_sys.msg_control = ctl_buf;
337 } 362 }
338 kern_msg.msg_flags = solaris_to_linux_msgflags(user_flags); 363 msg_sys.msg_flags = solaris_to_linux_msgflags(user_flags);
339 364
340 lock_kernel(); 365 if (sock->file->f_flags & O_NONBLOCK)
341 sock = sockfd_lookup(fd, &err); 366 msg_sys.msg_flags |= MSG_DONTWAIT;
342 if (sock != NULL) { 367 err = sock_sendmsg(sock, &msg_sys, total_len);
343 if (sock->file->f_flags & O_NONBLOCK)
344 kern_msg.msg_flags |= MSG_DONTWAIT;
345 err = sock_sendmsg(sock, &kern_msg, total_len);
346 sockfd_put(sock);
347 }
348 unlock_kernel();
349 368
350out_freectl: 369out_freectl:
351 /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */ 370 if (ctl_buf != ctl)
352 if(ctl_buf != ctl) 371 sock_kfree_s(sock->sk, ctl_buf, ctl_len);
353 kfree(ctl_buf);
354out_freeiov: 372out_freeiov:
355 if(kern_msg.msg_iov != iov) 373 if (iov != iovstack)
356 kfree(kern_msg.msg_iov); 374 sock_kfree_s(sock->sk, iov, iov_size);
357out: 375out_put:
376 sockfd_put(sock);
377out:
358 return err; 378 return err;
359} 379}
360 380
361asmlinkage int solaris_recvmsg(int fd, struct sol_nmsghdr __user *user_msg, unsigned int user_flags) 381asmlinkage int solaris_recvmsg(int fd, struct sol_nmsghdr __user *user_msg, unsigned int user_flags)
362{ 382{
363 struct iovec iovstack[UIO_FASTIOV];
364 struct msghdr kern_msg;
365 char addr[MAX_SOCK_ADDR];
366 struct socket *sock; 383 struct socket *sock;
384 struct iovec iovstack[UIO_FASTIOV];
367 struct iovec *iov = iovstack; 385 struct iovec *iov = iovstack;
386 struct msghdr msg_sys;
387 unsigned long cmsg_ptr;
388 int err, iov_size, total_len, len;
389
390 /* kernel mode address */
391 char addr[MAX_SOCK_ADDR];
392
393 /* user mode address pointers */
368 struct sockaddr __user *uaddr; 394 struct sockaddr __user *uaddr;
369 int __user *uaddr_len; 395 int __user *uaddr_len;
370 unsigned long cmsg_ptr;
371 int err, total_len, len = 0;
372 396
373 if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) 397 if (msghdr_from_user32_to_kern(&msg_sys, user_msg))
374 return -EFAULT; 398 return -EFAULT;
375 if(kern_msg.msg_iovlen > UIO_MAXIOV)
376 return -EINVAL;
377 399
378 uaddr = kern_msg.msg_name; 400 sock = sockfd_lookup(fd, &err);
401 if (!sock)
402 goto out;
403
404 err = -EMSGSIZE;
405 if (msg_sys.msg_iovlen > UIO_MAXIOV)
406 goto out_put;
407
408 /* Check whether to allocate the iovec area*/
409 err = -ENOMEM;
410 iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
411 if (msg_sys.msg_iovlen > UIO_FASTIOV) {
412 iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
413 if (!iov)
414 goto out_put;
415 }
416
417 /*
418 * Save the user-mode address (verify_iovec will change the
419 * kernel msghdr to use the kernel address space)
420 */
421
422 uaddr = (void __user *) msg_sys.msg_name;
379 uaddr_len = &user_msg->msg_namelen; 423 uaddr_len = &user_msg->msg_namelen;
380 err = verify_compat_iovec(&kern_msg, iov, addr, VERIFY_WRITE); 424 err = verify_compat_iovec(&msg_sys, iov, addr, VERIFY_WRITE);
381 if (err < 0) 425 if (err < 0)
382 goto out; 426 goto out_freeiov;
383 total_len = err; 427 total_len = err;
384 428
385 cmsg_ptr = (unsigned long) kern_msg.msg_control; 429 cmsg_ptr = (unsigned long) msg_sys.msg_control;
386 kern_msg.msg_flags = 0; 430 msg_sys.msg_flags = MSG_CMSG_COMPAT;
387 431
388 lock_kernel(); 432 if (sock->file->f_flags & O_NONBLOCK)
389 sock = sockfd_lookup(fd, &err); 433 user_flags |= MSG_DONTWAIT;
390 if (sock != NULL) { 434
391 if (sock->file->f_flags & O_NONBLOCK) 435 err = sock_recvmsg(sock, &msg_sys, total_len, user_flags);
392 user_flags |= MSG_DONTWAIT; 436 if(err < 0)
393 err = sock_recvmsg(sock, &kern_msg, total_len, user_flags); 437 goto out_freeiov;
394 if(err >= 0) 438
395 len = err; 439 len = err;
396 sockfd_put(sock); 440
397 } 441 if (uaddr != NULL) {
398 unlock_kernel(); 442 err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len);
399 443 if (err < 0)
400 if(uaddr != NULL && err >= 0) 444 goto out_freeiov;
401 err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
402 if(err >= 0) {
403 err = __put_user(linux_to_solaris_msgflags(kern_msg.msg_flags), &user_msg->msg_flags);
404 if(!err) {
405 /* XXX Convert cmsg back into userspace 32-bit format... */
406 err = __put_user((unsigned long)kern_msg.msg_control - cmsg_ptr,
407 &user_msg->msg_controllen);
408 }
409 } 445 }
446 err = __put_user(linux_to_solaris_msgflags(msg_sys.msg_flags), &user_msg->msg_flags);
447 if (err)
448 goto out_freeiov;
449 err = __put_user((unsigned long)msg_sys.msg_control - cmsg_ptr,
450 &user_msg->msg_controllen);
451 if (err)
452 goto out_freeiov;
453 err = len;
410 454
411 if(kern_msg.msg_iov != iov) 455out_freeiov:
412 kfree(kern_msg.msg_iov); 456 if (iov != iovstack)
457 sock_kfree_s(sock->sk, iov, iov_size);
458out_put:
459 sockfd_put(sock);
413out: 460out:
414 if(err < 0) 461 return err;
415 return err;
416 return len;
417} 462}