Linux EFI development
 help / color / mirror / Atom feed
From: Ross Philipson <ross.philipson@gmail.com>
To: linux-kernel@vger.kernel.org, x86@kernel.org,
	linux-integrity@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-crypto@vger.kernel.org, kexec@lists.infradead.org,
	linux-efi@vger.kernel.org, iommu@lists.linux.dev
Cc: ross.philipson@gmail.com, dpsmith@apertussolutions.com,
	tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
	hpa@zytor.com, dave.hansen@linux.intel.com, ardb@kernel.org,
	mjg59@srcf.ucam.org, James.Bottomley@hansenpartnership.com,
	peterhuewe@gmx.de, jarkko@kernel.org, jgg@ziepe.ca,
	luto@amacapital.net, nivedita@alum.mit.edu,
	herbert@gondor.apana.org.au, davem@davemloft.net, corbet@lwn.net,
	ebiederm@xmission.com, dwmw2@infradead.org,
	baolu.lu@linux.intel.com, kanth.ghatraju@oracle.com,
	daniel.kiper@oracle.com, andrew.cooper3@citrix.com,
	trenchboot-devel@googlegroups.com
Subject: [PATCH v16 29/38] x86/tpm: Early startup TPM PCR extending driver
Date: Fri, 15 May 2026 14:14:01 -0700	[thread overview]
Message-ID: <20260515211410.31440-30-ross.philipson@gmail.com> (raw)
In-Reply-To: <20260515211410.31440-1-ross.philipson@gmail.com>

Introduce a driver that can interact minimally with the TPM. This
allows the Secure Launch startup code to extend measurement values
into the TPM's DRTM PCR banks early in the launch process.

The driver implementation only currently supports basic initialization
and PCR extend commands. An extend command can be sent to both TPM 2.0 or
1.2 chip but only the TIS/FIFO interface is currently supported. The TCG
specs for these interface can be found here:

https://trustedcomputinggroup.org/resource/pc-client-work-group-pc-client-specific-tpm-interface-specification-tis/
https://trustedcomputinggroup.org/resource/tpm-2-0-mobile-command-response-buffer-interface-specification/

Note this TPM driver implementation relies as much as possible on
existing mainline kernel TPM code.

Co-developed-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Co-developed-by: Alec Brown <alec.r.brown@oracle.com>
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Signed-off-by: Ross Philipson <ross.philipson@gmail.com>
---
 arch/x86/boot/startup/Makefile  |   1 +
 arch/x86/boot/startup/exports.h |   7 +
 arch/x86/boot/startup/tpm.h     |  47 +++
 arch/x86/boot/startup/tpm_drv.c | 567 ++++++++++++++++++++++++++++++++
 4 files changed, 622 insertions(+)
 create mode 100644 arch/x86/boot/startup/tpm.h
 create mode 100644 arch/x86/boot/startup/tpm_drv.c

diff --git a/arch/x86/boot/startup/Makefile b/arch/x86/boot/startup/Makefile
index 527cba7e4560..ecf86ce5ebf7 100644
--- a/arch/x86/boot/startup/Makefile
+++ b/arch/x86/boot/startup/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= sme.o sev-startup.o
 slaunch-objs			+= lib-sha1.o
 slaunch-objs			+= lib-sha256.o
 slaunch-objs			+= lib-sha512.o
+slaunch-objs			+= tpm_drv.o
 obj-$(CONFIG_SECURE_LAUNCH)	+= $(slaunch-objs)
 
 pi-objs				:= $(patsubst %.o,$(obj)/%.o,$(obj-y))
diff --git a/arch/x86/boot/startup/exports.h b/arch/x86/boot/startup/exports.h
index 01d2363dc445..4b82ddbd62a8 100644
--- a/arch/x86/boot/startup/exports.h
+++ b/arch/x86/boot/startup/exports.h
@@ -12,3 +12,10 @@ PROVIDE(snp_cpuid			= __pi_snp_cpuid);
 PROVIDE(snp_cpuid_get_table		= __pi_snp_cpuid_get_table);
 PROVIDE(svsm_issue_call			= __pi_svsm_issue_call);
 PROVIDE(svsm_process_result_codes	= __pi_svsm_process_result_codes);
