Linux Integrity Measurement development
 help / color / mirror / Atom feed
* [RFC v2 0/5] tpm_crb: Add command and response buffer chunking support
@ 2026-03-24 18:12 Arun Menon
  2026-03-24 18:12 ` [RFC v2 1/5] tpm_crb: Add register definitions of TPM CRB chunking fields Arun Menon
                   ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: Arun Menon @ 2026-03-24 18:12 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jarkko Sakkinen, linux-integrity, Peter Huewe, Jason Gunthorpe,
	Arun Menon

The new version of TCG TPM v185 (currently under review [1]) supports
sending data/commands in chunks for the CRB (Command Response Buffer)
interface. This is in line with the initiative to support PQC algorithms.

This series implements the logic to send and receive larger TPM
cmd/rsp between the linux guest and the TPM backend in chunks.
Currently, the TPM CRB driver is limited by the physical size of the
MMIO window. When userspace attempts to send a payload that exceeds this
size, the driver rejects it.

This series introduces chunking support. The driver now checks the CRB
interface capability for CRB_INTF_CAP_CRB_CHUNK. If supported by the
backend, the driver will slice oversized commands into MMIO-sized
chunks, signalling the backend via CRB_START_NEXT_CHUNK, and finalizing
with CRB_START_INVOKE. Responses are also read back in a similar chunked
manner.

If the backend does not support chunking, the driver retains its legacy
behaviour and enforces the standard size limits.

This feature also requires the QEMU to interpret the data in chunks and
forward it to the TPM backend and subsequently dispatch the TPM response
in chunks back to the linux guest. This is implemented in [2]

[1] https://trustedcomputinggroup.org/wp-content/uploads/PC-Client-Specific-Platform-TPM-Profile-for-TPM-2p0-v1p07_rc1_121225.pdf
[2] https://lore.kernel.org/qemu-devel/20260319135316.37412-1-armenon@redhat.com/

v2
--
- Add size checks before copying memory.
- Update TPM_BUFSIZE to 8KB.
- Commit messages updated to indicate motivation and logic of the change.

Arun Menon (5):
  tpm_crb: Add register definitions of TPM CRB chunking fields
  tpm_crb: Add new wrapper function to invoke start method
  tpm_crb: Implement command and response chunking logic
  tpm: Increase TPM_BUFSIZE to 8kB for chunking support
  tpm: tis_i2c: Use local 4KB buffer to limit memory usage

 drivers/char/tpm/tpm.h         |   2 +-
 drivers/char/tpm/tpm_crb.c     | 199 +++++++++++++++++++++++----------
 drivers/char/tpm/tpm_tis_i2c.c |   6 +-
 3 files changed, 146 insertions(+), 61 deletions(-)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [RFC v2 1/5] tpm_crb: Add register definitions of TPM CRB chunking fields
  2026-03-24 18:12 [RFC v2 0/5] tpm_crb: Add command and response buffer chunking support Arun Menon
@ 2026-03-24 18:12 ` Arun Menon
  2026-05-09 14:41   ` Jarkko Sakkinen
  2026-03-24 18:12 ` [RFC v2 2/5] tpm_crb: Add new wrapper function to invoke start method Arun Menon
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Arun Menon @ 2026-03-24 18:12 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jarkko Sakkinen, linux-integrity, Peter Huewe, Jason Gunthorpe,
	Arun Menon

Post-quantum cryptographic (PQC) algorithms can require buffer sizes that
exceed the physical capacity of the TPM's Command/Response Buffer (CRB).
To support these larger payloads, the TPM 2.0 CRB specification [1]
allows for data chunking when the physical MMIO window is smaller than
the required buffer size.

To support this protocol, the TPM driver must be able to detect the
chunking capability, and signal the backend using specific start
method flags, also known as the control area start register bits.

As per sections 6.4.2.2 and 6.5.3.9 of the specification document [1]
Add 2 new bit flags to the existing enum crb_start and add the
capability bit.
- CRB_INTF_CAP_CRB_CHUNK: A capability bit used to detect if the backend
  supports chunking.
- CRB_START_NEXT_CHUNK: A control bit to signal the TPM to consume the
  current command buffer, or to get the next chunk from the response
  buffer.
- CRB_START_RESP_RETRY: A control bit to signal retransmission of a
  response buffer.

[1] https://trustedcomputinggroup.org/wp-content/uploads/PC-Client-Specific-Platform-TPM-Profile-for-TPM-2p0-v1p07_rc1_121225.pdf

Signed-off-by: Arun Menon <armenon@redhat.com>
---
 drivers/char/tpm/tpm_crb.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index 6c25305c256ef..67c0061d4cab7 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -56,12 +56,18 @@ enum crb_ctrl_sts {
 
 enum crb_start {
 	CRB_START_INVOKE	= BIT(0),
+	CRB_START_RESP_RETRY = BIT(1),
+	CRB_START_NEXT_CHUNK = BIT(2),
 };
 
 enum crb_cancel {
 	CRB_CANCEL_INVOKE	= BIT(0),
 };
 
+enum crb_intf {
+	CRB_INTF_CAP_CRB_CHUNK = BIT(10),
+};
+
 struct crb_regs_head {
 	u32 loc_state;
 	u32 reserved1;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC v2 2/5] tpm_crb: Add new wrapper function to invoke start method
  2026-03-24 18:12 [RFC v2 0/5] tpm_crb: Add command and response buffer chunking support Arun Menon
  2026-03-24 18:12 ` [RFC v2 1/5] tpm_crb: Add register definitions of TPM CRB chunking fields Arun Menon
@ 2026-03-24 18:12 ` Arun Menon
  2026-05-09 14:43   ` Jarkko Sakkinen
  2026-03-24 18:12 ` [RFC v2 3/5] tpm_crb: Implement command and response chunking logic Arun Menon
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Arun Menon @ 2026-03-24 18:12 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jarkko Sakkinen, linux-integrity, Peter Huewe, Jason Gunthorpe,
	Arun Menon

The current implementation handles different platform start methods
(ACPI, ARM SMC, and ARM FFA) directly within crb_send(), but it is
limited to triggering the CRB_START_INVOKE bit.

To support cmd/rsp chunking, the driver must be able to send other
control bits, like CRB_START_NEXT_CHUNK, using these same
platform-specific paths.

By moving this logic into a new helper function, crb_trigger_tpm(),
the driver can now send any required control bit across all supported
platforms. This prepares the driver for the upcoming chunking support.

No functional change is intended.

Signed-off-by: Arun Menon <armenon@redhat.com>
---
 drivers/char/tpm/tpm_crb.c | 50 ++++++++++++++++++++------------------
 1 file changed, 27 insertions(+), 23 deletions(-)

diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index 67c0061d4cab7..922bcf7a69ad5 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -445,6 +445,32 @@ static int tpm_crb_smc_start(struct device *dev, unsigned long func_id)
 }
 #endif
 
+static int crb_trigger_tpm(struct tpm_chip *chip, u32 start_cmd)
+{
+	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
+	int rc = 0;
+	/* The reason for the extra quirk is that the PTT in 4th Gen Core CPUs
+	 * report only ACPI start but in practice seems to require both
+	 * CRB start, hence invoking CRB start method if hid == MSFT0101.
+	 */
+	if (priv->sm == ACPI_TPM2_COMMAND_BUFFER ||
+	    priv->sm == ACPI_TPM2_MEMORY_MAPPED ||
+	    !strcmp(priv->hid, "MSFT0101"))
+		iowrite32(start_cmd, &priv->regs_t->ctrl_start);
+	if (priv->sm == ACPI_TPM2_START_METHOD ||
+	    priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD)
+		rc = crb_do_acpi_start(chip);
+	if (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) {
+		iowrite32(start_cmd, &priv->regs_t->ctrl_start);
+		rc = tpm_crb_smc_start(&chip->dev, priv->smc_func_id);
+	}
+	if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) {
+		iowrite32(start_cmd, &priv->regs_t->ctrl_start);
+		rc = tpm_crb_ffa_start(CRB_FFA_START_TYPE_COMMAND, chip->locality);
+	}
+	return rc;
+}
+
 static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
 {
 	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
@@ -470,29 +496,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
 	/* Make sure that cmd is populated before issuing start. */
 	wmb();
 
-	/* The reason for the extra quirk is that the PTT in 4th Gen Core CPUs
-	 * report only ACPI start but in practice seems to require both
-	 * CRB start, hence invoking CRB start method if hid == MSFT0101.
-	 */
-	if (priv->sm == ACPI_TPM2_COMMAND_BUFFER ||
-	    priv->sm == ACPI_TPM2_MEMORY_MAPPED ||
-	    !strcmp(priv->hid, "MSFT0101"))
-		iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start);
-
-	if (priv->sm == ACPI_TPM2_START_METHOD ||
-	    priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD)
-		rc = crb_do_acpi_start(chip);
-
-	if (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) {
-		iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start);
-		rc = tpm_crb_smc_start(&chip->dev, priv->smc_func_id);
-	}
-
-	if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) {
-		iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start);
-		rc = tpm_crb_ffa_start(CRB_FFA_START_TYPE_COMMAND, chip->locality);
-	}
-
+	rc = crb_trigger_tpm(chip, CRB_START_INVOKE);
 	if (rc)
 		return rc;
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC v2 3/5] tpm_crb: Implement command and response chunking logic
  2026-03-24 18:12 [RFC v2 0/5] tpm_crb: Add command and response buffer chunking support Arun Menon
  2026-03-24 18:12 ` [RFC v2 1/5] tpm_crb: Add register definitions of TPM CRB chunking fields Arun Menon
  2026-03-24 18:12 ` [RFC v2 2/5] tpm_crb: Add new wrapper function to invoke start method Arun Menon
