summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHong Liu <hong.liu@intel.com>2019-02-12 20:05:20 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-04-05 22:34:36 +0200
commit2fe8be270932ea0ab076aa42c0ecc914f6ae1753 (patch)
treeac60f18c5c6246e65dbd2af53d37702b38a80735
parente6eef52400547322907c2e5e4eb8a825f8ed4e59 (diff)
downloadblackbird-obmc-linux-2fe8be270932ea0ab076aa42c0ecc914f6ae1753.tar.gz
blackbird-obmc-linux-2fe8be270932ea0ab076aa42c0ecc914f6ae1753.zip
HID: intel-ish-hid: avoid binding wrong ishtp_cl_device
[ Upstream commit 0d28f49412405d87d3aae83da255070a46e67627 ] When performing a warm reset in ishtp bus driver, the ishtp_cl_device will not be removed, its fw_client still points to the already freed ishtp_device.fw_clients array. Later after driver finishing ishtp client enumeration, this dangling pointer may cause driver to bind the wrong ishtp_cl_device to the new client, causing wrong callback to be called for messages intended for the new client. This helps in development of firmware where frequent switching of firmwares is required without Linux reboot. Signed-off-by: Hong Liu <hong.liu@intel.com> Tested-by: Hongyan Song <hongyan.song@intel.com> Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/hid/intel-ish-hid/ishtp/bus.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c
index 728dc6d4561a..a271d6d169b1 100644
--- a/drivers/hid/intel-ish-hid/ishtp/bus.c
+++ b/drivers/hid/intel-ish-hid/ishtp/bus.c
@@ -675,7 +675,8 @@ int ishtp_cl_device_bind(struct ishtp_cl *cl)
spin_lock_irqsave(&cl->dev->device_list_lock, flags);
list_for_each_entry(cl_device, &cl->dev->device_list,
device_link) {
- if (cl_device->fw_client->client_id == cl->fw_client_id) {
+ if (cl_device->fw_client &&
+ cl_device->fw_client->client_id == cl->fw_client_id) {
cl->device = cl_device;
rv = 0;
break;
@@ -735,6 +736,7 @@ void ishtp_bus_remove_all_clients(struct ishtp_device *ishtp_dev,
spin_lock_irqsave(&ishtp_dev->device_list_lock, flags);
list_for_each_entry_safe(cl_device, n, &ishtp_dev->device_list,
device_link) {
+ cl_device->fw_client = NULL;
if (warm_reset && cl_device->reference_count)
continue;
OpenPOWER on IntegriCloud