From patchwork Thu Jul 15 19:30:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Hung X-Patchwork-Id: 1505884 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=FLqPWtm3; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GQkxM14DKz9vM8; Fri, 16 Jul 2021 05:30:45 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1m474C-00065V-Hu; Thu, 15 Jul 2021 19:30:40 +0000 Received: from smtp-relay-canonical-1.internal ([10.131.114.174] helo=smtp-relay-canonical-1.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1m474B-000659-2R for kernel-team@lists.ubuntu.com; Thu, 15 Jul 2021 19:30:39 +0000 Received: from canonical.com (1.general.alexhung.us.vpn [10.172.65.254]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-canonical-1.canonical.com (Postfix) with ESMTPSA id 6E154409F4 for ; Thu, 15 Jul 2021 19:30:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1626377438; bh=hIDPueaf4RlBDbbAwkUX0zrfpj+23gywt6GMatat/k4=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=FLqPWtm3d37NDoNpnvAc7gosc19yPds7uc67ngK/fM2nuI9h/WqKBqIb0kqfTNZgt /cV2tQq6DUGqT9ULZaI+I4xAm5njJnY/jx3sR6zNxlMFcbPBKIfIeT3the3bN/IoiN sTlv0xVDZ0tD8He8YinJJovfupLigE0+6RvNrKfMC1aqXFHyQRLYikrnXrDJJzSNbX v7IfnLBQMiQzMweqBkyLlG3AzE1qL+2ZRn7gmQVbba1WuigxT1N+02L5aWu7mYs2Z2 iJ2sJZEzuJxld1TNod7n0wOkqXNnxBG9C07oQnJX7fLTj3hTdYfjvXMjXqVQrWd7FP 5bEXAd+5jKLwg== From: Alex Hung To: kernel-team@lists.ubuntu.com Subject: [SRU][F/G][PATCH] HID: sony: Workaround for DS4 dongle hotplug kernel crash. Date: Thu, 15 Jul 2021 13:30:33 -0600 Message-Id: <20210715193033.573411-2-alex.hung@canonical.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210715193033.573411-1-alex.hung@canonical.com> References: <20210715193033.573411-1-alex.hung@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Roderick Colenbrander The hid-sony driver has custom DS4 connect/disconnect logic for the DS4 dongle, which is a USB dongle acting as a proxy to Bluetooth connected DS4. The connect/disconnect logic works fine generally, however not in conjunction with Steam. Steam implements its own DS4 driver using hidraw. Both hid-sony and Steam are issuing their own HID requests and are racing each other during DS4 dongle connect/disconnect resulting in a kernel crash in hid-sony. The problem is that upon a DS4 connect to the dongle, hid-sony kicks of 'ds4_get_calibration_data' from within its dongle hotplug code. The calibration code issues raw HID feature report for reportID 0x02. When Steam is running, it issues a feature report for reportID 0x12 typically just prior to hid-sony requesting feature reportID 0x02. The result is that 'ds4_get_calibration_data' receives the data Steam requested as that's the HID report returing first. Currently this results in it processing invalid data, which ultimately results in a divide by zero upon a future 'dualshock4_parse_report'. The solution for now is to check within 'ds4_get_calibration_data' to check if we received data for the feature report we issued and if not retry. This fixes bug 206785. BugLink: https://bugs.launchpad.net/bugs/1935846 Signed-off-by: Roderick Colenbrander Signed-off-by: Jiri Kosina (cherry picked from commit f5dc93b7875bcb8be77baa792cc9432aaf65365b) Signed-off-by: Alex Hung --- drivers/hid/hid-sony.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 2f073f5..c7baedf 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -1597,16 +1597,38 @@ static int dualshock4_get_calibration_data(struct sony_sc *sc) * of the controller, so that it sends input reports of type 0x11. */ if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) { + int retries; + buf = kmalloc(DS4_FEATURE_REPORT_0x02_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; - ret = hid_hw_raw_request(sc->hdev, 0x02, buf, - DS4_FEATURE_REPORT_0x02_SIZE, - HID_FEATURE_REPORT, - HID_REQ_GET_REPORT); - if (ret < 0) - goto err_stop; + /* We should normally receive the feature report data we asked + * for, but hidraw applications such as Steam can issue feature + * reports as well. In particular for Dongle reconnects, Steam + * and this function are competing resulting in often receiving + * data for a different HID report, so retry a few times. + */ + for (retries = 0; retries < 3; retries++) { + ret = hid_hw_raw_request(sc->hdev, 0x02, buf, + DS4_FEATURE_REPORT_0x02_SIZE, + HID_FEATURE_REPORT, + HID_REQ_GET_REPORT); + if (ret < 0) + goto err_stop; + + if (buf[0] != 0x02) { + if (retries < 2) { + hid_warn(sc->hdev, "Retrying DualShock 4 get calibration report (0x02) request\n"); + continue; + } else { + ret = -EILSEQ; + goto err_stop; + } + } else { + break; + } + } } else { u8 bthdr = 0xA3; u32 crc;