From patchwork Mon Oct 24 11:31:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg KH X-Patchwork-Id: 8359 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp391897wru; Mon, 24 Oct 2022 04:34:13 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4vUR2KS5HhGEvG2z0fO7KspogpWngm5hoDIvS2cLajdukJbzkSp0jBNzxt7J/bOiErHa70 X-Received: by 2002:a05:6a02:47:b0:46e:ea48:9543 with SMTP id az7-20020a056a02004700b0046eea489543mr8304159pgb.6.1666611252888; Mon, 24 Oct 2022 04:34:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666611252; cv=none; d=google.com; s=arc-20160816; b=DoeOyjPTPY10e5h0CFeJqpFoQrynafiilM8d9sQsZgwRPOibv5Fss1+QGCqcBTFvpe ouP0ZrjaAxPYQSvrJ4n5Ho1PMCHrJXZ2zxTNTD9twIZ2CBdTliWEJsQSh4vTyOeiCaxj KUTSK/0ehk+7v91AwO7avXU4tW/310Nq+clKCMcvyzEa415MGQKivdYZSnnP4iSxBfN1 aHetJ4paEX7qJpJcMFR7wfmZvW05Ozyt5daiobftZeXmvi9Pww9ncUy2zgrElvNVFIe6 04o0ydat2dO1aQllC0x7XlbzmShpgHvQf8bkSIC9VCBbtIMrSVFMthuSIh7z0eaQyWy6 fM1A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=eogU5n7fO6aW2CeKTrpb9w+1VbMIkfA5d9dN6SBK66Q=; b=cOV7vHt5NWrWiO9NBxNpZafAP07Q4fjnRox3G1SksCHjL6TvkhdwRg4zabP0W7o9JA tRByngE6YT2MN55RtvxK84weV0UmPKXlo6epGKzJW3OxRVN4MH3r+ylbvEWo23Yd6Q0a gweOkDLNhpyAvQS7PeMsJ592JTMSva4q1LUmEJlh/FzxqHzubzjE/Ca5U71Y0yk0bkuP 1OuKGGObMylqMXrSC5h4oZlh0Hd3sBqqN8LqNru9kD7kWU+yXOBSWnPlsq9Ymiey+vfT qH+zyTh2mT7ldfXCAI61FQS94JruCgh14Dbs7bqaYEMBhlzOmcL/QqX8fn75JX4GZ6Bl BYlQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=YFE4f4z3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id 5-20020a631145000000b004428327e6dfsi35683115pgr.174.2022.10.24.04.33.59; Mon, 24 Oct 2022 04:34:12 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=YFE4f4z3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230302AbiJXLdR (ORCPT + 99 others); Mon, 24 Oct 2022 07:33:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57254 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230312AbiJXLch (ORCPT ); Mon, 24 Oct 2022 07:32:37 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2D25C550BC; Mon, 24 Oct 2022 04:32:26 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id B64E0B81144; Mon, 24 Oct 2022 11:32:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 10C28C433D6; Mon, 24 Oct 2022 11:32:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1666611142; bh=ANMp6hiyB/8WBsFZyh1qIrbFk27cX/q2qOwTak6f1TY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YFE4f4z3kvEh6m/8qyTwGapyG64QVKXpkvumgx3yhcr5w8ikLIBz3LaSlcwOx7l9D FN9TpmC6N425hMxpoJPsJpKfYmXGJYdl7ob5/OUWV+u5UQw1DDjnHINh6XbpZ4RySs 2e9PT378GmIWiDXAMEHEF4L0OVpT+Y9NzX8Bce7o= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Roderick Colenbrander , Benjamin Tissoires Subject: [PATCH 6.0 06/20] HID: playstation: stop DualSense output work on remove. Date: Mon, 24 Oct 2022 13:31:08 +0200 Message-Id: <20221024112934.685810726@linuxfoundation.org> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221024112934.415391158@linuxfoundation.org> References: <20221024112934.415391158@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747568561337633497?= X-GMAIL-MSGID: =?utf-8?q?1747568561337633497?= From: Roderick Colenbrander commit 182934a1e93b17f4edf71f4fcc8d19b19a6fe67a upstream. Ensure we don't schedule any new output work on removal and wait for any existing work to complete. If we don't do this e.g. rumble work can get queued during deletion and we trigger a kernel crash. Signed-off-by: Roderick Colenbrander CC: stable@vger.kernel.org Signed-off-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20221010212313.78275-2-roderick.colenbrander@sony.com Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-playstation.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) --- a/drivers/hid/hid-playstation.c +++ b/drivers/hid/hid-playstation.c @@ -46,6 +46,7 @@ struct ps_device { uint32_t fw_version; int (*parse_report)(struct ps_device *dev, struct hid_report *report, u8 *data, int size); + void (*remove)(struct ps_device *dev); }; /* Calibration data for playstation motion sensors. */ @@ -174,6 +175,7 @@ struct dualsense { struct led_classdev player_leds[5]; struct work_struct output_worker; + bool output_worker_initialized; void *output_report_dmabuf; uint8_t output_seq; /* Sequence number for output report. */ }; @@ -299,6 +301,7 @@ static const struct {int x; int y; } ps_ {0, 0}, }; +static inline void dualsense_schedule_work(struct dualsense *ds); static void dualsense_set_lightbar(struct dualsense *ds, uint8_t red, uint8_t green, uint8_t blue); /* @@ -792,6 +795,7 @@ err_free: return ret; } + static int dualsense_get_firmware_info(struct dualsense *ds) { uint8_t *buf; @@ -881,7 +885,7 @@ static int dualsense_player_led_set_brig ds->update_player_leds = true; spin_unlock_irqrestore(&ds->base.lock, flags); - schedule_work(&ds->output_worker); + dualsense_schedule_work(ds); return 0; } @@ -925,6 +929,16 @@ static void dualsense_init_output_report } } +static inline void dualsense_schedule_work(struct dualsense *ds) +{ + unsigned long flags; + + spin_lock_irqsave(&ds->base.lock, flags); + if (ds->output_worker_initialized) + schedule_work(&ds->output_worker); + spin_unlock_irqrestore(&ds->base.lock, flags); +} + /* * Helper function to send DualSense output reports. Applies a CRC at the end of a report * for Bluetooth reports. @@ -1085,7 +1099,7 @@ static int dualsense_parse_report(struct spin_unlock_irqrestore(&ps_dev->lock, flags); /* Schedule updating of microphone state at hardware level. */ - schedule_work(&ds->output_worker); + dualsense_schedule_work(ds); } ds->last_btn_mic_state = btn_mic_state; @@ -1200,10 +1214,22 @@ static int dualsense_play_effect(struct ds->motor_right = effect->u.rumble.weak_magnitude / 256; spin_unlock_irqrestore(&ds->base.lock, flags); - schedule_work(&ds->output_worker); + dualsense_schedule_work(ds); return 0; } +static void dualsense_remove(struct ps_device *ps_dev) +{ + struct dualsense *ds = container_of(ps_dev, struct dualsense, base); + unsigned long flags; + + spin_lock_irqsave(&ds->base.lock, flags); + ds->output_worker_initialized = false; + spin_unlock_irqrestore(&ds->base.lock, flags); + + cancel_work_sync(&ds->output_worker); +} + static int dualsense_reset_leds(struct dualsense *ds) { struct dualsense_output_report report; @@ -1240,7 +1266,7 @@ static void dualsense_set_lightbar(struc ds->lightbar_blue = blue; spin_unlock_irqrestore(&ds->base.lock, flags); - schedule_work(&ds->output_worker); + dualsense_schedule_work(ds); } static void dualsense_set_player_leds(struct dualsense *ds) @@ -1263,7 +1289,7 @@ static void dualsense_set_player_leds(st ds->update_player_leds = true; ds->player_leds_state = player_ids[player_id]; - schedule_work(&ds->output_worker); + dualsense_schedule_work(ds); } static struct ps_device *dualsense_create(struct hid_device *hdev) @@ -1302,7 +1328,9 @@ static struct ps_device *dualsense_creat ps_dev->battery_capacity = 100; /* initial value until parse_report. */ ps_dev->battery_status = POWER_SUPPLY_STATUS_UNKNOWN; ps_dev->parse_report = dualsense_parse_report; + ps_dev->remove = dualsense_remove; INIT_WORK(&ds->output_worker, dualsense_output_worker); + ds->output_worker_initialized = true; hid_set_drvdata(hdev, ds); max_output_report_size = sizeof(struct dualsense_output_report_bt); @@ -1470,6 +1498,9 @@ static void ps_remove(struct hid_device ps_devices_list_remove(dev); ps_device_release_player_id(dev); + if (dev->remove) + dev->remove(dev); + hid_hw_close(hdev); hid_hw_stop(hdev); }