@ 2026-03-24 18:12 ` Arun Menon
  2026-05-09 14:53   ` Jarkko Sakkinen
  2026-03-24 18:12 ` [RFC v2 4/5] tpm: Increase TPM_BUFSIZE to 8kB for chunking support Arun Menon
  2026-03-24 18:12 ` [RFC v2 5/5] tpm: tis_i2c: Use local 4KB buffer to limit memory usage Arun Menon
  4 siblings, 1 reply; 15+ messages in thread
From: Arun Menon @ 2026-03-24 18:12 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jarkko Sakkinen, linux-integrity, Peter Huewe, Jason Gunthorpe,
	Arun Menon

With the introduction of support for Post Quantum Cryptography
algorithms in TPM, the commands and responses will grow in size.
Some TPMs have a physical hardware memory window (MMIO) that is
smaller than the commands we need to send. Therefore this commit
implements the core logic of sending/receiving data in chunks.

Instead of sending the whole command at once, the driver now sends it in
small chunks. After each chunk, it signals the TPM using a nextChunk
signal, and waits for the TPM to consume the data. Once the final piece
is delivered, the driver signals the TPM to begin execution by toggling
the start invoke bit. We use the same logic in reverse to read large
responses from the TPM.

This allows the driver to handle large payloads even when the hardware
interface has limited memory. This kernel-side support corresponds to
the backend implementation in QEMU [1]. QEMU reassembles the chunks
before passing them to the TPM emulator.

[1] https://lore.kernel.org/qemu-devel/20260319135316.37412-1-armenon@redhat.com/

Signed-off-by: Arun Menon <armenon@redhat.com>
---
 drivers/char/tpm/tpm_crb.c | 155 +++++++++++++++++++++++++++----------
 1 file changed, 114 insertions(+), 41 deletions(-)

diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index 922bcf7a69ad5..a97fc5e9927e3 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -104,11 +104,13 @@ struct crb_priv {
 	u8 __iomem *cmd;
 	u8 __iomem *rsp;
 	u32 cmd_size;
+	u32 rsp_size;
 	u32 smc_func_id;
 	u32 __iomem *pluton_start_addr;
 	u32 __iomem *pluton_reply_addr;
 	u8 ffa_flags;
 	u8 ffa_attributes;
+	bool chunking_supported;
 };
 
 struct tpm2_crb_smc {
@@ -368,38 +370,6 @@ static u8 crb_status(struct tpm_chip *chip)
 	return sts;
 }
 
-static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count)
-{
-	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
-	unsigned int expected;
-
-	/* A sanity check that the upper layer wants to get at least the header
-	 * as that is the minimum size for any TPM response.
-	 */
-	if (count < TPM_HEADER_SIZE)
-		return -EIO;
-
-	/* If this bit is set, according to the spec, the TPM is in
-	 * unrecoverable condition.
-	 */
-	if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
-		return -EIO;
-
-	/* Read the first 8 bytes in order to get the length of the response.
-	 * We read exactly a quad word in order to make sure that the remaining
-	 * reads will be aligned.
-	 */
-	memcpy_fromio(buf, priv->rsp, 8);
-
-	expected = be32_to_cpup((__be32 *)&buf[2]);
-	if (expected > count || expected < TPM_HEADER_SIZE)
-		return -EIO;
-
-	memcpy_fromio(&buf[8], &priv->rsp[8], expected - 8);
-
-	return expected;
-}
-
 static int crb_do_acpi_start(struct tpm_chip *chip)
 {
 	union acpi_object *obj;
@@ -474,6 +444,8 @@ static int crb_trigger_tpm(struct tpm_chip *chip, u32 start_cmd)
 static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
 {
 	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
+	size_t offset = 0;
+	size_t chunk_size;
 	int rc = 0;
 
 	/* Zero the cancel register so that the next command will not get
@@ -481,7 +453,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
 	 */
 	iowrite32(0, &priv->regs_t->ctrl_cancel);
 
-	if (len > priv->cmd_size) {
+	if (len > priv->cmd_size && !priv->chunking_supported) {
 		dev_err(&chip->dev, "invalid command count value %zd %d\n",
 			len, priv->cmd_size);
 		return -E2BIG;
@@ -491,18 +463,108 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
 	if (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON)
 		__crb_cmd_ready(&chip->dev, priv, chip->locality);
 
-	memcpy_toio(priv->cmd, buf, len);
+	while (offset < len) {
+		chunk_size = min_t(size_t, len - offset, priv->cmd_size);
 
-	/* Make sure that cmd is populated before issuing start. */
-	wmb();
-
-	rc = crb_trigger_tpm(chip, CRB_START_INVOKE);
-	if (rc)
-		return rc;
+		if (chunk_size == 0)
+			break;
 
+		memcpy_toio(priv->cmd, buf + offset, chunk_size);
+		offset += chunk_size;
+
+		/* Make sure that cmd is populated before issuing start. */
+		wmb();
+		if (offset < len) {
+			rc = crb_trigger_tpm(chip, CRB_START_NEXT_CHUNK);
+			if (rc)
+				return rc;
+			if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_start,
+			    CRB_START_NEXT_CHUNK, 0, TPM2_TIMEOUT_C)) {
+				dev_err(&chip->dev,
+					"Timeout waiting for backend to consume chunk\n");
+				return -ETIME;
+			}
+		} else {
+			rc = crb_trigger_tpm(chip, CRB_START_INVOKE);
+			if (rc)
+				return rc;
+		}
+	}
 	return crb_try_pluton_doorbell(priv, false);
 }
 
+static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count)
+{
+	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
+	unsigned int expected;
+	size_t offset = 0;
+	size_t chunk_size;
+	size_t first_read;
+	int rc;
+
+	/* A sanity check that the upper layer wants to get at least the header
+	 * as that is the minimum size for any TPM response.
+	 */
+	if (count < TPM_HEADER_SIZE)
+		return -EIO;
+
+	/* If this bit is set, according to the spec, the TPM is in
+	 * unrecoverable condition.
+	 */
+	if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
+		return -EIO;
+
+	/* Read the first 8 bytes in order to get the length of the response.
+	 * We read exactly a quad word in order to make sure that the remaining
+	 * reads will be aligned.
+	 */
+	memcpy_fromio(buf, priv->rsp, 8);
+
+	expected = be32_to_cpup((__be32 *)&buf[2]);
+	if (expected > count || expected < TPM_HEADER_SIZE)
+		return -EIO;
+
+	/*
+	 * Set chunk_size by comparing the size of the buffer that the upper layer has
+	 * allocated (count) to the hardware tpm limit (priv->rsp_size).
+	 * This is to prevent buffer overflow while writing to buf.
+	 */
+	chunk_size = min_t(size_t, count, priv->rsp_size);
+	if (chunk_size < 8)
+		return -EIO;
+
+	/*
+	 * Compare the actual size of the response we found in the header to the chunk_size.
+	 */
+	first_read = min_t(size_t, expected, chunk_size);
+
+	memcpy_fromio(&buf[8], &priv->rsp[8], first_read - 8);
+	offset = first_read;
+
+	while (offset < expected) {
+		if (!priv->chunking_supported) {
+			dev_err(&chip->dev, "Response larger than MMIO and chunking not supported\n");
+			return -EIO;
+		}
+
+		rc = crb_trigger_tpm(chip, CRB_START_NEXT_CHUNK);
+		if (rc)
+			return rc;
+
+		if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_start,
+					 CRB_START_NEXT_CHUNK, 0, TPM2_TIMEOUT_C)) {
+			dev_err(&chip->dev, "Timeout waiting for backend response\n");
+			return -ETIME;
+		}
+
+		chunk_size = min_t(size_t, expected - offset, priv->rsp_size);
+		memcpy_fromio(buf + offset, priv->rsp, chunk_size);
+		offset += chunk_size;
+	}
+
+	return expected;
+}
+
 static void crb_cancel(struct tpm_chip *chip)
 {
 	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
@@ -727,6 +789,15 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
 		goto out;
 	}
 
