--- /dev/null
+From 0c5661ecc5dd7ce296870a3eb7b62b1b280a5e89 Mon Sep 17 00:00:00 2001
+From: Emil Tantilov <emil.s.tantilov@intel.com>
+Date: Fri, 23 Feb 2018 12:39:41 -0800
+Subject: ixgbe: fix crash in build_skb Rx code path
+
+From: Emil Tantilov <emil.s.tantilov@intel.com>
+
+commit 0c5661ecc5dd7ce296870a3eb7b62b1b280a5e89 upstream.
+
+Add check for build_skb enabled ring in ixgbe_dma_sync_frag().
+In that case &skb_shinfo(skb)->frags[0] may not always be set which
+can lead to a crash. Instead we derive the page offset from skb->data.
+
+Fixes: 42073d91a214 ("ixgbe: Have the CPU take ownership of the buffers sooner")
+CC: stable <stable@vger.kernel.org>
+Reported-by: Ambarish Soman <asoman@redhat.com>
+Suggested-by: Alexander Duyck <alexander.h.duyck@intel.com>
+Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
+Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+@@ -1877,6 +1877,14 @@ static void ixgbe_dma_sync_frag(struct i
+ ixgbe_rx_pg_size(rx_ring),
+ DMA_FROM_DEVICE,
+ IXGBE_RX_DMA_ATTR);
++ } else if (ring_uses_build_skb(rx_ring)) {
++ unsigned long offset = (unsigned long)(skb->data) & ~PAGE_MASK;
++
++ dma_sync_single_range_for_cpu(rx_ring->dev,
++ IXGBE_CB(skb)->dma,
++ offset,
++ skb_headlen(skb),
++ DMA_FROM_DEVICE);
+ } else {
+ struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[0];
+
bluetooth-btusb-use-dmi-matching-for-qca-reset_resume-quirking.patch
+ixgbe-fix-crash-in-build_skb-rx-code-path.patch
+tpm-st33zp24-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
+tpm-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
+tpm_i2c_infineon-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
+tpm_i2c_nuvoton-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
+tpm_tis-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
+tpm-constify-transmit-data-pointers.patch
+tpm_tis_spi-use-dma-safe-memory-for-spi-transfers.patch
--- /dev/null
+From c37fbc09bd4977736f6bc4050c6f099c587052a7 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Thu, 7 Sep 2017 15:30:45 +0200
+Subject: tpm: constify transmit data pointers
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit c37fbc09bd4977736f6bc4050c6f099c587052a7 upstream.
+
+Making cmd_getticks 'const' introduced a couple of harmless warnings:
+
+drivers/char/tpm/tpm_tis_core.c: In function 'probe_itpm':
+drivers/char/tpm/tpm_tis_core.c:469:31: error: passing argument 2 of 'tpm_tis_send_data' discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
+ rc = tpm_tis_send_data(chip, cmd_getticks, len);
+drivers/char/tpm/tpm_tis_core.c:477:31: error: passing argument 2 of 'tpm_tis_send_data' discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
+ rc = tpm_tis_send_data(chip, cmd_getticks, len);
+drivers/char/tpm/tpm_tis_core.c:255:12: note: expected 'u8 * {aka unsigned char *}' but argument is of type 'const u8 * {aka const unsigned char *}'
+ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
+
+This changes the related functions to all take 'const' pointers
+so that gcc can see this as being correct. I had to slightly
+modify the logic around tpm_tis_spi_transfer() for this to work
+without introducing ugly casts.
+
+Cc: stable@vger.kernel.org
+Fixes: 5e35bd8e06b9 ("tpm_tis: make array cmd_getticks static const to shink object code size")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm_tis.c | 2 +-
+ drivers/char/tpm/tpm_tis_core.c | 4 ++--
+ drivers/char/tpm/tpm_tis_core.h | 4 ++--
+ drivers/char/tpm/tpm_tis_spi.c | 25 +++++++++++--------------
+ 4 files changed, 16 insertions(+), 19 deletions(-)
+
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -223,7 +223,7 @@ static int tpm_tcg_read_bytes(struct tpm
+ }
+
+ static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
+- u8 *value)
++ const u8 *value)
+ {
+ struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
+
+--- a/drivers/char/tpm/tpm_tis_core.c
++++ b/drivers/char/tpm/tpm_tis_core.c
+@@ -253,7 +253,7 @@ out:
+ * tpm.c can skip polling for the data to be available as the interrupt is
+ * waited for here
+ */
+-static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
++static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
+ {
+ struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+ int rc, status, burstcnt;
+@@ -344,7 +344,7 @@ static void disable_interrupts(struct tp
+ * tpm.c can skip polling for the data to be available as the interrupt is
+ * waited for here
+ */
+-static int tpm_tis_send_main(struct tpm_chip *chip, u8 *buf, size_t len)
++static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
+ {
+ struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+ int rc;
+--- a/drivers/char/tpm/tpm_tis_core.h
++++ b/drivers/char/tpm/tpm_tis_core.h
+@@ -98,7 +98,7 @@ struct tpm_tis_phy_ops {
+ int (*read_bytes)(struct tpm_tis_data *data, u32 addr, u16 len,
+ u8 *result);
+ int (*write_bytes)(struct tpm_tis_data *data, u32 addr, u16 len,
+- u8 *value);
++ const u8 *value);
+ int (*read16)(struct tpm_tis_data *data, u32 addr, u16 *result);
+ int (*read32)(struct tpm_tis_data *data, u32 addr, u32 *result);
+ int (*write32)(struct tpm_tis_data *data, u32 addr, u32 src);
+@@ -128,7 +128,7 @@ static inline int tpm_tis_read32(struct
+ }
+
+ static inline int tpm_tis_write_bytes(struct tpm_tis_data *data, u32 addr,
+- u16 len, u8 *value)
++ u16 len, const u8 *value)
+ {
+ return data->phy_ops->write_bytes(data, addr, len, value);
+ }
+--- a/drivers/char/tpm/tpm_tis_spi.c
++++ b/drivers/char/tpm/tpm_tis_spi.c
+@@ -57,7 +57,7 @@ static inline struct tpm_tis_spi_phy *to
+ }
+
+ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
+- u8 *buffer, u8 direction)
++ u8 *in, const u8 *out)
+ {
+ struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data);
+ int ret = 0;
+@@ -71,7 +71,7 @@ static int tpm_tis_spi_transfer(struct t
+ while (len) {
+ transfer_len = min_t(u16, len, MAX_SPI_FRAMESIZE);
+
+- phy->tx_buf[0] = direction | (transfer_len - 1);
++ phy->tx_buf[0] = (in ? 0x80 : 0) | (transfer_len - 1);
+ phy->tx_buf[1] = 0xd4;
+ phy->tx_buf[2] = addr >> 8;
+ phy->tx_buf[3] = addr;
+@@ -112,14 +112,8 @@ static int tpm_tis_spi_transfer(struct t
+ spi_xfer.cs_change = 0;
+ spi_xfer.len = transfer_len;
+ spi_xfer.delay_usecs = 5;
+-
+- if (direction) {
+- spi_xfer.tx_buf = NULL;
+- spi_xfer.rx_buf = buffer;
+- } else {
+- spi_xfer.tx_buf = buffer;
+- spi_xfer.rx_buf = NULL;
+- }
++ spi_xfer.tx_buf = out;
++ spi_xfer.rx_buf = in;
+
+ spi_message_init(&m);
+ spi_message_add_tail(&spi_xfer, &m);
+@@ -128,7 +122,10 @@ static int tpm_tis_spi_transfer(struct t
+ goto exit;
+
+ len -= transfer_len;
+- buffer += transfer_len;
++ if (in)
++ in += transfer_len;
++ if (out)
++ out += transfer_len;
+ }
+
+ exit:
+@@ -139,13 +136,13 @@ exit:
+ static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
+ u16 len, u8 *result)
+ {
+- return tpm_tis_spi_transfer(data, addr, len, result, 0x80);
++ return tpm_tis_spi_transfer(data, addr, len, result, NULL);
+ }
+
+ static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr,
+- u16 len, u8 *value)
++ u16 len, const u8 *value)
+ {
+- return tpm_tis_spi_transfer(data, addr, len, value, 0);
++ return tpm_tis_spi_transfer(data, addr, len, NULL, value);
+ }
+
+ static int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result)
--- /dev/null
+From 3be23274755ee85771270a23af7691dc9b3a95db Mon Sep 17 00:00:00 2001
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Date: Thu, 8 Feb 2018 12:28:08 -0800
+Subject: tpm: fix potential buffer overruns caused by bit glitches on the bus
+
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+
+commit 3be23274755ee85771270a23af7691dc9b3a95db upstream.
+
+Discrete TPMs are often connected over slow serial buses which, on
+some platforms, can have glitches causing bit flips. If a bit does
+flip it could cause an overrun if it's in one of the size parameters,
+so sanity check that we're not overrunning the provided buffer when
+doing a memcpy().
+
+Signed-off-by: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Cc: stable@vger.kernel.org
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: James Morris <james.morris@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm-interface.c | 4 ++++
+ drivers/char/tpm/tpm2-cmd.c | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+--- a/drivers/char/tpm/tpm-interface.c
++++ b/drivers/char/tpm/tpm-interface.c
+@@ -1228,6 +1228,10 @@ int tpm_get_random(u32 chip_num, u8 *out
+ break;
+
+ recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len);
++ if (recd > num_bytes) {
++ total = -EFAULT;
++ break;
++ }
+
+ rlength = be32_to_cpu(tpm_cmd.header.out.length);
+ if (rlength < offsetof(struct tpm_getrandom_out, rng_data) +
+--- a/drivers/char/tpm/tpm2-cmd.c
++++ b/drivers/char/tpm/tpm2-cmd.c
+@@ -683,6 +683,10 @@ static int tpm2_unseal_cmd(struct tpm_ch
+ if (!rc) {
+ data_len = be16_to_cpup(
+ (__be16 *) &buf.data[TPM_HEADER_SIZE + 4]);
++ if (data_len < MIN_KEY_SIZE || data_len > MAX_KEY_SIZE + 1) {
++ rc = -EFAULT;
++ goto out;
++ }
+
+ rlength = be32_to_cpu(((struct tpm2_cmd *)&buf)
+ ->header.out.length);
--- /dev/null
+From 6d24cd186d9fead3722108dec1b1c993354645ff Mon Sep 17 00:00:00 2001
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Date: Thu, 8 Feb 2018 12:29:09 -0800
+Subject: tpm: st33zp24: fix potential buffer overruns caused by bit glitches on the bus
+
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+
+commit 6d24cd186d9fead3722108dec1b1c993354645ff upstream.
+
+Discrete TPMs are often connected over slow serial buses which, on
+some platforms, can have glitches causing bit flips. In all the
+driver _recv() functions, we need to use a u32 to unmarshal the
+response size, otherwise a bit flip of the 31st bit would cause the
+expected variable to go negative, which would then try to read a huge
+amount of data. Also sanity check that the expected amount of data is
+large enough for the TPM header.
+
+Signed-off-by: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Cc: stable@vger.kernel.org
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: James Morris <james.morris@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/st33zp24/st33zp24.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/tpm/st33zp24/st33zp24.c
++++ b/drivers/char/tpm/st33zp24/st33zp24.c
+@@ -457,7 +457,7 @@ static int st33zp24_recv(struct tpm_chip
+ size_t count)
+ {
+ int size = 0;
+- int expected;
++ u32 expected;
+
+ if (!chip)
+ return -EBUSY;
+@@ -474,7 +474,7 @@ static int st33zp24_recv(struct tpm_chip
+ }
+
+ expected = be32_to_cpu(*(__be32 *)(buf + 2));
+- if (expected > count) {
++ if (expected > count || expected < TPM_HEADER_SIZE) {
+ size = -EIO;
+ goto out;
+ }
--- /dev/null
+From 9b8cb28d7c62568a5916bdd7ea1c9176d7f8f2ed Mon Sep 17 00:00:00 2001
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Date: Thu, 8 Feb 2018 12:30:01 -0800
+Subject: tpm_i2c_infineon: fix potential buffer overruns caused by bit glitches on the bus
+
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+
+commit 9b8cb28d7c62568a5916bdd7ea1c9176d7f8f2ed upstream.
+
+Discrete TPMs are often connected over slow serial buses which, on
+some platforms, can have glitches causing bit flips. In all the
+driver _recv() functions, we need to use a u32 to unmarshal the
+response size, otherwise a bit flip of the 31st bit would cause the
+expected variable to go negative, which would then try to read a huge
+amount of data. Also sanity check that the expected amount of data is
+large enough for the TPM header.
+
+Signed-off-by: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Cc: stable@vger.kernel.org
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: James Morris <james.morris@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm_i2c_infineon.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/tpm/tpm_i2c_infineon.c
++++ b/drivers/char/tpm/tpm_i2c_infineon.c
+@@ -473,7 +473,8 @@ static int recv_data(struct tpm_chip *ch
+ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
+ {
+ int size = 0;
+- int expected, status;
++ int status;
++ u32 expected;
+
+ if (count < TPM_HEADER_SIZE) {
+ size = -EIO;
+@@ -488,7 +489,7 @@ static int tpm_tis_i2c_recv(struct tpm_c
+ }
+
+ expected = be32_to_cpu(*(__be32 *)(buf + 2));
+- if ((size_t) expected > count) {
++ if (((size_t) expected > count) || (expected < TPM_HEADER_SIZE)) {
+ size = -EIO;
+ goto out;
+ }
--- /dev/null
+From f9d4d9b5a5ef2f017bc344fb65a58a902517173b Mon Sep 17 00:00:00 2001
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Date: Thu, 8 Feb 2018 12:31:16 -0800
+Subject: tpm_i2c_nuvoton: fix potential buffer overruns caused by bit glitches on the bus
+
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+
+commit f9d4d9b5a5ef2f017bc344fb65a58a902517173b upstream.
+
+Discrete TPMs are often connected over slow serial buses which, on
+some platforms, can have glitches causing bit flips. In all the
+driver _recv() functions, we need to use a u32 to unmarshal the
+response size, otherwise a bit flip of the 31st bit would cause the
+expected variable to go negative, which would then try to read a huge
+amount of data. Also sanity check that the expected amount of data is
+large enough for the TPM header.
+
+Signed-off-by: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Cc: stable@vger.kernel.org
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: James Morris <james.morris@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm_i2c_nuvoton.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/tpm/tpm_i2c_nuvoton.c
++++ b/drivers/char/tpm/tpm_i2c_nuvoton.c
+@@ -281,7 +281,11 @@ static int i2c_nuvoton_recv(struct tpm_c
+ struct device *dev = chip->dev.parent;
+ struct i2c_client *client = to_i2c_client(dev);
+ s32 rc;
+- int expected, status, burst_count, retries, size = 0;
++ int status;
++ int burst_count;
++ int retries;
++ int size = 0;
++ u32 expected;
+
+ if (count < TPM_HEADER_SIZE) {
+ i2c_nuvoton_ready(chip); /* return to idle */
+@@ -323,7 +327,7 @@ static int i2c_nuvoton_recv(struct tpm_c
+ * to machine native
+ */
+ expected = be32_to_cpu(*(__be32 *) (buf + 2));
+- if (expected > count) {
++ if (expected > count || expected < size) {
+ dev_err(dev, "%s() expected > count\n", __func__);
+ size = -EIO;
+ continue;
--- /dev/null
+From 6bb320ca4a4a7b5b3db8c8d7250cc40002046878 Mon Sep 17 00:00:00 2001
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Date: Thu, 8 Feb 2018 12:32:06 -0800
+Subject: tpm_tis: fix potential buffer overruns caused by bit glitches on the bus
+
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+
+commit 6bb320ca4a4a7b5b3db8c8d7250cc40002046878 upstream.
+
+Discrete TPMs are often connected over slow serial buses which, on
+some platforms, can have glitches causing bit flips. In all the
+driver _recv() functions, we need to use a u32 to unmarshal the
+response size, otherwise a bit flip of the 31st bit would cause the
+expected variable to go negative, which would then try to read a huge
+amount of data. Also sanity check that the expected amount of data is
+large enough for the TPM header.
+
+Signed-off-by: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Cc: stable@vger.kernel.org
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: James Morris <james.morris@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm_tis_core.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/tpm/tpm_tis_core.c
++++ b/drivers/char/tpm/tpm_tis_core.c
+@@ -202,7 +202,8 @@ static int tpm_tis_recv(struct tpm_chip
+ {
+ struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+ int size = 0;
+- int expected, status;
++ int status;
++ u32 expected;
+
+ if (count < TPM_HEADER_SIZE) {
+ size = -EIO;
+@@ -217,7 +218,7 @@ static int tpm_tis_recv(struct tpm_chip
+ }
+
+ expected = be32_to_cpu(*(__be32 *) (buf + 2));
+- if (expected > count) {
++ if (expected > count || expected < TPM_HEADER_SIZE) {
+ size = -EIO;
+ goto out;
+ }
--- /dev/null
+From 6b3a13173f23e798e1ba213dd4a2c065a3b8d751 Mon Sep 17 00:00:00 2001
+From: Alexander Steffen <Alexander.Steffen@infineon.com>
+Date: Mon, 11 Sep 2017 12:26:52 +0200
+Subject: tpm_tis_spi: Use DMA-safe memory for SPI transfers
+
+From: Alexander Steffen <Alexander.Steffen@infineon.com>
+
+commit 6b3a13173f23e798e1ba213dd4a2c065a3b8d751 upstream.
+
+The buffers used as tx_buf/rx_buf in a SPI transfer need to be DMA-safe.
+This cannot be guaranteed for the buffers passed to tpm_tis_spi_read_bytes
+and tpm_tis_spi_write_bytes. Therefore, we need to use our own DMA-safe
+buffer and copy the data to/from it.
+
+The buffer needs to be allocated separately, to ensure that it is
+cacheline-aligned and not shared with other data, so that DMA can work
+correctly.
+
+Fixes: 0edbfea537d1 ("tpm/tpm_tis_spi: Add support for spi phy")
+Cc: stable@vger.kernel.org
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Alexander Steffen <Alexander.Steffen@infineon.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm_tis_spi.c | 45 ++++++++++++++++++++++++-----------------
+ 1 file changed, 27 insertions(+), 18 deletions(-)
+
+--- a/drivers/char/tpm/tpm_tis_spi.c
++++ b/drivers/char/tpm/tpm_tis_spi.c
+@@ -46,9 +46,7 @@
+ struct tpm_tis_spi_phy {
+ struct tpm_tis_data priv;
+ struct spi_device *spi_device;
+-
+- u8 tx_buf[4];
+- u8 rx_buf[4];
++ u8 *iobuf;
+ };
+
+ static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *data)
+@@ -71,14 +69,14 @@ static int tpm_tis_spi_transfer(struct t
+ while (len) {
+ transfer_len = min_t(u16, len, MAX_SPI_FRAMESIZE);
+
+- phy->tx_buf[0] = (in ? 0x80 : 0) | (transfer_len - 1);
+- phy->tx_buf[1] = 0xd4;
+- phy->tx_buf[2] = addr >> 8;
+- phy->tx_buf[3] = addr;
++ phy->iobuf[0] = (in ? 0x80 : 0) | (transfer_len - 1);
++ phy->iobuf[1] = 0xd4;
++ phy->iobuf[2] = addr >> 8;
++ phy->iobuf[3] = addr;
+
+ memset(&spi_xfer, 0, sizeof(spi_xfer));
+- spi_xfer.tx_buf = phy->tx_buf;
+- spi_xfer.rx_buf = phy->rx_buf;
++ spi_xfer.tx_buf = phy->iobuf;
++ spi_xfer.rx_buf = phy->iobuf;
+ spi_xfer.len = 4;
+ spi_xfer.cs_change = 1;
+
+@@ -88,9 +86,9 @@ static int tpm_tis_spi_transfer(struct t
+ if (ret < 0)
+ goto exit;
+
+- if ((phy->rx_buf[3] & 0x01) == 0) {
++ if ((phy->iobuf[3] & 0x01) == 0) {
+ // handle SPI wait states
+- phy->tx_buf[0] = 0;
++ phy->iobuf[0] = 0;
+
+ for (i = 0; i < TPM_RETRY; i++) {
+ spi_xfer.len = 1;
+@@ -99,7 +97,7 @@ static int tpm_tis_spi_transfer(struct t
+ ret = spi_sync_locked(phy->spi_device, &m);
+ if (ret < 0)
+ goto exit;
+- if (phy->rx_buf[0] & 0x01)
++ if (phy->iobuf[0] & 0x01)
+ break;
+ }
+
+@@ -112,8 +110,14 @@ static int tpm_tis_spi_transfer(struct t
+ spi_xfer.cs_change = 0;
+ spi_xfer.len = transfer_len;
+ spi_xfer.delay_usecs = 5;
+- spi_xfer.tx_buf = out;
+- spi_xfer.rx_buf = in;
++
++ if (in) {
++ spi_xfer.tx_buf = NULL;
++ } else if (out) {
++ spi_xfer.rx_buf = NULL;
++ memcpy(phy->iobuf, out, transfer_len);
++ out += transfer_len;
++ }
+
+ spi_message_init(&m);
+ spi_message_add_tail(&spi_xfer, &m);
+@@ -121,11 +125,12 @@ static int tpm_tis_spi_transfer(struct t
+ if (ret < 0)
+ goto exit;
+
+- len -= transfer_len;
+- if (in)
++ if (in) {
++ memcpy(in, phy->iobuf, transfer_len);
+ in += transfer_len;
+- if (out)
+- out += transfer_len;
++ }
++
++ len -= transfer_len;
+ }
+
+ exit:
+@@ -191,6 +196,10 @@ static int tpm_tis_spi_probe(struct spi_
+
+ phy->spi_device = dev;
+
++ phy->iobuf = devm_kmalloc(&dev->dev, MAX_SPI_FRAMESIZE, GFP_KERNEL);
++ if (!phy->iobuf)
++ return -ENOMEM;
++
+ return tpm_tis_core_init(&dev->dev, &phy->priv, -1, &tpm_spi_phy_ops,
+ NULL);
+ }