From patchwork Thu Sep 22 16:56:53 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aleksandar Markovic X-Patchwork-Id: 9346267 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 535B060757 for ; Thu, 22 Sep 2016 17:52:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 47B862AC04 for ; Thu, 22 Sep 2016 17:52:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3A3602AC07; Thu, 22 Sep 2016 17:52:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 71BC12AC04 for ; Thu, 22 Sep 2016 17:52:37 +0000 (UTC) Received: from localhost ([::1]:55356 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bn8Ak-0005yl-FF for patchwork-qemu-devel@patchwork.kernel.org; Thu, 22 Sep 2016 13:52:34 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59148) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bn7Kr-0001Cj-Lw for qemu-devel@nongnu.org; Thu, 22 Sep 2016 12:58:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bn7Ko-000733-HW for qemu-devel@nongnu.org; Thu, 22 Sep 2016 12:58:57 -0400 Received: from mx2.rt-rk.com ([89.216.37.149]:33004 helo=mail.rt-rk.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bn7Ko-00072F-58 for qemu-devel@nongnu.org; Thu, 22 Sep 2016 12:58:54 -0400 Received: from localhost (localhost [127.0.0.1]) by mail.rt-rk.com (Postfix) with ESMTP id 37D4F1A22B7; Thu, 22 Sep 2016 18:58:53 +0200 (CEST) X-Virus-Scanned: amavisd-new at rt-rk.com Received: from mcs19.domain.local (mcs19.domain.local [10.10.13.51]) by mail.rt-rk.com (Postfix) with ESMTPSA id 1AF171A1FAB; Thu, 22 Sep 2016 18:58:53 +0200 (CEST) From: Aleksandar Markovic To: qemu-devel@nongnu.org, riku.voipio@iki.fi, laurent@vivier.eu, peter.maydell@linaro.org, petar.jovanovic@imgtec.com, miodrag.dinic@imgtec.com, aleksandar.rikalo@imgtec.com, aleksandar.markovic@imgtec.com Date: Thu, 22 Sep 2016 18:56:53 +0200 Message-Id: <20160922165712.79809-5-aleksandar.markovic@rt-rk.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20160922165712.79809-1-aleksandar.markovic@rt-rk.com> References: <20160922165712.79809-1-aleksandar.markovic@rt-rk.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 89.216.37.149 Subject: [Qemu-devel] [PATCH v7 04/10] linux-user: Add support for sysfs() syscall X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Aleksandar Markovic This patch implements Qemu user mode sysfs() syscall support. Syscall sysfs() involves returning information about the filesystem types currently present in the kernel, and can operate in three distinct flavors, depending on its first argument. Its specific is that its declaration is threefold: int sysfs(int option, const char *fsname); int sysfs(int option, unsigned int fs_index, char *buf); int sysfs(int option); Its implementation in Linux kernel is at fs/filesystems.c, line 184. The implementation in Qemu user mode is based on invocation of host's sysfs(), and its key part is in the correspondent case segment of the main switch statement of the function do_syscall(), in file linux-user/syscalls.c. All necessary conversions of data structures from target to host and from host to target are covered. Based on the value of the first argument, three cases are distinguished, and such conversions are implemented separately for each case. Relevant support for "-strace" option is included in files linux-user/strace.c and linux-user/strace.list. This patch also fixes failures of LTP tests sysfs01, sysfs02, sysfs03, sysfs04, sysfs05, and sysfs06, if executed in Qemu user mode. Signed-off-by: Aleksandar Markovic --- linux-user/strace.c | 27 +++++++++++++++++++++++++++ linux-user/strace.list | 2 +- linux-user/syscall.c | 39 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/linux-user/strace.c b/linux-user/strace.c index a61717d..772711b 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -2342,6 +2342,33 @@ print_kill(const struct syscallname *name, } #endif +#ifdef TARGET_NR_sysfs +static void +print_sysfs(const struct syscallname *name, + abi_long arg0, abi_long arg1, abi_long arg2, + abi_long arg3, abi_long arg4, abi_long arg5) +{ + print_syscall_prologue(name); + /* arg0 is normally 1, 2, or 3 */ + switch (arg0) { + case 1: + print_raw_param("%d", arg0, 0); + print_string(arg1, 1); + break; + case 2: + print_raw_param("%d", arg0, 0); + print_raw_param("%u", arg1, 0); + print_pointer(arg2, 1); + break; + /* if arg0 is 3, desired output is the same as default */ + default: + print_raw_param("%d", arg0, 1); + break; + } + print_syscall_epilogue(name); +} +#endif + /* * An array of all of the syscalls we know about */ diff --git a/linux-user/strace.list b/linux-user/strace.list index 01aecfc..38139ba 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -1372,7 +1372,7 @@ { TARGET_NR_sys_epoll_wait, "sys_epoll_wait" , NULL, NULL, NULL }, #endif #ifdef TARGET_NR_sysfs -{ TARGET_NR_sysfs, "sysfs" , NULL, NULL, NULL }, +{ TARGET_NR_sysfs, "sysfs" , NULL, print_sysfs, NULL }, #endif #ifdef TARGET_NR_sysinfo { TARGET_NR_sysinfo, "sysinfo" , NULL, NULL, NULL }, diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 1af3e10..563796a 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7450,7 +7450,7 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags, if (fake_open->filename) { const char *tmpdir; - char filename[PATH_MAX]; + char filename[128]; int fd, r; /* create temporary file to map stat to */ @@ -9666,9 +9666,42 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_bdflush: goto unimplemented; #endif -#ifdef TARGET_NR_sysfs +#if defined(TARGET_NR_sysfs) case TARGET_NR_sysfs: - goto unimplemented; + switch (arg1) { + case 1: + { + p = lock_user_string(arg2); + if (!p) { + goto efault; + } + ret = get_errno(syscall(__NR_sysfs, arg1, p)); + unlock_user(p, arg2, 0); + } + break; + case 2: + { + char buf[PATH_MAX]; + memset(buf, 0, PATH_MAX); + ret = get_errno(syscall(__NR_sysfs, arg1, arg2, buf)); + if (!is_error(ret)) { + int len = PATH_MAX; + if (len > strlen(buf)) { + len = strlen(buf); + } + if (copy_to_user(arg3, buf, len) != 0) { + goto efault; + } + } + } + break; + case 3: + ret = get_errno(syscall(__NR_sysfs, arg1)); + break; + default: + ret = -EINVAL; + } + break; #endif case TARGET_NR_personality: ret = get_errno(personality(arg1));