+	if (priv->regs_h) {
+		u32 intf_id = ioread32((u32 __iomem *)&priv->regs_h->intf_id);
+
+		if (intf_id & CRB_INTF_CAP_CRB_CHUNK) {
+			priv->chunking_supported = true;
+			dev_info(dev, "CRB Chunking is supported by backend\n");
+		}
+	}
+
 	memcpy_fromio(&__rsp_pa, &priv->regs_t->ctrl_rsp_pa, 8);
 	rsp_pa = le64_to_cpu(__rsp_pa);
 	rsp_size = ioread32(&priv->regs_t->ctrl_rsp_size);
@@ -764,8 +835,10 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
 	priv->rsp = priv->cmd;
 
 out:
-	if (!ret)
+	if (!ret) {
 		priv->cmd_size = cmd_size;
+		priv->rsp_size = rsp_size;
+	}
 
 	__crb_go_idle(dev, priv, 0);
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC v2 4/5] tpm: Increase TPM_BUFSIZE to 8kB for chunking support
  2026-03-24 18:12 [RFC v2 0/5] tpm_crb: Add command and response buffer chunking support Arun Menon
                   ` (2 preceding siblings ...)
  2026-03-24 18:12 ` [RFC v2 3/5] tpm_crb: Implement command and response chunking logic Arun Menon
@ 2026-03-24 18:12 ` Arun Menon
  2026-05-09 14:54   ` Jarkko Sakkinen
  2026-03-24 18:12 ` [RFC v2 5/5] tpm: tis_i2c: Use local 4KB buffer to limit memory usage Arun Menon
  4 siblings, 1 reply; 15+ messages in thread
From: Arun Menon @ 2026-03-24 18:12 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jarkko Sakkinen, linux-integrity, Peter Huewe, Jason Gunthorpe,
	Arun Menon

The size of the command is checked against TPM_BUFSIZE early on before
even sending it to the backend. We therefore need to increase the
TPM_BUFSIZE to allow support for larger commands.

For now, 8KB seems sufficient for ML-KEM and ML-DSA algorithms and it is
also order-1 safe.

Signed-off-by: Arun Menon <armenon@redhat.com>
---
 drivers/char/tpm/tpm.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 87d68ddf270a7..26c3765fbd732 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -33,7 +33,7 @@
 #endif
 
 #define TPM_MINOR		224	/* officially assigned */
-#define TPM_BUFSIZE		4096
+#define TPM_BUFSIZE		8192
 #define TPM_NUM_DEVICES		65536
 #define TPM_RETRY		50
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC v2 5/5] tpm: tis_i2c: Use local 4KB buffer to limit memory usage
  2026-03-24 18:12 [RFC v2 0/5] tpm_crb: Add command and response buffer chunking support Arun Menon
                   ` (3 preceding siblings ...)
  2026-03-24 18:12 ` [RFC v2 4/5] tpm: Increase TPM_BUFSIZE to 8kB for chunking support Arun Menon
@ 2026-03-24 18:12 ` Arun Menon
  4 siblings, 0 replies; 15+ messages in thread
From: Arun Menon @ 2026-03-24 18:12 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jarkko Sakkinen, linux-integrity, Peter Huewe, Jason Gunthorpe,
	Arun Menon

The global increase of TPM_BUFSIZE to 8KB is necessary to support
Post-Quantum Cryptography (PQC) payloads. However, applying this increase
to the tpm_tis_i2c driver is unnecessary and wasteful due to physical
transport limitations as pointed out in [1]

This commit introduces a local buffer limit that is used in the i2c
driver.

[1] https://sashiko.dev/#/patchset/20260324071803.324774-1-armenon%40redhat.com?patch=8319

Signed-off-by: Arun Menon <armenon@redhat.com>
---
 drivers/char/tpm/tpm_tis_i2c.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/char/tpm/tpm_tis_i2c.c b/drivers/char/tpm/tpm_tis_i2c.c
index 6cd07dd34507e..db19d459ea1e1 100644
--- a/drivers/char/tpm/tpm_tis_i2c.c
+++ b/drivers/char/tpm/tpm_tis_i2c.c
@@ -54,6 +54,8 @@
 #define TPM_INTF_CAPABILITY_ZERO 0x0FFFF000
 #define TPM_I2C_INTERFACE_CAPABILITY_ZERO 0x80000000
 
