]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.3-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Dec 2015 22:43:25 +0000 (14:43 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Dec 2015 22:43:25 +0000 (14:43 -0800)
added patches:
acpi-pm-fix-incorrect-wakeup-irq-setting-during-suspend-to-idle.patch
acpi-use-correct-irq-when-uninstalling-acpi-interrupt-handler.patch
acpi-using-correct-irq-when-waiting-for-events.patch
revert-vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch
tipc-fix-kfree_skb-of-uninitialised-pointer.patch
toshiba_acpi-initialize-hotkey_event_type-variable.patch
tpm-tpm_tis-fix-tpm_tis-acpi-detection-issue-with-tpm-2.0.patch
vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch

queue-4.3/acpi-pm-fix-incorrect-wakeup-irq-setting-during-suspend-to-idle.patch [new file with mode: 0644]
queue-4.3/acpi-use-correct-irq-when-uninstalling-acpi-interrupt-handler.patch [new file with mode: 0644]
queue-4.3/acpi-using-correct-irq-when-waiting-for-events.patch [new file with mode: 0644]
queue-4.3/revert-vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch [new file with mode: 0644]
queue-4.3/tipc-fix-kfree_skb-of-uninitialised-pointer.patch [new file with mode: 0644]
queue-4.3/toshiba_acpi-initialize-hotkey_event_type-variable.patch [new file with mode: 0644]
queue-4.3/tpm-tpm_tis-fix-tpm_tis-acpi-detection-issue-with-tpm-2.0.patch [new file with mode: 0644]
queue-4.3/vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch [new file with mode: 0644]

diff --git a/queue-4.3/acpi-pm-fix-incorrect-wakeup-irq-setting-during-suspend-to-idle.patch b/queue-4.3/acpi-pm-fix-incorrect-wakeup-irq-setting-during-suspend-to-idle.patch
new file mode 100644 (file)
index 0000000..76be6f8
--- /dev/null
@@ -0,0 +1,55 @@
+From 8c01275e0cdf1959aa25c322fd5870c097733195 Mon Sep 17 00:00:00 2001
+From: Chen Yu <yu.c.chen@intel.com>
+Date: Sun, 25 Oct 2015 01:02:46 +0800
+Subject: ACPI / PM: Fix incorrect wakeup IRQ setting during suspend-to-idle
+
+From: Chen Yu <yu.c.chen@intel.com>
+
+commit 8c01275e0cdf1959aa25c322fd5870c097733195 upstream.
+
+For an ACPI compatible system, the SCI (ACPI System Control
+Interrupt) is used to wake the system up from suspend-to-idle.
+Once the CPU is woken up by the SCI, the interrupt handler will
+first check if the current IRQ has been configured for system
+wakeup, so irq_pm_check_wakeup() is invoked to validate the IRQ
+number.  However, during suspend-to-idle, enable_irq_wake() is
+called for acpi_gbl_FADT.sci_interrupt, although the IRQ number
+that the SCI handler has been installed for should be passed to
+it instead.  Thus, if acpi_gbl_FADT.sci_interrupt happens to be
+different from that number, ACPI interrupts will not be able to
+wake up the system from sleep.
+
+Fix this problem by passing the IRQ number returned by
+acpi_gsi_to_irq() to enable_irq_wake() instead of
+acpi_gbl_FADT.sci_interrupt.
+
+Acked-by: Lv Zheng <lv.zheng@intel.com>
+Signed-off-by: Chen Yu <yu.c.chen@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/sleep.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/acpi/sleep.c
++++ b/drivers/acpi/sleep.c
+@@ -632,14 +632,16 @@ static int acpi_freeze_prepare(void)
+       acpi_enable_wakeup_devices(ACPI_STATE_S0);
+       acpi_enable_all_wakeup_gpes();
+       acpi_os_wait_events_complete();
+-      enable_irq_wake(acpi_gbl_FADT.sci_interrupt);
++      if (acpi_sci_irq_valid())
++              enable_irq_wake(acpi_sci_irq);
+       return 0;
+ }
+ static void acpi_freeze_restore(void)
+ {
+       acpi_disable_wakeup_devices(ACPI_STATE_S0);
+-      disable_irq_wake(acpi_gbl_FADT.sci_interrupt);
++      if (acpi_sci_irq_valid())
++              disable_irq_wake(acpi_sci_irq);
+       acpi_enable_all_runtime_gpes();
+ }
diff --git a/queue-4.3/acpi-use-correct-irq-when-uninstalling-acpi-interrupt-handler.patch b/queue-4.3/acpi-use-correct-irq-when-uninstalling-acpi-interrupt-handler.patch
new file mode 100644 (file)
index 0000000..e5f41d1
--- /dev/null
@@ -0,0 +1,76 @@
+From 49e4b84333f338d4f183f28f1f3c1131b9fb2b5a Mon Sep 17 00:00:00 2001
+From: Chen Yu <yu.c.chen@intel.com>
+Date: Sun, 25 Oct 2015 01:02:19 +0800
+Subject: ACPI: Use correct IRQ when uninstalling ACPI interrupt handler
+
+From: Chen Yu <yu.c.chen@intel.com>
+
+commit 49e4b84333f338d4f183f28f1f3c1131b9fb2b5a upstream.
+
+Currently when the system is trying to uninstall the ACPI interrupt
+handler, it uses acpi_gbl_FADT.sci_interrupt as the IRQ number.
+However, the IRQ number that the ACPI interrupt handled is installed
+for comes from acpi_gsi_to_irq() and that is the number that should
+be used for the handler removal.
+
+Fix this problem by using the mapped IRQ returned from acpi_gsi_to_irq()
+as appropriate.
+
+Acked-by: Lv Zheng <lv.zheng@intel.com>
+Signed-off-by: Chen Yu <yu.c.chen@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/osl.c   |    9 ++++++---
+ include/linux/acpi.h |    6 ++++++
+ 2 files changed, 12 insertions(+), 3 deletions(-)
+
+--- a/drivers/acpi/osl.c
++++ b/drivers/acpi/osl.c
+@@ -81,6 +81,7 @@ static struct workqueue_struct *kacpid_w
+ static struct workqueue_struct *kacpi_notify_wq;
+ static struct workqueue_struct *kacpi_hotplug_wq;
+ static bool acpi_os_initialized;
++unsigned int acpi_sci_irq = INVALID_ACPI_IRQ;
+ /*
+  * This list of permanent mappings is for memory that may be accessed from
+@@ -856,17 +857,19 @@ acpi_os_install_interrupt_handler(u32 gs
+               acpi_irq_handler = NULL;
+               return AE_NOT_ACQUIRED;
+       }
++      acpi_sci_irq = irq;
+       return AE_OK;
+ }
+-acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
++acpi_status acpi_os_remove_interrupt_handler(u32 gsi, acpi_osd_handler handler)
+ {
+-      if (irq != acpi_gbl_FADT.sci_interrupt)
++      if (gsi != acpi_gbl_FADT.sci_interrupt || !acpi_sci_irq_valid())
+               return AE_BAD_PARAMETER;
+-      free_irq(irq, acpi_irq);
++      free_irq(acpi_sci_irq, acpi_irq);
+       acpi_irq_handler = NULL;
++      acpi_sci_irq = INVALID_ACPI_IRQ;
+       return AE_OK;
+ }
+--- a/include/linux/acpi.h
++++ b/include/linux/acpi.h
+@@ -193,6 +193,12 @@ int acpi_ioapic_registered(acpi_handle h
+ void acpi_irq_stats_init(void);
+ extern u32 acpi_irq_handled;
+ extern u32 acpi_irq_not_handled;
++extern unsigned int acpi_sci_irq;
++#define INVALID_ACPI_IRQ      ((unsigned)-1)
++static inline bool acpi_sci_irq_valid(void)
++{
++      return acpi_sci_irq != INVALID_ACPI_IRQ;
++}
+ extern int sbf_port;
+ extern unsigned long acpi_realmode_flags;
diff --git a/queue-4.3/acpi-using-correct-irq-when-waiting-for-events.patch b/queue-4.3/acpi-using-correct-irq-when-waiting-for-events.patch
new file mode 100644 (file)
index 0000000..c339f59
--- /dev/null
@@ -0,0 +1,36 @@
+From efb1cf7d28b8aeacec53e9ba8f3f2809c5cb9686 Mon Sep 17 00:00:00 2001
+From: Chen Yu <yu.c.chen@intel.com>
+Date: Sun, 25 Oct 2015 01:02:36 +0800
+Subject: ACPI: Using correct irq when waiting for events
+
+From: Chen Yu <yu.c.chen@intel.com>
+
+commit efb1cf7d28b8aeacec53e9ba8f3f2809c5cb9686 upstream.
+
+When the system is waiting for GPE/fixed event handler to finish,
+it uses acpi_gbl_FADT.sci_interrupt directly as the IRQ number.
+However, the remapped IRQ returned by acpi_gsi_to_irq() should be
+passed to synchronize_hardirq() instead of it.
+
+Acked-by: Lv Zheng <lv.zheng@intel.com>
+Signed-off-by: Chen Yu <yu.c.chen@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/osl.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/acpi/osl.c
++++ b/drivers/acpi/osl.c
+@@ -1183,8 +1183,8 @@ void acpi_os_wait_events_complete(void)
+        * Make sure the GPE handler or the fixed event handler is not used
+        * on another CPU after removal.
+        */
+-      if (acpi_irq_handler)
+-              synchronize_hardirq(acpi_gbl_FADT.sci_interrupt);
++      if (acpi_sci_irq_valid())
++              synchronize_hardirq(acpi_sci_irq);
+       flush_workqueue(kacpid_wq);
+       flush_workqueue(kacpi_notify_wq);
+ }
diff --git a/queue-4.3/revert-vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch b/queue-4.3/revert-vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch
new file mode 100644 (file)
index 0000000..92b56a4
--- /dev/null
@@ -0,0 +1,61 @@
+From ben@decadent.org.uk  Thu Dec 17 14:12:57 2015
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Tue, 15 Dec 2015 15:31:49 +0000
+Subject: Revert "vrf: fix double free and memory corruption on register_netdevice failure"
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: David Ahern <dsa@cumulusnetworks.com>, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Nikolay Aleksandrov <nikolay@cumulusnetworks.com>, "David S. Miller" <davem@davemloft.net>
+Message-ID: <20151215153149.GO28542@decadent.org.uk>
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+This reverts commit b3abad339f8e268bb261e5844ab68b18a7797c29, which
+was an attempt to backport commit 7f109f7cc37108cba7243bc832988525b0d85909
+upstream.  The backport introduced a deadlock and other bugs.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Acked-by: David S. Miller <davem@davemloft.net>
+Acked-by: David Ahern <dsa@cumulusnetworks.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/vrf.c |   15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/vrf.c
++++ b/drivers/net/vrf.c
+@@ -581,6 +581,7 @@ static int vrf_newlink(struct net *src_n
+ {
+       struct net_vrf *vrf = netdev_priv(dev);
+       struct net_vrf_dev *vrf_ptr;
++      int err;
+       if (!data || !data[IFLA_VRF_TABLE])
+               return -EINVAL;
+@@ -589,16 +590,26 @@ static int vrf_newlink(struct net *src_n
+       dev->priv_flags |= IFF_VRF_MASTER;
++      err = -ENOMEM;
+       vrf_ptr = kmalloc(sizeof(*dev->vrf_ptr), GFP_KERNEL);
+       if (!vrf_ptr)
+-              return -ENOMEM;
++              goto out_fail;
+       vrf_ptr->ifindex = dev->ifindex;
+       vrf_ptr->tb_id = vrf->tb_id;
++      err = register_netdevice(dev);
++      if (err < 0)
++              goto out_fail;
++
+       rcu_assign_pointer(dev->vrf_ptr, vrf_ptr);
+-      return register_netdev(dev);
++      return 0;
++
++out_fail:
++      kfree(vrf_ptr);
++      free_netdev(dev);
++      return err;
+ }
+ static size_t vrf_nl_getsize(const struct net_device *dev)
diff --git a/queue-4.3/tipc-fix-kfree_skb-of-uninitialised-pointer.patch b/queue-4.3/tipc-fix-kfree_skb-of-uninitialised-pointer.patch
new file mode 100644 (file)
index 0000000..004ec99
--- /dev/null
@@ -0,0 +1,34 @@
+From ben@decadent.org.uk  Thu Dec 17 14:16:22 2015
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Tue, 15 Dec 2015 21:21:57 +0000
+Subject: tipc: Fix kfree_skb() of uninitialised pointer
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: stable@vger.kernel.org, ying.xue@windriver.com, "David S. Miller" <davem@davemloft.net>
+Message-ID: <20151215212156.GQ28542@decadent.org.uk>
+Content-Disposition: inline
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+Commit 7098356baca7 ("tipc: fix error handling of expanding buffer
+headroom") added a "goto tx_error".  This is fine upstream, but
+when backported to 4.3 it results in attempting to free the clone
+before it has been allocated.  In this early error case, no
+cleanup is needed.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/tipc/udp_media.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/tipc/udp_media.c
++++ b/net/tipc/udp_media.c
+@@ -162,7 +162,7 @@ static int tipc_udp_send_msg(struct net
+       if (skb_headroom(skb) < UDP_MIN_HEADROOM) {
+               err = pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC);
+               if (err)
+-                      goto tx_error;
++                      return err;
+       }
+       clone = skb_clone(skb, GFP_ATOMIC);
diff --git a/queue-4.3/toshiba_acpi-initialize-hotkey_event_type-variable.patch b/queue-4.3/toshiba_acpi-initialize-hotkey_event_type-variable.patch
new file mode 100644 (file)
index 0000000..85dbfc6
--- /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
+@@ -2676,6 +2676,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.3/tpm-tpm_tis-fix-tpm_tis-acpi-detection-issue-with-tpm-2.0.patch b/queue-4.3/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/vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch b/queue-4.3/vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch
new file mode 100644 (file)
index 0000000..20001ba
--- /dev/null
@@ -0,0 +1,78 @@
+From ben@decadent.org.uk  Thu Dec 17 14:14:13 2015
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Tue, 15 Dec 2015 15:32:20 +0000
+Subject: vrf: fix double free and memory corruption on register_netdevice failure
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: David Ahern <dsa@cumulusnetworks.com>, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Nikolay Aleksandrov <nikolay@cumulusnetworks.com>, "David S. Miller" <davem@davemloft.net>
+Message-ID: <20151215153220.GP28542@decadent.org.uk>
+Content-Disposition: inline
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+commit 7f109f7cc37108cba7243bc832988525b0d85909 upstream.
+
+When vrf's ->newlink is called, if register_netdevice() fails then it
+does free_netdev(), but that's also done by rtnl_newlink() so a second
+free happens and memory gets corrupted, to reproduce execute the
+following line a couple of times (1 - 5 usually is enough):
+$ for i in `seq 1 5`; do ip link add vrf: type vrf table 1; done;
+This works because we fail in register_netdevice() because of the wrong
+name "vrf:".
+
+And here's a trace of one crash:
+[   28.792157] ------------[ cut here ]------------
+[   28.792407] kernel BUG at fs/namei.c:246!
+[   28.792608] invalid opcode: 0000 [#1] SMP
+[   28.793240] Modules linked in: vrf nfsd auth_rpcgss oid_registry nfs_acl nfs lockd grace sunrpc crct10dif_pclmul crc32_pclmul crc32c_intel qxl drm_kms_helper ttm drm aesni_intel aes_x86_64 psmouse glue_helper lrw evdev gf128mul i2c_piix4 ablk_helper cryptd ppdev parport_pc parport serio_raw pcspkr virtio_balloon virtio_console i2c_core acpi_cpufreq button 9pnet_virtio 9p 9pnet fscache ipv6 autofs4 ext4 crc16 mbcache jbd2 virtio_blk virtio_net sg sr_mod cdrom ata_generic ehci_pci uhci_hcd ehci_hcd e1000 usbcore usb_common ata_piix libata virtio_pci virtio_ring virtio scsi_mod floppy
+[   28.796016] CPU: 0 PID: 1148 Comm: ld-linux-x86-64 Not tainted
+4.4.0-rc1+ #24
+[   28.796016] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.8.1-20150318_183358- 04/01/2014
+[   28.796016] task: ffff8800352561c0 ti: ffff88003592c000 task.ti: ffff88003592c000
+[   28.796016] RIP: 0010:[<ffffffff812187b3>]  [<ffffffff812187b3>] putname+0x43/0x60
+[   28.796016] RSP: 0018:ffff88003592fe88  EFLAGS: 00010246
+[   28.796016] RAX: 0000000000000000 RBX: ffff8800352561c0 RCX: 0000000000000001
+[   28.796016] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff88003784f000
+[   28.796016] RBP: ffff88003592ff08 R08: 0000000000000001 R09: 0000000000000000
+[   28.796016] R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000000
+[   28.796016] R13: 000000000000047c R14: ffff88003784f000 R15: ffff8800358c4a00
+[   28.796016] FS:  0000000000000000(0000) GS:ffff88003fc00000(0000) knlGS:0000000000000000
+[   28.796016] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   28.796016] CR2: 00007ffd583bc2d9 CR3: 0000000035a99000 CR4: 00000000000406f0
+[   28.796016] Stack:
+[   28.796016]  ffffffff8121045d ffffffff812102d3 ffff8800352561c0 ffff880035a91660
+[   28.796016]  ffff8800008a9880 0000000000000000 ffffffff81a49940 00ffffff81218684
+[   28.796016]  ffff8800352561c0 000000000000047c 0000000000000000 ffff880035b36d80
+[   28.796016] Call Trace:
+[   28.796016]  [<ffffffff8121045d>] ?  do_execveat_common.isra.34+0x74d/0x930
+[   28.796016]  [<ffffffff812102d3>] ?  do_execveat_common.isra.34+0x5c3/0x930
+[   28.796016]  [<ffffffff8121066c>] do_execve+0x2c/0x30
+[   28.796016]  [<ffffffff810939a0>] call_usermodehelper_exec_async+0xf0/0x140
+[   28.796016]  [<ffffffff810938b0>] ? umh_complete+0x40/0x40
+[   28.796016]  [<ffffffff815cb1af>] ret_from_fork+0x3f/0x70
+[   28.796016] Code: 48 8d 47 1c 48 89 e5 53 48 8b 37 48 89 fb 48 39 c6 74 1a 48 8b 3d 7e e9 8f 00 e8 49 fa fc ff 48 89 df e8 f1 01 fd ff 5b 5d f3 c3 <0f> 0b 48 89 fe 48 8b 3d 61 e9 8f 00 e8 2c fa fc ff 5b 5d eb e9
+[   28.796016] RIP  [<ffffffff812187b3>] putname+0x43/0x60
+[   28.796016]  RSP <ffff88003592fe88>
+
+Fixes: 193125dbd8eb ("net: Introduce VRF device driver")
+Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Acked-by: David Ahern <dsa@cumulusnetworks.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+[bwh: For 4.3, retain the kfree() on failure]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Acked-by: David S. Miller <davem@davemloft.net>
+Acked-by: David Ahern <dsa@cumulusnetworks.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/vrf.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/net/vrf.c
++++ b/drivers/net/vrf.c
+@@ -608,7 +608,6 @@ static int vrf_newlink(struct net *src_n
+ out_fail:
+       kfree(vrf_ptr);
+-      free_netdev(dev);
+       return err;
+ }