[v2,090/108] linux-user: Fix clock_nanosleep

Message ID 20180610030220.3777-91-richard.henderson@linaro.org
State New
Headers show
Series
  • linux-user: Split do_syscall
Related show

Commit Message

Richard Henderson June 10, 2018, 3:02 a.m.
When we switched from using clock_nanosleep to safe_clock_nanosleep,
we changed from the user-level API to the kernel-level ABI.  These
have different senses of the errno value.

The special handling for PowerPC is not requied while we're following
the kernel ABI.

Fixes: 9e518226f43
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 linux-user/syscall.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

-- 
2.17.1

Patch

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 6f19f75c67..1c1e05dc26 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7884,18 +7884,20 @@  IMPL(clock_nanosleep)
     struct timespec ts;
     abi_long ret;
 
-    target_to_host_timespec(&ts, arg3);
-    ret = get_errno(safe_clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
-    if (arg4) {
-        host_to_target_timespec(arg4, &ts);
+    /* Note that while the user-level api for clock_nanosleep
+     * returns a positive errno values, the kernel-level api
+     * continues to return negative errno values.  Also note
+     * that safe_clock_nanosleep mirrors the kernel api.
+     */
+    ret = target_to_host_timespec(&ts, arg3);
+    if (ret == 0) {
+        ret = safe_clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL);
+        if (ret) {
+            ret = -host_to_target_errno(-ret);
+        } else if (arg4) {
+            ret = host_to_target_timespec(arg4, &ts);
+        }
     }
-#if defined(TARGET_PPC)
-    /* clock_nanosleep is odd in that it returns positive errno values.
-     * On PPC, CR0 bit 3 should be set in such a situation. */
-    if (ret && ret != -TARGET_ERESTARTSYS) {
-        ((CPUPPCState *)cpu_env)->crf[0] |= 1;
-    }
-#endif
     return ret;
 }