+#define TPM_I2C_BUFSIZE 4096
+
 struct tpm_tis_i2c_phy {
 	struct tpm_tis_data priv;
 	struct i2c_client *i2c_client;
@@ -232,7 +234,7 @@ static int tpm_tis_i2c_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
 	int ret;
 	u16 wrote = 0;
 
-	if (len > TPM_BUFSIZE - 1)
+	if (len > TPM_I2C_BUFSIZE - 1)
 		return -EIO;
 
 	phy->io_buf[0] = reg;
@@ -339,7 +341,7 @@ static int tpm_tis_i2c_probe(struct i2c_client *dev)
 	if (!phy)
 		return -ENOMEM;
 
-	phy->io_buf = devm_kzalloc(&dev->dev, TPM_BUFSIZE, GFP_KERNEL);
+	phy->io_buf = devm_kzalloc(&dev->dev, TPM_I2C_BUFSIZE, GFP_KERNEL);
 	if (!phy->io_buf)
 		return -ENOMEM;
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [RFC v2 1/5] tpm_crb: Add register definitions of TPM CRB chunking fields
  2026-03-24 18:12 ` [RFC v2 1/5] tpm_crb: Add register definitions of TPM CRB chunking fields Arun Menon
@ 2026-05-09 14:41   ` Jarkko Sakkinen
  0 siblings, 0 replies; 15+ messages in thread
From: Jarkko Sakkinen @ 2026-05-09 14:41 UTC (permalink / raw)
  To: Arun Menon; +Cc: linux-kernel, linux-integrity, Peter Huewe, Jason Gunthorpe

On Tue, Mar 24, 2026 at 11:42:40PM +0530, Arun Menon wrote:
> Post-quantum cryptographic (PQC) algorithms can require buffer sizes that
> exceed the physical capacity of the TPM's Command/Response Buffer (CRB).
> To support these larger payloads, the TPM 2.0 CRB specification [1]
> allows for data chunking when the physical MMIO window is smaller than
> the required buffer size.
> 
> To support this protocol, the TPM driver must be able to detect the
> chunking capability, and signal the backend using specific start
> method flags, also known as the control area start register bits.
> 
> As per sections 6.4.2.2 and 6.5.3.9 of the specification document [1]
> Add 2 new bit flags to the existing enum crb_start and add the
> capability bit.
> - CRB_INTF_CAP_CRB_CHUNK: A capability bit used to detect if the backend
>   supports chunking.
> - CRB_START_NEXT_CHUNK: A control bit to signal the TPM to consume the
>   current command buffer, or to get the next chunk from the response
>   buffer.
> - CRB_START_RESP_RETRY: A control bit to signal retransmission of a
>   response buffer.
> 
> [1] https://trustedcomputinggroup.org/wp-content/uploads/PC-Client-Specific-Platform-TPM-Profile-for-TPM-2p0-v1p07_rc1_121225.pdf
> 
> Signed-off-by: Arun Menon <armenon@redhat.com>
> ---
>  drivers/char/tpm/tpm_crb.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
> index 6c25305c256ef..67c0061d4cab7 100644
> --- a/drivers/char/tpm/tpm_crb.c
> +++ b/drivers/char/tpm/tpm_crb.c
> @@ -56,12 +56,18 @@ enum crb_ctrl_sts {
>  
>  enum crb_start {
>  	CRB_START_INVOKE	= BIT(0),
> +	CRB_START_RESP_RETRY = BIT(1),
> +	CRB_START_NEXT_CHUNK = BIT(2),
>  };
>  
>  enum crb_cancel {
>  	CRB_CANCEL_INVOKE	= BIT(0),
>  };
>  
> +enum crb_intf {
> +	CRB_INTF_CAP_CRB_CHUNK = BIT(10),
> +};
> +
>  struct crb_regs_head {
>  	u32 loc_state;
>  	u32 reserved1;
> -- 
> 2.53.0
> 

Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>

BR, Jarkko

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC v2 2/5] tpm_crb: Add new wrapper function to invoke start method
  2026-03-24 18:12 ` [RFC v2 2/5] tpm_crb: Add new wrapper function to invoke start method Arun Menon
@ 2026-05-09 14:43   ` Jarkko Sakkinen
  2026-05-13 11:08     ` Arun Menon
  0 siblings, 1 reply; 15+ messages in thread
From: Jarkko Sakkinen @ 2026-05-09 14:43 UTC (permalink / raw)
  To: Arun Menon; +Cc: linux-kernel, linux-integrity, Peter Huewe, Jason Gunthorpe

On Tue, Mar 24, 2026 at 11:42:41PM +0530, Arun Menon wrote:
> The current implementation handles different platform start methods
> (ACPI, ARM SMC, and ARM FFA) directly within crb_send(), but it is
> limited to triggering the CRB_START_INVOKE bit.
> 
> To support cmd/rsp chunking, the driver must be able to send other
> control bits, like CRB_START_NEXT_CHUNK, using these same
> platform-specific paths.
> 
> By moving this logic into a new helper function, crb_trigger_tpm(),
> the driver can now send any required control bit across all supported
> platforms. This prepares the driver for the upcoming chunking support.
> 
> No functional change is intended.
> 
> Signed-off-by: Arun Menon <armenon@redhat.com>
> ---
>  drivers/char/tpm/tpm_crb.c | 50 ++++++++++++++++++++------------------
>  1 file changed, 27 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
> index 67c0061d4cab7..922bcf7a69ad5 100644
> --- a/drivers/char/tpm/tpm_crb.c
> +++ b/drivers/char/tpm/tpm_crb.c
> @@ -445,6 +445,32 @@ static int tpm_crb_smc_start(struct device *dev, unsigned long func_id)
>  }
>  #endif
>  
> +static int crb_trigger_tpm(struct tpm_chip *chip, u32 start_cmd)

tpm_crb_start?

I'd also split this into two commits:

1. One that splits the helper.
2. Second that adds the new stuff.

> +{
> +	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> +	int rc = 0;
> +	/* The reason for the extra quirk is that the PTT in 4th Gen Core CPUs
> +	 * report only ACPI start but in practice seems to require both
> +	 * CRB start, hence invoking CRB start method if hid == MSFT0101.
> +	 */
> +	if (priv->sm == ACPI_TPM2_COMMAND_BUFFER ||
> +	    priv->sm == ACPI_TPM2_MEMORY_MAPPED ||
> +	    !strcmp(priv->hid, "MSFT0101"))
> +		iowrite32(start_cmd, &priv->regs_t->ctrl_start);
> +	if (priv->sm == ACPI_TPM2_START_METHOD ||
> +	    priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD)
> +		rc = crb_do_acpi_start(chip);
> +	if (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) {
> +		iowrite32(start_cmd, &priv->regs_t->ctrl_start);
> +		rc = tpm_crb_smc_start(&chip->dev, priv->smc_func_id);
> +	}
> +	if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) {
> +		iowrite32(start_cmd, &priv->regs_t->ctrl_start);
> +		rc = tpm_crb_ffa_start(CRB_FFA_START_TYPE_COMMAND, chip->locality);
> +	}
> +	return rc;
> +}
> +
>  static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
>  {
>  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> @@ -470,29 +496,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
>  	/* Make sure that cmd is populated before issuing start. */
>  	wmb();
>  
> -	/* The reason for the extra quirk is that the PTT in 4th Gen Core CPUs
> -	 * report only ACPI start but in practice seems to require both
> -	 * CRB start, hence invoking CRB start method if hid == MSFT0101.
> -	 */
> -	if (priv->sm == ACPI_TPM2_COMMAND_BUFFER ||
> -	    priv->sm == ACPI_TPM2_MEMORY_MAPPED ||
> -	    !strcmp(priv->hid, "MSFT0101"))
> -		iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start);
> -
> -	if (priv->sm == ACPI_TPM2_START_METHOD ||
> -	    priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD)
> -		rc = crb_do_acpi_start(chip);
> -
> -	if (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) {
> -		iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start);
> -		rc = tpm_crb_smc_start(&chip->dev, priv->smc_func_id);
> -	}
> -
> -	if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) {
> -		iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start);
> -		rc = tpm_crb_ffa_start(CRB_FFA_START_TYPE_COMMAND, chip->locality);
> -	}
> -
> +	rc = crb_trigger_tpm(chip, CRB_START_INVOKE);
>  	if (rc)
>  		return rc;
>  
> -- 
> 2.53.0
> 

BR, Jarkko

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC v2 3/5] tpm_crb: Implement command and response chunking logic
  2026-03-24 18:12 ` [RFC v2 3/5] tpm_crb: Implement command and response chunking logic Arun Menon
@ 2026-05-09 14:53   ` Jarkko Sakkinen
  2026-05-13 11:07     ` Arun Menon
  0 siblings, 1 reply; 15+ messages in thread
From: Jarkko Sakkinen @ 2026-05-09 14:53 UTC (permalink / raw)
  To: Arun Menon; +Cc: linux-kernel, linux-integrity, Peter Huewe, Jason Gunthorpe

On Tue, Mar 24, 2026 at 11:42:42PM +0530, Arun Menon wrote:
> With the introduction of support for Post Quantum Cryptography
> algorithms in TPM, the commands and responses will grow in size.
> Some TPMs have a physical hardware memory window (MMIO) that is
> smaller than the commands we need to send. Therefore this commit
> implements the core logic of sending/receiving data in chunks.
> 
> Instead of sending the whole command at once, the driver now sends it in
> small chunks. After each chunk, it signals the TPM using a nextChunk
> signal, and waits for the TPM to consume the data. Once the final piece
> is delivered, the driver signals the TPM to begin execution by toggling
> the start invoke bit. We use the same logic in reverse to read large
> responses from the TPM.
> 
> This allows the driver to handle large payloads even when the hardware
> interface has limited memory. This kernel-side support corresponds to
> the backend implementation in QEMU [1]. QEMU reassembles the chunks
> before passing them to the TPM emulator.
> 
> [1] https://lore.kernel.org/qemu-devel/20260319135316.37412-1-armenon@redhat.com/
> 
> Signed-off-by: Arun Menon <armenon@redhat.com>
> ---

This is really bad at rationalizing the code change, which are heavy.

Couldn't you instead:

1. Rename crb_recv as tpm_crb_recv_no_chunks().
2. Add tpm_crb_recv_chunks().
3. Add new tpm_crb_recv(), which delegates either.

I would not mind too much if they have some duplicate logic. It's less
of a harm than convolution caused by interleaving.

>  drivers/char/tpm/tpm_crb.c | 155 +++++++++++++++++++++++++++----------
>  1 file changed, 114 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
> index 922bcf7a69ad5..a97fc5e9927e3 100644
> --- a/drivers/char/tpm/tpm_crb.c
> +++ b/drivers/char/tpm/tpm_crb.c
> @@ -104,11 +104,13 @@ struct crb_priv {
>  	u8 __iomem *cmd;
>  	u8 __iomem *rsp;
>  	u32 cmd_size;
> +	u32 rsp_size;
>  	u32 smc_func_id;
>  	u32 __iomem *pluton_start_addr;
>  	u32 __iomem *pluton_reply_addr;
>  	u8 ffa_flags;
>  	u8 ffa_attributes;
> +	bool chunking_supported;

Why not "u32 intf_id" i.e. cache the value of the register?

>  };
>  
>  struct tpm2_crb_smc {
> @@ -368,38 +370,6 @@ static u8 crb_status(struct tpm_chip *chip)
>  	return sts;
>  }
>  
> -static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count)
> -{
> -	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> -	unsigned int expected;
> -
> -	/* A sanity check that the upper layer wants to get at least the header
> -	 * as that is the minimum size for any TPM response.
> -	 */
> -	if (count < TPM_HEADER_SIZE)
> -		return -EIO;
> -
> -	/* If this bit is set, according to the spec, the TPM is in
> -	 * unrecoverable condition.
> -	 */
> -	if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
> -		return -EIO;
> -
> -	/* Read the first 8 bytes in order to get the length of the response.
> -	 * We read exactly a quad word in order to make sure that the remaining
> -	 * reads will be aligned.
> -	 */
> -	memcpy_fromio(buf, priv->rsp, 8);
> -
> -	expected = be32_to_cpup((__be32 *)&buf[2]);
> -	if (expected > count || expected < TPM_HEADER_SIZE)
> -		return -EIO;
> -
> -	memcpy_fromio(&buf[8], &priv->rsp[8], expected - 8);
> -
> -	return expected;
> -}
> -
>  static int crb_do_acpi_start(struct tpm_chip *chip)
>  {
>  	union acpi_object *obj;
> @@ -474,6 +444,8 @@ static int crb_trigger_tpm(struct tpm_chip *chip, u32 start_cmd)
>  static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
>  {
>  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> +	size_t offset = 0;
> +	size_t chunk_size;
>  	int rc = 0;
>  
>  	/* Zero the cancel register so that the next command will not get
> @@ -481,7 +453,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
>  	 */
>  	iowrite32(0, &priv->regs_t->ctrl_cancel);
>  
> -	if (len > priv->cmd_size) {
> +	if (len > priv->cmd_size && !priv->chunking_supported) {
>  		dev_err(&chip->dev, "invalid command count value %zd %d\n",
>  			len, priv->cmd_size);
>  		return -E2BIG;
> @@ -491,18 +463,108 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
>  	if (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON)
>  		__crb_cmd_ready(&chip->dev, priv, chip->locality);
>  
> -	memcpy_toio(priv->cmd, buf, len);
> +	while (offset < len) {
> +		chunk_size = min_t(size_t, len - offset, priv->cmd_size);
>  
> -	/* Make sure that cmd is populated before issuing start. */
> -	wmb();
> -
> -	rc = crb_trigger_tpm(chip, CRB_START_INVOKE);
> -	if (rc)
> -		return rc;
> +		if (chunk_size == 0)
> +			break;
>  
> +		memcpy_toio(priv->cmd, buf + offset, chunk_size);
> +		offset += chunk_size;
> +
> +		/* Make sure that cmd is populated before issuing start. */
> +		wmb();
> +		if (offset < len) {
> +			rc = crb_trigger_tpm(chip, CRB_START_NEXT_CHUNK);
> +			if (rc)
> +				return rc;
> +			if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_start,
> +			    CRB_START_NEXT_CHUNK, 0, TPM2_TIMEOUT_C)) {
> +				dev_err(&chip->dev,
> +					"Timeout waiting for backend to consume chunk\n");
> +				return -ETIME;
> +			}
> +		} else {
> +			rc = crb_trigger_tpm(chip, CRB_START_INVOKE);
> +			if (rc)
> +				return rc;
> +		}
> +	}
>  	return crb_try_pluton_doorbell(priv, false);
>  }
>  
> +static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count)
> +{
> +	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> +	unsigned int expected;
> +	size_t offset = 0;
> +	size_t chunk_size;
> +	size_t first_read;
> +	int rc;
> +
> +	/* A sanity check that the upper layer wants to get at least the header
> +	 * as that is the minimum size for any TPM response.
> +	 */
> +	if (count < TPM_HEADER_SIZE)
> +		return -EIO;
> +
> +	/* If this bit is set, according to the spec, the TPM is in
> +	 * unrecoverable condition.
> +	 */
> +	if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
> +		return -EIO;
> +
> +	/* Read the first 8 bytes in order to get the length of the response.
> +	 * We read exactly a quad word in order to make sure that the remaining
> +	 * reads will be aligned.
> +	 */
> +	memcpy_fromio(buf, priv->rsp, 8);
> +
> +	expected = be32_to_cpup((__be32 *)&buf[2]);
> +	if (expected > count || expected < TPM_HEADER_SIZE)
> +		return -EIO;
> +
> +	/*
> +	 * Set chunk_size by comparing the size of the buffer that the upper layer has
> +	 * allocated (count) to the hardware tpm limit (priv->rsp_size).
> +	 * This is to prevent buffer overflow while writing to buf.
> +	 */
> +	chunk_size = min_t(size_t, count, priv->rsp_size);
> +	if (chunk_size < 8)
> +		return -EIO;
> +
> +	/*
> +	 * Compare the actual size of the response we found in the header to the chunk_size.
> +	 */
> +	first_read = min_t(size_t, expected, chunk_size);
> +
> +	memcpy_fromio(&buf[8], &priv->rsp[8], first_read - 8);
> +	offset = first_read;
> +
> +	while (offset < expected) {
> +		if (!priv->chunking_supported) {
> +			dev_err(&chip->dev, "Response larger than MMIO and chunking not supported\n");
> +			return -EIO;
> +		}
> +
> +		rc = crb_trigger_tpm(chip, CRB_START_NEXT_CHUNK);
> +		if (rc)
> +			return rc;
> +
> +		if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_start,
> +					 CRB_START_NEXT_CHUNK, 0, TPM2_TIMEOUT_C)) {
> +			dev_err(&chip->dev, "Timeout waiting for backend response\n");
> +			return -ETIME;
> +		}
> +
> +		chunk_size = min_t(size_t, expected - offset, priv->rsp_size);
> +		memcpy_fromio(buf + offset, priv->rsp, chunk_size);
> +		offset += chunk_size;
> +	}
> +
> +	return expected;
> +}
> +
>  static void crb_cancel(struct tpm_chip *chip)
>  {
>  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> @@ -727,6 +789,15 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
>  		goto out;
>  	}
>  
> +	if (priv->regs_h) {
> +		u32 intf_id = ioread32((u32 __iomem *)&priv->regs_h->intf_id);
> +
> +		if (intf_id & CRB_INTF_CAP_CRB_CHUNK) {
> +			priv->chunking_supported = true;
> +			dev_info(dev, "CRB Chunking is supported by backend\n");
> +		}
> +	}
> +
>  	memcpy_fromio(&__rsp_pa, &priv->regs_t->ctrl_rsp_pa, 8);
>  	rsp_pa = le64_to_cpu(__rsp_pa);
>  	rsp_size = ioread32(&priv->regs_t->ctrl_rsp_size);
> @@ -764,8 +835,10 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
>  	priv->rsp = priv->cmd;
>  
>  out:
> -	if (!ret)
> +	if (!ret) {
>  		priv->cmd_size = cmd_size;
> +		priv->rsp_size = rsp_size;
> +	}
>  
>  	__crb_go_idle(dev, priv, 0);
>  
> -- 
> 2.53.0
> 

