[v7,65/74] linux-user: Split out getrlimit, setrlimit

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

Commit Message

Richard Henderson May 19, 2019, 8:37 p.m.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 linux-user/syscall-defs.h     |  6 ++++
 linux-user/syscall-proc.inc.c | 52 +++++++++++++++++++++++++++++++++++
 linux-user/syscall.c          | 46 -------------------------------
 linux-user/strace.list        |  6 ----
 4 files changed, 58 insertions(+), 52 deletions(-)

-- 
2.17.1

Patch

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 3ba697fd53..34426a2e23 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -72,6 +72,9 @@  SYSCALL_DEF(getpid);
 #ifdef TARGET_NR_getppid
 SYSCALL_DEF(getppid);
 #endif
+#ifdef TARGET_NR_getrlimit
+SYSCALL_DEF(getrlimit, ARG_DEC, ARG_PTR);
+#endif
 SYSCALL_DEF(getsid, ARG_DEC);
 #ifdef TARGET_NR_getxpid
 SYSCALL_DEF(getxpid);
@@ -212,6 +215,9 @@  SYSCALL_DEF(semget, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
 SYSCALL_DEF(sethostname, ARG_STR);
 SYSCALL_DEF(setpgid, ARG_DEC, ARG_DEC);
+#ifdef TARGET_NR_setrlimit
+SYSCALL_DEF(setrlimit, ARG_DEC, ARG_PTR);
+#endif
 SYSCALL_DEF(setsid);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semop)
 SYSCALL_DEF(semop, ARG_DEC, ARG_PTR, ARG_DEC);
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
index b1a801fb62..1238b08191 100644
--- a/linux-user/syscall-proc.inc.c
+++ b/linux-user/syscall-proc.inc.c
@@ -479,6 +479,26 @@  SYSCALL_IMPL(getppid)
 }
 #endif
 
+#ifdef TARGET_NR_getrlimit
+SYSCALL_IMPL(getrlimit)
+{
+    int resource = target_to_host_resource(arg1);
+    struct target_rlimit *target_rlim;
+    struct rlimit rlim;
+    abi_long ret;
+
+    ret = get_errno(getrlimit(resource, &rlim));
+    if (!is_error(ret)) {
+        if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0)) {
+            return -TARGET_EFAULT;
+        }
+        target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
+        target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
+        unlock_user_struct(target_rlim, arg2, 1);
+    }
+    return ret;
+}
+#endif
 SYSCALL_IMPL(getsid)
 {
     return get_errno(getsid(arg1));
@@ -518,6 +538,38 @@  SYSCALL_IMPL(setpgid)
     return get_errno(setpgid(arg1, arg2));
 }
 
+#ifdef TARGET_NR_setrlimit
+SYSCALL_IMPL(setrlimit)
+{
+    int resource = target_to_host_resource(arg1);
+    struct target_rlimit *target_rlim;
+    struct rlimit rlim;
+
+    if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1)) {
+        return -TARGET_EFAULT;
+    }
+    rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
+    rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
+    unlock_user_struct(target_rlim, arg2, 0);
+
+    /*
+     * If we just passed through resource limit settings for memory then
+     * they would also apply to QEMU's own allocations, and QEMU will
+     * crash or hang or die if its allocations fail. Ideally we would
+     * track the guest allocations in QEMU and apply the limits ourselves.
+     * For now, just tell the guest the call succeeded but don't actually
+     * limit anything.
+     */
+    if (resource != RLIMIT_AS &&
+        resource != RLIMIT_DATA &&
+        resource != RLIMIT_STACK) {
+        return get_errno(setrlimit(resource, &rlim));
+    } else {
+        return 0;
+    }
+}
+#endif
+
 SYSCALL_IMPL(setsid)
 {
     return get_errno(setsid());
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 6dd4196647..401450b0e3 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4240,52 +4240,6 @@  static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
     void *p;
 
     switch(num) {
-#ifdef TARGET_NR_setrlimit
-    case TARGET_NR_setrlimit:
-        {
-            int resource = target_to_host_resource(arg1);
-            struct target_rlimit *target_rlim;
-            struct rlimit rlim;
-            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
-                return -TARGET_EFAULT;
-            rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
-            rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
-            unlock_user_struct(target_rlim, arg2, 0);
-            /*
-             * If we just passed through resource limit settings for memory then
-             * they would also apply to QEMU's own allocations, and QEMU will
-             * crash or hang or die if its allocations fail. Ideally we would
-             * track the guest allocations in QEMU and apply the limits ourselves.
-             * For now, just tell the guest the call succeeded but don't actually
-             * limit anything.
-             */
-            if (resource != RLIMIT_AS &&
-                resource != RLIMIT_DATA &&
-                resource != RLIMIT_STACK) {
-                return get_errno(setrlimit(resource, &rlim));
-            } else {
-                return 0;
-            }
-        }
-#endif
-#ifdef TARGET_NR_getrlimit
-    case TARGET_NR_getrlimit:
-        {
-            int resource = target_to_host_resource(arg1);
-            struct target_rlimit *target_rlim;
-            struct rlimit rlim;
-
-            ret = get_errno(getrlimit(resource, &rlim));
-            if (!is_error(ret)) {
-                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
-                    return -TARGET_EFAULT;
-                target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
-                target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
-                unlock_user_struct(target_rlim, arg2, 1);
-            }
-        }
-        return ret;
-#endif
     case TARGET_NR_getrusage:
         {
             struct rusage rusage;
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 361ceec853..711ad9c0aa 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -280,9 +280,6 @@ 
 #ifdef TARGET_NR_getresuid32
 { TARGET_NR_getresuid32, "getresuid32" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_getrlimit
-{ TARGET_NR_getrlimit, "getrlimit" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_get_robust_list
 { TARGET_NR_get_robust_list, "get_robust_list" , NULL, NULL, NULL },
 #endif
@@ -1061,9 +1058,6 @@ 
 #ifdef TARGET_NR_setreuid32
 { TARGET_NR_setreuid32, "setreuid32" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_setrlimit
-{ TARGET_NR_setrlimit, "setrlimit" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_set_robust_list
 { TARGET_NR_set_robust_list, "set_robust_list" , NULL, NULL, NULL },
 #endif