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 /kernel/timer.c | |
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>
Diffstat (limited to 'kernel/timer.c')
-rw-r--r-- | kernel/timer.c | 58 |
1 files changed, 33 insertions, 25 deletions
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 | ||