BR, Jarkko

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC v2 4/5] tpm: Increase TPM_BUFSIZE to 8kB for chunking support
  2026-03-24 18:12 ` [RFC v2 4/5] tpm: Increase TPM_BUFSIZE to 8kB for chunking support Arun Menon
@ 2026-05-09 14:54   ` Jarkko Sakkinen
  2026-05-09 15:07     ` Jarkko Sakkinen
  2026-05-13 11:09     ` Arun Menon
  0 siblings, 2 replies; 15+ messages in thread
From: Jarkko Sakkinen @ 2026-05-09 14:54 UTC (permalink / raw)
  To: Arun Menon; +Cc: linux-kernel, linux-integrity, Peter Huewe, Jason Gunthorpe

On Tue, Mar 24, 2026 at 11:42:43PM +0530, Arun Menon wrote:
> The size of the command is checked against TPM_BUFSIZE early on before
> even sending it to the backend. We therefore need to increase the
> TPM_BUFSIZE to allow support for larger commands.
> 
> For now, 8KB seems sufficient for ML-KEM and ML-DSA algorithms and it is
> also order-1 safe.
> 
> Signed-off-by: Arun Menon <armenon@redhat.com>
> ---
>  drivers/char/tpm/tpm.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> index 87d68ddf270a7..26c3765fbd732 100644
> --- a/drivers/char/tpm/tpm.h
> +++ b/drivers/char/tpm/tpm.h
> @@ -33,7 +33,7 @@
>  #endif
>  
>  #define TPM_MINOR		224	/* officially assigned */
> -#define TPM_BUFSIZE		4096
> +#define TPM_BUFSIZE		8192
>  #define TPM_NUM_DEVICES		65536
>  #define TPM_RETRY		50
>  
> -- 
> 2.53.0
> 

