[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>
This commit is contained in:
committed by
Linus Torvalds
parent
72fd4a35a8
commit
d4d23add3a
@ -579,70 +579,6 @@ asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *off
|
||||
}
|
||||
|
||||
|
||||
struct sysinfo32 {
|
||||
s32 uptime;
|
||||
u32 loads[3];
|
||||
u32 totalram;
|
||||
u32 freeram;
|
||||
u32 sharedram;
|
||||
u32 bufferram;
|
||||
u32 totalswap;
|
||||
u32 freeswap;
|
||||
unsigned short procs;
|
||||
u32 totalhigh;
|
||||
u32 freehigh;
|
||||
u32 mem_unit;
|
||||
char _f[12];
|
||||
};
|
||||
|
||||
/* We used to call sys_sysinfo and translate the result. But sys_sysinfo
|
||||
* undoes the good work done elsewhere, and rather than undoing the
|
||||
* damage, I decided to just duplicate the code from sys_sysinfo here.
|
||||
*/
|
||||
|
||||
asmlinkage int sys32_sysinfo(struct sysinfo32 __user *info)
|
||||
{
|
||||
struct sysinfo val;
|
||||
int err;
|
||||
unsigned long seq;
|
||||
|
||||
/* We don't need a memset here because we copy the
|
||||
* struct to userspace once element at a time.
|
||||
*/
|
||||
|
||||
do {
|
||||
seq = read_seqbegin(&xtime_lock);
|
||||
val.uptime = jiffies / HZ;
|
||||
|
||||
val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
|
||||
val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT);
|
||||
val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT);
|
||||
|
||||
val.procs = nr_threads;
|
||||
} while (read_seqretry(&xtime_lock, seq));
|
||||
|
||||
|
||||
si_meminfo(&val);
|
||||
si_swapinfo(&val);
|
||||
|
||||
err = put_user (val.uptime, &info->uptime);
|
||||
err |= __put_user (val.loads[0], &info->loads[0]);
|
||||
err |= __put_user (val.loads[1], &info->loads[1]);
|
||||
err |= __put_user (val.loads[2], &info->loads[2]);
|
||||
err |= __put_user (val.totalram, &info->totalram);
|
||||
err |= __put_user (val.freeram, &info->freeram);
|
||||
err |= __put_user (val.sharedram, &info->sharedram);
|
||||
err |= __put_user (val.bufferram, &info->bufferram);
|
||||
err |= __put_user (val.totalswap, &info->totalswap);
|
||||
err |= __put_user (val.freeswap, &info->freeswap);
|
||||
err |= __put_user (val.procs, &info->procs);
|
||||
err |= __put_user (val.totalhigh, &info->totalhigh);
|
||||
err |= __put_user (val.freehigh, &info->freehigh);
|
||||
err |= __put_user (val.mem_unit, &info->mem_unit);
|
||||
return err ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
|
||||
/* lseek() needs a wrapper because 'offset' can be negative, but the top
|
||||
* half of the argument has been zeroed by syscall.S.
|
||||
*/
|
||||
|
@ -197,7 +197,7 @@
|
||||
/* struct rusage contains longs... */
|
||||
ENTRY_COMP(wait4)
|
||||
ENTRY_SAME(swapoff) /* 115 */
|
||||
ENTRY_DIFF(sysinfo)
|
||||
ENTRY_COMP(sysinfo)
|
||||
ENTRY_SAME(shutdown)
|
||||
ENTRY_SAME(fsync)
|
||||
ENTRY_SAME(madvise)
|
||||
|
Reference in New Issue
Block a user