diff options
| author | Kyle McMartin <kyle@parisc-linux.org> | 2007-02-10 04:46:00 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-11 13:51:32 -0500 |
| commit | d4d23add3abcd18d8021b99f230df608ccb2f007 (patch) | |
| tree | 756c5a7d21a9f5a25f10bfcec40c01aecc596c2f | |
| parent | 72fd4a35a824331d7a0f4168d7576502d95d34b3 (diff) | |
[PATCH] Common compat_sys_sysinfo
I noticed that almost all architectures implemented exactly the same
sys32_sysinfo... except parisc, where a bug was to be found in handling of
the uptime. So let's remove a whole whack of code for fun and profit.
Cribbed compat_sys_sysinfo from x86_64's implementation, since I figured it
would be the best tested.
This patch incorporates Arnd's suggestion of not using set_fs/get_fs, but
instead extracting out the common code from sys_sysinfo.
Cc: Christoph Hellwig <hch@infradead.org>
Cc: <linux-arch@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | arch/ia64/ia32/ia32_entry.S | 2 | ||||
| -rw-r--r-- | arch/ia64/ia32/sys_ia32.c | 68 | ||||
| -rw-r--r-- | arch/mips/kernel/linux32.c | 44 | ||||
| -rw-r--r-- | arch/mips/kernel/scall64-n32.S | 2 | ||||
| -rw-r--r-- | arch/mips/kernel/scall64-o32.S | 2 | ||||
| -rw-r--r-- | arch/parisc/kernel/sys_parisc32.c | 64 | ||||
| -rw-r--r-- | arch/parisc/kernel/syscall_table.S | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/sys_ppc32.c | 67 | ||||
| -rw-r--r-- | arch/s390/kernel/compat_linux.c | 45 | ||||
| -rw-r--r-- | arch/s390/kernel/compat_wrapper.S | 6 | ||||
| -rw-r--r-- | arch/s390/kernel/syscalls.S | 2 | ||||
| -rw-r--r-- | arch/sparc64/kernel/sys_sparc32.c | 64 | ||||
| -rw-r--r-- | arch/sparc64/kernel/systbls.S | 2 | ||||
| -rw-r--r-- | arch/x86_64/ia32/ia32entry.S | 2 | ||||
| -rw-r--r-- | arch/x86_64/ia32/sys_ia32.c | 66 | ||||
| -rw-r--r-- | include/linux/kernel.h | 3 | ||||
| -rw-r--r-- | kernel/compat.c | 66 | ||||
| -rw-r--r-- | kernel/timer.c | 58 |
18 files changed, 112 insertions, 453 deletions
diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S index a32cd59b81ed..687e5fdc9683 100644 --- a/arch/ia64/ia32/ia32_entry.S +++ b/arch/ia64/ia32/ia32_entry.S | |||
| @@ -326,7 +326,7 @@ ia32_syscall_table: | |||
| 326 | data8 sys_ni_syscall | 326 | data8 sys_ni_syscall |
| 327 | data8 compat_sys_wait4 | 327 | data8 compat_sys_wait4 |
| 328 | data8 sys_swapoff /* 115 */ | 328 | data8 sys_swapoff /* 115 */ |
| 329 | data8 sys32_sysinfo | 329 | data8 compat_sys_sysinfo |
| 330 | data8 sys32_ipc | 330 | data8 sys32_ipc |
| 331 | data8 sys_fsync | 331 | data8 sys_fsync |
| 332 | data8 sys32_sigreturn | 332 | data8 sys32_sigreturn |
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index 957681c39ad9..d430d36ae49d 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c | |||
| @@ -2209,74 +2209,6 @@ sys32_fstat64 (unsigned int fd, struct stat64 __user *statbuf) | |||
| 2209 | return ret; | 2209 | return ret; |
| 2210 | } | 2210 | } |
| 2211 | 2211 | ||
| 2212 | struct sysinfo32 { | ||
| 2213 | s32 uptime; | ||
| 2214 | u32 loads[3]; | ||
| 2215 | u32 totalram; | ||
| 2216 | u32 freeram; | ||
| 2217 | u32 sharedram; | ||
| 2218 | u32 bufferram; | ||
| 2219 | u32 totalswap; | ||
| 2220 | u32 freeswap; | ||
| 2221 | u16 procs; | ||
| 2222 | u16 pad; | ||
| 2223 | u32 totalhigh; | ||
| 2224 | u32 freehigh; | ||
| 2225 | u32 mem_unit; | ||
| 2226 | char _f[8]; | ||
| 2227 | }; | ||
| 2228 | |||
| 2229 | asmlinkage long | ||
| 2230 | sys32_sysinfo (struct sysinfo32 __user *info) | ||
| 2231 | { | ||
| 2232 | struct sysinfo s; | ||
| 2233 | long ret, err; | ||
| 2234 | int bitcount = 0; | ||
| 2235 | mm_segment_t old_fs = get_fs(); | ||
| 2236 | |||
| 2237 | set_fs(KERNEL_DS); | ||
| 2238 | ret = sys_sysinfo((struct sysinfo __user *) &s); | ||
| 2239 | set_fs(old_fs); | ||
| 2240 | /* Check to see if any memory value is too large for 32-bit and | ||
| 2241 | * scale down if needed. | ||
| 2242 | */ | ||
| 2243 | if ((s.totalram >> 32) || (s.totalswap >> 32)) { | ||
| 2244 | while (s.mem_unit < PAGE_SIZE) { | ||
| 2245 | s.mem_unit <<= 1; | ||
| 2246 | bitcount++; | ||
| 2247 | } | ||
| 2248 | s.totalram >>= bitcount; | ||
| 2249 | s.freeram >>= bitcount; | ||
| 2250 | s.sharedram >>= bitcount; | ||
| 2251 | s.bufferram >>= bitcount; | ||
| 2252 | s.totalswap >>= bitcount; | ||
| 2253 | s.freeswap >>= bitcount; | ||
| 2254 | s.totalhigh >>= bitcount; | ||
| 2255 | s.freehigh >>= bitcount; | ||
| 2256 | } | ||
| 2257 | |||
| 2258 | if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) | ||
| 2259 | return -EFAULT; | ||
| 2260 | |||
| 2261 | err = __put_user(s.uptime, &info->uptime); | ||
| 2262 | err |= __put_user(s.loads[0], &info->loads[0]); | ||
| 2263 | err |= __put_user(s.loads[1], &info->loads[1]); | ||
| 2264 | err |= __put_user(s.loads[2], &info->loads[2]); | ||
| 2265 | err |= __put_user(s.totalram, &info->totalram); | ||
| 2266 | err |= __put_user(s.freeram, &info->freeram); | ||
| 2267 | err |= __put_user(s.sharedram, &info->sharedram); | ||
| 2268 | err |= __put_user(s.bufferram, &info->bufferram); | ||
| 2269 | err |= __put_user(s.totalswap, &info->totalswap); | ||
| 2270 | err |= __put_user(s.freeswap, &info->freeswap); | ||
| 2271 | err |= __put_user(s.procs, &info->procs); | ||
| 2272 | err |= __put_user (s.totalhigh, &info->totalhigh); | ||
| 2273 | err |= __put_user (s.freehigh, &info->freehigh); | ||
| 2274 | err |= __put_user (s.mem_unit, &info->mem_unit); | ||
| 2275 | if (err) | ||
| 2276 | return -EFAULT; | ||
| 2277 | return ret; | ||
| 2278 | } | ||
| 2279 | |||
| 2280 | asmlinkage long | 2212 | asmlinkage long |
| 2281 | sys32_sched_rr_get_interval (pid_t pid, struct compat_timespec __user *interval) | 2213 | sys32_sched_rr_get_interval (pid_t pid, struct compat_timespec __user *interval) |
| 2282 | { | 2214 | { |
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 0b8ce59429a8..ca7ad78f4def 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c | |||
| @@ -193,50 +193,6 @@ sysn32_waitid(int which, compat_pid_t pid, | |||
| 193 | return ret; | 193 | return ret; |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | struct sysinfo32 { | ||
| 197 | s32 uptime; | ||
| 198 | u32 loads[3]; | ||
| 199 | u32 totalram; | ||
| 200 | u32 freeram; | ||
| 201 | u32 sharedram; | ||
| 202 | u32 bufferram; | ||
| 203 | u32 totalswap; | ||
| 204 | u32 freeswap; | ||
| 205 | u16 procs; | ||
| 206 | u32 totalhigh; | ||
| 207 | u32 freehigh; | ||
| 208 | u32 mem_unit; | ||
| 209 | char _f[8]; | ||
| 210 | }; | ||
| 211 | |||
| 212 | asmlinkage int sys32_sysinfo(struct sysinfo32 __user *info) | ||
| 213 | { | ||
| 214 | struct sysinfo s; | ||
| 215 | int ret, err; | ||
| 216 | mm_segment_t old_fs = get_fs (); | ||
| 217 | |||
| 218 | set_fs (KERNEL_DS); | ||
| 219 | ret = sys_sysinfo((struct sysinfo __user *)&s); | ||
| 220 | set_fs (old_fs); | ||
| 221 | err = put_user (s.uptime, &info->uptime); | ||
| 222 | err |= __put_user (s.loads[0], &info->loads[0]); | ||
| 223 | err |= __put_user (s.loads[1], &info->loads[1]); | ||
| 224 | err |= __put_user (s.loads[2], &info->loads[2]); | ||
| 225 | err |= __put_user (s.totalram, &info->totalram); | ||
| 226 | err |= __put_user (s.freeram, &info->freeram); | ||
| 227 | err |= __put_user (s.sharedram, &info->sharedram); | ||
| 228 | err |= __put_user (s.bufferram, &info->bufferram); | ||
| 229 | err |= __put_user (s.totalswap, &info->totalswap); | ||
| 230 | err |= __put_user (s.freeswap, &info->freeswap); | ||
| 231 | err |= __put_user (s.procs, &info->procs); | ||
| 232 | err |= __put_user (s.totalhigh, &info->totalhigh); | ||
| 233 | err |= __put_user (s.freehigh, &info->freehigh); | ||
| 234 | err |= __put_user (s.mem_unit, &info->mem_unit); | ||
| 235 | if (err) | ||
| 236 | return -EFAULT; | ||
| 237 | return ret; | ||
| 238 | } | ||
| 239 | |||
| 240 | #define RLIM_INFINITY32 0x7fffffff | 196 | #define RLIM_INFINITY32 0x7fffffff |
| 241 | #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) | 197 | #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) |
| 242 | 198 | ||
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 39add2341aa2..ee8802b59758 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
| @@ -217,7 +217,7 @@ EXPORT(sysn32_call_table) | |||
| 217 | PTR sys32_gettimeofday | 217 | PTR sys32_gettimeofday |
| 218 | PTR compat_sys_getrlimit /* 6095 */ | 218 | PTR compat_sys_getrlimit /* 6095 */ |
| 219 | PTR compat_sys_getrusage | 219 | PTR compat_sys_getrusage |
| 220 | PTR sys32_sysinfo | 220 | PTR compat_sys_sysinfo |
| 221 | PTR compat_sys_times | 221 | PTR compat_sys_times |
| 222 | PTR sys32_ptrace | 222 | PTR sys32_ptrace |
| 223 | PTR sys_getuid /* 6100 */ | 223 | PTR sys_getuid /* 6100 */ |
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index c58b8e0105ea..c5f590ca99b0 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
| @@ -321,7 +321,7 @@ sys_call_table: | |||
| 321 | PTR sys_ni_syscall /* sys_vm86 */ | 321 | PTR sys_ni_syscall /* sys_vm86 */ |
| 322 | PTR compat_sys_wait4 | 322 | PTR compat_sys_wait4 |
| 323 | PTR sys_swapoff /* 4115 */ | 323 | PTR sys_swapoff /* 4115 */ |
| 324 | PTR sys32_sysinfo | 324 | PTR compat_sys_sysinfo |
| 325 | PTR sys32_ipc | 325 | PTR sys32_ipc |
| 326 | PTR sys_fsync | 326 | PTR sys_fsync |
| 327 | PTR sys32_sigreturn | 327 | PTR sys32_sigreturn |
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index 29be4377aca6..ce3245f87fdd 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c | |||
| @@ -579,70 +579,6 @@ asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *off | |||
| 579 | } | 579 | } |
| 580 | 580 | ||
| 581 | 581 | ||
| 582 | struct sysinfo32 { | ||
| 583 | s32 uptime; | ||
| 584 | u32 loads[3]; | ||
| 585 | u32 totalram; | ||
| 586 | u32 freeram; | ||
| 587 | u32 sharedram; | ||
| 588 | u32 bufferram; | ||
| 589 | u32 totalswap; | ||
| 590 | u32 freeswap; | ||
| 591 | unsigned short procs; | ||
| 592 | u32 totalhigh; | ||
| 593 | u32 freehigh; | ||
| 594 | u32 mem_unit; | ||
| 595 | char _f[12]; | ||
| 596 | }; | ||
| 597 | |||
| 598 | /* We used to call sys_sysinfo and translate the result. But sys_sysinfo | ||
| 599 | * undoes the good work done elsewhere, and rather than undoing the | ||
| 600 | * damage, I decided to just duplicate the code from sys_sysinfo here. | ||
| 601 | */ | ||
| 602 | |||
| 603 | asmlinkage int sys32_sysinfo(struct sysinfo32 __user *info) | ||
| 604 | { | ||
| 605 | struct sysinfo val; | ||
| 606 | int err; | ||
| 607 | unsigned long seq; | ||
| 608 | |||
| 609 | /* We don't need a memset here because we copy the | ||
| 610 | * struct to userspace once element at a time. | ||
| 611 | */ | ||
| 612 | |||
| 613 | do { | ||
| 614 | seq = read_seqbegin(&xtime_lock); | ||
| 615 | val.uptime = jiffies / HZ; | ||
| 616 | |||
| 617 | val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); | ||
| 618 | val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT); | ||
| 619 | val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT); | ||
| 620 | |||
| 621 | val.procs = nr_threads; | ||
| 622 | } while (read_seqretry(&xtime_lock, seq)); | ||
| 623 | |||
| 624 | |||
| 625 | si_meminfo(&val); | ||
| 626 | si_swapinfo(&val); | ||
| 627 | |||
| 628 | err = put_user (val.uptime, &info->uptime); | ||
| 629 | err |= __put_user (val.loads[0], &info->loads[0]); | ||
| 630 | err |= __put_user (val.loads[1], &info->loads[1]); | ||
| 631 | err |= __put_user (val.loads[2], &info->loads[2]); | ||
| 632 | err |= __put_user (val.totalram, &info->totalram); | ||
| 633 | err |= __put_user (val.freeram, &info->freeram); | ||
| 634 | err |= __put_user (val.sharedram, &info->sharedram); | ||
| 635 | err |= __put_user (val.bufferram, &info->bufferram); | ||
| 636 | err |= __put_user (val.totalswap, &info->totalswap); | ||
| 637 | err |= __put_user (val.freeswap, &info->freeswap); | ||
| 638 | err |= __put_user (val.procs, &info->procs); | ||
| 639 | err |= __put_user (val.totalhigh, &info->totalhigh); | ||
| 640 | err |= __put_user (val.freehigh, &info->freehigh); | ||
| 641 | err |= __put_user (val.mem_unit, &info->mem_unit); | ||
| 642 | return err ? -EFAULT : 0; | ||
| 643 | } | ||
| 644 | |||
| 645 | |||
| 646 | /* lseek() needs a wrapper because 'offset' can be negative, but the top | 582 | /* lseek() needs a wrapper because 'offset' can be negative, but the top |
| 647 | * half of the argument has been zeroed by syscall.S. | 583 | * half of the argument has been zeroed by syscall.S. |
| 648 | */ | 584 | */ |
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 701d66a596e8..be8eb9a0d24a 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S | |||
| @@ -197,7 +197,7 @@ | |||
| 197 | /* struct rusage contains longs... */ | 197 | /* struct rusage contains longs... */ |
| 198 | ENTRY_COMP(wait4) | 198 | ENTRY_COMP(wait4) |
| 199 | ENTRY_SAME(swapoff) /* 115 */ | 199 | ENTRY_SAME(swapoff) /* 115 */ |
| 200 | ENTRY_DIFF(sysinfo) | 200 | ENTRY_COMP(sysinfo) |
| 201 | ENTRY_SAME(shutdown) | 201 | ENTRY_SAME(shutdown) |
| 202 | ENTRY_SAME(fsync) | 202 | ENTRY_SAME(fsync) |
| 203 | ENTRY_SAME(madvise) | 203 | ENTRY_SAME(madvise) |
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 03a2a2f30d66..673e8d9df7f5 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c | |||
| @@ -198,73 +198,6 @@ static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) | |||
| 198 | __put_user(i->tv_usec, &o->tv_usec))); | 198 | __put_user(i->tv_usec, &o->tv_usec))); |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | struct sysinfo32 { | ||
| 202 | s32 uptime; | ||
| 203 | u32 loads[3]; | ||
| 204 | u32 totalram; | ||
| 205 | u32 freeram; | ||
| 206 | u32 sharedram; | ||
| 207 | u32 bufferram; | ||
| 208 | u32 totalswap; | ||
| 209 | u32 freeswap; | ||
| 210 | unsigned short procs; | ||
| 211 | unsigned short pad; | ||
| 212 | u32 totalhigh; | ||
| 213 | u32 freehigh; | ||
| 214 | u32 mem_unit; | ||
| 215 | char _f[20-2*sizeof(int)-sizeof(int)]; | ||
| 216 | }; | ||
| 217 | |||
| 218 | asmlinkage long compat_sys_sysinfo(struct sysinfo32 __user *info) | ||
| 219 | { | ||
| 220 | struct sysinfo s; | ||
| 221 | int ret, err; | ||
| 222 | int bitcount=0; | ||
| 223 | mm_segment_t old_fs = get_fs (); | ||
| 224 | |||
| 225 | /* The __user cast is valid due to set_fs() */ | ||
| 226 | set_fs (KERNEL_DS); | ||
| 227 | ret = sys_sysinfo((struct sysinfo __user *)&s); | ||
| 228 | set_fs (old_fs); | ||
| 229 | |||
| 230 | /* Check to see if any memory value is too large for 32-bit and | ||
| 231 | * scale down if needed. | ||
| 232 | */ | ||
| 233 | if ((s.totalram >> 32) || (s.totalswap >> 32)) { | ||
| 234 | while (s.mem_unit < PAGE_SIZE) { | ||
| 235 | s.mem_unit <<= 1; | ||
| 236 | bitcount++; | ||
| 237 | } | ||
| 238 | s.totalram >>=bitcount; | ||
| 239 | s.freeram >>= bitcount; | ||
| 240 | s.sharedram >>= bitcount; | ||
| 241 | s.bufferram >>= bitcount; | ||
| 242 | s.totalswap >>= bitcount; | ||
| 243 | s.freeswap >>= bitcount; | ||
| 244 | s.totalhigh >>= bitcount; | ||
| 245 | s.freehigh >>= bitcount; | ||
| 246 | } | ||
| 247 | |||
| 248 | err = put_user (s.uptime, &info->uptime); | ||
| 249 | err |= __put_user (s.loads[0], &info->loads[0]); | ||
| 250 | err |= __put_user (s.loads[1], &info->loads[1]); | ||
| 251 | err |= __put_user (s.loads[2], &info->loads[2]); | ||
| 252 | err |= __put_user (s.totalram, &info->totalram); | ||
| 253 | err |= __put_user (s.freeram, &info->freeram); | ||
| 254 | err |= __put_user (s.sharedram, &info->sharedram); | ||
| 255 | err |= __put_user (s.bufferram, &info->bufferram); | ||
| 256 | err |= __put_user (s.totalswap, &info->totalswap); | ||
| 257 | err |= __put_user (s.freeswap, &info->freeswap); | ||
| 258 | err |= __put_user (s.procs, &info->procs); | ||
| 259 | err |= __put_user (s.totalhigh, &info->totalhigh); | ||
| 260 | err |= __put_user (s.freehigh, &info->freehigh); | ||
| 261 | err |= __put_user (s.mem_unit, &info->mem_unit); | ||
| 262 | if (err) | ||
| 263 | return -EFAULT; | ||
| 264 | |||
| 265 | return ret; | ||
| 266 | } | ||
| 267 | |||
| 268 | 201 | ||
| 269 | 202 | ||
| 270 | 203 | ||
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 666bb6daa148..664c669b1856 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c | |||
| @@ -398,51 +398,6 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) | |||
| 398 | return err; | 398 | return err; |
| 399 | } | 399 | } |
| 400 | 400 | ||
| 401 | struct sysinfo32 { | ||
| 402 | s32 uptime; | ||
| 403 | u32 loads[3]; | ||
| 404 | u32 totalram; | ||
| 405 | u32 freeram; | ||
| 406 | u32 sharedram; | ||
| 407 | u32 bufferram; | ||
| 408 | u32 totalswap; | ||
| 409 | u32 freeswap; | ||
| 410 | unsigned short procs; | ||
| 411 | unsigned short pads; | ||
| 412 | u32 totalhigh; | ||
| 413 | u32 freehigh; | ||
| 414 | unsigned int mem_unit; | ||
| 415 | char _f[8]; | ||
| 416 | }; | ||
| 417 | |||
| 418 | asmlinkage long sys32_sysinfo(struct sysinfo32 __user *info) | ||
| 419 | { | ||
| 420 | struct sysinfo s; | ||
| 421 | int ret, err; | ||
| 422 | mm_segment_t old_fs = get_fs (); | ||
| 423 | |||
| 424 | set_fs (KERNEL_DS); | ||
| 425 | ret = sys_sysinfo((struct sysinfo __force __user *) &s); | ||
| 426 | set_fs (old_fs); | ||
| 427 | err = put_user (s.uptime, &info->uptime); | ||
| 428 | err |= __put_user (s.loads[0], &info->loads[0]); | ||
| 429 | err |= __put_user (s.loads[1], &info->loads[1]); | ||
| 430 | err |= __put_user (s.loads[2], &info->loads[2]); | ||
| 431 | err |= __put_user (s.totalram, &info->totalram); | ||
| 432 | err |= __put_user (s.freeram, &info->freeram); | ||
| 433 | err |= __put_user (s.sharedram, &info->sharedram); | ||
| 434 | err |= __put_user (s.bufferram, &info->bufferram); | ||
| 435 | err |= __put_user (s.totalswap, &info->totalswap); | ||
| 436 | err |= __put_user (s.freeswap, &info->freeswap); | ||
| 437 | err |= __put_user (s.procs, &info->procs); | ||
| 438 | err |= __put_user (s.totalhigh, &info->totalhigh); | ||
| 439 | err |= __put_user (s.freehigh, &info->freehigh); | ||
| 440 | err |= __put_user (s.mem_unit, &info->mem_unit); | ||
| 441 | if (err) | ||
| 442 | return -EFAULT; | ||
| 443 | return ret; | ||
| 444 | } | ||
| 445 | |||
| 446 | asmlinkage long sys32_sched_rr_get_interval(compat_pid_t pid, | 401 | asmlinkage long sys32_sched_rr_get_interval(compat_pid_t pid, |
| 447 | struct compat_timespec __user *interval) | 402 | struct compat_timespec __user *interval) |
| 448 | { | 403 | { |
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 71e54ef0931e..97901296894e 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S | |||
| @@ -517,10 +517,10 @@ sys32_swapoff_wrapper: | |||
| 517 | llgtr %r2,%r2 # const char * | 517 | llgtr %r2,%r2 # const char * |
| 518 | jg sys_swapoff # branch to system call | 518 | jg sys_swapoff # branch to system call |
| 519 | 519 | ||
| 520 | .globl sys32_sysinfo_wrapper | 520 | .globl compat_sys_sysinfo_wrapper |
| 521 | sys32_sysinfo_wrapper: | 521 | compat_sys_sysinfo_wrapper: |
| 522 | llgtr %r2,%r2 # struct sysinfo_emu31 * | 522 | llgtr %r2,%r2 # struct sysinfo_emu31 * |
| 523 | jg sys32_sysinfo # branch to system call | 523 | jg compat_sys_sysinfo # branch to system call |
| 524 | 524 | ||
| 525 | .globl sys32_ipc_wrapper | 525 | .globl sys32_ipc_wrapper |
| 526 | sys32_ipc_wrapper: | 526 | sys32_ipc_wrapper: |
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index a4ceae3dbcf1..a52c44455bf0 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S | |||
| @@ -124,7 +124,7 @@ NI_SYSCALL /* old "idle" system call */ | |||
| 124 | NI_SYSCALL /* vm86old for i386 */ | 124 | NI_SYSCALL /* vm86old for i386 */ |
| 125 | SYSCALL(sys_wait4,sys_wait4,compat_sys_wait4_wrapper) | 125 | SYSCALL(sys_wait4,sys_wait4,compat_sys_wait4_wrapper) |
| 126 | SYSCALL(sys_swapoff,sys_swapoff,sys32_swapoff_wrapper) /* 115 */ | 126 | SYSCALL(sys_swapoff,sys_swapoff,sys32_swapoff_wrapper) /* 115 */ |
| 127 | SYSCALL(sys_sysinfo,sys_sysinfo,sys32_sysinfo_wrapper) | 127 | SYSCALL(sys_sysinfo,sys_sysinfo,compat_sys_sysinfo_wrapper) |
| 128 | SYSCALL(sys_ipc,sys_ipc,sys32_ipc_wrapper) | 128 | SYSCALL(sys_ipc,sys_ipc,sys32_ipc_wrapper) |
| 129 | SYSCALL(sys_fsync,sys_fsync,sys32_fsync_wrapper) | 129 | SYSCALL(sys_fsync,sys_fsync,sys32_fsync_wrapper) |
| 130 | SYSCALL(sys_sigreturn_glue,sys_sigreturn_glue,sys32_sigreturn_glue) | 130 | SYSCALL(sys_sigreturn_glue,sys_sigreturn_glue,sys32_sigreturn_glue) |
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index e27cb71bd8e2..7876a0226285 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c | |||
| @@ -459,70 +459,6 @@ asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2) | |||
| 459 | return sys_sysfs(option, arg1, arg2); | 459 | return sys_sysfs(option, arg1, arg2); |
| 460 | } | 460 | } |
| 461 | 461 | ||
| 462 | struct sysinfo32 { | ||
| 463 | s32 uptime; | ||
| 464 | u32 loads[3]; | ||
| 465 | u32 totalram; | ||
| 466 | u32 freeram; | ||
| 467 | u32 sharedram; | ||
| 468 | u32 bufferram; | ||
| 469 | u32 totalswap; | ||
| 470 | u32 freeswap; | ||
| 471 | unsigned short procs; | ||
| 472 | unsigned short pad; | ||
| 473 | u32 totalhigh; | ||
| 474 | u32 freehigh; | ||
| 475 | u32 mem_unit; | ||
| 476 | char _f[20-2*sizeof(int)-sizeof(int)]; | ||
| 477 | }; | ||
| 478 | |||
| 479 | asmlinkage long sys32_sysinfo(struct sysinfo32 __user *info) | ||
| 480 | { | ||
| 481 | struct sysinfo s; | ||
| 482 | int ret, err; | ||
| 483 | int bitcount = 0; | ||
| 484 | mm_segment_t old_fs = get_fs (); | ||
| 485 | |||
| 486 | set_fs(KERNEL_DS); | ||
| 487 | ret = sys_sysinfo((struct sysinfo __user *) &s); | ||
| 488 | set_fs(old_fs); | ||
| 489 | /* Check to see if any memory value is too large for 32-bit and | ||
| 490 | * scale down if needed. | ||
| 491 | */ | ||
| 492 | if ((s.totalram >> 32) || (s.totalswap >> 32)) { | ||
| 493 | while (s.mem_unit < PAGE_SIZE) { | ||
| 494 | s.mem_unit <<= 1; | ||
| 495 | bitcount++; | ||
| 496 | } | ||
| 497 | s.totalram >>= bitcount; | ||
| 498 | s.freeram >>= bitcount; | ||
| 499 | s.sharedram >>= bitcount; | ||
| 500 | s.bufferram >>= bitcount; | ||
| 501 | s.totalswap >>= bitcount; | ||
| 502 | s.freeswap >>= bitcount; | ||
| 503 | s.totalhigh >>= bitcount; | ||
| 504 | s.freehigh >>= bitcount; | ||
| 505 | } | ||
| 506 | |||
| 507 | err = put_user (s.uptime, &info->uptime); | ||
| 508 | err |= __put_user (s.loads[0], &info->loads[0]); | ||
| 509 | err |= __put_user (s.loads[1], &info->loads[1]); | ||
| 510 | err |= __put_user (s.loads[2], &info->loads[2]); | ||
| 511 | err |= __put_user (s.totalram, &info->totalram); | ||
| 512 | err |= __put_user (s.freeram, &info->freeram); | ||
| 513 | err |= __put_user (s.sharedram, &info->sharedram); | ||
| 514 | err |= __put_user (s.bufferram, &info->bufferram); | ||
| 515 | err |= __put_user (s.totalswap, &info->totalswap); | ||
| 516 | err |= __put_user (s.freeswap, &info->freeswap); | ||
| 517 | err |= __put_user (s.procs, &info->procs); | ||
| 518 | err |= __put_user (s.totalhigh, &info->totalhigh); | ||
| 519 | err |= __put_user (s.freehigh, &info->freehigh); | ||
| 520 | err |= __put_user (s.mem_unit, &info->mem_unit); | ||
| 521 | if (err) | ||
| 522 | return -EFAULT; | ||
| 523 | return ret; | ||
| 524 | } | ||
| 525 | |||
| 526 | asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval) | 462 | asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval) |
| 527 | { | 463 | { |
| 528 | struct timespec t; | 464 | struct timespec t; |
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 9a8026797ac0..948b7d2d5874 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S | |||
| @@ -61,7 +61,7 @@ sys_call_table32: | |||
| 61 | .word sys32_epoll_wait, sys32_ioprio_set, sys_getppid, sys32_sigaction, sys_sgetmask | 61 | .word sys32_epoll_wait, sys32_ioprio_set, sys_getppid, sys32_sigaction, sys_sgetmask |
| 62 | /*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir | 62 | /*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir |
| 63 | .word sys32_readahead, sys32_socketcall, sys32_syslog, sys32_lookup_dcookie, sys32_fadvise64 | 63 | .word sys32_readahead, sys32_socketcall, sys32_syslog, sys32_lookup_dcookie, sys32_fadvise64 |
| 64 | /*210*/ .word sys32_fadvise64_64, sys32_tgkill, sys32_waitpid, sys_swapoff, sys32_sysinfo | 64 | /*210*/ .word sys32_fadvise64_64, sys32_tgkill, sys32_waitpid, sys_swapoff, compat_sys_sysinfo |
| 65 | .word sys32_ipc, sys32_sigreturn, sys_clone, sys32_ioprio_get, compat_sys_adjtimex | 65 | .word sys32_ipc, sys32_sigreturn, sys_clone, sys32_ioprio_get, compat_sys_adjtimex |
| 66 | /*220*/ .word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys32_getpgid | 66 | /*220*/ .word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys32_getpgid |
| 67 | .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16 | 67 | .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16 |
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index b4aa875e175b..5f32cf4de5fb 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S | |||
| @@ -515,7 +515,7 @@ ia32_sys_call_table: | |||
| 515 | .quad sys32_vm86_warning /* vm86old */ | 515 | .quad sys32_vm86_warning /* vm86old */ |
| 516 | .quad compat_sys_wait4 | 516 | .quad compat_sys_wait4 |
| 517 | .quad sys_swapoff /* 115 */ | 517 | .quad sys_swapoff /* 115 */ |
| 518 | .quad sys32_sysinfo | 518 | .quad compat_sys_sysinfo |
| 519 | .quad sys32_ipc | 519 | .quad sys32_ipc |
| 520 | .quad sys_fsync | 520 | .quad sys_fsync |
| 521 | .quad stub32_sigreturn | 521 | .quad stub32_sigreturn |
diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c index c9bac3af29d6..200fdde18d96 100644 --- a/arch/x86_64/ia32/sys_ia32.c +++ b/arch/x86_64/ia32/sys_ia32.c | |||
| @@ -523,72 +523,6 @@ sys32_sysfs(int option, u32 arg1, u32 arg2) | |||
| 523 | return sys_sysfs(option, arg1, arg2); | 523 | return sys_sysfs(option, arg1, arg2); |
| 524 | } | 524 | } |
| 525 | 525 | ||
| 526 | struct sysinfo32 { | ||
| 527 | s32 uptime; | ||
| 528 | u32 loads[3]; | ||
| 529 | u32 totalram; | ||
| 530 | u32 freeram; | ||
| 531 | u32 sharedram; | ||
| 532 | u32 bufferram; | ||
| 533 | u32 totalswap; | ||
| 534 | u32 freeswap; | ||
| 535 | unsigned short procs; | ||
| 536 | unsigned short pad; | ||
| 537 | u32 totalhigh; | ||
| 538 | u32 freehigh; | ||
| 539 | u32 mem_unit; | ||
| 540 | char _f[20-2*sizeof(u32)-sizeof(int)]; | ||
| 541 | }; | ||
| 542 | |||
| 543 | asmlinkage long | ||
| 544 | sys32_sysinfo(struct sysinfo32 __user *info) | ||
| 545 | { | ||
| 546 | struct sysinfo s; | ||
| 547 | int ret; | ||
| 548 | mm_segment_t old_fs = get_fs (); | ||
| 549 | int bitcount = 0; | ||
| 550 | |||
| 551 | set_fs (KERNEL_DS); | ||
| 552 | ret = sys_sysinfo((struct sysinfo __user *)&s); | ||
| 553 | set_fs (old_fs); | ||
| 554 | |||
| 555 | /* Check to see if any memory value is too large for 32-bit and scale | ||
| 556 | * down if needed | ||
| 557 | */ | ||
| 558 | if ((s.totalram >> 32) || (s.totalswap >> 32)) { | ||
| 559 | while (s.mem_unit < PAGE_SIZE) { | ||
| 560 | s.mem_unit <<= 1; | ||
| 561 | bitcount++; | ||
| 562 | } | ||
| 563 | s.totalram >>= bitcount; | ||
| 564 | s.freeram >>= bitcount; | ||
| 565 | s.sharedram >>= bitcount; | ||
| 566 | s.bufferram >>= bitcount; | ||
| 567 | s.totalswap >>= bitcount; | ||
| 568 | s.freeswap >>= bitcount; | ||
| 569 | s.totalhigh >>= bitcount; | ||
| 570 | s.freehigh >>= bitcount; | ||
| 571 | } | ||
| 572 | |||
| 573 | if (!access_ok(VERIFY_WRITE, info, sizeof(struct sysinfo32)) || | ||
| 574 | __put_user (s.uptime, &info->uptime) || | ||
| 575 | __put_user (s.loads[0], &info->loads[0]) || | ||
| 576 | __put_user (s.loads[1], &info->loads[1]) || | ||
| 577 | __put_user (s.loads[2], &info->loads[2]) || | ||
| 578 | __put_user (s.totalram, &info->totalram) || | ||
| 579 | __put_user (s.freeram, &info->freeram) || | ||
| 580 | __put_user (s.sharedram, &info->sharedram) || | ||
| 581 | __put_user (s.bufferram, &info->bufferram) || | ||
| 582 | __put_user (s.totalswap, &info->totalswap) || | ||
| 583 | __put_user (s.freeswap, &info->freeswap) || | ||
| 584 | __put_user (s.procs, &info->procs) || | ||
| 585 | __put_user (s.totalhigh, &info->totalhigh) || | ||
| 586 | __put_user (s.freehigh, &info->freehigh) || | ||
| 587 | __put_user (s.mem_unit, &info->mem_unit)) | ||
| 588 | return -EFAULT; | ||
| 589 | return 0; | ||
| 590 | } | ||
| 591 | |||
| 592 | asmlinkage long | 526 | asmlinkage long |
| 593 | sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval) | 527 | sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval) |
| 594 | { | 528 | { |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index e1a429ada97f..7e861303cbde 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
| @@ -313,6 +313,9 @@ static inline int __attribute__ ((format (printf, 1, 2))) pr_debug(const char * | |||
| 313 | (void)__tmp; \ | 313 | (void)__tmp; \ |
| 314 | }) | 314 | }) |
| 315 | 315 | ||
| 316 | struct sysinfo; | ||
| 317 | extern int do_sysinfo(struct sysinfo *info); | ||
| 318 | |||
| 316 | #endif /* __KERNEL__ */ | 319 | #endif /* __KERNEL__ */ |
| 317 | 320 | ||
| 318 | #define SI_LOAD_SHIFT 16 | 321 | #define SI_LOAD_SHIFT 16 |
diff --git a/kernel/compat.c b/kernel/compat.c index 6952dd057300..cebb4c28c039 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
| @@ -1016,3 +1016,69 @@ asmlinkage long compat_sys_migrate_pages(compat_pid_t pid, | |||
| 1016 | return sys_migrate_pages(pid, nr_bits + 1, old, new); | 1016 | return sys_migrate_pages(pid, nr_bits + 1, old, new); |
| 1017 | } | 1017 | } |
| 1018 | #endif | 1018 | #endif |
| 1019 | |||
| 1020 | struct compat_sysinfo { | ||
| 1021 | s32 uptime; | ||
| 1022 | u32 loads[3]; | ||
| 1023 | u32 totalram; | ||
| 1024 | u32 freeram; | ||
| 1025 | u32 sharedram; | ||
| 1026 | u32 bufferram; | ||
| 1027 | u32 totalswap; | ||
| 1028 | u32 freeswap; | ||
| 1029 | u16 procs; | ||
| 1030 | u16 pad; | ||
| 1031 | u32 totalhigh; | ||
| 1032 | u32 freehigh; | ||
| 1033 | u32 mem_unit; | ||
| 1034 | char _f[20-2*sizeof(u32)-sizeof(int)]; | ||
| 1035 | }; | ||
| 1036 | |||
| 1037 | asmlinkage long | ||
| 1038 | compat_sys_sysinfo(struct compat_sysinfo __user *info) | ||
| 1039 | { | ||
| 1040 | struct sysinfo s; | ||
| 1041 | |||
| 1042 | do_sysinfo(&s); | ||
| 1043 | |||
| 1044 | /* Check to see if any memory value is too large for 32-bit and scale | ||
| 1045 | * down if needed | ||
| 1046 | */ | ||
| 1047 | if ((s.totalram >> 32) || (s.totalswap >> 32)) { | ||
| 1048 | int bitcount = 0; | ||
| 1049 | |||
| 1050 | while (s.mem_unit < PAGE_SIZE) { | ||
| 1051 | s.mem_unit <<= 1; | ||
| 1052 | bitcount++; | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | s.totalram >>= bitcount; | ||
| 1056 | s.freeram >>= bitcount; | ||
| 1057 | s.sharedram >>= bitcount; | ||
| 1058 | s.bufferram >>= bitcount; | ||
| 1059 | s.totalswap >>= bitcount; | ||
| 1060 | s.freeswap >>= bitcount; | ||
| 1061 | s.totalhigh >>= bitcount; | ||
| 1062 | s.freehigh >>= bitcount; | ||
| 1063 | } | ||
| 1064 | |||
| 1065 | if (!access_ok(VERIFY_WRITE, info, sizeof(struct compat_sysinfo)) || | ||
| 1066 | __put_user (s.uptime, &info->uptime) || | ||
| 1067 | __put_user (s.loads[0], &info->loads[0]) || | ||
| 1068 | __put_user (s.loads[1], &info->loads[1]) || | ||
| 1069 | __put_user (s.loads[2], &info->loads[2]) || | ||
| 1070 | __put_user (s.totalram, &info->totalram) || | ||
| 1071 | __put_user (s.freeram, &info->freeram) || | ||
| 1072 | __put_user (s.sharedram, &info->sharedram) || | ||
| 1073 | __put_user (s.bufferram, &info->bufferram) || | ||
| 1074 | __put_user (s.totalswap, &info->totalswap) || | ||
| 1075 | __put_user (s.freeswap, &info->freeswap) || | ||
| 1076 | __put_user (s.procs, &info->procs) || | ||
| 1077 | __put_user (s.totalhigh, &info->totalhigh) || | ||
| 1078 | __put_user (s.freehigh, &info->freehigh) || | ||
| 1079 | __put_user (s.mem_unit, &info->mem_unit)) | ||
| 1080 | return -EFAULT; | ||
| 1081 | |||
| 1082 | return 0; | ||
| 1083 | } | ||
| 1084 | |||
diff --git a/kernel/timer.c b/kernel/timer.c index 31ab627df8a0..8533c3796082 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
| @@ -1392,17 +1392,16 @@ asmlinkage long sys_gettid(void) | |||
| 1392 | } | 1392 | } |
| 1393 | 1393 | ||
| 1394 | /** | 1394 | /** |
| 1395 | * sys_sysinfo - fill in sysinfo struct | 1395 | * do_sysinfo - fill in sysinfo struct |
| 1396 | * @info: pointer to buffer to fill | 1396 | * @info: pointer to buffer to fill |
| 1397 | */ | 1397 | */ |
| 1398 | asmlinkage long sys_sysinfo(struct sysinfo __user *info) | 1398 | int do_sysinfo(struct sysinfo *info) |
| 1399 | { | 1399 | { |
| 1400 | struct sysinfo val; | ||
| 1401 | unsigned long mem_total, sav_total; | 1400 | unsigned long mem_total, sav_total; |
| 1402 | unsigned int mem_unit, bitcount; | 1401 | unsigned int mem_unit, bitcount; |
| 1403 | unsigned long seq; | 1402 | unsigned long seq; |
| 1404 | 1403 | ||
| 1405 | memset((char *)&val, 0, sizeof(struct sysinfo)); | 1404 | memset(info, 0, sizeof(struct sysinfo)); |
| 1406 | 1405 | ||
| 1407 | do { | 1406 | do { |
| 1408 | struct timespec tp; | 1407 | struct timespec tp; |
| @@ -1422,17 +1421,17 @@ asmlinkage long sys_sysinfo(struct sysinfo __user *info) | |||
| 1422 | tp.tv_nsec = tp.tv_nsec - NSEC_PER_SEC; | 1421 | tp.tv_nsec = tp.tv_nsec - NSEC_PER_SEC; |
| 1423 | tp.tv_sec++; | 1422 | tp.tv_sec++; |
| 1424 | } | 1423 | } |
| 1425 | val.uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0); | 1424 | info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0); |
| 1426 | 1425 | ||
| 1427 | val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); | 1426 | info->loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); |
| 1428 | val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT); | 1427 | info->loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT); |
| 1429 | val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT); | 1428 | info->loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT); |
| 1430 | 1429 | ||
| 1431 | val.procs = nr_threads; | 1430 | info->procs = nr_threads; |
| 1432 | } while (read_seqretry(&xtime_lock, seq)); | 1431 | } while (read_seqretry(&xtime_lock, seq)); |
| 1433 | 1432 | ||
| 1434 | si_meminfo(&val); | 1433 | si_meminfo(info); |
| 1435 | si_swapinfo(&val); | 1434 | si_swapinfo(info); |
| 1436 | 1435 | ||
| 1437 | /* | 1436 | /* |
| 1438 | * If the sum of all the available memory (i.e. ram + swap) | 1437 | * If the sum of all the available memory (i.e. ram + swap) |
| @@ -1443,11 +1442,11 @@ asmlinkage long sys_sysinfo(struct sysinfo __user *info) | |||
| 1443 | * -Erik Andersen <andersee@debian.org> | 1442 | * -Erik Andersen <andersee@debian.org> |
| 1444 | */ | 1443 | */ |
| 1445 | 1444 | ||
| 1446 | mem_total = val.totalram + val.totalswap; | 1445 | mem_total = info->totalram + info->totalswap; |
| 1447 | if (mem_total < val.totalram || mem_total < val.totalswap) | 1446 | if (mem_total < info->totalram || mem_total < info->totalswap) |
| 1448 | goto out; | 1447 | goto out; |
| 1449 | bitcount = 0; | 1448 | bitcount = 0; |
| 1450 | mem_unit = val.mem_unit; | 1449 | mem_unit = info->mem_unit; |
| 1451 | while (mem_unit > 1) { | 1450 | while (mem_unit > 1) { |
| 1452 | bitcount++; | 1451 | bitcount++; |
| 1453 | mem_unit >>= 1; | 1452 | mem_unit >>= 1; |
| @@ -1459,22 +1458,31 @@ asmlinkage long sys_sysinfo(struct sysinfo __user *info) | |||
| 1459 | 1458 | ||
| 1460 | /* | 1459 | /* |
| 1461 | * If mem_total did not overflow, multiply all memory values by | 1460 | * If mem_total did not overflow, multiply all memory values by |
| 1462 | * val.mem_unit and set it to 1. This leaves things compatible | 1461 | * info->mem_unit and set it to 1. This leaves things compatible |
| 1463 | * with 2.2.x, and also retains compatibility with earlier 2.4.x | 1462 | * with 2.2.x, and also retains compatibility with earlier 2.4.x |
| 1464 | * kernels... | 1463 | * kernels... |
| 1465 | */ | 1464 | */ |
| 1466 | 1465 | ||
| 1467 | val.mem_unit = 1; | 1466 | info->mem_unit = 1; |
| 1468 | val.totalram <<= bitcount; | 1467 | info->totalram <<= bitcount; |
| 1469 | val.freeram <<= bitcount; | 1468 | info->freeram <<= bitcount; |
| 1470 | val.sharedram <<= bitcount; | 1469 | info->sharedram <<= bitcount; |
| 1471 | val.bufferram <<= bitcount; | 1470 | info->bufferram <<= bitcount; |
| 1472 | val.totalswap <<= bitcount; | 1471 | info->totalswap <<= bitcount; |
| 1473 | val.freeswap <<= bitcount; | 1472 | info->freeswap <<= bitcount; |
| 1474 | val.totalhigh <<= bitcount; | 1473 | info->totalhigh <<= bitcount; |
| 1475 | val.freehigh <<= bitcount; | 1474 | info->freehigh <<= bitcount; |
| 1475 | |||
| 1476 | out: | ||
| 1477 | return 0; | ||
| 1478 | } | ||
| 1479 | |||
| 1480 | asmlinkage long sys_sysinfo(struct sysinfo __user *info) | ||
| 1481 | { | ||
| 1482 | struct sysinfo val; | ||
| 1483 | |||
| 1484 | do_sysinfo(&val); | ||
| 1476 | 1485 | ||
| 1477 | out: | ||
| 1478 | if (copy_to_user(info, &val, sizeof(struct sysinfo))) | 1486 | if (copy_to_user(info, &val, sizeof(struct sysinfo))) |
| 1479 | return -EFAULT; | 1487 | return -EFAULT; |
| 1480 | 1488 | ||