Shouldn't this prepend previous patch?

BR, Jarkko

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC v2 4/5] tpm: Increase TPM_BUFSIZE to 8kB for chunking support
  2026-05-09 14:54   ` Jarkko Sakkinen
@ 2026-05-09 15:07     ` Jarkko Sakkinen
  2026-05-13 11:06       ` Arun Menon
  2026-05-13 11:09     ` Arun Menon
  1 sibling, 1 reply; 15+ messages in thread
From: Jarkko Sakkinen @ 2026-05-09 15:07 UTC (permalink / raw)
  To: Arun Menon; +Cc: linux-kernel, linux-integrity, Peter Huewe, Jason Gunthorpe

On Sat, May 09, 2026 at 05:54:25PM +0300, Jarkko Sakkinen wrote:
> On Tue, Mar 24, 2026 at 11:42:43PM +0530, Arun Menon wrote:
> > The size of the command is checked against TPM_BUFSIZE early on before
> > even sending it to the backend. We therefore need to increase the
> > TPM_BUFSIZE to allow support for larger commands.
> > 
> > For now, 8KB seems sufficient for ML-KEM and ML-DSA algorithms and it is
> > also order-1 safe.
> > 
> > Signed-off-by: Arun Menon <armenon@redhat.com>
> > ---
> >  drivers/char/tpm/tpm.h | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> > index 87d68ddf270a7..26c3765fbd732 100644
> > --- a/drivers/char/tpm/tpm.h
> > +++ b/drivers/char/tpm/tpm.h
> > @@ -33,7 +33,7 @@
> >  #endif
> >  
> >  #define TPM_MINOR		224	/* officially assigned */
> > -#define TPM_BUFSIZE		4096
> > +#define TPM_BUFSIZE		8192
> >  #define TPM_NUM_DEVICES		65536
> >  #define TPM_RETRY		50
> >  
> > -- 
> > 2.53.0
> > 
> 
> Shouldn't this prepend previous patch?

Also did you remark that tpm_buf would also need changes as it is fixed
to PAGE_SIZE?

I've made a patch that essentially makes tpm_buf size variable as caller
does kzalloc:

https://lore.kernel.org/linux-integrity/20260125192526.782202-12-jarkko@kernel.org/

I'd see this as pretty good long-term solution.

BR, Jarkko

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC v2 4/5] tpm: Increase TPM_BUFSIZE to 8kB for chunking support
  2026-05-09 15:07     ` Jarkko Sakkinen
@ 2026-05-13 11:06       ` Arun Menon
  0 siblings, 0 replies; 15+ messages in thread
From: Arun Menon @ 2026-05-13 11:06 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: linux-kernel, linux-integrity, Peter Huewe, Jason Gunthorpe

On Sat, May 09, 2026 at 06:07:11PM +0300, Jarkko Sakkinen wrote:
> On Sat, May 09, 2026 at 05:54:25PM +0300, Jarkko Sakkinen wrote:
> > On Tue, Mar 24, 2026 at 11:42:43PM +0530, Arun Menon wrote:
> > > The size of the command is checked against TPM_BUFSIZE early on before
> > > even sending it to the backend. We therefore need to increase the
> > > TPM_BUFSIZE to allow support for larger commands.
> > > 
> > > For now, 8KB seems sufficient for ML-KEM and ML-DSA algorithms and it is
> > > also order-1 safe.
> > > 
> > > Signed-off-by: Arun Menon <armenon@redhat.com>
> > > ---
> > >  drivers/char/tpm/tpm.h | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> > > index 87d68ddf270a7..26c3765fbd732 100644
> > > --- a/drivers/char/tpm/tpm.h
> > > +++ b/drivers/char/tpm/tpm.h
> > > @@ -33,7 +33,7 @@
> > >  #endif
> > >  
> > >  #define TPM_MINOR		224	/* officially assigned */
> > > -#define TPM_BUFSIZE		4096
> > > +#define TPM_BUFSIZE		8192
> > >  #define TPM_NUM_DEVICES		65536
> > >  #define TPM_RETRY		50
> > >  
> > > -- 
> > > 2.53.0
> > > 
> > 
> > Shouldn't this prepend previous patch?
> 
> Also did you remark that tpm_buf would also need changes as it is fixed
> to PAGE_SIZE?

TPM_BUFSIZE can be increased, in its new location include/linux/tpm.h as
per the patch : https://lore.kernel.org/linux-integrity/20260125192526.782202-12-jarkko@kernel.org/
and I think that alone will take care of the check if (size > TPM_BUFSIZE)
in tpm_common_write() in drivers/char/tpm/tpm-dev-common.c.

However I was not able to apply the mbox file cleanly on the existing
branches for-next-tpm and for-next-keys. I could apply them cleanly on
the old branch (next). Please guide.

I would only change the TPM_BUFSIZE set in 
[PATCH v9 11/11] tpm-buf: Implement managed allocations to 8192.

> 
> I've made a patch that essentially makes tpm_buf size variable as caller
> does kzalloc:
> 
> https://lore.kernel.org/linux-integrity/20260125192526.782202-12-jarkko@kernel.org/
> 
> I'd see this as pretty good long-term solution.

Indeed. 

> 
> BR, Jarkko
> 


Regards,
Arun Menon


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC v2 3/5] tpm_crb: Implement command and response chunking logic
  2026-05-09 14:53   ` Jarkko Sakkinen
@ 2026-05-13 11:07     ` Arun Menon
  0 siblings, 0 replies; 15+ messages in thread
From: Arun Menon @ 2026-05-13 11:07 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: linux-kernel, linux-integrity, Peter Huewe, Jason Gunthorpe

On Sat, May 09, 2026 at 05:53:51PM +0300, Jarkko Sakkinen wrote:
> On Tue, Mar 24, 2026 at 11:42:42PM +0530, Arun Menon wrote:
> > With the introduction of support for Post Quantum Cryptography
> > algorithms in TPM, the commands and responses will grow in size.
> > Some TPMs have a physical hardware memory window (MMIO) that is
> > smaller than the commands we need to send. Therefore this commit
> > implements the core logic of sending/receiving data in chunks.
> > 
> > Instead of sending the whole command at once, the driver now sends it in
> > small chunks. After each chunk, it signals the TPM using a nextChunk
> > signal, and waits for the TPM to consume the data. Once the final piece
> > is delivered, the driver signals the TPM to begin execution by toggling
> > the start invoke bit. We use the same logic in reverse to read large
> > responses from the TPM.
> > 
> > This allows the driver to handle large payloads even when the hardware
> > interface has limited memory. This kernel-side support corresponds to
> > the backend implementation in QEMU [1]. QEMU reassembles the chunks
> > before passing them to the TPM emulator.
> > 
> > [1] https://lore.kernel.org/qemu-devel/20260319135316.37412-1-armenon@redhat.com/
> > 
> > Signed-off-by: Arun Menon <armenon@redhat.com>
> > ---
> 
> This is really bad at rationalizing the code change, which are heavy.
> 
> Couldn't you instead:
> 
> 1. Rename crb_recv as tpm_crb_recv_no_chunks().
> 2. Add tpm_crb_recv_chunks().
> 3. Add new tpm_crb_recv(), which delegates either.
> 
> I would not mind too much if they have some duplicate logic. It's less
> of a harm than convolution caused by interleaving.

Sure. I will amend this in v3.
Thank you.