+
+#ifdef CONFIG_SECURE_LAUNCH
+__pi_bcmp				= bcmp;
+__pi_memcmp				= memcmp;
+__pi_strlen				= strlen;
+__pi___WARN_trap			= __WARN_trap;
+#endif
diff --git a/arch/x86/boot/startup/tpm.h b/arch/x86/boot/startup/tpm.h
new file mode 100644
index 000000000000..1a11396b68c6
--- /dev/null
+++ b/arch/x86/boot/startup/tpm.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * TPM early extend header file.
+ *
+ * Copyright (c) 2026 Apertus Solutions, LLC
+ * Copyright (c) 2026, Oracle and/or its affiliates.
+ */
+
+#ifndef BOOT_COMPRESSED_TPM_H
+#define BOOT_COMPRESSED_TPM_H
+
+enum early_tis_defaults {
+	TPM_TIMEOUT		= 5, /* ms */
+	TIS_DURATION		= 120000, /* 120 secs in ms */
+};
+
+enum tpm_family {
+	TPM_FAMILY_INVALID	= 0,
+	TPM_FAMILY_12		= 1,
+	TPM_FAMILY_20		= 2
+};
+
+struct tpm_chip {
+	enum tpm_family family;
+	u64 baseaddr;
+	int locality;
+	int did;
+	int vid;
+
+	/* in ms */
+	ktime_t timeout_a;
+	ktime_t timeout_b;
+	ktime_t timeout_c;
+	ktime_t timeout_d;
+};
+
+bool tpm_tis_check_locality(struct tpm_chip *chip, int loc);
+void tpm_tis_release_locality(struct tpm_chip *chip);
+int tpm_tis_request_locality(struct tpm_chip *chip, int loc);
+void tpm_tis_disable_interrupts(struct tpm_chip *chip);
+int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash);
+int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
+		    struct tpm_digest *digests, u32 digest_count);
+int early_tpm_init(struct tpm_chip *chip, u64 baseaddr);
+int early_tpm_fini(struct tpm_chip *chip);
+
+#endif /* BOOT_COMPRESSED_TPM_H */
diff --git a/arch/x86/boot/startup/tpm_drv.c b/arch/x86/boot/startup/tpm_drv.c
new file mode 100644
index 000000000000..99971b06f768
--- /dev/null
+++ b/arch/x86/boot/startup/tpm_drv.c
@@ -0,0 +1,567 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Based of the original tpm_tis.c implementation as found in the
+ * Linux 2.6 code base.
+ *
+ * Copyright (C) 2005, 2006 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@watson.ibm.com>
+ * Kylene Hall <kjhall@us.ibm.com>
+ */
+
+#include <crypto/sha2.h>
+#include <asm/io.h>
+
+#include <linux/tpm_command.h>
+#include <linux/tpm_ptp.h>
+#include <linux/tpm_buf.h>
+
+#include "tpm.h"
+
+static u8 tpm_buf_page[PAGE_SIZE];
+
+/*
+ * Single threaded environment only running on BSP. Use a single shared
+ * page for all TPM extend operations.
+ */
+static inline struct tpm_buf *tpm_buf_alloc_page(void)
+{
+	memset(tpm_buf_page, 0, PAGE_SIZE);
+	return (struct tpm_buf *)tpm_buf_page;
+}
+
+static inline void tpm_buf_free_page(void)
+{
+	memset(tpm_buf_page, 0, PAGE_SIZE);
+}
+
+/* Pull in TPM buffer management support */
+#include "../../../../drivers/char/tpm/tpm-buf.c"
+
+static u32 __init tpm_get_alg_size(u16 alg_id)
+{
+	switch (alg_id) {
+	case TPM_ALG_SHA1:
+		return TPM_DIGEST_SIZE;
+	case TPM_ALG_SHA256:
+	case TPM_ALG_SM3_256:
+		return SHA256_DIGEST_SIZE;
+	case TPM_ALG_SHA384:
+		return SHA384_DIGEST_SIZE;
+	case TPM_ALG_SHA512:
+	default:
+		return SHA512_DIGEST_SIZE;
+	};
+}
+
+static inline u8 tpm_read8(struct tpm_chip *chip, u32 field)
+{
+	return readb((void *)(chip->baseaddr | field));
+}
+
+static inline void tpm_write8(struct tpm_chip *chip, u32 field, u8 val)
+{
+	writeb(val, (void *)(chip->baseaddr | field));
+}
+
+static inline u32 tpm_read32(struct tpm_chip *chip, u32 field)
+{
+	return readl((void *)(chip->baseaddr | field));
+}
+
+static inline void tpm_write32(struct tpm_chip *chip, u32 field, u32 val)
+{
+	writel(val, (void *)(chip->baseaddr | field));
+}
+
+/*
+ * In the setup kernel environment, it is far too early to calibrate time.
+ * Assume a 5GHz processor (the upper end of the Fam19h range), allowing
+ * reasonable timeouts on slower systems.
+ */
+static unsigned long ticks_per_ms = (5UL * 1000 * 1000 /* CPU in KHz */);
+
+static inline ktime_t tpm_now_ms(void)
+{
+	return rdtsc()/ticks_per_ms;
+}
+
+static inline void tpm_mdelay(unsigned int msecs)
+{
+	unsigned long ticks = msecs * ticks_per_ms;
+	unsigned long s, e;
+
+	s = rdtsc();
+	do {
+		cpu_relax();
+		e = rdtsc();
+	} while ((e - s) < ticks);
+}
+
+static inline u8 __tis_status(struct tpm_chip *chip)
+{
+	return tpm_read8(chip, TPM_STS(chip->locality));
+}
+
+static inline void __tis_cancel(struct tpm_chip *chip)
+{
+	/* This causes the current command to be aborted */
+	tpm_write8(chip, TPM_STS(chip->locality), TPM_STS_COMMAND_READY);
+}
+
+static int __init __tis_get_burstcount(struct tpm_chip *chip)
+{
+	ktime_t stop;
+	int burstcnt;
+
+	stop = tpm_now_ms() + chip->timeout_d;
+	do {
+		burstcnt = tpm_read8(chip, (TPM_STS(chip->locality) + 1));
+		burstcnt += tpm_read8(chip, TPM_STS(chip->locality) + 2) << 8;
+
+		if (burstcnt)
+			return burstcnt;
+
+		tpm_mdelay(TPM_TIMEOUT);
+	} while (tpm_now_ms() < stop);
+
+	return -EBUSY;
+}
+
+static int __init __tis_wait_for_stat(struct tpm_chip *chip, u8 mask, ktime_t timeout)
+{
+	ktime_t stop;
+	u8 status;
+
+	if ((__tis_status(chip) & mask) == mask)
+		return 0;
+
+	stop = tpm_now_ms() + timeout;
+	do {
+		tpm_mdelay(TPM_TIMEOUT);
+
+		status = __tis_status(chip);
+		if ((status & mask) == mask)
+			return 0;
+	} while (tpm_now_ms() < stop);
+
+	return -ETIME;
+}
+
+static int __init __tis_recv_data(struct tpm_chip *chip, u8 *buf, int count)
+{
+	int size = 0;
+	int burstcnt;
+
+	while (size < count &&
+	       __tis_wait_for_stat(chip,
+				   TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+				   chip->timeout_c) == 0) {
+		burstcnt = __tis_get_burstcount(chip);
+
+		for ( ; burstcnt > 0 && size < count; --burstcnt)
+			buf[size++] = tpm_read8(chip, TPM_DATA_FIFO(chip->locality));
+	}
+
+	return size;
+}
+
+/**
+ * tpm_tis_check_locality - Check if the given locality is the active one
+ * @chip:	The TPM chip instance
+ * @loc:	The locality to check
+ *
+ * Return: true - locality active, false - not active
+ */
+bool __init tpm_tis_check_locality(struct tpm_chip *chip, int loc)
+{
+	u8 res = tpm_read8(chip, TPM_ACCESS(loc));
+
+	if ((res & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
+		   (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
+		chip->locality = loc;
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * tpm_tis_release_locality - Release the active locality
+ * @chip:	The TPM chip instance
+ */
+void __init tpm_tis_release_locality(struct tpm_chip *chip)
+{
+	u8 res = tpm_read8(chip, TPM_ACCESS(chip->locality));
+
+	if ((res & (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
+		   (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
+		tpm_write8(chip, TPM_ACCESS(chip->locality), TPM_ACCESS_RELINQUISH_LOCALITY);
+
+	chip->locality = 0;
+}
+
+/**
+ * tpm_tis_request_locality - Request to make the given locality the active one
+ * @chip:	The TPM chip instance
+ * @loc:	The locality to make active/set as current
+ *
+ * Return:
+ *  >= 0 - Success, new active locality returned or locality already active
+ *  < 0  - Error occurred
+ */
+int __init tpm_tis_request_locality(struct tpm_chip *chip, int loc)
+{
+	ktime_t stop;
+
+	if (tpm_tis_check_locality(chip, loc))
+		return loc;
+
+	/* Set the new locality */
+	tpm_write8(chip, TPM_ACCESS(loc), TPM_ACCESS_REQUEST_USE);
+
+	stop = tpm_now_ms() + chip->timeout_b;
+	do {
+		if (tpm_tis_check_locality(chip, loc))
+			return loc;
+
+		tpm_mdelay(TPM_TIMEOUT);
+	} while (tpm_now_ms() < stop);
+
+	return -1;
+}
+
+/**
+ * tpm_tis_disable_interrupts - Disable interrupts for the TPM, use polling mode only
+ * @chip:	The TPM chip instance
+ */
+void __init tpm_tis_disable_interrupts(struct tpm_chip *chip)
+{
+	u32 intmask;
+
+	intmask = tpm_read32(chip, TPM_INT_ENABLE(chip->locality));
+	/* Disable everything to make sure it is in a consistent state */
+	intmask &= ~(TPM_GLOBAL_INT_ENABLE | TPM_INTF_CMD_READY_INT |
+		     TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
+		     TPM_INTF_DATA_AVAIL_INT);
+	tpm_write32(chip, TPM_INT_ENABLE(chip->locality), intmask);
+}
+
+/**
+ * tpm_tis_recv - Receive response data from TPM via TIS FIFO
+ * @chip:	The TPM chip instance
+ * @buf:	The response buffer
+ * @count:	Length of the response buffer
+ *
+ * Return:
+ *  = 0 - Success, no response data
+ *  > 0 - Success, value is the response data length
+ *  < 0 - Error occurred
+ */
+static int __init tpm_tis_recv(struct tpm_chip *chip, u8 *buf, int count)
+{
+	int expected, status, size = 0, rc = -EIO;
+
+	if (count < TPM_HEADER_SIZE)
+		goto out;
+
+	/* Read first 10 bytes, including tag, paramsize, and result */
+	size = __tis_recv_data(chip, buf, TPM_HEADER_SIZE);
+	if (size < TPM_HEADER_SIZE)
+		goto out;
+
+	expected = be32_to_cpu(*((u32 *)(buf + 2)));
+	if (expected > count)
+		goto out;
+
+	size += __tis_recv_data(chip, &buf[TPM_HEADER_SIZE], expected - TPM_HEADER_SIZE);
+	if (size < expected) {
+		rc = -ETIME;
+		goto out;
+	}
+
+	__tis_wait_for_stat(chip, TPM_STS_VALID, chip->timeout_c);
+
+	status = __tis_status(chip);
+	if (status & TPM_STS_DATA_AVAIL) {
+		rc = -EIO;
+		goto out;
+	}
+
+	/* Done with receive, move to Command Ready state */
+	__tis_cancel(chip);
+
+	return size;
+out:
+	__tis_cancel(chip);
+	tpm_tis_release_locality(chip);
+	return rc;
+}
+
+/**
+ * tpm_tis_send - Send command to TPM via TIS FIFO
+ * @chip:	The TPM chip instance
+ * @buf:	The command buffer
+ * @len:	Length of the command buffer to send
+ *
+ * Return:
+ *  = len - Success, all data sent
+ *  < 0	  - Error occurred
+ */
+static int __init tpm_tis_send(struct tpm_chip *chip, u8 *buf, int len)
+{
+	int status, burstcnt = 0;
+	int count = 0;
+	int rc = 0;
+
+	status = __tis_status(chip);
+	if ((status & TPM_STS_COMMAND_READY) == 0) {
+		__tis_cancel(chip);
+		if (__tis_wait_for_stat(chip, TPM_STS_COMMAND_READY, chip->timeout_b) < 0) {
+			rc = -ETIME;
+			goto out_err;
+		}
+	}
+
+	while (count < len - 1) {
+		burstcnt = __tis_get_burstcount(chip);
+		for ( ; burstcnt > 0 && count < len - 1; --burstcnt)
+			tpm_write8(chip, TPM_DATA_FIFO(chip->locality), buf[count++]);
+
+		__tis_wait_for_stat(chip, TPM_STS_VALID, chip->timeout_c);
+		status = __tis_status(chip);
+		if ((status & TPM_STS_DATA_EXPECT) == 0) {
+			rc = -EIO;
+			goto out_err;
+		}
+	}
+
+	/* Write last byte */
+	tpm_write8(chip, TPM_DATA_FIFO(chip->locality), buf[count]);
+	__tis_wait_for_stat(chip, TPM_STS_VALID, chip->timeout_c);
+	status = __tis_status(chip);
+	if ((status & TPM_STS_DATA_EXPECT) != 0) {
+		rc = -EIO;
+		goto out_err;
+	}
+
+	/* Go and do it */
+	tpm_write8(chip, TPM_STS(chip->locality), TPM_STS_GO);
+
+	return len;
+
+out_err:
+	__tis_cancel(chip);
+	tpm_tis_release_locality(chip);
+	return rc;
+}
+
+/**
+ * tpm_tis_transmit - Transmit a TPM FIFO command
+ * @chip:	The TPM chip instance
+ * @buf:	The request and response buffer object
+ * @bufsize:	Entire size available in buffer
+ *
+ * Return:
+ *  = 0 - Success, no returned data
+ *  > 0 - Success, value is the return data length
+ *  < 0 - Error occurred
+ */
+static int __init tpm_tis_transmit(struct tpm_chip *chip, u8 *buf, u32 bufsize)
+{
+	ktime_t stop;
+	u32 count;
+	u8 status;
+	int rc;
+
+	count = be32_to_cpu(*((u32 *) (buf + 2)));
+	if (count == 0)
+		return -ENODATA;
+
+	if (count > bufsize)
+		return -E2BIG;
+
+	rc = tpm_tis_send(chip, buf, count);
+	if (rc < 0)
+		goto out;
+
+	stop = tpm_now_ms() + TIS_DURATION;
+	do {
+		status = __tis_status(chip);
+		if ((status & (TPM_STS_DATA_AVAIL | TPM_STS_VALID)) ==
+			      (TPM_STS_DATA_AVAIL | TPM_STS_VALID))
+			goto out_recv;
+
+		if (status == TPM_STS_COMMAND_READY) {
+			rc = -ECANCELED;
+			goto out;
+		}
+
+		tpm_mdelay(TPM_TIMEOUT);
+		rmb();
+	} while (tpm_now_ms() < stop);
+
+	/* Cancel the command */
+	__tis_cancel(chip);
+	rc = -ETIME;
+	goto out;
+
+out_recv:
+	rc = tpm_tis_recv(chip, buf, bufsize);
+	if (rc >= 0) {
+		if (rc > 0 && rc < TPM_HEADER_SIZE)
+			return -EFAULT;
+		return rc;
+	}
+	/* Else return was an error, nothing to receive */
+
+out:
+	return rc;
+}
+
+/**
+ * tpm_find_interface_and_family - interface FIFO/CRB, family 2.0 or 1.2
+ * @chip:	The TPM chip instance
+ *
+ * Return: TPM family ID enum
+ */
+static enum tpm_family __init tpm_find_interface_and_family(struct tpm_chip *chip)
+{
+	struct tpm_intf_capability intf_cap;
+	struct tpm_interface_id intf_id;
+
+	/* Sort out whether it is 1.x */
+	intf_cap.val = tpm_read32(chip, TPM_INTF_CAPS(0));
+	if ((intf_cap.interface_version == TPM_TIS_INTF_12) ||
+	    (intf_cap.interface_version == TPM_TIS_INTF_13))
+		return TPM_FAMILY_12; /* Always TIS */
+
+	/* Assume that it is 2.0 but check if the interface is CRB */
+	intf_id.val = tpm_read32(chip, TPM_INTF_ID(0));
+	if (intf_id.interface_type == TPM_CRB_INTF_ACTIVE)
+		return TPM_FAMILY_INVALID;
+
+	/* Else TPM 2.0 with TIS interface */
+	return TPM_FAMILY_20;
+}
+
+/**
+ * tpm1_pcr_extend - send a TPM1 extend command to the device
+ * @chip:	a TPM chip to use
+ * @pcr_idx:	the PCR index to extend for the current locality
+ * @hash:	the SHA1 hash digest to extend
+ *
+ * Return:
+ * * 0		- OK
+ * * -errno	- A system error
+ * * TPM_RC	- A TPM error
+ */
+int __init tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash)
+{
+	struct tpm_buf *buf = tpm_buf_alloc_page();
+	int rc = 0;
+
+	tpm_buf_init(buf, TPM_BUFSIZE);
+	tpm_buf_reset(buf, TPM_TAG_RQU_COMMAND, TPM_ORD_PCR_EXTEND);
+
+	tpm_buf_append_u32(buf, pcr_idx);
+	tpm_buf_append(buf, hash, TPM_DIGEST_SIZE);
+
+	rc = tpm_tis_transmit(chip, buf->data, PAGE_SIZE);
+
+	/* Ignoring output */
+	if (rc > 0)
+		rc = 0;
+
+	tpm_buf_free_page();
+
+	return rc;
+}
+
+/**
+ * tpm2_pcr_extend() - send a TPM2 extend command to the device
+ *
+ * @chip:		TPM chip to use.
+ * @pcr_idx:		index of the PCR.
+ * @digests:		list of PCR banks and corresponding digest values to extend.
+ * @digest_count:	count of digests to extend
+ *
+ * Return:
+ * * 0		- OK
+ * * -errno	- A system error
+ * * TPM_RC	- A TPM error
+ */
+int __init tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
+			   struct tpm_digest *digests, u32 digest_count)
+{
+	struct tpm_buf *buf = tpm_buf_alloc_page();
+	int rc = 0, i;
+
+	tpm_buf_init(buf, TPM_BUFSIZE);
+	tpm_buf_reset(buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
+
+	tpm_buf_append_u32(buf, pcr_idx);
+
+	/* Setup a NULL auth session for the command */
+	tpm_buf_append_u32(buf, 9);
+	/* auth handle */
+	tpm_buf_append_u32(buf, TPM2_RS_PW);
+	/* nonce */
+	tpm_buf_append_u16(buf, 0);
+	/* attributes */
+	tpm_buf_append_u8(buf, 0);
+	/* passphrase */
+	tpm_buf_append_u16(buf, 0);
+
+	tpm_buf_append_u32(buf, digest_count);
+
+	for (i = 0; i < digest_count; i++) {
+		tpm_buf_append_u16(buf, digests[i].alg_id);
+		tpm_buf_append(buf, (const unsigned char *)&digests[i].digest,
+			       tpm_get_alg_size(digests[i].alg_id));
+	}
+
+	rc = tpm_tis_transmit(chip, buf->data, PAGE_SIZE);
+
+	/* Ignoring output */
+	if (rc > 0)
+		rc = 0;
+
+	tpm_buf_free_page();
+
+	return rc;
+}
+
+int __init early_tpm_init(struct tpm_chip *chip, u64 baseaddr)
+{
+	u32 didvid;
+
+	memset(chip, 0, sizeof(*chip));
+	chip->baseaddr = baseaddr;
+
+	chip->family = tpm_find_interface_and_family(chip);
+	if (chip->family == TPM_FAMILY_INVALID)
+		return TPM_ERR_INVALID_FAMILY;
+
+	/* Set default timeouts */
+	chip->timeout_a = TIS_SHORT_TIMEOUT;
+	chip->timeout_b = TIS_LONG_TIMEOUT;
+	chip->timeout_c = TIS_SHORT_TIMEOUT;
+	chip->timeout_d = TIS_SHORT_TIMEOUT;
+
+	/* Get the vendor and device ids */
+	didvid = tpm_read32(chip, TPM_DID_VID(0));
+	chip->did = didvid >> 16;
+	chip->vid = didvid & 0xFFFF;
+
+	return TPM_SUCCESS;
+}
+
+int __init early_tpm_fini(struct tpm_chip *chip)
+{
+	tpm_tis_release_locality(chip);
+	memset(chip, 0, sizeof(*chip));
+
+	return TPM_SUCCESS;
+}
-- 
2.47.3


  parent reply	other threads:[~2026-05-15 21:15 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-15 21:13 [PATCH v16 00/38] x86: Secure Launch support for Intel TXT Ross Philipson
2026-05-15 21:13 ` [PATCH v16 01/38] tpm: Initial step to reorganize TPM public headers Ross Philipson
2026-05-15 23:03   ` Jarkko Sakkinen
2026-05-15 23:05     ` Jason Gunthorpe
2026-05-15 23:10       ` Dave Hansen
2026-05-15 23:51       ` Jarkko Sakkinen
2026-05-15 21:13 ` [PATCH v16 02/38] tpm: Move TPM1 specific definitions to the command header Ross Philipson
2026-05-15 23:14   ` Jarkko Sakkinen
2026-05-15 21:13 ` [PATCH v16 03/38] tpm: Move TPM2 " Ross Philipson
2026-05-15 23:15   ` Jarkko Sakkinen
2026-05-15 21:13 ` [PATCH v16 04/38] tpm: Move TPM common base " Ross Philipson
2026-05-15 23:22   ` Jarkko Sakkinen
2026-05-15 21:13 ` [PATCH v16 05/38] tpm: Move platform specific definitions to the new PTP header Ross Philipson
2026-05-15 21:13 ` [PATCH v16 06/38] tpm: Remove main TPM header from TPM event log header Ross Philipson
2026-05-15 21:13 ` [PATCH v16 07/38] tpm-buf: Merge TPM_BUF_BOUNDARY_ERROR and TPM_BUF_OVERFLOW Ross Philipson
2026-05-15 21:13 ` [PATCH v16 08/38] tpm-buf: Remove chip parameter from tpm_buf_append_handle() Ross Philipson
2026-05-15 21:13 ` [PATCH v16 09/38] tpm-buf: Implement managed allocations Ross Philipson
2026-05-15 21:13 ` [PATCH v16 10/38] tpm-buf: Add TPM buffer support header for standalone reuse Ross Philipson
2026-05-15 21:13 ` [PATCH v16 11/38] tpm/tpm_tis: Close all localities Ross Philipson
2026-05-15 21:13 ` [PATCH v16 12/38] tpm/tpm_tis: Address positive localities in tpm_tis_request_locality() Ross Philipson
2026-05-15 21:13 ` [PATCH v16 13/38] tpm/tpm_tis: Allow locality to be set to a different value Ross Philipson
2026-05-15 21:13 ` [PATCH v16 14/38] tpm/sysfs: Show locality used by kernel Ross Philipson
2026-05-15 21:13 ` [PATCH v16 15/38] Documentation/security: Secure Launch kernel documentation Ross Philipson
2026-05-15 22:02   ` Randy Dunlap
2026-05-15 21:13 ` [PATCH v16 16/38] x86: Secure Launch Kconfig Ross Philipson
2026-05-15 21:13 ` [PATCH v16 17/38] x86: Secure Launch Resource Table header file Ross Philipson
2026-05-15 21:13 ` [PATCH v16 18/38] x86/efi: Secure Launch Resource Table EFI definitions " Ross Philipson
2026-05-15 21:13 ` [PATCH v16 19/38] x86: Secure Launch main " Ross Philipson
2026-05-15 21:13 ` [PATCH v16 20/38] x86/txt: Intel Trusted eXecution Technology (TXT) definitions Ross Philipson
2026-05-15 21:13 ` [PATCH v16 21/38] lib/crypto: Add SHA1 support for pre-boot environments Ross Philipson
2026-05-15 21:13 ` [PATCH v16 22/38] lib/crypto: Add SHA512 " Ross Philipson
2026-05-15 21:13 ` [PATCH v16 23/38] x86: Allow WARN_trap() macro to be included in " Ross Philipson
2026-05-15 21:13 ` [PATCH v16 24/38] x86/msr: Add variable MTRR base/mask and x2apic ID registers Ross Philipson
2026-05-15 21:13 ` [PATCH v16 25/38] x86/boot: Slight refactor of the 5 level paging logic Ross Philipson
2026-05-15 21:13 ` [PATCH v16 26/38] x86: Add early SHA-1 support for Secure Launch early measurements Ross Philipson
2026-05-15 21:13 ` [PATCH v16 27/38] x86: Add early SHA-256 " Ross Philipson
2026-05-15 21:14 ` [PATCH v16 28/38] x86: Add early SHA-384/512 " Ross Philipson
2026-05-15 21:14 ` Ross Philipson [this message]
2026-05-15 22:32   ` [PATCH v16 29/38] x86/tpm: Early startup TPM PCR extending driver Dave Hansen
2026-05-15 21:14 ` [PATCH v16 30/38] x86/slaunch: Add MLE header and Secure Launch entrypoint to the core kernel Ross Philipson
2026-05-15 21:14 ` [PATCH v16 31/38] x86/slaunch: Secure Launch kernel early boot initialization Ross Philipson
2026-05-15 21:14 ` [PATCH v16 32/38] x86/slaunch: Secure Launch kernel late " Ross Philipson
2026-05-15 21:14 ` [PATCH v16 33/38] x86/slaunch: Secure Launch SMP bringup support Ross Philipson
2026-05-15 21:14 ` [PATCH v16 34/38] kexec/slaunch: Secure Launch kexec SEXIT support Ross Philipson
2026-05-15 21:14 ` [PATCH v16 35/38] reboot/slaunch: Secure Launch SEXIT support on reboot paths Ross Philipson
2026-05-15 21:14 ` [PATCH v16 36/38] x86/slaunch: Secure Launch late initcall platform module Ross Philipson
2026-05-15 21:14 ` [PATCH v16 37/38] x86/efistub: EFI stub DRTM support for Secure Launch Ross Philipson
2026-05-15 21:14 ` [PATCH v16 38/38] x86/boot: Legacy boot " Ross Philipson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260515211410.31440-30-ross.philipson@gmail.com \
    --to=ross.philipson@gmail.com \
    --cc=James.Bottomley@hansenpartnership.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=ardb@kernel.org \
    --cc=baolu.lu@linux.intel.com \
    --cc=bp@alien8.de \
    --cc=corbet@lwn.net \
    --cc=daniel.kiper@oracle.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=davem@davemloft.net \
    --cc=dpsmith@apertussolutions.com \
    --cc=dwmw2@infradead.org \
    --cc=ebiederm@xmission.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=hpa@zytor.com \
    --cc=iommu@lists.linux.dev \
    --cc=jarkko@kernel.org \
    --cc=jgg@ziepe.ca \
    --cc=kanth.ghatraju@oracle.com \
    --cc=kexec@lists.infradead.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=mingo@redhat.com \
    --cc=mjg59@srcf.ucam.org \
    --cc=nivedita@alum.mit.edu \
    --cc=peterhuewe@gmx.de \
    --cc=tglx@linutronix.de \
    --cc=trenchboot-devel@googlegroups.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox