[PATCH 12/12] sched_setaffinity: Don't use function calls as arguments to INTERNAL_SYSCALL.
Markos Chandras
markos.chandras at gmail.com
Thu Feb 21 10:12:09 UTC 2013
From: Markos Chandras <markos.chandras at imgtec.com>
This patch fixes a bug in sched_setaffinity() for Meta where the affinity
argument was ignored when trying to set a process's scheduling
affinity.
INTERNAL_SYSCALL places its arguments in the argument registers in
preparation for a system call, e.g.
register int arg1 __asm__ ("D1Ar1") = _arg1;
register int arg2 __asm__ ("D0Ar2") = _arg2;
The problem comes when a function call is passed as an argment to
INTERNAL_SYSCALL and the following code results,
register int arg1 __asm__ ("D1Ar1") = _arg1;
register int arg2 __asm__ ("D0Ar2") = _arg2;
register int arg3 __asm__ ("D1Ar3") = func();
Now, because the compiler is smart enough to figure out the argument
registers are not preserved across a function call, and that "func"
takes no arguments, the assignments to D1Ar1 and D0Ar2 are dead code
and the compiler eliminates them. Consequently, the syscall is
performed with garbage arguments in D1Ar1 and D0Ar2.
The solution is to use a temporary variable in which we store the
result of func() and assign that temporary variable to D1Ar3.
Signed-off-by: Markos Chandras <markos.chandras at imgtec.com>
---
libc/sysdeps/linux/common/sched_setaffinity.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libc/sysdeps/linux/common/sched_setaffinity.c b/libc/sysdeps/linux/common/sched_setaffinity.c
index 927744e..f6be783 100644
--- a/libc/sysdeps/linux/common/sched_setaffinity.c
+++ b/libc/sysdeps/linux/common/sched_setaffinity.c
@@ -35,10 +35,11 @@ int sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *cpuset)
if (unlikely (__kernel_cpumask_size == 0)) {
INTERNAL_SYSCALL_DECL (err);
int res;
+ pid_t _pid = getpid();
size_t psize = 128;
void *p = alloca (psize);
- while (res = INTERNAL_SYSCALL (sched_getaffinity, err, 3, getpid (),
+ while (res = INTERNAL_SYSCALL (sched_getaffinity, err, 3, _pid,
psize, p),
INTERNAL_SYSCALL_ERROR_P (res, err)
&& INTERNAL_SYSCALL_ERRNO (res, err) == EINVAL)
--
1.8.1.2
More information about the uClibc
mailing list