> 
> >  drivers/char/tpm/tpm_crb.c | 155 +++++++++++++++++++++++++++----------
> >  1 file changed, 114 insertions(+), 41 deletions(-)
> > 
> > diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
> > index 922bcf7a69ad5..a97fc5e9927e3 100644
> > --- a/drivers/char/tpm/tpm_crb.c
> > +++ b/drivers/char/tpm/tpm_crb.c
> > @@ -104,11 +104,13 @@ struct crb_priv {
> >  	u8 __iomem *cmd;
> >  	u8 __iomem *rsp;
> >  	u32 cmd_size;
> > +	u32 rsp_size;
> >  	u32 smc_func_id;
> >  	u32 __iomem *pluton_start_addr;
> >  	u32 __iomem *pluton_reply_addr;
> >  	u8 ffa_flags;
> >  	u8 ffa_attributes;
> > +	bool chunking_supported;
> 
> Why not "u32 intf_id" i.e. cache the value of the register?
> 
> >  };
> >  
> >  struct tpm2_crb_smc {
> > @@ -368,38 +370,6 @@ static u8 crb_status(struct tpm_chip *chip)
> >  	return sts;
> >  }
> >  
> > -static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count)
> > -{
> > -	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> > -	unsigned int expected;
> > -
> > -	/* A sanity check that the upper layer wants to get at least the header
> > -	 * as that is the minimum size for any TPM response.
> > -	 */
> > -	if (count < TPM_HEADER_SIZE)
> > -		return -EIO;
> > -
> > -	/* If this bit is set, according to the spec, the TPM is in
> > -	 * unrecoverable condition.
> > -	 */
> > -	if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
> > -		return -EIO;
> > -
> > -	/* Read the first 8 bytes in order to get the length of the response.
> > -	 * We read exactly a quad word in order to make sure that the remaining
> > -	 * reads will be aligned.
> > -	 */
> > -	memcpy_fromio(buf, priv->rsp, 8);
> > -
> > -	expected = be32_to_cpup((__be32 *)&buf[2]);
> > -	if (expected > count || expected < TPM_HEADER_SIZE)
> > -		return -EIO;
> > -
> > -	memcpy_fromio(&buf[8], &priv->rsp[8], expected - 8);
> > -
> > -	return expected;
> > -}
> > -
> >  static int crb_do_acpi_start(struct tpm_chip *chip)
> >  {
> >  	union acpi_object *obj;
> > @@ -474,6 +444,8 @@ static int crb_trigger_tpm(struct tpm_chip *chip, u32 start_cmd)
> >  static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
> >  {
> >  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> > +	size_t offset = 0;
> > +	size_t chunk_size;
> >  	int rc = 0;
> >  
> >  	/* Zero the cancel register so that the next command will not get
> > @@ -481,7 +453,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
> >  	 */
> >  	iowrite32(0, &priv->regs_t->ctrl_cancel);
> >  
> > -	if (len > priv->cmd_size) {
> > +	if (len > priv->cmd_size && !priv->chunking_supported) {
> >  		dev_err(&chip->dev, "invalid command count value %zd %d\n",
> >  			len, priv->cmd_size);
> >  		return -E2BIG;
> > @@ -491,18 +463,108 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
> >  	if (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON)
> >  		__crb_cmd_ready(&chip->dev, priv, chip->locality);
> >  
> > -	memcpy_toio(priv->cmd, buf, len);
> > +	while (offset < len) {
> > +		chunk_size = min_t(size_t, len - offset, priv->cmd_size);
> >  
> > -	/* Make sure that cmd is populated before issuing start. */
> > -	wmb();
> > -
> > -	rc = crb_trigger_tpm(chip, CRB_START_INVOKE);
> > -	if (rc)
> > -		return rc;
> > +		if (chunk_size == 0)
> > +			break;
> >  
> > +		memcpy_toio(priv->cmd, buf + offset, chunk_size);
> > +		offset += chunk_size;
> > +
> > +		/* Make sure that cmd is populated before issuing start. */
> > +		wmb();
> > +		if (offset < len) {
> > +			rc = crb_trigger_tpm(chip, CRB_START_NEXT_CHUNK);
> > +			if (rc)
> > +				return rc;
> > +			if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_start,
> > +			    CRB_START_NEXT_CHUNK, 0, TPM2_TIMEOUT_C)) {
> > +				dev_err(&chip->dev,
> > +					"Timeout waiting for backend to consume chunk\n");
> > +				return -ETIME;
> > +			}
> > +		} else {
> > +			rc = crb_trigger_tpm(chip, CRB_START_INVOKE);
> > +			if (rc)
> > +				return rc;
> > +		}
> > +	}
> >  	return crb_try_pluton_doorbell(priv, false);
> >  }
> >  
> > +static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count)
> > +{
> > +	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> > +	unsigned int expected;
> > +	size_t offset = 0;
> > +	size_t chunk_size;
> > +	size_t first_read;
> > +	int rc;
> > +
> > +	/* A sanity check that the upper layer wants to get at least the header
> > +	 * as that is the minimum size for any TPM response.
> > +	 */
> > +	if (count < TPM_HEADER_SIZE)
> > +		return -EIO;
> > +
> > +	/* If this bit is set, according to the spec, the TPM is in
> > +	 * unrecoverable condition.
> > +	 */
> > +	if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
> > +		return -EIO;
> > +
> > +	/* Read the first 8 bytes in order to get the length of the response.
> > +	 * We read exactly a quad word in order to make sure that the remaining
> > +	 * reads will be aligned.
> > +	 */
> > +	memcpy_fromio(buf, priv->rsp, 8);
> > +
> > +	expected = be32_to_cpup((__be32 *)&buf[2]);
> > +	if (expected > count || expected < TPM_HEADER_SIZE)
> > +		return -EIO;
> > +
> > +	/*
> > +	 * Set chunk_size by comparing the size of the buffer that the upper layer has
> > +	 * allocated (count) to the hardware tpm limit (priv->rsp_size).
> > +	 * This is to prevent buffer overflow while writing to buf.
> > +	 */
> > +	chunk_size = min_t(size_t, count, priv->rsp_size);
> > +	if (chunk_size < 8)
> > +		return -EIO;
> > +
> > +	/*
> > +	 * Compare the actual size of the response we found in the header to the chunk_size.
> > +	 */
> > +	first_read = min_t(size_t, expected, chunk_size);
> > +
> > +	memcpy_fromio(&buf[8], &priv->rsp[8], first_read - 8);
> > +	offset = first_read;
> > +
> > +	while (offset < expected) {
> > +		if (!priv->chunking_supported) {
> > +			dev_err(&chip->dev, "Response larger than MMIO and chunking not supported\n");
> > +			return -EIO;
> > +		}
> > +
> > +		rc = crb_trigger_tpm(chip, CRB_START_NEXT_CHUNK);
> > +		if (rc)
> > +			return rc;
> > +
> > +		if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_start,
> > +					 CRB_START_NEXT_CHUNK, 0, TPM2_TIMEOUT_C)) {
> > +			dev_err(&chip->dev, "Timeout waiting for backend response\n");
> > +			return -ETIME;
> > +		}
> > +
> > +		chunk_size = min_t(size_t, expected - offset, priv->rsp_size);
> > +		memcpy_fromio(buf + offset, priv->rsp, chunk_size);
> > +		offset += chunk_size;
> > +	}
> > +
> > +	return expected;
> > +}
> > +
> >  static void crb_cancel(struct tpm_chip *chip)
> >  {
> >  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> > @@ -727,6 +789,15 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
> >  		goto out;
> >  	}
> >  
> > +	if (priv->regs_h) {
> > +		u32 intf_id = ioread32((u32 __iomem *)&priv->regs_h->intf_id);
> > +
> > +		if (intf_id & CRB_INTF_CAP_CRB_CHUNK) {
> > +			priv->chunking_supported = true;
> > +			dev_info(dev, "CRB Chunking is supported by backend\n");
> > +		}
> > +	}
> > +
> >  	memcpy_fromio(&__rsp_pa, &priv->regs_t->ctrl_rsp_pa, 8);
> >  	rsp_pa = le64_to_cpu(__rsp_pa);
> >  	rsp_size = ioread32(&priv->regs_t->ctrl_rsp_size);
> > @@ -764,8 +835,10 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
> >  	priv->rsp = priv->cmd;
> >  
> >  out:
> > -	if (!ret)
> > +	if (!ret) {
> >  		priv->cmd_size = cmd_size;
> > +		priv->rsp_size = rsp_size;
> > +	}
> >  
> >  	__crb_go_idle(dev, priv, 0);
> >  
> > -- 
> > 2.53.0
> > 
> 
> BR, Jarkko
> 

