From bcd12f301d1b002bd8a5b351c9c488879f870eee Mon Sep 17 00:00:00 2001 From: Kyle Roarty Date: Tue, 11 May 2021 16:53:56 -0500 Subject: [PATCH] arch-x86,sim: Implement sched_getaffinity sched_getaffinity is different from other syscalls in the raw syscall return the size of the cpumask being used to represent the CPU bit mask. Because of this, when a library (libnuma in this case) directly called sched_getaffinity and got a return value of 0, it errored out, thinking that there were no CPUs available. This implementation assumes that all CPUs are available, so it sets all simulated CPUs in the bitmask Change-Id: Id95c919986cc98a411877056256604f57a29f0f9 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/46243 Tested-by: kokoro Reviewed-by: Matt Sinclair Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power --- src/arch/x86/linux/syscall_tbl64.cc | 2 +- src/sim/syscall_emul.hh | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/arch/x86/linux/syscall_tbl64.cc b/src/arch/x86/linux/syscall_tbl64.cc index 94837cd080..7231595fe7 100644 --- a/src/arch/x86/linux/syscall_tbl64.cc +++ b/src/arch/x86/linux/syscall_tbl64.cc @@ -244,7 +244,7 @@ SyscallDescTable EmuLinux::syscallDescs64 = { { 201, "time", timeFunc }, { 202, "futex", futexFunc }, { 203, "sched_setaffinity", ignoreFunc }, - { 204, "sched_getaffinity", ignoreFunc }, + { 204, "sched_getaffinity", schedGetaffinityFunc }, { 205, "set_thread_area" }, { 206, "io_setup" }, { 207, "io_destroy" }, diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index cd2d8d16ef..3c1ad04f72 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -57,6 +57,7 @@ /// application on the host machine. #if defined(__linux__) +#include #include #include @@ -2603,4 +2604,26 @@ eventfdFunc(SyscallDesc *desc, ThreadContext *tc, #endif } +/// Target sched_getaffinity +template +SyscallReturn +schedGetaffinityFunc(SyscallDesc *desc, ThreadContext *tc, + pid_t pid, size_t cpusetsize, VPtr<> cpu_set_mask) +{ +#if defined(__linux__) + if (cpusetsize < CPU_ALLOC_SIZE(tc->getSystemPtr()->threads.size())) + return -EINVAL; + + BufferArg maskBuf(cpu_set_mask, cpusetsize); + maskBuf.copyIn(tc->getVirtProxy()); + for (int i = 0; i < tc->getSystemPtr()->threads.size(); i++) { + CPU_SET(i, (cpu_set_t *)maskBuf.bufferPtr()); + } + maskBuf.copyOut(tc->getVirtProxy()); + return CPU_ALLOC_SIZE(tc->getSystemPtr()->threads.size()); +#else + warnUnsupportedOS("sched_getaffinity"); + return -1; +#endif +} #endif // __SIM_SYSCALL_EMUL_HH__