ia64/linux-2.6.18-xen.hg

view arch/alpha/kernel/osf_sys.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /*
2 * linux/arch/alpha/kernel/osf_sys.c
3 *
4 * Copyright (C) 1995 Linus Torvalds
5 */
7 /*
8 * This file handles some of the stranger OSF/1 system call interfaces.
9 * Some of the system calls expect a non-C calling standard, others have
10 * special parameter blocks..
11 */
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/mm.h>
17 #include <linux/smp.h>
18 #include <linux/smp_lock.h>
19 #include <linux/stddef.h>
20 #include <linux/syscalls.h>
21 #include <linux/unistd.h>
22 #include <linux/ptrace.h>
23 #include <linux/slab.h>
24 #include <linux/user.h>
25 #include <linux/a.out.h>
26 #include <linux/utsname.h>
27 #include <linux/time.h>
28 #include <linux/timex.h>
29 #include <linux/major.h>
30 #include <linux/stat.h>
31 #include <linux/mman.h>
32 #include <linux/shm.h>
33 #include <linux/poll.h>
34 #include <linux/file.h>
35 #include <linux/types.h>
36 #include <linux/ipc.h>
37 #include <linux/namei.h>
38 #include <linux/uio.h>
39 #include <linux/vfs.h>
40 #include <linux/rcupdate.h>
42 #include <asm/fpu.h>
43 #include <asm/io.h>
44 #include <asm/uaccess.h>
45 #include <asm/system.h>
46 #include <asm/sysinfo.h>
47 #include <asm/hwrpb.h>
48 #include <asm/processor.h>
50 extern int do_pipe(int *);
52 /*
53 * Brk needs to return an error. Still support Linux's brk(0) query idiom,
54 * which OSF programs just shouldn't be doing. We're still not quite
55 * identical to OSF as we don't return 0 on success, but doing otherwise
56 * would require changes to libc. Hopefully this is good enough.
57 */
58 asmlinkage unsigned long
59 osf_brk(unsigned long brk)
60 {
61 unsigned long retval = sys_brk(brk);
62 if (brk && brk != retval)
63 retval = -ENOMEM;
64 return retval;
65 }
67 /*
68 * This is pure guess-work..
69 */
70 asmlinkage int
71 osf_set_program_attributes(unsigned long text_start, unsigned long text_len,
72 unsigned long bss_start, unsigned long bss_len)
73 {
74 struct mm_struct *mm;
76 lock_kernel();
77 mm = current->mm;
78 mm->end_code = bss_start + bss_len;
79 mm->brk = bss_start + bss_len;
80 #if 0
81 printk("set_program_attributes(%lx %lx %lx %lx)\n",
82 text_start, text_len, bss_start, bss_len);
83 #endif
84 unlock_kernel();
85 return 0;
86 }
88 /*
89 * OSF/1 directory handling functions...
90 *
91 * The "getdents()" interface is much more sane: the "basep" stuff is
92 * braindamage (it can't really handle filesystems where the directory
93 * offset differences aren't the same as "d_reclen").
94 */
95 #define NAME_OFFSET offsetof (struct osf_dirent, d_name)
96 #define ROUND_UP(x) (((x)+3) & ~3)
98 struct osf_dirent {
99 unsigned int d_ino;
100 unsigned short d_reclen;
101 unsigned short d_namlen;
102 char d_name[1];
103 };
105 struct osf_dirent_callback {
106 struct osf_dirent __user *dirent;
107 long __user *basep;
108 unsigned int count;
109 int error;
110 };
112 static int
113 osf_filldir(void *__buf, const char *name, int namlen, loff_t offset,
114 ino_t ino, unsigned int d_type)
115 {
116 struct osf_dirent __user *dirent;
117 struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf;
118 unsigned int reclen = ROUND_UP(NAME_OFFSET + namlen + 1);
120 buf->error = -EINVAL; /* only used if we fail */
121 if (reclen > buf->count)
122 return -EINVAL;
123 if (buf->basep) {
124 if (put_user(offset, buf->basep))
125 return -EFAULT;
126 buf->basep = NULL;
127 }
128 dirent = buf->dirent;
129 put_user(ino, &dirent->d_ino);
130 put_user(namlen, &dirent->d_namlen);
131 put_user(reclen, &dirent->d_reclen);
132 if (copy_to_user(dirent->d_name, name, namlen) ||
133 put_user(0, dirent->d_name + namlen))
134 return -EFAULT;
135 dirent = (void __user *)dirent + reclen;
136 buf->dirent = dirent;
137 buf->count -= reclen;
138 return 0;
139 }
141 asmlinkage int
142 osf_getdirentries(unsigned int fd, struct osf_dirent __user *dirent,
143 unsigned int count, long __user *basep)
144 {
145 int error;
146 struct file *file;
147 struct osf_dirent_callback buf;
149 error = -EBADF;
150 file = fget(fd);
151 if (!file)
152 goto out;
154 buf.dirent = dirent;
155 buf.basep = basep;
156 buf.count = count;
157 buf.error = 0;
159 error = vfs_readdir(file, osf_filldir, &buf);
160 if (error < 0)
161 goto out_putf;
163 error = buf.error;
164 if (count != buf.count)
165 error = count - buf.count;
167 out_putf:
168 fput(file);
169 out:
170 return error;
171 }
173 #undef ROUND_UP
174 #undef NAME_OFFSET
176 asmlinkage unsigned long
177 osf_mmap(unsigned long addr, unsigned long len, unsigned long prot,
178 unsigned long flags, unsigned long fd, unsigned long off)
179 {
180 struct file *file = NULL;
181 unsigned long ret = -EBADF;
183 #if 0
184 if (flags & (_MAP_HASSEMAPHORE | _MAP_INHERIT | _MAP_UNALIGNED))
185 printk("%s: unimplemented OSF mmap flags %04lx\n",
186 current->comm, flags);
187 #endif
188 if (!(flags & MAP_ANONYMOUS)) {
189 file = fget(fd);
190 if (!file)
191 goto out;
192 }
193 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
194 down_write(&current->mm->mmap_sem);
195 ret = do_mmap(file, addr, len, prot, flags, off);
196 up_write(&current->mm->mmap_sem);
197 if (file)
198 fput(file);
199 out:
200 return ret;
201 }
204 /*
205 * The OSF/1 statfs structure is much larger, but this should
206 * match the beginning, at least.
207 */
208 struct osf_statfs {
209 short f_type;
210 short f_flags;
211 int f_fsize;
212 int f_bsize;
213 int f_blocks;
214 int f_bfree;
215 int f_bavail;
216 int f_files;
217 int f_ffree;
218 __kernel_fsid_t f_fsid;
219 };
221 static int
222 linux_to_osf_statfs(struct kstatfs *linux_stat, struct osf_statfs __user *osf_stat,
223 unsigned long bufsiz)
224 {
225 struct osf_statfs tmp_stat;
227 tmp_stat.f_type = linux_stat->f_type;
228 tmp_stat.f_flags = 0; /* mount flags */
229 tmp_stat.f_fsize = linux_stat->f_frsize;
230 tmp_stat.f_bsize = linux_stat->f_bsize;
231 tmp_stat.f_blocks = linux_stat->f_blocks;
232 tmp_stat.f_bfree = linux_stat->f_bfree;
233 tmp_stat.f_bavail = linux_stat->f_bavail;
234 tmp_stat.f_files = linux_stat->f_files;
235 tmp_stat.f_ffree = linux_stat->f_ffree;
236 tmp_stat.f_fsid = linux_stat->f_fsid;
237 if (bufsiz > sizeof(tmp_stat))
238 bufsiz = sizeof(tmp_stat);
239 return copy_to_user(osf_stat, &tmp_stat, bufsiz) ? -EFAULT : 0;
240 }
242 static int
243 do_osf_statfs(struct dentry * dentry, struct osf_statfs __user *buffer,
244 unsigned long bufsiz)
245 {
246 struct kstatfs linux_stat;
247 int error = vfs_statfs(dentry, &linux_stat);
248 if (!error)
249 error = linux_to_osf_statfs(&linux_stat, buffer, bufsiz);
250 return error;
251 }
253 asmlinkage int
254 osf_statfs(char __user *path, struct osf_statfs __user *buffer, unsigned long bufsiz)
255 {
256 struct nameidata nd;
257 int retval;
259 retval = user_path_walk(path, &nd);
260 if (!retval) {
261 retval = do_osf_statfs(nd.dentry, buffer, bufsiz);
262 path_release(&nd);
263 }
264 return retval;
265 }
267 asmlinkage int
268 osf_fstatfs(unsigned long fd, struct osf_statfs __user *buffer, unsigned long bufsiz)
269 {
270 struct file *file;
271 int retval;
273 retval = -EBADF;
274 file = fget(fd);
275 if (file) {
276 retval = do_osf_statfs(file->f_dentry, buffer, bufsiz);
277 fput(file);
278 }
279 return retval;
280 }
282 /*
283 * Uhh.. OSF/1 mount parameters aren't exactly obvious..
284 *
285 * Although to be frank, neither are the native Linux/i386 ones..
286 */
287 struct ufs_args {
288 char __user *devname;
289 int flags;
290 uid_t exroot;
291 };
293 struct cdfs_args {
294 char __user *devname;
295 int flags;
296 uid_t exroot;
298 /* This has lots more here, which Linux handles with the option block
299 but I'm too lazy to do the translation into ASCII. */
300 };
302 struct procfs_args {
303 char __user *devname;
304 int flags;
305 uid_t exroot;
306 };
308 /*
309 * We can't actually handle ufs yet, so we translate UFS mounts to
310 * ext2fs mounts. I wouldn't mind a UFS filesystem, but the UFS
311 * layout is so braindead it's a major headache doing it.
312 *
313 * Just how long ago was it written? OTOH our UFS driver may be still
314 * unhappy with OSF UFS. [CHECKME]
315 */
316 static int
317 osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags)
318 {
319 int retval;
320 struct cdfs_args tmp;
321 char *devname;
323 retval = -EFAULT;
324 if (copy_from_user(&tmp, args, sizeof(tmp)))
325 goto out;
326 devname = getname(tmp.devname);
327 retval = PTR_ERR(devname);
328 if (IS_ERR(devname))
329 goto out;
330 retval = do_mount(devname, dirname, "ext2", flags, NULL);
331 putname(devname);
332 out:
333 return retval;
334 }
336 static int
337 osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags)
338 {
339 int retval;
340 struct cdfs_args tmp;
341 char *devname;
343 retval = -EFAULT;
344 if (copy_from_user(&tmp, args, sizeof(tmp)))
345 goto out;
346 devname = getname(tmp.devname);
347 retval = PTR_ERR(devname);
348 if (IS_ERR(devname))
349 goto out;
350 retval = do_mount(devname, dirname, "iso9660", flags, NULL);
351 putname(devname);
352 out:
353 return retval;
354 }
356 static int
357 osf_procfs_mount(char *dirname, struct procfs_args __user *args, int flags)
358 {
359 struct procfs_args tmp;
361 if (copy_from_user(&tmp, args, sizeof(tmp)))
362 return -EFAULT;
364 return do_mount("", dirname, "proc", flags, NULL);
365 }
367 asmlinkage int
368 osf_mount(unsigned long typenr, char __user *path, int flag, void __user *data)
369 {
370 int retval = -EINVAL;
371 char *name;
373 lock_kernel();
375 name = getname(path);
376 retval = PTR_ERR(name);
377 if (IS_ERR(name))
378 goto out;
379 switch (typenr) {
380 case 1:
381 retval = osf_ufs_mount(name, data, flag);
382 break;
383 case 6:
384 retval = osf_cdfs_mount(name, data, flag);
385 break;
386 case 9:
387 retval = osf_procfs_mount(name, data, flag);
388 break;
389 default:
390 printk("osf_mount(%ld, %x)\n", typenr, flag);
391 }
392 putname(name);
393 out:
394 unlock_kernel();
395 return retval;
396 }
398 asmlinkage int
399 osf_utsname(char __user *name)
400 {
401 int error;
403 down_read(&uts_sem);
404 error = -EFAULT;
405 if (copy_to_user(name + 0, system_utsname.sysname, 32))
406 goto out;
407 if (copy_to_user(name + 32, system_utsname.nodename, 32))
408 goto out;
409 if (copy_to_user(name + 64, system_utsname.release, 32))
410 goto out;
411 if (copy_to_user(name + 96, system_utsname.version, 32))
412 goto out;
413 if (copy_to_user(name + 128, system_utsname.machine, 32))
414 goto out;
416 error = 0;
417 out:
418 up_read(&uts_sem);
419 return error;
420 }
422 asmlinkage unsigned long
423 sys_getpagesize(void)
424 {
425 return PAGE_SIZE;
426 }
428 asmlinkage unsigned long
429 sys_getdtablesize(void)
430 {
431 return NR_OPEN;
432 }
434 /*
435 * For compatibility with OSF/1 only. Use utsname(2) instead.
436 */
437 asmlinkage int
438 osf_getdomainname(char __user *name, int namelen)
439 {
440 unsigned len;
441 int i;
443 if (!access_ok(VERIFY_WRITE, name, namelen))
444 return -EFAULT;
446 len = namelen;
447 if (namelen > 32)
448 len = 32;
450 down_read(&uts_sem);
451 for (i = 0; i < len; ++i) {
452 __put_user(system_utsname.domainname[i], name + i);
453 if (system_utsname.domainname[i] == '\0')
454 break;
455 }
456 up_read(&uts_sem);
458 return 0;
459 }
461 /*
462 * The following stuff should move into a header file should it ever
463 * be labeled "officially supported." Right now, there is just enough
464 * support to avoid applications (such as tar) printing error
465 * messages. The attributes are not really implemented.
466 */
468 /*
469 * Values for Property list entry flag
470 */
471 #define PLE_PROPAGATE_ON_COPY 0x1 /* cp(1) will copy entry
472 by default */
473 #define PLE_FLAG_MASK 0x1 /* Valid flag values */
474 #define PLE_FLAG_ALL -1 /* All flag value */
476 struct proplistname_args {
477 unsigned int pl_mask;
478 unsigned int pl_numnames;
479 char **pl_names;
480 };
482 union pl_args {
483 struct setargs {
484 char __user *path;
485 long follow;
486 long nbytes;
487 char __user *buf;
488 } set;
489 struct fsetargs {
490 long fd;
491 long nbytes;
492 char __user *buf;
493 } fset;
494 struct getargs {
495 char __user *path;
496 long follow;
497 struct proplistname_args __user *name_args;
498 long nbytes;
499 char __user *buf;
500 int __user *min_buf_size;
501 } get;
502 struct fgetargs {
503 long fd;
504 struct proplistname_args __user *name_args;
505 long nbytes;
506 char __user *buf;
507 int __user *min_buf_size;
508 } fget;
509 struct delargs {
510 char __user *path;
511 long follow;
512 struct proplistname_args __user *name_args;
513 } del;
514 struct fdelargs {
515 long fd;
516 struct proplistname_args __user *name_args;
517 } fdel;
518 };
520 enum pl_code {
521 PL_SET = 1, PL_FSET = 2,
522 PL_GET = 3, PL_FGET = 4,
523 PL_DEL = 5, PL_FDEL = 6
524 };
526 asmlinkage long
527 osf_proplist_syscall(enum pl_code code, union pl_args __user *args)
528 {
529 long error;
530 int __user *min_buf_size_ptr;
532 lock_kernel();
533 switch (code) {
534 case PL_SET:
535 if (get_user(error, &args->set.nbytes))
536 error = -EFAULT;
537 break;
538 case PL_FSET:
539 if (get_user(error, &args->fset.nbytes))
540 error = -EFAULT;
541 break;
542 case PL_GET:
543 error = get_user(min_buf_size_ptr, &args->get.min_buf_size);
544 if (error)
545 break;
546 error = put_user(0, min_buf_size_ptr);
547 break;
548 case PL_FGET:
549 error = get_user(min_buf_size_ptr, &args->fget.min_buf_size);
550 if (error)
551 break;
552 error = put_user(0, min_buf_size_ptr);
553 break;
554 case PL_DEL:
555 case PL_FDEL:
556 error = 0;
557 break;
558 default:
559 error = -EOPNOTSUPP;
560 break;
561 };
562 unlock_kernel();
563 return error;
564 }
566 asmlinkage int
567 osf_sigstack(struct sigstack __user *uss, struct sigstack __user *uoss)
568 {
569 unsigned long usp = rdusp();
570 unsigned long oss_sp = current->sas_ss_sp + current->sas_ss_size;
571 unsigned long oss_os = on_sig_stack(usp);
572 int error;
574 if (uss) {
575 void __user *ss_sp;
577 error = -EFAULT;
578 if (get_user(ss_sp, &uss->ss_sp))
579 goto out;
581 /* If the current stack was set with sigaltstack, don't
582 swap stacks while we are on it. */
583 error = -EPERM;
584 if (current->sas_ss_sp && on_sig_stack(usp))
585 goto out;
587 /* Since we don't know the extent of the stack, and we don't
588 track onstack-ness, but rather calculate it, we must
589 presume a size. Ho hum this interface is lossy. */
590 current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ;
591 current->sas_ss_size = SIGSTKSZ;
592 }
594 if (uoss) {
595 error = -EFAULT;
596 if (! access_ok(VERIFY_WRITE, uoss, sizeof(*uoss))
597 || __put_user(oss_sp, &uoss->ss_sp)
598 || __put_user(oss_os, &uoss->ss_onstack))
599 goto out;
600 }
602 error = 0;
603 out:
604 return error;
605 }
607 asmlinkage long
608 osf_sysinfo(int command, char __user *buf, long count)
609 {
610 static char * sysinfo_table[] = {
611 system_utsname.sysname,
612 system_utsname.nodename,
613 system_utsname.release,
614 system_utsname.version,
615 system_utsname.machine,
616 "alpha", /* instruction set architecture */
617 "dummy", /* hardware serial number */
618 "dummy", /* hardware manufacturer */
619 "dummy", /* secure RPC domain */
620 };
621 unsigned long offset;
622 char *res;
623 long len, err = -EINVAL;
625 offset = command-1;
626 if (offset >= ARRAY_SIZE(sysinfo_table)) {
627 /* Digital UNIX has a few unpublished interfaces here */
628 printk("sysinfo(%d)", command);
629 goto out;
630 }
632 down_read(&uts_sem);
633 res = sysinfo_table[offset];
634 len = strlen(res)+1;
635 if (len > count)
636 len = count;
637 if (copy_to_user(buf, res, len))
638 err = -EFAULT;
639 else
640 err = 0;
641 up_read(&uts_sem);
642 out:
643 return err;
644 }
646 asmlinkage unsigned long
647 osf_getsysinfo(unsigned long op, void __user *buffer, unsigned long nbytes,
648 int __user *start, void __user *arg)
649 {
650 unsigned long w;
651 struct percpu_struct *cpu;
653 switch (op) {
654 case GSI_IEEE_FP_CONTROL:
655 /* Return current software fp control & status bits. */
656 /* Note that DU doesn't verify available space here. */
658 w = current_thread_info()->ieee_state & IEEE_SW_MASK;
659 w = swcr_update_status(w, rdfpcr());
660 if (put_user(w, (unsigned long __user *) buffer))
661 return -EFAULT;
662 return 0;
664 case GSI_IEEE_STATE_AT_SIGNAL:
665 /*
666 * Not sure anybody will ever use this weird stuff. These
667 * ops can be used (under OSF/1) to set the fpcr that should
668 * be used when a signal handler starts executing.
669 */
670 break;
672 case GSI_UACPROC:
673 if (nbytes < sizeof(unsigned int))
674 return -EINVAL;
675 w = (current_thread_info()->flags >> UAC_SHIFT) & UAC_BITMASK;
676 if (put_user(w, (unsigned int __user *)buffer))
677 return -EFAULT;
678 return 1;
680 case GSI_PROC_TYPE:
681 if (nbytes < sizeof(unsigned long))
682 return -EINVAL;
683 cpu = (struct percpu_struct*)
684 ((char*)hwrpb + hwrpb->processor_offset);
685 w = cpu->type;
686 if (put_user(w, (unsigned long __user*)buffer))
687 return -EFAULT;
688 return 1;
690 case GSI_GET_HWRPB:
691 if (nbytes < sizeof(*hwrpb))
692 return -EINVAL;
693 if (copy_to_user(buffer, hwrpb, nbytes) != 0)
694 return -EFAULT;
695 return 1;
697 default:
698 break;
699 }
701 return -EOPNOTSUPP;
702 }
704 asmlinkage unsigned long
705 osf_setsysinfo(unsigned long op, void __user *buffer, unsigned long nbytes,
706 int __user *start, void __user *arg)
707 {
708 switch (op) {
709 case SSI_IEEE_FP_CONTROL: {
710 unsigned long swcr, fpcr;
711 unsigned int *state;
713 /*
714 * Alpha Architecture Handbook 4.7.7.3:
715 * To be fully IEEE compiant, we must track the current IEEE
716 * exception state in software, because spurrious bits can be
717 * set in the trap shadow of a software-complete insn.
718 */
720 if (get_user(swcr, (unsigned long __user *)buffer))
721 return -EFAULT;
722 state = &current_thread_info()->ieee_state;
724 /* Update softare trap enable bits. */
725 *state = (*state & ~IEEE_SW_MASK) | (swcr & IEEE_SW_MASK);
727 /* Update the real fpcr. */
728 fpcr = rdfpcr() & FPCR_DYN_MASK;
729 fpcr |= ieee_swcr_to_fpcr(swcr);
730 wrfpcr(fpcr);
732 return 0;
733 }
735 case SSI_IEEE_RAISE_EXCEPTION: {
736 unsigned long exc, swcr, fpcr, fex;
737 unsigned int *state;
739 if (get_user(exc, (unsigned long __user *)buffer))
740 return -EFAULT;
741 state = &current_thread_info()->ieee_state;
742 exc &= IEEE_STATUS_MASK;
744 /* Update softare trap enable bits. */
745 swcr = (*state & IEEE_SW_MASK) | exc;
746 *state |= exc;
748 /* Update the real fpcr. */
749 fpcr = rdfpcr();
750 fpcr |= ieee_swcr_to_fpcr(swcr);
751 wrfpcr(fpcr);
753 /* If any exceptions set by this call, and are unmasked,
754 send a signal. Old exceptions are not signaled. */
755 fex = (exc >> IEEE_STATUS_TO_EXCSUM_SHIFT) & swcr;
756 if (fex) {
757 siginfo_t info;
758 int si_code = 0;
760 if (fex & IEEE_TRAP_ENABLE_DNO) si_code = FPE_FLTUND;
761 if (fex & IEEE_TRAP_ENABLE_INE) si_code = FPE_FLTRES;
762 if (fex & IEEE_TRAP_ENABLE_UNF) si_code = FPE_FLTUND;
763 if (fex & IEEE_TRAP_ENABLE_OVF) si_code = FPE_FLTOVF;
764 if (fex & IEEE_TRAP_ENABLE_DZE) si_code = FPE_FLTDIV;
765 if (fex & IEEE_TRAP_ENABLE_INV) si_code = FPE_FLTINV;
767 info.si_signo = SIGFPE;
768 info.si_errno = 0;
769 info.si_code = si_code;
770 info.si_addr = NULL; /* FIXME */
771 send_sig_info(SIGFPE, &info, current);
772 }
773 return 0;
774 }
776 case SSI_IEEE_STATE_AT_SIGNAL:
777 case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
778 /*
779 * Not sure anybody will ever use this weird stuff. These
780 * ops can be used (under OSF/1) to set the fpcr that should
781 * be used when a signal handler starts executing.
782 */
783 break;
785 case SSI_NVPAIRS: {
786 unsigned long v, w, i;
787 unsigned int old, new;
789 for (i = 0; i < nbytes; ++i) {
791 if (get_user(v, 2*i + (unsigned int __user *)buffer))
792 return -EFAULT;
793 if (get_user(w, 2*i + 1 + (unsigned int __user *)buffer))
794 return -EFAULT;
795 switch (v) {
796 case SSIN_UACPROC:
797 again:
798 old = current_thread_info()->flags;
799 new = old & ~(UAC_BITMASK << UAC_SHIFT);
800 new = new | (w & UAC_BITMASK) << UAC_SHIFT;
801 if (cmpxchg(&current_thread_info()->flags,
802 old, new) != old)
803 goto again;
804 break;
806 default:
807 return -EOPNOTSUPP;
808 }
809 }
810 return 0;
811 }
813 default:
814 break;
815 }
817 return -EOPNOTSUPP;
818 }
820 /* Translations due to the fact that OSF's time_t is an int. Which
821 affects all sorts of things, like timeval and itimerval. */
823 extern struct timezone sys_tz;
825 struct timeval32
826 {
827 int tv_sec, tv_usec;
828 };
830 struct itimerval32
831 {
832 struct timeval32 it_interval;
833 struct timeval32 it_value;
834 };
836 static inline long
837 get_tv32(struct timeval *o, struct timeval32 __user *i)
838 {
839 return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
840 (__get_user(o->tv_sec, &i->tv_sec) |
841 __get_user(o->tv_usec, &i->tv_usec)));
842 }
844 static inline long
845 put_tv32(struct timeval32 __user *o, struct timeval *i)
846 {
847 return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
848 (__put_user(i->tv_sec, &o->tv_sec) |
849 __put_user(i->tv_usec, &o->tv_usec)));
850 }
852 static inline long
853 get_it32(struct itimerval *o, struct itimerval32 __user *i)
854 {
855 return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
856 (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
857 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
858 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
859 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
860 }
862 static inline long
863 put_it32(struct itimerval32 __user *o, struct itimerval *i)
864 {
865 return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
866 (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
867 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
868 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
869 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
870 }
872 static inline void
873 jiffies_to_timeval32(unsigned long jiffies, struct timeval32 *value)
874 {
875 value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
876 value->tv_sec = jiffies / HZ;
877 }
879 asmlinkage int
880 osf_gettimeofday(struct timeval32 __user *tv, struct timezone __user *tz)
881 {
882 if (tv) {
883 struct timeval ktv;
884 do_gettimeofday(&ktv);
885 if (put_tv32(tv, &ktv))
886 return -EFAULT;
887 }
888 if (tz) {
889 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
890 return -EFAULT;
891 }
892 return 0;
893 }
895 asmlinkage int
896 osf_settimeofday(struct timeval32 __user *tv, struct timezone __user *tz)
897 {
898 struct timespec kts;
899 struct timezone ktz;
901 if (tv) {
902 if (get_tv32((struct timeval *)&kts, tv))
903 return -EFAULT;
904 }
905 if (tz) {
906 if (copy_from_user(&ktz, tz, sizeof(*tz)))
907 return -EFAULT;
908 }
910 kts.tv_nsec *= 1000;
912 return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
913 }
915 asmlinkage int
916 osf_getitimer(int which, struct itimerval32 __user *it)
917 {
918 struct itimerval kit;
919 int error;
921 error = do_getitimer(which, &kit);
922 if (!error && put_it32(it, &kit))
923 error = -EFAULT;
925 return error;
926 }
928 asmlinkage int
929 osf_setitimer(int which, struct itimerval32 __user *in, struct itimerval32 __user *out)
930 {
931 struct itimerval kin, kout;
932 int error;
934 if (in) {
935 if (get_it32(&kin, in))
936 return -EFAULT;
937 } else
938 memset(&kin, 0, sizeof(kin));
940 error = do_setitimer(which, &kin, out ? &kout : NULL);
941 if (error || !out)
942 return error;
944 if (put_it32(out, &kout))
945 return -EFAULT;
947 return 0;
949 }
951 asmlinkage int
952 osf_utimes(char __user *filename, struct timeval32 __user *tvs)
953 {
954 struct timeval ktvs[2];
956 if (tvs) {
957 if (get_tv32(&ktvs[0], &tvs[0]) ||
958 get_tv32(&ktvs[1], &tvs[1]))
959 return -EFAULT;
960 }
962 return do_utimes(AT_FDCWD, filename, tvs ? ktvs : NULL);
963 }
965 #define MAX_SELECT_SECONDS \
966 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
968 asmlinkage int
969 osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp,
970 struct timeval32 __user *tvp)
971 {
972 fd_set_bits fds;
973 char *bits;
974 size_t size;
975 long timeout;
976 int ret = -EINVAL;
977 struct fdtable *fdt;
978 int max_fdset;
980 timeout = MAX_SCHEDULE_TIMEOUT;
981 if (tvp) {
982 time_t sec, usec;
984 if (!access_ok(VERIFY_READ, tvp, sizeof(*tvp))
985 || __get_user(sec, &tvp->tv_sec)
986 || __get_user(usec, &tvp->tv_usec)) {
987 ret = -EFAULT;
988 goto out_nofds;
989 }
991 if (sec < 0 || usec < 0)
992 goto out_nofds;
994 if ((unsigned long) sec < MAX_SELECT_SECONDS) {
995 timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
996 timeout += sec * (unsigned long) HZ;
997 }
998 }
1000 rcu_read_lock();
1001 fdt = files_fdtable(current->files);
1002 max_fdset = fdt->max_fdset;
1003 rcu_read_unlock();
1004 if (n < 0 || n > max_fdset)
1005 goto out_nofds;
1007 /*
1008 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
1009 * since we used fdset we need to allocate memory in units of
1010 * long-words.
1011 */
1012 ret = -ENOMEM;
1013 size = FDS_BYTES(n);
1014 bits = kmalloc(6 * size, GFP_KERNEL);
1015 if (!bits)
1016 goto out_nofds;
1017 fds.in = (unsigned long *) bits;
1018 fds.out = (unsigned long *) (bits + size);
1019 fds.ex = (unsigned long *) (bits + 2*size);
1020 fds.res_in = (unsigned long *) (bits + 3*size);
1021 fds.res_out = (unsigned long *) (bits + 4*size);
1022 fds.res_ex = (unsigned long *) (bits + 5*size);
1024 if ((ret = get_fd_set(n, inp->fds_bits, fds.in)) ||
1025 (ret = get_fd_set(n, outp->fds_bits, fds.out)) ||
1026 (ret = get_fd_set(n, exp->fds_bits, fds.ex)))
1027 goto out;
1028 zero_fd_set(n, fds.res_in);
1029 zero_fd_set(n, fds.res_out);
1030 zero_fd_set(n, fds.res_ex);
1032 ret = do_select(n, &fds, &timeout);
1034 /* OSF does not copy back the remaining time. */
1036 if (ret < 0)
1037 goto out;
1038 if (!ret) {
1039 ret = -ERESTARTNOHAND;
1040 if (signal_pending(current))
1041 goto out;
1042 ret = 0;
1045 if (set_fd_set(n, inp->fds_bits, fds.res_in) ||
1046 set_fd_set(n, outp->fds_bits, fds.res_out) ||
1047 set_fd_set(n, exp->fds_bits, fds.res_ex))
1048 ret = -EFAULT;
1050 out:
1051 kfree(bits);
1052 out_nofds:
1053 return ret;
1056 struct rusage32 {
1057 struct timeval32 ru_utime; /* user time used */
1058 struct timeval32 ru_stime; /* system time used */
1059 long ru_maxrss; /* maximum resident set size */
1060 long ru_ixrss; /* integral shared memory size */
1061 long ru_idrss; /* integral unshared data size */
1062 long ru_isrss; /* integral unshared stack size */
1063 long ru_minflt; /* page reclaims */
1064 long ru_majflt; /* page faults */
1065 long ru_nswap; /* swaps */
1066 long ru_inblock; /* block input operations */
1067 long ru_oublock; /* block output operations */
1068 long ru_msgsnd; /* messages sent */
1069 long ru_msgrcv; /* messages received */
1070 long ru_nsignals; /* signals received */
1071 long ru_nvcsw; /* voluntary context switches */
1072 long ru_nivcsw; /* involuntary " */
1073 };
1075 asmlinkage int
1076 osf_getrusage(int who, struct rusage32 __user *ru)
1078 struct rusage32 r;
1080 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
1081 return -EINVAL;
1083 memset(&r, 0, sizeof(r));
1084 switch (who) {
1085 case RUSAGE_SELF:
1086 jiffies_to_timeval32(current->utime, &r.ru_utime);
1087 jiffies_to_timeval32(current->stime, &r.ru_stime);
1088 r.ru_minflt = current->min_flt;
1089 r.ru_majflt = current->maj_flt;
1090 break;
1091 case RUSAGE_CHILDREN:
1092 jiffies_to_timeval32(current->signal->cutime, &r.ru_utime);
1093 jiffies_to_timeval32(current->signal->cstime, &r.ru_stime);
1094 r.ru_minflt = current->signal->cmin_flt;
1095 r.ru_majflt = current->signal->cmaj_flt;
1096 break;
1099 return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;
1102 asmlinkage long
1103 osf_wait4(pid_t pid, int __user *ustatus, int options,
1104 struct rusage32 __user *ur)
1106 struct rusage r;
1107 long ret, err;
1108 mm_segment_t old_fs;
1110 if (!ur)
1111 return sys_wait4(pid, ustatus, options, NULL);
1113 old_fs = get_fs();
1115 set_fs (KERNEL_DS);
1116 ret = sys_wait4(pid, ustatus, options, (struct rusage __user *) &r);
1117 set_fs (old_fs);
1119 if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur)))
1120 return -EFAULT;
1122 err = 0;
1123 err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec);
1124 err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec);
1125 err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec);
1126 err |= __put_user(r.ru_stime.tv_usec, &ur->ru_stime.tv_usec);
1127 err |= __put_user(r.ru_maxrss, &ur->ru_maxrss);
1128 err |= __put_user(r.ru_ixrss, &ur->ru_ixrss);
1129 err |= __put_user(r.ru_idrss, &ur->ru_idrss);
1130 err |= __put_user(r.ru_isrss, &ur->ru_isrss);
1131 err |= __put_user(r.ru_minflt, &ur->ru_minflt);
1132 err |= __put_user(r.ru_majflt, &ur->ru_majflt);
1133 err |= __put_user(r.ru_nswap, &ur->ru_nswap);
1134 err |= __put_user(r.ru_inblock, &ur->ru_inblock);
1135 err |= __put_user(r.ru_oublock, &ur->ru_oublock);
1136 err |= __put_user(r.ru_msgsnd, &ur->ru_msgsnd);
1137 err |= __put_user(r.ru_msgrcv, &ur->ru_msgrcv);
1138 err |= __put_user(r.ru_nsignals, &ur->ru_nsignals);
1139 err |= __put_user(r.ru_nvcsw, &ur->ru_nvcsw);
1140 err |= __put_user(r.ru_nivcsw, &ur->ru_nivcsw);
1142 return err ? err : ret;
1145 /*
1146 * I don't know what the parameters are: the first one
1147 * seems to be a timeval pointer, and I suspect the second
1148 * one is the time remaining.. Ho humm.. No documentation.
1149 */
1150 asmlinkage int
1151 osf_usleep_thread(struct timeval32 __user *sleep, struct timeval32 __user *remain)
1153 struct timeval tmp;
1154 unsigned long ticks;
1156 if (get_tv32(&tmp, sleep))
1157 goto fault;
1159 ticks = timeval_to_jiffies(&tmp);
1161 ticks = schedule_timeout_interruptible(ticks);
1163 if (remain) {
1164 jiffies_to_timeval(ticks, &tmp);
1165 if (put_tv32(remain, &tmp))
1166 goto fault;
1169 return 0;
1170 fault:
1171 return -EFAULT;
1175 struct timex32 {
1176 unsigned int modes; /* mode selector */
1177 long offset; /* time offset (usec) */
1178 long freq; /* frequency offset (scaled ppm) */
1179 long maxerror; /* maximum error (usec) */
1180 long esterror; /* estimated error (usec) */
1181 int status; /* clock command/status */
1182 long constant; /* pll time constant */
1183 long precision; /* clock precision (usec) (read only) */
1184 long tolerance; /* clock frequency tolerance (ppm)
1185 * (read only)
1186 */
1187 struct timeval32 time; /* (read only) */
1188 long tick; /* (modified) usecs between clock ticks */
1190 long ppsfreq; /* pps frequency (scaled ppm) (ro) */
1191 long jitter; /* pps jitter (us) (ro) */
1192 int shift; /* interval duration (s) (shift) (ro) */
1193 long stabil; /* pps stability (scaled ppm) (ro) */
1194 long jitcnt; /* jitter limit exceeded (ro) */
1195 long calcnt; /* calibration intervals (ro) */
1196 long errcnt; /* calibration errors (ro) */
1197 long stbcnt; /* stability limit exceeded (ro) */
1199 int :32; int :32; int :32; int :32;
1200 int :32; int :32; int :32; int :32;
1201 int :32; int :32; int :32; int :32;
1202 };
1204 asmlinkage int
1205 sys_old_adjtimex(struct timex32 __user *txc_p)
1207 struct timex txc;
1208 int ret;
1210 /* copy relevant bits of struct timex. */
1211 if (copy_from_user(&txc, txc_p, offsetof(struct timex32, time)) ||
1212 copy_from_user(&txc.tick, &txc_p->tick, sizeof(struct timex32) -
1213 offsetof(struct timex32, time)))
1214 return -EFAULT;
1216 ret = do_adjtimex(&txc);
1217 if (ret < 0)
1218 return ret;
1220 /* copy back to timex32 */
1221 if (copy_to_user(txc_p, &txc, offsetof(struct timex32, time)) ||
1222 (copy_to_user(&txc_p->tick, &txc.tick, sizeof(struct timex32) -
1223 offsetof(struct timex32, tick))) ||
1224 (put_tv32(&txc_p->time, &txc.time)))
1225 return -EFAULT;
1227 return ret;
1230 /* Get an address range which is currently unmapped. Similar to the
1231 generic version except that we know how to honor ADDR_LIMIT_32BIT. */
1233 static unsigned long
1234 arch_get_unmapped_area_1(unsigned long addr, unsigned long len,
1235 unsigned long limit)
1237 struct vm_area_struct *vma = find_vma(current->mm, addr);
1239 while (1) {
1240 /* At this point: (!vma || addr < vma->vm_end). */
1241 if (limit - len < addr)
1242 return -ENOMEM;
1243 if (!vma || addr + len <= vma->vm_start)
1244 return addr;
1245 addr = vma->vm_end;
1246 vma = vma->vm_next;
1250 unsigned long
1251 arch_get_unmapped_area(struct file *filp, unsigned long addr,
1252 unsigned long len, unsigned long pgoff,
1253 unsigned long flags)
1255 unsigned long limit;
1257 /* "32 bit" actually means 31 bit, since pointers sign extend. */
1258 if (current->personality & ADDR_LIMIT_32BIT)
1259 limit = 0x80000000;
1260 else
1261 limit = TASK_SIZE;
1263 if (len > limit)
1264 return -ENOMEM;
1266 /* First, see if the given suggestion fits.
1268 The OSF/1 loader (/sbin/loader) relies on us returning an
1269 address larger than the requested if one exists, which is
1270 a terribly broken way to program.
1272 That said, I can see the use in being able to suggest not
1273 merely specific addresses, but regions of memory -- perhaps
1274 this feature should be incorporated into all ports? */
1276 if (addr) {
1277 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
1278 if (addr != (unsigned long) -ENOMEM)
1279 return addr;
1282 /* Next, try allocating at TASK_UNMAPPED_BASE. */
1283 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
1284 len, limit);
1285 if (addr != (unsigned long) -ENOMEM)
1286 return addr;
1288 /* Finally, try allocating in low memory. */
1289 addr = arch_get_unmapped_area_1 (PAGE_SIZE, len, limit);
1291 return addr;
1294 #ifdef CONFIG_OSF4_COMPAT
1296 /* Clear top 32 bits of iov_len in the user's buffer for
1297 compatibility with old versions of OSF/1 where iov_len
1298 was defined as int. */
1299 static int
1300 osf_fix_iov_len(const struct iovec __user *iov, unsigned long count)
1302 unsigned long i;
1304 for (i = 0 ; i < count ; i++) {
1305 int __user *iov_len_high = (int __user *)&iov[i].iov_len + 1;
1307 if (put_user(0, iov_len_high))
1308 return -EFAULT;
1310 return 0;
1313 asmlinkage ssize_t
1314 osf_readv(unsigned long fd, const struct iovec __user * vector, unsigned long count)
1316 if (unlikely(personality(current->personality) == PER_OSF4))
1317 if (osf_fix_iov_len(vector, count))
1318 return -EFAULT;
1319 return sys_readv(fd, vector, count);
1322 asmlinkage ssize_t
1323 osf_writev(unsigned long fd, const struct iovec __user * vector, unsigned long count)
1325 if (unlikely(personality(current->personality) == PER_OSF4))
1326 if (osf_fix_iov_len(vector, count))
1327 return -EFAULT;
1328 return sys_writev(fd, vector, count);
1331 #endif