Regards,
Arun Menon


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC v2 2/5] tpm_crb: Add new wrapper function to invoke start method
  2026-05-09 14:43   ` Jarkko Sakkinen
@ 2026-05-13 11:08     ` Arun Menon
  0 siblings, 0 replies; 15+ messages in thread
From: Arun Menon @ 2026-05-13 11:08 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: linux-kernel, linux-integrity, Peter Huewe, Jason Gunthorpe

On Sat, May 09, 2026 at 05:43:10PM +0300, Jarkko Sakkinen wrote:
> On Tue, Mar 24, 2026 at 11:42:41PM +0530, Arun Menon wrote:
> > The current implementation handles different platform start methods
> > (ACPI, ARM SMC, and ARM FFA) directly within crb_send(), but it is
> > limited to triggering the CRB_START_INVOKE bit.
> > 
> > To support cmd/rsp chunking, the driver must be able to send other
> > control bits, like CRB_START_NEXT_CHUNK, using these same
> > platform-specific paths.
> > 
> > By moving this logic into a new helper function, crb_trigger_tpm(),
> > the driver can now send any required control bit across all supported
> > platforms. This prepares the driver for the upcoming chunking support.
> > 
> > No functional change is intended.
> > 
> > Signed-off-by: Arun Menon <armenon@redhat.com>
> > ---
> >  drivers/char/tpm/tpm_crb.c | 50 ++++++++++++++++++++------------------
> >  1 file changed, 27 insertions(+), 23 deletions(-)
> > 
> > diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
> > index 67c0061d4cab7..922bcf7a69ad5 100644
> > --- a/drivers/char/tpm/tpm_crb.c
> > +++ b/drivers/char/tpm/tpm_crb.c
> > @@ -445,6 +445,32 @@ static int tpm_crb_smc_start(struct device *dev, unsigned long func_id)
> >  }
> >  #endif
> >  
> > +static int crb_trigger_tpm(struct tpm_chip *chip, u32 start_cmd)
> 
> tpm_crb_start?

Yes, it can be renamed. On the qemu side also, its renamed and made
consistent with the spec.

> 
> I'd also split this into two commits:
> 
> 1. One that splits the helper.
> 2. Second that adds the new stuff.

Yes. Will do. Thank you.

> 
> > +{
> > +	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> > +	int rc = 0;
> > +	/* The reason for the extra quirk is that the PTT in 4th Gen Core CPUs
> > +	 * report only ACPI start but in practice seems to require both
> > +	 * CRB start, hence invoking CRB start method if hid == MSFT0101.
> > +	 */
> > +	if (priv->sm == ACPI_TPM2_COMMAND_BUFFER ||
> > +	    priv->sm == ACPI_TPM2_MEMORY_MAPPED ||
> > +	    !strcmp(priv->hid, "MSFT0101"))
> > +		iowrite32(start_cmd, &priv->regs_t->ctrl_start);
> > +	if (priv->sm == ACPI_TPM2_START_METHOD ||
> > +	    priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD)
> > +		rc = crb_do_acpi_start(chip);
> > +	if (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) {
> > +		iowrite32(start_cmd, &priv->regs_t->ctrl_start);
> > +		rc = tpm_crb_smc_start(&chip->dev, priv->smc_func_id);
> > +	}
> > +	if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) {
> > +		iowrite32(start_cmd, &priv->regs_t->ctrl_start);
> > +		rc = tpm_crb_ffa_start(CRB_FFA_START_TYPE_COMMAND, chip->locality);
> > +	}
> > +	return rc;
> > +}
> > +
> >  static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
> >  {
> >  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> > @@ -470,29 +496,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
> >  	/* Make sure that cmd is populated before issuing start. */
> >  	wmb();
> >  
> > -	/* The reason for the extra quirk is that the PTT in 4th Gen Core CPUs
> > -	 * report only ACPI start but in practice seems to require both
> > -	 * CRB start, hence invoking CRB start method if hid == MSFT0101.
> > -	 */
> > -	if (priv->sm == ACPI_TPM2_COMMAND_BUFFER ||
> > -	    priv->sm == ACPI_TPM2_MEMORY_MAPPED ||
> > -	    !strcmp(priv->hid, "MSFT0101"))
> > -		iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start);
> > -
> > -	if (priv->sm == ACPI_TPM2_START_METHOD ||
> > -	    priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD)
> > -		rc = crb_do_acpi_start(chip);
> > -
> > -	if (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) {
> > -		iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start);
> > -		rc = tpm_crb_smc_start(&chip->dev, priv->smc_func_id);
> > -	}
> > -
> > -	if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) {
> > -		iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start);
> > -		rc = tpm_crb_ffa_start(CRB_FFA_START_TYPE_COMMAND, chip->locality);
> > -	}
> > -
> > +	rc = crb_trigger_tpm(chip, CRB_START_INVOKE);
> >  	if (rc)
> >  		return rc;
> >  
> > -- 
> > 2.53.0
> > 
> 
> BR, Jarkko
> 

Regards,
Arun Menon


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC v2 4/5] tpm: Increase TPM_BUFSIZE to 8kB for chunking support
  2026-05-09 14:54   ` Jarkko Sakkinen
  2026-05-09 15:07     ` Jarkko Sakkinen
@ 2026-05-13 11:09     ` Arun Menon
  1 sibling, 0 replies; 15+ messages in thread
From: Arun Menon @ 2026-05-13 11:09 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: linux-kernel, linux-integrity, Peter Huewe, Jason Gunthorpe

On Sat, May 09, 2026 at 05:54:21PM +0300, Jarkko Sakkinen wrote:
> On Tue, Mar 24, 2026 at 11:42:43PM +0530, Arun Menon wrote:
> > The size of the command is checked against TPM_BUFSIZE early on before
> > even sending it to the backend. We therefore need to increase the
> > TPM_BUFSIZE to allow support for larger commands.
> > 
> > For now, 8KB seems sufficient for ML-KEM and ML-DSA algorithms and it is
> > also order-1 safe.
> > 
> > Signed-off-by: Arun Menon <armenon@redhat.com>
> > ---
> >  drivers/char/tpm/tpm.h | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> > index 87d68ddf270a7..26c3765fbd732 100644
> > --- a/drivers/char/tpm/tpm.h
> > +++ b/drivers/char/tpm/tpm.h
> > @@ -33,7 +33,7 @@
> >  #endif
> >  
> >  #define TPM_MINOR		224	/* officially assigned */
> > -#define TPM_BUFSIZE		4096
> > +#define TPM_BUFSIZE		8192
> >  #define TPM_NUM_DEVICES		65536
> >  #define TPM_RETRY		50
> >  
> > -- 
> > 2.53.0
> > 
> 
> Shouldn't this prepend previous patch?

yes, I am going to put this and the i2c patch before the chunking logic.
Thanks.

> 
> BR, Jarkko
> 

Regards,
Arun Menon


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-05-13 11:09 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-24 18:12 [RFC v2 0/5] tpm_crb: Add command and response buffer chunking support Arun Menon
2026-03-24 18:12 ` [RFC v2 1/5] tpm_crb: Add register definitions of TPM CRB chunking fields Arun Menon
2026-05-09 14:41   ` Jarkko Sakkinen
2026-03-24 18:12 ` [RFC v2 2/5] tpm_crb: Add new wrapper function to invoke start method Arun Menon
2026-05-09 14:43   ` Jarkko Sakkinen
2026-05-13 11:08     ` Arun Menon
2026-03-24 18:12 ` [RFC v2 3/5] tpm_crb: Implement command and response chunking logic Arun Menon
2026-05-09 14:53   ` Jarkko Sakkinen
2026-05-13 11:07     ` Arun Menon
2026-03-24 18:12 ` [RFC v2 4/5] tpm: Increase TPM_BUFSIZE to 8kB for chunking support Arun Menon
2026-05-09 14:54   ` Jarkko Sakkinen
2026-05-09 15:07     ` Jarkko Sakkinen
2026-05-13 11:06       ` Arun Menon
2026-05-13 11:09     ` Arun Menon
2026-03-24 18:12 ` [RFC v2 5/5] tpm: tis_i2c: Use local 4KB buffer to limit memory usage Arun Menon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox