]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Dec 2015 22:43:18 +0000 (14:43 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Dec 2015 22:43:18 +0000 (14:43 -0800)
added patches:
toshiba_acpi-initialize-hotkey_event_type-variable.patch
tpm-tpm_tis-fix-tpm_tis-acpi-detection-issue-with-tpm-2.0.patch

queue-4.1/series [new file with mode: 0644]
queue-4.1/toshiba_acpi-initialize-hotkey_event_type-variable.patch [new file with mode: 0644]
queue-4.1/tpm-tpm_tis-fix-tpm_tis-acpi-detection-issue-with-tpm-2.0.patch [new file with mode: 0644]
queue-4.3/series [new file with mode: 0644]

diff --git a/queue-4.1/series b/queue-4.1/series
new file mode 100644 (file)
index 0000000..0b41a9b
--- /dev/null
@@ -0,0 +1,2 @@
+tpm-tpm_tis-fix-tpm_tis-acpi-detection-issue-with-tpm-2.0.patch
+toshiba_acpi-initialize-hotkey_event_type-variable.patch
diff --git a/queue-4.1/toshiba_acpi-initialize-hotkey_event_type-variable.patch b/queue-4.1/toshiba_acpi-initialize-hotkey_event_type-variable.patch
new file mode 100644 (file)
index 0000000..e4ff3a0
--- /dev/null
@@ -0,0 +1,35 @@
+From d2f20619942fe4618160a7fa3dbdcbac335cff59 Mon Sep 17 00:00:00 2001
+From: Azael Avalos <coproscefalo@gmail.com>
+Date: Wed, 4 Nov 2015 09:28:26 -0700
+Subject: toshiba_acpi: Initialize hotkey_event_type variable
+
+From: Azael Avalos <coproscefalo@gmail.com>
+
+commit d2f20619942fe4618160a7fa3dbdcbac335cff59 upstream.
+
+Commit 53147b6cabee5e8d1997b5682fcc0c3b72ddf9c2 ("toshiba_acpi: Fix
+hotkeys registration on some toshiba models") fixed an issue on some
+laptops regarding hotkeys registration, however, if failed to address
+the initialization of the hotkey_event_type variable, and thus, it can
+lead to potential unwanted effects as the variable is being checked.
+
+This patch initializes such variable to avoid such unwanted effects.
+
+Signed-off-by: Azael Avalos <coproscefalo@gmail.com>
+Signed-off-by: Darren Hart <dvhart@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/platform/x86/toshiba_acpi.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/platform/x86/toshiba_acpi.c
++++ b/drivers/platform/x86/toshiba_acpi.c
+@@ -2764,6 +2764,7 @@ static int toshiba_acpi_add(struct acpi_
+       ret = toshiba_function_keys_get(dev, &special_functions);
+       dev->kbd_function_keys_supported = !ret;
++      dev->hotkey_event_type = 0;
+       if (toshiba_acpi_setup_keyboard(dev))
+               pr_info("Unable to activate hotkeys\n");
diff --git a/queue-4.1/tpm-tpm_tis-fix-tpm_tis-acpi-detection-issue-with-tpm-2.0.patch b/queue-4.1/tpm-tpm_tis-fix-tpm_tis-acpi-detection-issue-with-tpm-2.0.patch
new file mode 100644 (file)
index 0000000..e39c45e
--- /dev/null
@@ -0,0 +1,443 @@
+From 399235dc6e95400a1322a9999e92073bc572f0c8 Mon Sep 17 00:00:00 2001
+From: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Date: Tue, 29 Sep 2015 00:32:19 +0300
+Subject: tpm, tpm_tis: fix tpm_tis ACPI detection issue with TPM 2.0
+
+From: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+
+commit 399235dc6e95400a1322a9999e92073bc572f0c8 upstream.
+
+Both for FIFO and CRB interface TCG has decided to use the same HID
+MSFT0101. They can be differentiated by looking at the start method from
+TPM2 ACPI table. This patches makes necessary fixes to tpm_tis and
+tpm_crb modules in order to correctly detect, which module should be
+used.
+
+For MSFT0101 we must use struct acpi_driver because struct pnp_driver
+has a 7 character limitation.
+
+It turned out that the root cause in b371616b8 was not correct for
+https://bugzilla.kernel.org/show_bug.cgi?id=98181.
+
+v2:
+
+* One fixup was missing from v1: is_tpm2_fifo -> is_fifo
+
+v3:
+
+* Use pnp_driver for existing HIDs and acpi_driver only for MSFT0101 in
+  order ensure backwards compatibility.
+
+v4:
+
+* Check for FIFO before doing *anything* in crb_acpi_add().
+* There was return immediately after acpi_bus_unregister_driver() in
+  cleanup_tis(). This caused pnp_unregister_driver() not to be called.
+
+Reported-by: Michael Saunders <mick.saunders@gmail.com>
+Reported-by: Michael Marley <michael@michaelmarley.com>
+Reported-by: Jethro Beekman <kernel@jbeekman.nl>
+Reported-by: Matthew Garrett <mjg59@srcf.ucam.org>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Tested-by: Michael Marley <michael@michaelmarley.com>
+Tested-by: Mimi Zohar <zohar@linux.vnet.ibm.com> (on TPM 1.2)
+Reviewed-by: Peter Huewe <peterhuewe@gmx.de>
+Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm.h     |    7 +
+ drivers/char/tpm/tpm_crb.c |   32 ++-----
+ drivers/char/tpm/tpm_tis.c |  192 ++++++++++++++++++++++++++++++++++++++-------
+ 3 files changed, 181 insertions(+), 50 deletions(-)
+
+--- a/drivers/char/tpm/tpm.h
++++ b/drivers/char/tpm/tpm.h
+@@ -115,6 +115,13 @@ enum tpm2_startup_types {
+       TPM2_SU_STATE   = 0x0001,
+ };
++enum tpm2_start_method {
++      TPM2_START_ACPI = 2,
++      TPM2_START_FIFO = 6,
++      TPM2_START_CRB = 7,
++      TPM2_START_CRB_WITH_ACPI = 8,
++};
++
+ struct tpm_chip;
+ struct tpm_vendor_specific {
+--- a/drivers/char/tpm/tpm_crb.c
++++ b/drivers/char/tpm/tpm_crb.c
+@@ -34,12 +34,6 @@ enum crb_defaults {
+       CRB_ACPI_START_INDEX = 1,
+ };
+-enum crb_start_method {
+-      CRB_SM_ACPI_START = 2,
+-      CRB_SM_CRB = 7,
+-      CRB_SM_CRB_WITH_ACPI_START = 8,
+-};
+-
+ struct acpi_tpm2 {
+       struct acpi_table_header hdr;
+       u16 platform_class;
+@@ -220,12 +214,6 @@ static int crb_acpi_add(struct acpi_devi
+       u64 pa;
+       int rc;
+-      chip = tpmm_chip_alloc(dev, &tpm_crb);
+-      if (IS_ERR(chip))
+-              return PTR_ERR(chip);
+-
+-      chip->flags = TPM_CHIP_FLAG_TPM2;
+-
+       status = acpi_get_table(ACPI_SIG_TPM2, 1,
+                               (struct acpi_table_header **) &buf);
+       if (ACPI_FAILURE(status)) {
+@@ -233,13 +221,15 @@ static int crb_acpi_add(struct acpi_devi
+               return -ENODEV;
+       }
+-      /* At least some versions of AMI BIOS have a bug that TPM2 table has
+-       * zero address for the control area and therefore we must fail.
+-      */
+-      if (!buf->control_area_pa) {
+-              dev_err(dev, "TPM2 ACPI table has a zero address for the control area\n");
+-              return -EINVAL;
+-      }
++      /* Should the FIFO driver handle this? */
++      if (buf->start_method == TPM2_START_FIFO)
++              return -ENODEV;
++
++      chip = tpmm_chip_alloc(dev, &tpm_crb);
++      if (IS_ERR(chip))
++              return PTR_ERR(chip);
++
++      chip->flags = TPM_CHIP_FLAG_TPM2;
+       if (buf->hdr.length < sizeof(struct acpi_tpm2)) {
+               dev_err(dev, "TPM2 ACPI table has wrong size");
+@@ -259,11 +249,11 @@ static int crb_acpi_add(struct acpi_devi
+        * report only ACPI start but in practice seems to require both
+        * ACPI start and CRB start.
+        */
+-      if (sm == CRB_SM_CRB || sm == CRB_SM_CRB_WITH_ACPI_START ||
++      if (sm == TPM2_START_CRB || sm == TPM2_START_FIFO ||
+           !strcmp(acpi_device_hid(device), "MSFT0101"))
+               priv->flags |= CRB_FL_CRB_START;
+-      if (sm == CRB_SM_ACPI_START || sm == CRB_SM_CRB_WITH_ACPI_START)
++      if (sm == TPM2_START_ACPI || sm == TPM2_START_CRB_WITH_ACPI)
+               priv->flags |= CRB_FL_ACPI_START;
+       priv->cca = (struct crb_control_area __iomem *)
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -1,6 +1,6 @@
+ /*
+  * Copyright (C) 2005, 2006 IBM Corporation
+- * Copyright (C) 2014 Intel Corporation
++ * Copyright (C) 2014, 2015 Intel Corporation
+  *
+  * Authors:
+  * Leendert van Doorn <leendert@watson.ibm.com>
+@@ -28,6 +28,7 @@
+ #include <linux/wait.h>
+ #include <linux/acpi.h>
+ #include <linux/freezer.h>
++#include <acpi/actbl2.h>
+ #include "tpm.h"
+ enum tis_access {
+@@ -65,6 +66,17 @@ enum tis_defaults {
+       TIS_LONG_TIMEOUT = 2000,        /* 2 sec */
+ };
++struct tpm_info {
++      unsigned long start;
++      unsigned long len;
++      unsigned int irq;
++};
++
++static struct tpm_info tis_default_info = {
++      .start = TIS_MEM_BASE,
++      .len = TIS_MEM_LEN,
++      .irq = 0,
++};
+ /* Some timeout values are needed before it is known whether the chip is
+  * TPM 1.0 or TPM 2.0.
+@@ -91,26 +103,54 @@ struct priv_data {
+ };
+ #if defined(CONFIG_PNP) && defined(CONFIG_ACPI)
+-static int is_itpm(struct pnp_dev *dev)
++static int has_hid(struct acpi_device *dev, const char *hid)
+ {
+-      struct acpi_device *acpi = pnp_acpi_device(dev);
+       struct acpi_hardware_id *id;
+-      if (!acpi)
+-              return 0;
+-
+-      list_for_each_entry(id, &acpi->pnp.ids, list) {
+-              if (!strcmp("INTC0102", id->id))
++      list_for_each_entry(id, &dev->pnp.ids, list)
++              if (!strcmp(hid, id->id))
+                       return 1;
+-      }
+       return 0;
+ }
++
++static inline int is_itpm(struct acpi_device *dev)
++{
++      return has_hid(dev, "INTC0102");
++}
++
++static inline int is_fifo(struct acpi_device *dev)
++{
++      struct acpi_table_tpm2 *tbl;
++      acpi_status st;
++
++      /* TPM 1.2 FIFO */
++      if (!has_hid(dev, "MSFT0101"))
++              return 1;
++
++      st = acpi_get_table(ACPI_SIG_TPM2, 1,
++                          (struct acpi_table_header **) &tbl);
++      if (ACPI_FAILURE(st)) {
++              dev_err(&dev->dev, "failed to get TPM2 ACPI table\n");
++              return 0;
++      }
++
++      if (le32_to_cpu(tbl->start_method) != TPM2_START_FIFO)
++              return 0;
++
++      /* TPM 2.0 FIFO */
++      return 1;
++}
+ #else
+-static inline int is_itpm(struct pnp_dev *dev)
++static inline int is_itpm(struct acpi_device *dev)
+ {
+       return 0;
+ }
++
++static inline int is_fifo(struct acpi_device *dev)
++{
++      return 1;
++}
+ #endif
+ /* Before we attempt to access the TPM we must see that the valid bit is set.
+@@ -600,9 +640,8 @@ static void tpm_tis_remove(struct tpm_ch
+       release_locality(chip, chip->vendor.locality, 1);
+ }
+-static int tpm_tis_init(struct device *dev, acpi_handle acpi_dev_handle,
+-                      resource_size_t start, resource_size_t len,
+-                      unsigned int irq)
++static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
++                      acpi_handle acpi_dev_handle)
+ {
+       u32 vendor, intfcaps, intmask;
+       int rc, i, irq_s, irq_e, probe;
+@@ -622,7 +661,7 @@ static int tpm_tis_init(struct device *d
+       chip->acpi_dev_handle = acpi_dev_handle;
+ #endif
+-      chip->vendor.iobase = devm_ioremap(dev, start, len);
++      chip->vendor.iobase = devm_ioremap(dev, tpm_info->start, tpm_info->len);
+       if (!chip->vendor.iobase)
+               return -EIO;
+@@ -707,7 +746,7 @@ static int tpm_tis_init(struct device *d
+                 chip->vendor.iobase +
+                 TPM_INT_ENABLE(chip->vendor.locality));
+       if (interrupts)
+-              chip->vendor.irq = irq;
++              chip->vendor.irq = tpm_info->irq;
+       if (interrupts && !chip->vendor.irq) {
+               irq_s =
+                   ioread8(chip->vendor.iobase +
+@@ -890,27 +929,27 @@ static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm
+ static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
+                                     const struct pnp_device_id *pnp_id)
+ {
+-      resource_size_t start, len;
+-      unsigned int irq = 0;
++      struct tpm_info tpm_info = tis_default_info;
+       acpi_handle acpi_dev_handle = NULL;
+-      start = pnp_mem_start(pnp_dev, 0);
+-      len = pnp_mem_len(pnp_dev, 0);
++      tpm_info.start = pnp_mem_start(pnp_dev, 0);
++      tpm_info.len = pnp_mem_len(pnp_dev, 0);
+       if (pnp_irq_valid(pnp_dev, 0))
+-              irq = pnp_irq(pnp_dev, 0);
++              tpm_info.irq = pnp_irq(pnp_dev, 0);
+       else
+               interrupts = false;
+-      if (is_itpm(pnp_dev))
+-              itpm = true;
+-
+ #ifdef CONFIG_ACPI
+-      if (pnp_acpi_device(pnp_dev))
++      if (pnp_acpi_device(pnp_dev)) {
++              if (is_itpm(pnp_acpi_device(pnp_dev)))
++                      itpm = true;
++
+               acpi_dev_handle = pnp_acpi_device(pnp_dev)->handle;
++      }
+ #endif
+-      return tpm_tis_init(&pnp_dev->dev, acpi_dev_handle, start, len, irq);
++      return tpm_tis_init(&pnp_dev->dev, &tpm_info, acpi_dev_handle);
+ }
+ static struct pnp_device_id tpm_pnp_tbl[] = {
+@@ -930,6 +969,7 @@ MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
+ static void tpm_tis_pnp_remove(struct pnp_dev *dev)
+ {
+       struct tpm_chip *chip = pnp_get_drvdata(dev);
++
+       tpm_chip_unregister(chip);
+       tpm_tis_remove(chip);
+ }
+@@ -950,6 +990,79 @@ module_param_string(hid, tpm_pnp_tbl[TIS
+ MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
+ #endif
++#ifdef CONFIG_ACPI
++static int tpm_check_resource(struct acpi_resource *ares, void *data)
++{
++      struct tpm_info *tpm_info = (struct tpm_info *) data;
++      struct resource res;
++
++      if (acpi_dev_resource_interrupt(ares, 0, &res)) {
++              tpm_info->irq = res.start;
++      } else if (acpi_dev_resource_memory(ares, &res)) {
++              tpm_info->start = res.start;
++              tpm_info->len = resource_size(&res);
++      }
++
++      return 1;
++}
++
++static int tpm_tis_acpi_init(struct acpi_device *acpi_dev)
++{
++      struct list_head resources;
++      struct tpm_info tpm_info = tis_default_info;
++      int ret;
++
++      if (!is_fifo(acpi_dev))
++              return -ENODEV;
++
++      INIT_LIST_HEAD(&resources);
++      ret = acpi_dev_get_resources(acpi_dev, &resources, tpm_check_resource,
++                                   &tpm_info);
++      if (ret < 0)
++              return ret;
++
++      acpi_dev_free_resource_list(&resources);
++
++      if (!tpm_info.irq)
++              interrupts = false;
++
++      if (is_itpm(acpi_dev))
++              itpm = true;
++
++      return tpm_tis_init(&acpi_dev->dev, &tpm_info, acpi_dev->handle);
++}
++
++static int tpm_tis_acpi_remove(struct acpi_device *dev)
++{
++      struct tpm_chip *chip = dev_get_drvdata(&dev->dev);
++
++      tpm_chip_unregister(chip);
++      tpm_tis_remove(chip);
++
++      return 0;
++}
++
++static struct acpi_device_id tpm_acpi_tbl[] = {
++      {"MSFT0101", 0},        /* TPM 2.0 */
++      /* Add new here */
++      {"", 0},                /* User Specified */
++      {"", 0}                 /* Terminator */
++};
++MODULE_DEVICE_TABLE(acpi, tpm_acpi_tbl);
++
++static struct acpi_driver tis_acpi_driver = {
++      .name = "tpm_tis",
++      .ids = tpm_acpi_tbl,
++      .ops = {
++              .add = tpm_tis_acpi_init,
++              .remove = tpm_tis_acpi_remove,
++      },
++      .drv = {
++              .pm = &tpm_tis_pm,
++      },
++};
++#endif
++
+ static struct platform_driver tis_drv = {
+       .driver = {
+               .name           = "tpm_tis",
+@@ -966,9 +1079,25 @@ static int __init init_tis(void)
+ {
+       int rc;
+ #ifdef CONFIG_PNP
+-      if (!force)
+-              return pnp_register_driver(&tis_pnp_driver);
++      if (!force) {
++              rc = pnp_register_driver(&tis_pnp_driver);
++              if (rc)
++                      return rc;
++      }
++#endif
++#ifdef CONFIG_ACPI
++      if (!force) {
++              rc = acpi_bus_register_driver(&tis_acpi_driver);
++              if (rc) {
++#ifdef CONFIG_PNP
++                      pnp_unregister_driver(&tis_pnp_driver);
+ #endif
++                      return rc;
++              }
++      }
++#endif
++      if (!force)
++              return 0;
+       rc = platform_driver_register(&tis_drv);
+       if (rc < 0)
+@@ -978,7 +1107,7 @@ static int __init init_tis(void)
+               rc = PTR_ERR(pdev);
+               goto err_dev;
+       }
+-      rc = tpm_tis_init(&pdev->dev, NULL, TIS_MEM_BASE, TIS_MEM_LEN, 0);
++      rc = tpm_tis_init(&pdev->dev, &tis_default_info, NULL);
+       if (rc)
+               goto err_init;
+       return 0;
+@@ -992,9 +1121,14 @@ err_dev:
+ static void __exit cleanup_tis(void)
+ {
+       struct tpm_chip *chip;
+-#ifdef CONFIG_PNP
++#if defined(CONFIG_PNP) || defined(CONFIG_ACPI)
+       if (!force) {
++#ifdef CONFIG_ACPI
++              acpi_bus_unregister_driver(&tis_acpi_driver);
++#endif
++#ifdef CONFIG_PNP
+               pnp_unregister_driver(&tis_pnp_driver);
++#endif
+               return;
+       }
+ #endif
diff --git a/queue-4.3/series b/queue-4.3/series
new file mode 100644 (file)
index 0000000..65276a6
--- /dev/null
@@ -0,0 +1,8 @@
+revert-vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch
+vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch
+tipc-fix-kfree_skb-of-uninitialised-pointer.patch
+acpi-use-correct-irq-when-uninstalling-acpi-interrupt-handler.patch
+acpi-using-correct-irq-when-waiting-for-events.patch
+acpi-pm-fix-incorrect-wakeup-irq-setting-during-suspend-to-idle.patch
+tpm-tpm_tis-fix-tpm_tis-acpi-detection-issue-with-tpm-2.0.patch
+toshiba_acpi-initialize-hotkey_event_type-variable.patch