From patchwork Fri Feb 17 10:27:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Durrant X-Patchwork-Id: 9579539 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 24AB5600C5 for ; Fri, 17 Feb 2017 10:29:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 12FD32862B for ; Fri, 17 Feb 2017 10:29:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0805B286B7; Fri, 17 Feb 2017 10:29:50 +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=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 70D222862B for ; Fri, 17 Feb 2017 10:29:49 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cefkz-00086Z-F5; Fri, 17 Feb 2017 10:27:17 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cefkx-00085T-Pt for xen-devel@lists.xenproject.org; Fri, 17 Feb 2017 10:27:15 +0000 Received: from [85.158.143.35] by server-7.bemta-6.messagelabs.com id 7A/8B-26824-300D6A85; Fri, 17 Feb 2017 10:27:15 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupmkeJIrShJLcpLzFFi42JxWrohUpfpwrI Ig90HVC2+b5nM5MDocfjDFZYAxijWzLyk/IoE1ox7900KdhlUTP2xkbWB8ZxaFyMnh4SAv8Sr 5cuYQWw2AR2JqU8vsXYxcnCICKhI3N5rABJmFiiW+Pu/G6xEWCBc4sqRQ4wgJSwCqhIX7nCCh HkF3CXuf//MBDFRTuL88Z9g5ZwCHhIXd75m62Jk5xACqjmYDhIVApq9fuosNohOQYmTM5+wQC ySkDj44gXzBEbeWUhSs5CkFjAyrWJUL04tKkst0jXWSyrKTM8oyU3MzNE1NDDTy00tLk5MT81 JTCrWS87P3cQIDBgGINjB2PHP6RCjJAeTkijvomnLIoT4kvJTKjMSizPii0pzUosPMcpwcChJ 8N46C5QTLEpNT61Iy8wBhi5MWoKDR0kEIs1bXJCYW5yZDpE6xajLsW/7mZdMQix5+XmpUuK8l ueBigRAijJK8+BGwOLoEqOslDAvI9BRQjwFqUW5mSWo8q8YxTkYlYR574Cs4snMK4Hb9AroCC agIzojloIcUZKIkJJqYAxdN13bfp/1tE2slQ/ji3W8Fnz0zvgUEWB4Zt7TtXlqRR/23TF0Vn2 jKOSwJfoNm8iPy1Mit4e94cwJ2hO5oE/t8dvtFdODbolJJitGykSJzuf+vzSk3+/1njzROYkz y/515pyOWZh+OOzaS0vGFxw54eUm6xPmXI6f/urHZY/3rnfqbTq/iCuxFGckGmoxFxUnAgBuy +LpngIAAA== X-Env-Sender: prvs=214e09179=Paul.Durrant@citrix.com X-Msg-Ref: server-14.tower-21.messagelabs.com!1487327232!52460131!2 X-Originating-IP: [66.165.176.89] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni44OSA9PiAyMDMwMDc=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 9.2.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 39297 invoked from network); 17 Feb 2017 10:27:14 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-14.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 17 Feb 2017 10:27:14 -0000 X-IronPort-AV: E=Sophos;i="5.35,171,1484006400"; d="scan'208";a="407699456" From: Paul Durrant To: Date: Fri, 17 Feb 2017 10:27:08 +0000 Message-ID: <1487327229-14641-3-git-send-email-paul.durrant@citrix.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1487327229-14641-1-git-send-email-paul.durrant@citrix.com> References: <1487327229-14641-1-git-send-email-paul.durrant@citrix.com> MIME-Version: 1.0 Cc: Wei Liu , Paul Durrant , Ian Jackson Subject: [Xen-devel] [PATCH 3/4] tools/libxendevicemodel: introduce a Linux-specific implementation X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP My recent patch [1] to the Linux privcmd module introduced a dedicated mechanism for making dm_op hypercalls. This patch adds the necessary code to libxendevicemodel to take advantage of that mechanism if it is implemented in the tools domain kernel. [1] https://git.kernel.org/cgit/linux/kernel/git/ostr/linux.git/commit/?id=ab520be8 Signed-off-by: Paul Durrant Acked-by: Wei Liu --- Cc: Ian Jackson Cc: Wei Liu --- tools/include/xen-sys/Linux/privcmd.h | 13 ++++ tools/libs/devicemodel/Makefile | 2 +- tools/libs/devicemodel/linux.c | 123 ++++++++++++++++++++++++++++++++++ tools/libs/devicemodel/private.h | 4 ++ 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 tools/libs/devicemodel/linux.c diff --git a/tools/include/xen-sys/Linux/privcmd.h b/tools/include/xen-sys/Linux/privcmd.h index e4e666a..c80eb5e 100644 --- a/tools/include/xen-sys/Linux/privcmd.h +++ b/tools/include/xen-sys/Linux/privcmd.h @@ -75,6 +75,17 @@ typedef struct privcmd_mmapbatch_v2 { int __user *err; /* array of error codes */ } privcmd_mmapbatch_v2_t; +typedef struct privcmd_dm_op_buf { + void __user *uptr; + size_t size; +} privcmd_dm_op_buf_t; + +typedef struct privcmd_dm_op { + domid_t dom; + __u16 num; + const privcmd_dm_op_buf_t __user *ubufs; +} privcmd_dm_op_t; + /* * @cmd: IOCTL_PRIVCMD_HYPERCALL * @arg: &privcmd_hypercall_t @@ -88,5 +99,7 @@ typedef struct privcmd_mmapbatch_v2 { _IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t)) #define IOCTL_PRIVCMD_MMAPBATCH_V2 \ _IOC(_IOC_NONE, 'P', 4, sizeof(privcmd_mmapbatch_v2_t)) +#define IOCTL_PRIVCMD_DM_OP \ + _IOC(_IOC_NONE, 'P', 5, sizeof(privcmd_dm_op_t)) #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */ diff --git a/tools/libs/devicemodel/Makefile b/tools/libs/devicemodel/Makefile index b87bf84..1803942 100644 --- a/tools/libs/devicemodel/Makefile +++ b/tools/libs/devicemodel/Makefile @@ -11,7 +11,7 @@ CFLAGS += $(CFLAGS_libxentoollog) CFLAGS += $(CFLAGS_libxencall) SRCS-y += core.c -SRCS-$(CONFIG_Linux) += compat.c +SRCS-$(CONFIG_Linux) += linux.c SRCS-$(CONFIG_FreeBSD) += compat.c SRCS-$(CONFIG_SunOS) += compat.c SRCS-$(CONFIG_NetBSD) += compat.c diff --git a/tools/libs/devicemodel/linux.c b/tools/libs/devicemodel/linux.c new file mode 100644 index 0000000..7511ee7 --- /dev/null +++ b/tools/libs/devicemodel/linux.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2017 Citrix Systems Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "private.h" + +int osdep_xendevicemodel_open(xendevicemodel_handle *dmod) +{ + int fd = open("/dev/xen/privcmd", O_RDWR | O_CLOEXEC); + privcmd_dm_op_t uop; + int rc; + + if (fd < 0) { + /* + * If the 'new' privcmd interface doesn't exist then don't treat + * this as an error, but an old privcmd clearly won't implement + * IOCTL_PRIVCMD_DM_OP so don't bother trying to open it. + */ + if (errno == ENOENT || errno == ENXIO || errno == ENODEV) + goto out; + + PERROR("Could not obtain handle on privileged command interface"); + return -1; + } + + /* + * Check to see if IOCTL_PRIVCMD_DM_OP is implemented as we want to + * use that in preference to libxencall. + */ + uop.dom = DOMID_INVALID; + uop.num = 0; + uop.ubufs = NULL; + + rc = ioctl(fd, IOCTL_PRIVCMD_DM_OP, &uop); + if (rc < 0) { + close(fd); + fd = -1; + } + +out: + dmod->fd = fd; + return 0; +} + +int osdep_xendevicemodel_close(xendevicemodel_handle *dmod) +{ + if (dmod->fd < 0) + return 0; + + return close(dmod->fd); +} + +int osdep_xendevicemodel_op(xendevicemodel_handle *dmod, + domid_t domid, unsigned int nr_bufs, + struct xendevicemodel_buf bufs[]) +{ + privcmd_dm_op_buf_t *ubufs; + privcmd_dm_op_t uop; + unsigned int i; + int rc; + + if (dmod->fd < 0) + return xendevicemodel_xcall(dmod, domid, nr_bufs, bufs); + + ubufs = calloc(nr_bufs, sizeof (*ubufs)); + if (!ubufs) + return -1; + + for (i = 0; i < nr_bufs; i++) { + ubufs[i].uptr = bufs[i].ptr; + ubufs[i].size = bufs[i].size; + } + + uop.dom = domid; + uop.num = nr_bufs; + uop.ubufs = ubufs; + + rc = ioctl(dmod->fd, IOCTL_PRIVCMD_DM_OP, &uop); + + free(ubufs); + + if (rc < 0) + return -1; + + return 0; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/devicemodel/private.h b/tools/libs/devicemodel/private.h index 7c7acf2..5ce3b45 100644 --- a/tools/libs/devicemodel/private.h +++ b/tools/libs/devicemodel/private.h @@ -11,6 +11,7 @@ struct xendevicemodel_handle { xentoollog_logger *logger, *logger_tofree; unsigned int flags; xencall_handle *xcall; + int fd; }; struct xendevicemodel_buf { @@ -28,6 +29,9 @@ int osdep_xendevicemodel_op(xendevicemodel_handle *dmod, domid_t domid, unsigned int nr_bufs, struct xendevicemodel_buf bufs[]); +#define PERROR(_f...) \ + xtl_log(dmod->logger, XTL_ERROR, errno, "xendevicemodel", _f) + #endif /*