--- /dev/null
+From 334415b1334e34213f3338108af9c4917713e930 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Aug 2020 14:59:29 -0400
+Subject: tpm: Unify the mismatching TPM space buffer sizes
+
+From: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+
+[ Upstream commit 6c4e79d99e6f42b79040f1a33cd4018f5425030b ]
+
+The size of the buffers for storing context's and sessions can vary from
+arch to arch as PAGE_SIZE can be anything between 4 kB and 256 kB (the
+maximum for PPC64). Define a fixed buffer size set to 16 kB. This should be
+enough for most use with three handles (that is how many we allow at the
+moment). Parametrize the buffer size while doing this, so that it is easier
+to revisit this later on if required.
+
+Cc: stable@vger.kernel.org
+Reported-by: Stefan Berger <stefanb@linux.ibm.com>
+Fixes: 745b361e989a ("tpm: infrastructure for TPM spaces")
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Tested-by: Stefan Berger <stefanb@linux.ibm.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/tpm/tpm-chip.c | 9 ++-------
+ drivers/char/tpm/tpm.h | 6 +++++-
+ drivers/char/tpm/tpm2-space.c | 26 ++++++++++++++++----------
+ drivers/char/tpm/tpmrm-dev.c | 2 +-
+ 4 files changed, 24 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
+index 4946c5b37d04d..f79f877942733 100644
+--- a/drivers/char/tpm/tpm-chip.c
++++ b/drivers/char/tpm/tpm-chip.c
+@@ -276,13 +276,8 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
+ chip->cdev.owner = THIS_MODULE;
+ chip->cdevs.owner = THIS_MODULE;
+
+- chip->work_space.context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+- if (!chip->work_space.context_buf) {
+- rc = -ENOMEM;
+- goto out;
+- }
+- chip->work_space.session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+- if (!chip->work_space.session_buf) {
++ rc = tpm2_init_space(&chip->work_space, TPM2_SPACE_BUFFER_SIZE);
++ if (rc) {
+ rc = -ENOMEM;
+ goto out;
+ }
+diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
+index 289221d653cb2..b9a30f0b88257 100644
+--- a/drivers/char/tpm/tpm.h
++++ b/drivers/char/tpm/tpm.h
+@@ -188,6 +188,7 @@ struct tpm_space {
+ u8 *context_buf;
+ u32 session_tbl[3];
+ u8 *session_buf;
++ u32 buf_size;
+ };
+
+ enum tpm_chip_flags {
+@@ -278,6 +279,9 @@ struct tpm_output_header {
+
+ #define TPM_TAG_RQU_COMMAND 193
+
++/* TPM2 specific constants. */
++#define TPM2_SPACE_BUFFER_SIZE 16384 /* 16 kB */
++
+ struct stclear_flags_t {
+ __be16 tag;
+ u8 deactivated;
+@@ -595,7 +599,7 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
+ unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
+ int tpm2_probe(struct tpm_chip *chip);
+ int tpm2_find_cc(struct tpm_chip *chip, u32 cc);
+-int tpm2_init_space(struct tpm_space *space);
++int tpm2_init_space(struct tpm_space *space, unsigned int buf_size);
+ void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space);
+ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
+ u8 *cmd);
+diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
+index d2e101b32482f..9f4e22dcde270 100644
+--- a/drivers/char/tpm/tpm2-space.c
++++ b/drivers/char/tpm/tpm2-space.c
+@@ -43,18 +43,21 @@ static void tpm2_flush_sessions(struct tpm_chip *chip, struct tpm_space *space)
+ }
+ }
+
+-int tpm2_init_space(struct tpm_space *space)
++int tpm2_init_space(struct tpm_space *space, unsigned int buf_size)
+ {
+- space->context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
++ space->context_buf = kzalloc(buf_size, GFP_KERNEL);
+ if (!space->context_buf)
+ return -ENOMEM;
+
+- space->session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
++ space->session_buf = kzalloc(buf_size, GFP_KERNEL);
+ if (space->session_buf == NULL) {
+ kfree(space->context_buf);
++ /* Prevent caller getting a dangling pointer. */
++ space->context_buf = NULL;
+ return -ENOMEM;
+ }
+
++ space->buf_size = buf_size;
+ return 0;
+ }
+
+@@ -276,8 +279,10 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
+ sizeof(space->context_tbl));
+ memcpy(&chip->work_space.session_tbl, &space->session_tbl,
+ sizeof(space->session_tbl));
+- memcpy(chip->work_space.context_buf, space->context_buf, PAGE_SIZE);
+- memcpy(chip->work_space.session_buf, space->session_buf, PAGE_SIZE);
++ memcpy(chip->work_space.context_buf, space->context_buf,
++ space->buf_size);
++ memcpy(chip->work_space.session_buf, space->session_buf,
++ space->buf_size);
+
+ rc = tpm2_load_space(chip);
+ if (rc) {
+@@ -456,7 +461,7 @@ static int tpm2_save_space(struct tpm_chip *chip)
+ continue;
+
+ rc = tpm2_save_context(chip, space->context_tbl[i],
+- space->context_buf, PAGE_SIZE,
++ space->context_buf, space->buf_size,
+ &offset);
+ if (rc == -ENOENT) {
+ space->context_tbl[i] = 0;
+@@ -474,9 +479,8 @@ static int tpm2_save_space(struct tpm_chip *chip)
+ continue;
+
+ rc = tpm2_save_context(chip, space->session_tbl[i],
+- space->session_buf, PAGE_SIZE,
++ space->session_buf, space->buf_size,
+ &offset);
+-
+ if (rc == -ENOENT) {
+ /* handle error saving session, just forget it */
+ space->session_tbl[i] = 0;
+@@ -522,8 +526,10 @@ int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
+ sizeof(space->context_tbl));
+ memcpy(&space->session_tbl, &chip->work_space.session_tbl,
+ sizeof(space->session_tbl));
+- memcpy(space->context_buf, chip->work_space.context_buf, PAGE_SIZE);
+- memcpy(space->session_buf, chip->work_space.session_buf, PAGE_SIZE);
++ memcpy(space->context_buf, chip->work_space.context_buf,
++ space->buf_size);
++ memcpy(space->session_buf, chip->work_space.session_buf,
++ space->buf_size);
+
+ return 0;
+ }
+diff --git a/drivers/char/tpm/tpmrm-dev.c b/drivers/char/tpm/tpmrm-dev.c
+index 1a0e97a5da5a4..162fb16243d03 100644
+--- a/drivers/char/tpm/tpmrm-dev.c
++++ b/drivers/char/tpm/tpmrm-dev.c
+@@ -22,7 +22,7 @@ static int tpmrm_open(struct inode *inode, struct file *file)
+ if (priv == NULL)
+ return -ENOMEM;
+
+- rc = tpm2_init_space(&priv->space);
++ rc = tpm2_init_space(&priv->space, TPM2_SPACE_BUFFER_SIZE);
+ if (rc) {
+ kfree(priv);
+ return -ENOMEM;
+--
+2.25.1
+