From a1e9a9c0dfe47a3f13734be489b7953a2f8bdd83 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Wed, 18 Jul 2018 12:32:00 -0700 Subject: [PATCH 1/2] HID: intel-ish-hid: Prevent loading of driver on Mehlow On Mehlow Xeon-E workstation, ISH PCI device is enabled but without ISH firmware. Here the ISH device PCI device id was reused for some non Linux storage drivers. So this was not done for enabling ISH. But this has a undesirable side effect for Linux. Here the ISH driver will be loaded via PCI enumeration and will try to do reset sequence. But reset sequence will wait till timeout as there is no real ISH firmware is present to take action. This delay will add to boot time of Linux (This platform will still continue to boot after this timeout). To avoid this boot delay we need to prevent loading of ISH drivers on this platform. So we need to have hack to avoid treating this device as ISH on this platform. To identify this workstation, we need some runtime method. Luckily there are special PCI id on this workstation to distinguish from the client version of this platform. On client version, the ISH is supported using same PCI device id. So this change look for the presence of PCI device IDs A309 and A30A and exit. Signed-off-by: Srinivas Pandruvada Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/intel-ish-hid/ipc/pci-ish.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c index a2c53ea3b5ed..4a55eab39b88 100644 --- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c +++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c @@ -95,6 +95,13 @@ static int ish_init(struct ishtp_device *dev) return 0; } +static const struct pci_device_id ish_invalid_pci_ids[] = { + /* Mehlow platform special pci ids */ + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xA309)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xA30A)}, + {} +}; + /** * ish_probe() - PCI driver probe callback * @pdev: pci device @@ -110,6 +117,10 @@ static int ish_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct ish_hw *hw; int ret; + /* Check for invalid platforms for ISH support */ + if (pci_dev_present(ish_invalid_pci_ids)) + return -ENODEV; + /* enable pci dev */ ret = pci_enable_device(pdev); if (ret) { From 50fa92594a2bc76265f4bb357f9a25dd3bdb2c0a Mon Sep 17 00:00:00 2001 From: Anton Vasilyev Date: Wed, 1 Aug 2018 14:26:51 +0300 Subject: [PATCH 2/2] HID: intel_ish-hid: tx_buf memory leak on probe/remove ish_dev_init() allocates 512*176 bytes memory for tx_buf and stores it at &dev->wr_free_list_head.link list on ish_probe(). But there is no deallocation of this memory in ish_remove() and in ish_probe() error path. So current intel-ish-ipc provides 88 KB memory leak for each probe/release. The patch replaces kzalloc allocation by devm_kzalloc and removes ishtp_device *dev deallocation by kfree. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Anton Vasilyev Acked-by: Srinivas Pandruvada Signed-off-by: Jiri Kosina --- drivers/hid/intel-ish-hid/ipc/ipc.c | 9 ++++++--- drivers/hid/intel-ish-hid/ipc/pci-ish.c | 2 -- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/hid/intel-ish-hid/ipc/ipc.c b/drivers/hid/intel-ish-hid/ipc/ipc.c index 9a60ec13cb10..bfbca7ec54ce 100644 --- a/drivers/hid/intel-ish-hid/ipc/ipc.c +++ b/drivers/hid/intel-ish-hid/ipc/ipc.c @@ -907,8 +907,9 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev) struct ishtp_device *dev; int i; - dev = kzalloc(sizeof(struct ishtp_device) + sizeof(struct ish_hw), - GFP_KERNEL); + dev = devm_kzalloc(&pdev->dev, + sizeof(struct ishtp_device) + sizeof(struct ish_hw), + GFP_KERNEL); if (!dev) return NULL; @@ -925,7 +926,9 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev) for (i = 0; i < IPC_TX_FIFO_SIZE; ++i) { struct wr_msg_ctl_info *tx_buf; - tx_buf = kzalloc(sizeof(struct wr_msg_ctl_info), GFP_KERNEL); + tx_buf = devm_kzalloc(&pdev->dev, + sizeof(struct wr_msg_ctl_info), + GFP_KERNEL); if (!tx_buf) { /* * IPC buffers may be limited or not available diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c index 4a55eab39b88..050f9872f5c0 100644 --- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c +++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c @@ -183,7 +183,6 @@ free_irq: free_irq(pdev->irq, dev); free_device: pci_iounmap(pdev, hw->mem_addr); - kfree(dev); release_regions: pci_release_regions(pdev); disable_device: @@ -213,7 +212,6 @@ static void ish_remove(struct pci_dev *pdev) pci_release_regions(pdev); pci_clear_master(pdev); pci_disable_device(pdev); - kfree(ishtp_dev); } static struct device __maybe_unused *ish_resume_device;