From owner-svn-src-head@freebsd.org Sun Mar 29 23:00:53 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 47B5426733E; Sun, 29 Mar 2020 23:00:53 +0000 (UTC) (envelope-from wulf@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 48rB033F0Cz4XB9; Sun, 29 Mar 2020 23:00:51 +0000 (UTC) (envelope-from wulf@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 0CB93897C; Sun, 29 Mar 2020 23:00:34 +0000 (UTC) (envelope-from wulf@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 02TN0Xje082751; Sun, 29 Mar 2020 23:00:33 GMT (envelope-from wulf@FreeBSD.org) Received: (from wulf@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 02TN0XQp082750; Sun, 29 Mar 2020 23:00:33 GMT (envelope-from wulf@FreeBSD.org) Message-Id: <202003292300.02TN0XQp082750@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: wulf set sender to wulf@FreeBSD.org using -f From: Vladimir Kondratyev Date: Sun, 29 Mar 2020 23:00:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r359428 - head/sys/dev/evdev X-SVN-Group: head X-SVN-Commit-Author: wulf X-SVN-Commit-Paths: head/sys/dev/evdev X-SVN-Commit-Revision: 359428 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 29 Mar 2020 23:00:53 -0000 Author: wulf Date: Sun Mar 29 23:00:33 2020 New Revision: 359428 URL: https://svnweb.freebsd.org/changeset/base/359428 Log: evdev: Add COMPAT_FREEBSD32 support for amd64 arch Incompatibility between i386 and amd64 evdev ABIs was caused by presence of 'struct timeval' in evdev protocol. Replace it with 'struct timeval32' for 32 bit binaries. Big-endian platforms may require additional work due to bitstr_t (array of unsigned longs) usage in ioctl interface. MFC after: 2 weeks Modified: head/sys/dev/evdev/cdev.c Modified: head/sys/dev/evdev/cdev.c ============================================================================== --- head/sys/dev/evdev/cdev.c Sun Mar 29 20:03:46 2020 (r359427) +++ head/sys/dev/evdev/cdev.c Sun Mar 29 23:00:33 2020 (r359428) @@ -47,6 +47,18 @@ #include #include +#ifdef COMPAT_FREEBSD32 +#include +#include +#include +struct input_event32 { + struct timeval32 time; + uint16_t type; + uint16_t code; + int32_t value; +}; +#endif + #ifdef EVDEV_DEBUG #define debugf(client, fmt, args...) printf("evdev cdev: "fmt"\n", ##args) #else @@ -161,7 +173,14 @@ static int evdev_read(struct cdev *dev, struct uio *uio, int ioflag) { struct evdev_client *client; - struct input_event event; + union { + struct input_event t; +#ifdef COMPAT_FREEBSD32 + struct input_event32 t32; +#endif + } event; + struct input_event *head; + size_t evsize; int ret = 0; int remaining; @@ -175,11 +194,18 @@ evdev_read(struct cdev *dev, struct uio *uio, int iofl if (client->ec_revoked) return (ENODEV); +#ifdef COMPAT_FREEBSD32 + if (SV_CURPROC_FLAG(SV_ILP32)) + evsize = sizeof(struct input_event32); + else +#endif + evsize = sizeof(struct input_event); + /* Zero-sized reads are allowed for error checking */ - if (uio->uio_resid != 0 && uio->uio_resid < sizeof(struct input_event)) + if (uio->uio_resid != 0 && uio->uio_resid < evsize) return (EINVAL); - remaining = uio->uio_resid / sizeof(struct input_event); + remaining = uio->uio_resid / evsize; EVDEV_CLIENT_LOCKQ(client); @@ -196,14 +222,24 @@ evdev_read(struct cdev *dev, struct uio *uio, int iofl } while (ret == 0 && !EVDEV_CLIENT_EMPTYQ(client) && remaining > 0) { - memcpy(&event, &client->ec_buffer[client->ec_buffer_head], - sizeof(struct input_event)); + head = client->ec_buffer + client->ec_buffer_head; +#ifdef COMPAT_FREEBSD32 + if (SV_CURPROC_FLAG(SV_ILP32)) { + bzero(&event.t32, sizeof(struct input_event32)); + TV_CP(*head, event.t32, time); + CP(*head, event.t32, type); + CP(*head, event.t32, code); + CP(*head, event.t32, value); + } else +#endif + bcopy(head, &event.t, evsize); + client->ec_buffer_head = (client->ec_buffer_head + 1) % client->ec_buffer_size; remaining--; EVDEV_CLIENT_UNLOCKQ(client); - ret = uiomove(&event, sizeof(struct input_event), uio); + ret = uiomove(&event, evsize, uio); EVDEV_CLIENT_LOCKQ(client); } @@ -217,7 +253,13 @@ evdev_write(struct cdev *dev, struct uio *uio, int iof { struct evdev_dev *evdev = dev->si_drv1; struct evdev_client *client; - struct input_event event; + union { + struct input_event t; +#ifdef COMPAT_FREEBSD32 + struct input_event32 t32; +#endif + } event; + size_t evsize; int ret = 0; ret = devfs_get_cdevpriv((void **)&client); @@ -230,16 +272,30 @@ evdev_write(struct cdev *dev, struct uio *uio, int iof if (client->ec_revoked || evdev == NULL) return (ENODEV); - if (uio->uio_resid % sizeof(struct input_event) != 0) { +#ifdef COMPAT_FREEBSD32 + if (SV_CURPROC_FLAG(SV_ILP32)) + evsize = sizeof(struct input_event32); + else +#endif + evsize = sizeof(struct input_event); + + if (uio->uio_resid % evsize != 0) { debugf(client, "write size not multiple of input_event size"); return (EINVAL); } while (uio->uio_resid > 0 && ret == 0) { - ret = uiomove(&event, sizeof(struct input_event), uio); - if (ret == 0) - ret = evdev_inject_event(evdev, event.type, event.code, - event.value); + ret = uiomove(&event, evsize, uio); + if (ret == 0) { +#ifdef COMPAT_FREEBSD32 + if (SV_CURPROC_FLAG(SV_ILP32)) + ret = evdev_inject_event(evdev, event.t32.type, + event.t32.code, event.t32.value); + else +#endif + ret = evdev_inject_event(evdev, event.t.type, + event.t.code, event.t.value); + } } return (ret);