From nobody Wed Nov 5 20:03:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1537859703998462.5608253074638; Tue, 25 Sep 2018 00:15:03 -0700 (PDT) Received: from localhost ([::1]:51324 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g4hYk-00014u-Lb for importer@patchew.org; Tue, 25 Sep 2018 03:15:02 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49668) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g4hX9-0008Qk-5v for qemu-devel@nongnu.org; Tue, 25 Sep 2018 03:13:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g4hX4-00023p-6J for qemu-devel@nongnu.org; Tue, 25 Sep 2018 03:13:23 -0400 Received: from mail2.static.mailgun.info ([104.130.122.2]:35735) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g4hWy-0001w4-Nw for qemu-devel@nongnu.org; Tue, 25 Sep 2018 03:13:14 -0400 Received: from cerberus.teal.tolva.net (c-73-252-167-134.hsd1.ca.comcast.net [73.252.167.134]) by mxa.mailgun.org with ESMTP id 5ba9e006.7f36382ea730-smtp-out-n03; Tue, 25 Sep 2018 07:13:10 -0000 (UTC) DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg-relay.tolva.net; q=dns/txt; s=pic; t=1537859590; h=Content-Transfer-Encoding: Content-Type: MIME-Version: References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=QOQLxYEkqPeZ+pea3DyXnUpPb4vwx3jiiok5vVrWcaA=; b=ZUYTJ6wRvLat+QNfaWdx5G1KO/DpcULpEC4kJ1FBxSeztOXL/837KEfdaBCVvLSbYxj5T37x VleNIqaFFMBLV99LNxt72QQShNI/4W1JYHg+XDp01JcY/PlACSx6KkfHj+QohSVZH8EhyFWJ QQ+3XBaxuotKkclqbM2Unv/B9vw= X-Mailgun-Sending-Ip: 104.130.122.2 X-Mailgun-Sid: WyI5MDdkOCIsICJxZW11LWRldmVsQG5vbmdudS5vcmciLCAiN2Q3MzI5Il0= From: =?UTF-8?q?Cortland=20T=C3=B6lva?= To: qemu-devel@nongnu.org Date: Tue, 25 Sep 2018 00:12:26 -0700 Message-Id: <20180925071228.32040-2-cst@tolva.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180925071228.32040-1-cst@tolva.net> References: <20180925071228.32040-1-cst@tolva.net> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 104.130.122.2 Subject: [Qemu-devel] [PATCH v2 1/3] linux-user: Check for Linux USBFS in configure 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: , Cc: pbonzini@redhat.com, Laurent Vivier , =?UTF-8?q?Cortland=20T=C3=B6lva?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 In preparation for adding user mode emulation support for the Linux usbfs interface, check for its kernel header. Signed-off-by: Cortland T=C3=B6lva Reviewed-by: Laurent Vivier --- v2 patch uses check_include instead of doing things by hand. configure | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 7fd989aee1..5ebdb8901f 100755 --- a/configure +++ b/configure @@ -4234,7 +4234,14 @@ if compile_prog "" "" ; then memfd=3Dyes fi =20 - +# check for usbfs +have_usbfs=3Dno +if test "$linux_user" =3D "yes"; then + if check_include linux/usbdevice_fs.h; then + have_usbfs=3Dyes + fi + have_usbfs=3Dyes +fi =20 # check for fallocate fallocate=3Dno @@ -6345,6 +6352,9 @@ fi if test "$memfd" =3D "yes" ; then echo "CONFIG_MEMFD=3Dy" >> $config_host_mak fi +if test "$have_usbfs" =3D "yes" ; then + echo "CONFIG_USBFS=3Dy" >> $config_host_mak +fi if test "$fallocate" =3D "yes" ; then echo "CONFIG_FALLOCATE=3Dy" >> $config_host_mak fi --=20 2.11.0 From nobody Wed Nov 5 20:03:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1537860012205534.581167327941; Tue, 25 Sep 2018 00:20:12 -0700 (PDT) Received: from localhost ([::1]:51355 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g4hdi-00068l-RZ for importer@patchew.org; Tue, 25 Sep 2018 03:20:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49667) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g4hX9-0008Qj-60 for qemu-devel@nongnu.org; Tue, 25 Sep 2018 03:13:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g4hX6-00024J-KT for qemu-devel@nongnu.org; Tue, 25 Sep 2018 03:13:23 -0400 Received: from mail2.static.mailgun.info ([104.130.122.2]:52262) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g4hX6-00023c-Dk for qemu-devel@nongnu.org; Tue, 25 Sep 2018 03:13:20 -0400 Received: from cerberus.teal.tolva.net (c-73-252-167-134.hsd1.ca.comcast.net [73.252.167.134]) by mxa.mailgun.org with ESMTP id 5ba9e00c.7f36382ea730-smtp-out-n03; Tue, 25 Sep 2018 07:13:16 -0000 (UTC) DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg-relay.tolva.net; q=dns/txt; s=pic; t=1537859596; h=Content-Transfer-Encoding: Content-Type: MIME-Version: References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=RYzZh1TgFCbeVHQwlcnq4ewL3M8ia6Brx6QZB0TSah4=; b=cKjEKosCMsG4gt5E1HBVgiv4ztqEFiWYRrhFIG0PqlBrvNel7G82YTVr9QiIzOOWjg7j/nZG VGw/sBtdKaue/zma9UwSZVSFlsBw6bwn7ituiJ4dDH99UlA0/6dYRRKJPcemW2EasxuOMjl7 oSqKFCsrUIfSfqo1U4fFrOCyqmk= X-Mailgun-Sending-Ip: 104.130.122.2 X-Mailgun-Sid: WyI5MDdkOCIsICJxZW11LWRldmVsQG5vbmdudS5vcmciLCAiN2Q3MzI5Il0= From: =?UTF-8?q?Cortland=20T=C3=B6lva?= To: qemu-devel@nongnu.org Date: Tue, 25 Sep 2018 00:12:27 -0700 Message-Id: <20180925071228.32040-3-cst@tolva.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180925071228.32040-1-cst@tolva.net> References: <20180925071228.32040-1-cst@tolva.net> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 104.130.122.2 Subject: [Qemu-devel] [PATCH v2 2/3] linux-user: Define ordinary usbfs ioctls. 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: , Cc: Riku Voipio , Laurent Vivier , =?UTF-8?q?Cortland=20T=C3=B6lva?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Provide ioctl definitions for the generic thunk mechanism to convert most usbfs calls. Signed-off-by: Cortland T=C3=B6lva Reviewed-by: Laurent Vivier --- v2 patch lacks some types that are not used until patch 3/3 linux-user/ioctls.h | 38 ++++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 3 +++ linux-user/syscall_defs.h | 26 +++++++++++++++++++++++++ linux-user/syscall_types.h | 48 ++++++++++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 115 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 586c794639..92f6177f1d 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -131,6 +131,44 @@ IOCTL(FS_IOC_GETFLAGS, IOC_R, MK_PTR(TYPE_INT)) IOCTL(FS_IOC_SETFLAGS, IOC_W, MK_PTR(TYPE_INT)) =20 +#ifdef CONFIG_USBFS + /* USB ioctls */ + IOCTL(USBDEVFS_CONTROL, IOC_RW, + MK_PTR(MK_STRUCT(STRUCT_usbdevfs_ctrltransfer))) + IOCTL(USBDEVFS_BULK, IOC_RW, + MK_PTR(MK_STRUCT(STRUCT_usbdevfs_bulktransfer))) + IOCTL(USBDEVFS_RESETEP, IOC_W, MK_PTR(TYPE_INT)) + IOCTL(USBDEVFS_SETINTERFACE, IOC_W, + MK_PTR(MK_STRUCT(STRUCT_usbdevfs_setinterface))) + IOCTL(USBDEVFS_SETCONFIGURATION, IOC_W, MK_PTR(TYPE_INT)) + IOCTL(USBDEVFS_GETDRIVER, IOC_R, + MK_PTR(MK_STRUCT(STRUCT_usbdevfs_getdriver))) + IOCTL(USBDEVFS_DISCSIGNAL, IOC_W, + MK_PTR(MK_STRUCT(STRUCT_usbdevfs_disconnectsignal))) + IOCTL(USBDEVFS_CLAIMINTERFACE, IOC_W, MK_PTR(TYPE_INT)) + IOCTL(USBDEVFS_RELEASEINTERFACE, IOC_W, MK_PTR(TYPE_INT)) + IOCTL(USBDEVFS_CONNECTINFO, IOC_R, + MK_PTR(MK_STRUCT(STRUCT_usbdevfs_connectinfo))) + IOCTL(USBDEVFS_IOCTL, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_usbdevfs_ioctl))) + IOCTL(USBDEVFS_HUB_PORTINFO, IOC_R, + MK_PTR(MK_STRUCT(STRUCT_usbdevfs_hub_portinfo))) + IOCTL(USBDEVFS_RESET, 0, TYPE_NULL) + IOCTL(USBDEVFS_CLEAR_HALT, IOC_W, MK_PTR(TYPE_INT)) + IOCTL(USBDEVFS_DISCONNECT, 0, TYPE_NULL) + IOCTL(USBDEVFS_CONNECT, 0, TYPE_NULL) + IOCTL(USBDEVFS_CLAIM_PORT, IOC_W, MK_PTR(TYPE_INT)) + IOCTL(USBDEVFS_RELEASE_PORT, IOC_W, MK_PTR(TYPE_INT)) + IOCTL(USBDEVFS_GET_CAPABILITIES, IOC_R, MK_PTR(TYPE_INT)) + IOCTL(USBDEVFS_DISCONNECT_CLAIM, IOC_W, + MK_PTR(MK_STRUCT(STRUCT_usbdevfs_disconnect_claim))) +#ifdef USBDEVFS_DROP_PRIVILEGES + IOCTL(USBDEVFS_DROP_PRIVILEGES, IOC_W, MK_PTR(TYPE_INT)) +#endif +#ifdef USBDEVFS_GET_SPEED + IOCTL(USBDEVFS_GET_SPEED, 0, TYPE_NULL) +#endif +#endif /* CONFIG_USBFS */ + IOCTL(SIOCATMARK, IOC_R, MK_PTR(TYPE_INT)) IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT)) IOCTL(SIOCGIFFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq))) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 850b72a0c7..39f21b78c8 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -94,6 +94,9 @@ #include #endif #include +#if defined(CONFIG_USBFS) +#include +#endif #include #include #include diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 40bb60ef4c..357ee6a8c2 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -858,6 +858,32 @@ struct target_pollfd { =20 #define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap) =20 +#if defined(CONFIG_USBFS) +/* usb ioctls */ +#define TARGET_USBDEVFS_CONTROL TARGET_IOWR('U', 0, struct usbdevfs_ctrltr= ansfer) +#define TARGET_USBDEVFS_BULK TARGET_IOWR('U', 2, struct usbdevfs_bulktrans= fer) +#define TARGET_USBDEVFS_RESETEP TARGET_IOR('U', 3, int) +#define TARGET_USBDEVFS_SETINTERFACE TARGET_IOR('U', 4, struct usbdevfs_se= tinterface) +#define TARGET_USBDEVFS_SETCONFIGURATION TARGET_IOR('U', 5, int) +#define TARGET_USBDEVFS_GETDRIVER TARGET_IOW('U', 8, struct usbdevfs_getdr= iver) +#define TARGET_USBDEVFS_DISCSIGNAL TARGET_IOR('U', 14, struct usbdevfs_dis= connectsignal) +#define TARGET_USBDEVFS_CLAIMINTERFACE TARGET_IOR('U', 15, int) +#define TARGET_USBDEVFS_RELEASEINTERFACE TARGET_IOR('U', 16, int) +#define TARGET_USBDEVFS_CONNECTINFO TARGET_IOW('U', 17, struct usbdevfs_co= nnectinfo) +#define TARGET_USBDEVFS_IOCTL TARGET_IOWR('U', 18, struct usbdevfs_ioctl) +#define TARGET_USBDEVFS_HUB_PORTINFO TARGET_IOR('U', 19, struct usbdevfs_h= ub_portinfo) +#define TARGET_USBDEVFS_RESET TARGET_IO('U', 20) +#define TARGET_USBDEVFS_CLEAR_HALT TARGET_IOR('U', 21, int) +#define TARGET_USBDEVFS_DISCONNECT TARGET_IO('U', 22) +#define TARGET_USBDEVFS_CONNECT TARGET_IO('U', 23) +#define TARGET_USBDEVFS_CLAIM_PORT TARGET_IOR('U', 24, int) +#define TARGET_USBDEVFS_RELEASE_PORT TARGET_IOR('U', 25, int) +#define TARGET_USBDEVFS_GET_CAPABILITIES TARGET_IOR('U', 26, int) +#define TARGET_USBDEVFS_DISCONNECT_CLAIM TARGET_IOR('U', 27, struct usbdev= fs_disconnect_claim) +#define TARGET_USBDEVFS_DROP_PRIVILEGES TARGET_IOW('U', 30, int) +#define TARGET_USBDEVFS_GET_SPEED TARGET_IO('U', 31) +#endif /* CONFIG_USBFS */ + /* cdrom commands */ #define TARGET_CDROMPAUSE 0x5301 /* Pause Audio Operation */ #define TARGET_CDROMRESUME 0x5302 /* Resume paused Audio Operation */ diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h index 24631b09be..6f64a8bdf7 100644 --- a/linux-user/syscall_types.h +++ b/linux-user/syscall_types.h @@ -266,3 +266,51 @@ STRUCT(blkpg_ioctl_arg, TYPE_INT, /* flags */ TYPE_INT, /* datalen */ TYPE_PTRVOID) /* data */ + +#if defined(CONFIG_USBFS) +/* usb device ioctls */ +STRUCT(usbdevfs_ctrltransfer, + TYPE_CHAR, /* bRequestType */ + TYPE_CHAR, /* bRequest */ + TYPE_SHORT, /* wValue */ + TYPE_SHORT, /* wIndex */ + TYPE_SHORT, /* wLength */ + TYPE_INT, /* timeout */ + TYPE_PTRVOID) /* data */ + +STRUCT(usbdevfs_bulktransfer, + TYPE_INT, /* ep */ + TYPE_INT, /* len */ + TYPE_INT, /* timeout */ + TYPE_PTRVOID) /* data */ + +STRUCT(usbdevfs_setinterface, + TYPE_INT, /* interface */ + TYPE_INT) /* altsetting */ + +STRUCT(usbdevfs_disconnectsignal, + TYPE_INT, /* signr */ + TYPE_PTRVOID) /* context */ + +STRUCT(usbdevfs_getdriver, + TYPE_INT, /* interface */ + MK_ARRAY(TYPE_CHAR, USBDEVFS_MAXDRIVERNAME + 1)) /* driver */ + +STRUCT(usbdevfs_connectinfo, + TYPE_INT, /* devnum */ + TYPE_CHAR) /* slow */ + +STRUCT(usbdevfs_ioctl, + TYPE_INT, /* ifno */ + TYPE_INT, /* ioctl_code */ + TYPE_PTRVOID) /* data */ + +STRUCT(usbdevfs_hub_portinfo, + TYPE_CHAR, /* nports */ + MK_ARRAY(TYPE_CHAR, 127)) /* port */ + +STRUCT(usbdevfs_disconnect_claim, + TYPE_INT, /* interface */ + TYPE_INT, /* flags */ + MK_ARRAY(TYPE_CHAR, USBDEVFS_MAXDRIVERNAME + 1)) /* driver */ +#endif /* CONFIG_USBFS */ --=20 2.11.0 From nobody Wed Nov 5 20:03:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 153785988126964.56770936814917; Tue, 25 Sep 2018 00:18:01 -0700 (PDT) Received: from localhost ([::1]:51341 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g4hbc-0003T7-0W for importer@patchew.org; Tue, 25 Sep 2018 03:18:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49665) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g4hX9-0008Qi-5H for qemu-devel@nongnu.org; Tue, 25 Sep 2018 03:13:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g4hX6-00024P-LE for qemu-devel@nongnu.org; Tue, 25 Sep 2018 03:13:23 -0400 Received: from mail2.static.mailgun.info ([104.130.122.2]:35735) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g4hX6-0001w4-ES for qemu-devel@nongnu.org; Tue, 25 Sep 2018 03:13:20 -0400 Received: from cerberus.teal.tolva.net (c-73-252-167-134.hsd1.ca.comcast.net [73.252.167.134]) by mxa.mailgun.org with ESMTP id 5ba9e00e.7f36382ea730-smtp-out-n03; Tue, 25 Sep 2018 07:13:18 -0000 (UTC) DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg-relay.tolva.net; q=dns/txt; s=pic; t=1537859599; h=Content-Transfer-Encoding: Content-Type: MIME-Version: References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=c5amx+NdntauQ6DezdxWdVFazgD3as5WU7FCc7I6wG8=; b=Bn6HZxSf3/1HR0vhp2/R7Hp5OLVNUq1aawOqVJ2f0twX/Om3C63VSANRWkNN83U/H5DwouQX kECagp0wQ9wfoPPiga5L3PYh9sIQTASbdUGjkF5V5fUY10hgiRJuABuSCBADgOkhWkn0XYiv cFB65JGJBNiHuV/rgSmxivLUuWg= X-Mailgun-Sending-Ip: 104.130.122.2 X-Mailgun-Sid: WyI5MDdkOCIsICJxZW11LWRldmVsQG5vbmdudS5vcmciLCAiN2Q3MzI5Il0= From: =?UTF-8?q?Cortland=20T=C3=B6lva?= To: qemu-devel@nongnu.org Date: Tue, 25 Sep 2018 00:12:28 -0700 Message-Id: <20180925071228.32040-4-cst@tolva.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180925071228.32040-1-cst@tolva.net> References: <20180925071228.32040-1-cst@tolva.net> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 104.130.122.2 Subject: [Qemu-devel] [PATCH v2 3/3] linux-user: implement special usbfs ioctls. 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: , Cc: Riku Voipio , Laurent Vivier , =?UTF-8?q?Cortland=20T=C3=B6lva?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Userspace submits a USB Request Buffer to the kernel, optionally discards it, and finally reaps the URB. Thunk buffers from target to host and back. Tested by running an i386 scanner driver on ARMv7. Neither the discardurb ioctl nor the kernel's updating the argument to the reap ioctl with a pointer to a reaped URB are exercised by this. Signed-off-by: Cortland T=C3=B6lva --- Changes from v1: improve pointer cast to int compatibility remove unimplemented types for usb streams struct definitions moved to this patch where possible linux-user/ioctls.h | 8 +++ linux-user/syscall.c | 168 +++++++++++++++++++++++++++++++++++++++++= ++++ linux-user/syscall_defs.h | 4 ++ linux-user/syscall_types.h | 20 ++++++ 4 files changed, 200 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 92f6177f1d..f04461fff7 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -143,6 +143,14 @@ IOCTL(USBDEVFS_SETCONFIGURATION, IOC_W, MK_PTR(TYPE_INT)) IOCTL(USBDEVFS_GETDRIVER, IOC_R, MK_PTR(MK_STRUCT(STRUCT_usbdevfs_getdriver))) + IOCTL_SPECIAL(USBDEVFS_SUBMITURB, IOC_W, do_ioctl_usbdevfs_submiturb, + MK_PTR(MK_STRUCT(STRUCT_usbdevfs_urb))) + IOCTL_SPECIAL(USBDEVFS_DISCARDURB, IOC_RW, do_ioctl_usbdevfs_discardurb, + MK_PTR(MK_STRUCT(STRUCT_usbdevfs_urb))) + IOCTL_SPECIAL(USBDEVFS_REAPURB, IOC_R, do_ioctl_usbdevfs_reapurb, + MK_PTR(MK_STRUCT(STRUCT_usbdevfs_urb))) + IOCTL_SPECIAL(USBDEVFS_REAPURBNDELAY, IOC_R, do_ioctl_usbdevfs_reapurb, + MK_PTR(MK_STRUCT(STRUCT_usbdevfs_urb))) IOCTL(USBDEVFS_DISCSIGNAL, IOC_W, MK_PTR(MK_STRUCT(STRUCT_usbdevfs_disconnectsignal))) IOCTL(USBDEVFS_CLAIMINTERFACE, IOC_W, MK_PTR(TYPE_INT)) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 39f21b78c8..bb0bf7e03d 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5491,6 +5491,174 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *i= e, uint8_t *buf_temp, return ret; } =20 +#if defined(CONFIG_USBFS) +#if HOST_LONG_BITS > 64 +#error USBDEVFS thunks do not support >64 bit hosts yet. +#endif +static GHashTable *usbdevfs_urb_hashtable(void) +{ + static GHashTable *urb_hashtable; + + if (!urb_hashtable) { + urb_hashtable =3D g_hash_table_new(g_int64_hash, g_int64_equal); + } + return urb_hashtable; +} + +static abi_long +do_ioctl_usbdevfs_reapurb(const IOCTLEntry *ie, uint8_t *buf_temp, + int fd, int cmd, abi_long arg) +{ + const argtype *arg_type =3D ie->arg_type; + GHashTable * const urb_hash =3D usbdevfs_urb_hashtable(); + const argtype ptrvoid_arg_type[] =3D { TYPE_PTRVOID, 0, 0 }; + int target_size; + int64_t reaped_userurb; + int64_t target_urbptr; + uintptr_t target_urbptr_ptr; + char *tagged_urb; + void *argptr; + abi_long ret; + + target_size =3D thunk_type_size(++arg_type, THUNK_TARGET); + + ret =3D get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp)); + if (is_error(ret)) { + return ret; + } + + memcpy(&reaped_userurb, buf_temp, sizeof(int64_t)); + tagged_urb =3D ((char *)(uintptr_t)reaped_userurb) - sizeof(int64_t); + memcpy(&target_urbptr, tagged_urb, sizeof(int64_t)); + if (!target_urbptr) { + return -TARGET_EFAULT; + } + g_hash_table_remove(urb_hash, tagged_urb); + + argptr =3D lock_user(VERIFY_WRITE, (abi_long) target_urbptr, target_si= ze, 0); + if (!argptr) { + g_free(tagged_urb); + return -TARGET_EFAULT; + } + thunk_convert(argptr, (char *)(uintptr_t)reaped_userurb, arg_type, + THUNK_TARGET); + unlock_user(argptr, target_urbptr, target_size); + + target_size =3D thunk_type_size(ptrvoid_arg_type, THUNK_TARGET); + argptr =3D lock_user(VERIFY_WRITE, (abi_long)arg, target_size, 0); + if (!argptr) { + g_free(tagged_urb); + return -TARGET_EFAULT; + } + target_urbptr_ptr =3D (uintptr_t)target_urbptr; + thunk_convert(argptr, &target_urbptr_ptr, ptrvoid_arg_type, THUNK_TARG= ET); + unlock_user(argptr, (abi_long) arg, target_size); + g_free(tagged_urb); + return ret; +} + +static abi_long +do_ioctl_usbdevfs_discardurb(const IOCTLEntry *ie, + uint8_t *buf_temp __attribute__((unused)), + int fd, int cmd, abi_long arg) +{ + GHashTable * const urb_hash =3D usbdevfs_urb_hashtable(); + abi_long host_urb; + int64_t tag_urb_key; + char *tagged_urb; + + /* map target pointer back to host tagged URB. */ + tag_urb_key =3D (int64_t)arg; + tagged_urb =3D g_hash_table_lookup(urb_hash, &tag_urb_key); + if (!tagged_urb) { + return -TARGET_EFAULT; + } + /* offset from tag to urb */ + host_urb =3D (abi_long)(uintptr_t)(tagged_urb + sizeof(int64_t)); + return get_errno(safe_ioctl(fd, ie->host_cmd, host_urb)); +} + +static int convert_iso_packets(uint8_t *dst, int totlen, abi_long src) +{ + void *srcptr; + int host_size, target_size; + int i, iso_packets; + const argtype arg_type[] =3D { MK_STRUCT(STRUCT_usbdevfs_iso_packet_de= sc) }; + + if (((struct usbdevfs_urb *)dst)->type =3D=3D USBDEVFS_URB_TYPE_ISO) { + iso_packets =3D ((struct usbdevfs_urb *)dst)->number_of_packets; + } else { + iso_packets =3D 0; + } + + host_size =3D thunk_type_size(arg_type, THUNK_HOST); + target_size =3D thunk_type_size(arg_type, THUNK_TARGET); + + for (i =3D 0; i < iso_packets; ++i) { + if ((totlen + host_size) >=3D MAX_STRUCT_SIZE) { + break; + } + srcptr =3D lock_user(VERIFY_READ, src, target_size, 1); + thunk_convert(dst + totlen, srcptr, arg_type, THUNK_HOST); + unlock_user(srcptr, src, 0); + src +=3D target_size; + totlen +=3D host_size; + } + return totlen; +} + +static abi_long +do_ioctl_usbdevfs_submiturb(const IOCTLEntry *ie, uint8_t *buf_temp, + int fd, int cmd, abi_long arg) +{ + const argtype *arg_type =3D ie->arg_type; + int target_size; + int host_size; + abi_long ret; + char *tagged_urb =3D NULL; + void *argptr; + int64_t arg_tag; + GHashTable * const urb_hash =3D usbdevfs_urb_hashtable(); + + /* + * each submitted URB needs to map to a unique ID for the + * kernel, and that unique ID needs to be a pointer to + * host memory. hence, we need to malloc for each URB. + * isochronous transfers have a variable length struct. + */ + arg_type++; + host_size =3D thunk_type_size(arg_type, THUNK_HOST); + target_size =3D thunk_type_size(arg_type, THUNK_TARGET); + + argptr =3D lock_user(VERIFY_READ, arg, target_size, 1); + if (!argptr) { + return -TARGET_EFAULT; + } + thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); + unlock_user(argptr, arg, 0); + + host_size =3D convert_iso_packets(buf_temp, host_size, arg + target_si= ze); + + /* allocate extra space for a tag. */ + tagged_urb =3D g_try_malloc0(host_size + sizeof(int64_t)); + if (!tagged_urb) { + return -TARGET_ENOMEM; + } + memcpy(&tagged_urb[sizeof(int64_t)], buf_temp, host_size); + + ret =3D get_errno(safe_ioctl(fd, ie->host_cmd, &tagged_urb[sizeof(int6= 4_t)])); + if (is_error(ret)) { + g_free(tagged_urb); + } else { + arg_tag =3D (int64_t) arg; + memcpy(tagged_urb, &arg_tag, sizeof(int64_t)); + g_hash_table_insert(urb_hash, tagged_urb, tagged_urb); + } + + return ret; +} +#endif /* CONFIG_USBFS */ + static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int f= d, int cmd, abi_long arg) { diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 357ee6a8c2..eeb7204b9e 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -866,6 +866,10 @@ struct target_pollfd { #define TARGET_USBDEVFS_SETINTERFACE TARGET_IOR('U', 4, struct usbdevfs_se= tinterface) #define TARGET_USBDEVFS_SETCONFIGURATION TARGET_IOR('U', 5, int) #define TARGET_USBDEVFS_GETDRIVER TARGET_IOW('U', 8, struct usbdevfs_getdr= iver) +#define TARGET_USBDEVFS_SUBMITURB TARGET_IOR('U', 10, struct usbdevfs_urb) +#define TARGET_USBDEVFS_DISCARDURB TARGET_IO('U', 11) +#define TARGET_USBDEVFS_REAPURB TARGET_IOW('U', 12, int) +#define TARGET_USBDEVFS_REAPURBNDELAY TARGET_IOW('U', 13, int) #define TARGET_USBDEVFS_DISCSIGNAL TARGET_IOR('U', 14, struct usbdevfs_dis= connectsignal) #define TARGET_USBDEVFS_CLAIMINTERFACE TARGET_IOR('U', 15, int) #define TARGET_USBDEVFS_RELEASEINTERFACE TARGET_IOR('U', 16, int) diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h index 6f64a8bdf7..b98a23b0f1 100644 --- a/linux-user/syscall_types.h +++ b/linux-user/syscall_types.h @@ -300,6 +300,26 @@ STRUCT(usbdevfs_connectinfo, TYPE_INT, /* devnum */ TYPE_CHAR) /* slow */ =20 +STRUCT(usbdevfs_iso_packet_desc, + TYPE_INT, /* length */ + TYPE_INT, /* actual_length */ + TYPE_INT) /* status */ + +STRUCT(usbdevfs_urb, + TYPE_CHAR, /* type */ + TYPE_CHAR, /* endpoint */ + TYPE_INT, /* status */ + TYPE_INT, /* flags */ + TYPE_PTRVOID, /* buffer */ + TYPE_INT, /* buffer_length */ + TYPE_INT, /* actual_length */ + TYPE_INT, /* start_frame */ + TYPE_INT, /* union number_of_packets stream_id */ + TYPE_INT, /* error_count */ + TYPE_INT, /* signr */ + TYPE_PTRVOID, /* usercontext */ + MK_ARRAY(MK_STRUCT(STRUCT_usbdevfs_iso_packet_desc), 0)) /* desc */ + STRUCT(usbdevfs_ioctl, TYPE_INT, /* ifno */ TYPE_INT, /* ioctl_code */ --=20 2.11.0